obs-qsv11: Add HEVC

Co-authored-by: jpark37 <jpark37@users.noreply.github.com>
Co-authored-by: Jim <obs.jim@gmail.com>
This commit is contained in:
Yuriy Chumak
2022-11-22 07:29:31 -08:00
committed by Jim
co-authored by jpark37 Jim
parent 37a8835895
commit fceee90aa9
7 changed files with 283 additions and 12 deletions
+10
View File
@@ -363,3 +363,13 @@ enum qsv_cpu_platform qsv_get_cpu_platform()
//assume newer revisions are at least as capable as Haswell
return QSV_CPU_PLATFORM_INTEL;
}
int qsv_hevc_encoder_headers(qsv_t *pContext, uint8_t **pVPS, uint8_t **pSPS,
uint8_t **pPPS, uint16_t *pnVPS, uint16_t *pnSPS,
uint16_t *pnPPS)
{
QSV_Encoder_Internal *pEncoder = (QSV_Encoder_Internal *)pContext;
pEncoder->GetVpsSpsPps(pVPS, pSPS, pPPS, pnVPS, pnSPS, pnPPS);
return 0;
}
+7
View File
@@ -80,6 +80,7 @@ static const struct qsv_rate_control_info qsv_av1_ratecontrols[] =
static const char *const qsv_profile_names[] = {"high", "main", "baseline", 0};
static const char *const qsv_profile_names_av1[] = {"main", 0};
static const char *const qsv_profile_names_hevc[] = {"main", "main10", 0};
static const char *const qsv_usage_names[] = {"quality", "balanced", "speed",
"veryslow", "slower", "slow",
"medium", "fast", "faster",
@@ -92,11 +93,13 @@ struct adapter_info {
bool is_intel;
bool is_dgpu;
bool supports_av1;
bool supports_hevc;
};
enum qsv_codec {
QSV_CODEC_AVC,
QSV_CODEC_AV1,
QSV_CODEC_HEVC,
};
#define MAX_ADAPTERS 10
@@ -179,6 +182,10 @@ int qsv_encoder_headers(qsv_t *, uint8_t **pSPS, uint8_t **pPPS,
enum qsv_cpu_platform qsv_get_cpu_platform();
bool prefer_igpu_enc(int *iGPUIndex);
int qsv_hevc_encoder_headers(qsv_t *pContext, uint8_t **vVPS, uint8_t **pSPS,
uint8_t **pPPS, uint16_t *pnVPS, uint16_t *pnSPS,
uint16_t *pnPPS);
#ifdef __cplusplus
}
#endif
+57 -5
View File
@@ -180,7 +180,7 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec)
sts = m_pmfxENC->Init(&m_mfxEncParams);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
sts = GetVideoParam();
sts = GetVideoParam(codec);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
sts = InitBitstream();
@@ -201,9 +201,16 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
m_mfxEncParams.mfx.CodecId = MFX_CODEC_AVC;
else if (codec == QSV_CODEC_AV1)
m_mfxEncParams.mfx.CodecId = MFX_CODEC_AV1;
else if (codec == QSV_CODEC_HEVC)
m_mfxEncParams.mfx.CodecId = MFX_CODEC_HEVC;
m_mfxEncParams.mfx.GopOptFlag = MFX_GOP_STRICT;
m_mfxEncParams.mfx.NumSlice = 1;
if (codec == QSV_CODEC_HEVC) {
m_mfxEncParams.mfx.NumSlice = 0;
m_mfxEncParams.mfx.IdrInterval = 1;
} else {
m_mfxEncParams.mfx.NumSlice = 1;
}
m_mfxEncParams.mfx.TargetUsage = pParams->nTargetUsage;
m_mfxEncParams.mfx.CodecProfile = pParams->nCodecProfile;
m_mfxEncParams.mfx.FrameInfo.FrameRateExtN = pParams->nFpsNum;
@@ -227,6 +234,9 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
else
m_mfxEncParams.mfx.GopRefDist = pParams->nbFrames + 1;
if (codec == QSV_CODEC_HEVC)
m_mfxEncParams.mfx.LowPower = MFX_CODINGOPTION_OFF;
enum qsv_cpu_platform qsv_platform = qsv_get_cpu_platform();
if ((qsv_platform >= QSV_CPU_PLATFORM_ICL ||
qsv_platform == QSV_CPU_PLATFORM_UNKNOWN) &&
@@ -329,6 +339,19 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
m_mfxEncParams.NumExtParam = (mfxU16)iBuffers;
}
if (codec == QSV_CODEC_HEVC) {
if ((pParams->nWidth & 15) || (pParams->nHeight & 15)) {
memset(&m_ExtHEVCParam, 0, sizeof(m_ExtHEVCParam));
m_ExtHEVCParam.Header.BufferId = MFX_EXTBUFF_HEVC_PARAM;
m_ExtHEVCParam.Header.BufferSz = sizeof(m_ExtHEVCParam);
m_ExtHEVCParam.PicWidthInLumaSamples = pParams->nWidth;
m_ExtHEVCParam.PicHeightInLumaSamples =
pParams->nHeight;
extendedBuffers[iBuffers++] =
(mfxExtBuffer *)&m_ExtHEVCParam;
}
}
memset(&m_ExtVideoSignalInfo, 0, sizeof(m_ExtVideoSignalInfo));
m_ExtVideoSignalInfo.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
m_ExtVideoSignalInfo.Header.BufferSz = sizeof(m_ExtVideoSignalInfo);
@@ -502,7 +525,7 @@ mfxStatus QSV_Encoder_Internal::AllocateSurfaces()
return sts;
}
mfxStatus QSV_Encoder_Internal::GetVideoParam()
mfxStatus QSV_Encoder_Internal::GetVideoParam(enum qsv_codec codec)
{
memset(&m_parameter, 0, sizeof(m_parameter));
mfxExtCodingOptionSPSPPS opt;
@@ -511,18 +534,33 @@ mfxStatus QSV_Encoder_Internal::GetVideoParam()
opt.Header.BufferSz = sizeof(mfxExtCodingOptionSPSPPS);
static mfxExtBuffer *extendedBuffers[1];
extendedBuffers[0] = (mfxExtBuffer *)&opt;
m_parameter.ExtParam = extendedBuffers;
m_parameter.NumExtParam = 1;
opt.SPSBuffer = m_SPSBuffer;
opt.PPSBuffer = m_PPSBuffer;
opt.SPSBufSize = 1024; // m_nSPSBufferSize;
opt.PPSBufSize = 1024; // m_nPPSBufferSize;
mfxExtCodingOptionVPS opt_vps{};
if (codec == QSV_CODEC_HEVC) {
opt_vps.Header.BufferId = MFX_EXTBUFF_CODING_OPTION_VPS;
opt_vps.Header.BufferSz = sizeof(mfxExtCodingOptionVPS);
opt_vps.VPSBuffer = m_VPSBuffer;
opt_vps.VPSBufSize = 1024;
extendedBuffers[0] = (mfxExtBuffer *)&opt_vps;
extendedBuffers[1] = (mfxExtBuffer *)&opt;
m_parameter.NumExtParam = 2;
} else {
extendedBuffers[0] = (mfxExtBuffer *)&opt;
m_parameter.NumExtParam = 1;
}
mfxStatus sts = m_pmfxENC->GetVideoParam(&m_parameter);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
if (codec == QSV_CODEC_HEVC)
m_nVPSBufferSize = opt_vps.VPSBufSize;
m_nSPSBufferSize = opt.SPSBufSize;
m_nPPSBufferSize = opt.PPSBufSize;
@@ -538,6 +576,20 @@ void QSV_Encoder_Internal::GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf,
*pnPPSBuf = m_nPPSBufferSize;
}
void QSV_Encoder_Internal::GetVpsSpsPps(mfxU8 **pVPSBuf, mfxU8 **pSPSBuf,
mfxU8 **pPPSBuf, mfxU16 *pnVPSBuf,
mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf)
{
*pVPSBuf = m_VPSBuffer;
*pnVPSBuf = m_nVPSBufferSize;
*pSPSBuf = m_SPSBuffer;
*pnSPSBuf = m_nSPSBufferSize;
*pPPSBuf = m_PPSBuffer;
*pnPPSBuf = m_nPPSBufferSize;
}
mfxStatus QSV_Encoder_Internal::InitBitstream()
{
m_nTaskPool = m_parameter.AsyncDepth;
+6 -1
View File
@@ -67,6 +67,8 @@ public:
mfxStatus Open(qsv_param_t *pParams, enum qsv_codec codec);
void GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf, mfxU16 *pnSPSBuf,
mfxU16 *pnPPSBuf);
void GetVpsSpsPps(mfxU8 **pVPSBuf, mfxU8 **pSPSBuf, mfxU8 **pPPSBuf,
mfxU16 *pnVPSBuf, mfxU16 *pnSPSBuf, mfxU16 *pnPPSBuf);
mfxStatus Encode(uint64_t ts, uint8_t *pDataY, uint8_t *pDataUV,
uint32_t strideY, uint32_t strideUV,
mfxBitstream **pBS);
@@ -81,7 +83,7 @@ public:
protected:
mfxStatus InitParams(qsv_param_t *pParams, enum qsv_codec codec);
mfxStatus AllocateSurfaces();
mfxStatus GetVideoParam();
mfxStatus GetVideoParam(enum qsv_codec codec);
mfxStatus InitBitstream();
mfxStatus LoadNV12(mfxFrameSurface1 *pSurface, uint8_t *pDataY,
uint8_t *pDataUV, uint32_t strideY,
@@ -102,14 +104,17 @@ private:
mfxFrameSurface1 **m_pmfxSurfaces;
mfxU16 m_nSurfNum;
MFXVideoENCODE *m_pmfxENC;
mfxU8 m_VPSBuffer[1024];
mfxU8 m_SPSBuffer[1024];
mfxU8 m_PPSBuffer[1024];
mfxU16 m_nVPSBufferSize;
mfxU16 m_nSPSBufferSize;
mfxU16 m_nPPSBufferSize;
mfxVideoParam m_parameter;
mfxExtCodingOption3 m_co3;
mfxExtCodingOption2 m_co2;
mfxExtCodingOption m_co;
mfxExtHEVCParam m_ExtHEVCParam{};
mfxExtVideoSignalInfo m_ExtVideoSignalInfo{};
mfxExtChromaLocInfo m_ExtChromaLocInfo{};
mfxExtMasteringDisplayColourVolume m_ExtMasteringDisplayColourVolume{};
@@ -23,6 +23,7 @@ struct adapter_caps {
bool is_intel = false;
bool is_dgpu = false;
bool supports_av1 = false;
bool supports_hevc = false;
};
static std::map<uint32_t, adapter_caps> adapter_info;
@@ -72,6 +73,9 @@ static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
caps.is_intel = true;
caps.is_dgpu = dgpu;
caps.supports_av1 = has_encoder(impl, MFX_CODEC_AV1);
#if ENABLE_HEVC
caps.supports_hevc = has_encoder(impl, MFX_CODEC_HEVC);
#endif
return true;
}
@@ -80,7 +84,7 @@ DWORD WINAPI TimeoutThread(LPVOID param)
{
HANDLE hMainThread = (HANDLE)param;
DWORD ret = WaitForSingleObject(hMainThread, 5000);
DWORD ret = WaitForSingleObject(hMainThread, 8000);
if (ret == WAIT_TIMEOUT)
TerminateProcess(GetCurrentProcess(), STATUS_TIMEOUT);
@@ -121,6 +125,8 @@ try {
printf("is_dgpu=%s\n", caps.is_dgpu ? "true" : "false");
printf("supports_av1=%s\n",
caps.supports_av1 ? "true" : "false");
printf("supports_hevc=%s\n",
caps.supports_hevc ? "true" : "false");
}
return 0;
+12
View File
@@ -73,6 +73,8 @@ extern struct obs_encoder_info obs_qsv_encoder_tex;
extern struct obs_encoder_info obs_qsv_encoder_tex_v2;
extern struct obs_encoder_info obs_qsv_av1_encoder_tex;
extern struct obs_encoder_info obs_qsv_av1_encoder;
extern struct obs_encoder_info obs_qsv_hevc_encoder_tex;
extern struct obs_encoder_info obs_qsv_hevc_encoder;
extern bool av1_supported(mfxIMPL impl);
@@ -123,6 +125,7 @@ bool obs_module_load(void)
adapter_count = config_num_sections(config);
bool avc_supported = false;
bool av1_supported = false;
bool hevc_supported = false;
if (adapter_count > MAX_ADAPTERS)
adapter_count = MAX_ADAPTERS;
@@ -137,9 +140,12 @@ bool obs_module_load(void)
adapter->is_dgpu = config_get_bool(config, section, "is_dgpu");
adapter->supports_av1 =
config_get_bool(config, section, "supports_av1");
adapter->supports_hevc =
config_get_bool(config, section, "supports_hevc");
avc_supported |= adapter->is_intel;
av1_supported |= adapter->supports_av1;
hevc_supported |= adapter->supports_hevc;
}
if (avc_supported) {
@@ -152,6 +158,12 @@ bool obs_module_load(void)
obs_register_encoder(&obs_qsv_av1_encoder_tex);
obs_register_encoder(&obs_qsv_av1_encoder);
}
#if ENABLE_HEVC
if (hevc_supported) {
obs_register_encoder(&obs_qsv_hevc_encoder_tex);
obs_register_encoder(&obs_qsv_hevc_encoder);
}
#endif
fail:
config_close(config);
+184 -5
View File
@@ -59,6 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <util/darray.h>
#include <util/platform.h>
#include <obs-module.h>
#include <obs-hevc.h>
#include <obs-avc.h>
#include <d3d11.h>
#include <dxgi1_2.h>
@@ -127,6 +128,12 @@ static const char *obs_qsv_getname_av1(void *type_data)
return "QuickSync AV1";
}
static const char *obs_qsv_getname_hevc(void *type_data)
{
UNUSED_PARAMETER(type_data);
return "QuickSync HEVC";
}
static void obs_qsv_stop(void *data);
static void clear_data(struct obs_qsv *obsqsv)
@@ -198,6 +205,11 @@ static void obs_qsv_defaults_av1(obs_data_t *settings)
obs_qsv_defaults(settings, 2, QSV_CODEC_AV1);
}
static void obs_qsv_defaults_hevc(obs_data_t *settings)
{
obs_qsv_defaults(settings, 2, QSV_CODEC_HEVC);
}
static inline void add_strings(obs_property_t *list, const char *const *strings)
{
while (*strings) {
@@ -386,7 +398,8 @@ static obs_properties_t *obs_qsv_props(enum qsv_codec codec, void *unused,
prop = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
if (codec == QSV_CODEC_AVC)
if (codec == QSV_CODEC_AVC || codec == QSV_CODEC_HEVC)
add_rate_controls(prop, qsv_ratecontrols);
else if (codec == QSV_CODEC_AV1)
add_rate_controls(prop, qsv_av1_ratecontrols);
@@ -426,6 +439,8 @@ static obs_properties_t *obs_qsv_props(enum qsv_codec codec, void *unused,
add_strings(prop, qsv_profile_names);
else if (codec == QSV_CODEC_AV1)
add_strings(prop, qsv_profile_names_av1);
else if (codec == QSV_CODEC_HEVC)
add_strings(prop, qsv_profile_names_hevc);
obs_property_set_modified_callback(prop, profile_modified);
@@ -470,6 +485,12 @@ static obs_properties_t *obs_qsv_props_av1(void *unused)
return obs_qsv_props(QSV_CODEC_AV1, unused, 2);
}
static obs_properties_t *obs_qsv_props_hevc(void *unused)
{
UNUSED_PARAMETER(unused);
return obs_qsv_props(QSV_CODEC_HEVC, unused, 2);
}
static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings)
{
video_t *video = obs_encoder_video(obsqsv->encoder);
@@ -537,6 +558,20 @@ static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings)
else if (astrcmpi(profile, "high") == 0)
obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_HIGH;
} else if (obsqsv->codec == QSV_CODEC_HEVC) {
if (astrcmpi(profile, "main") == 0) {
obsqsv->params.nCodecProfile = MFX_PROFILE_HEVC_MAIN;
if (obs_p010_tex_active()) {
blog(LOG_WARNING,
"[qsv encoder] Forcing main10 for P010");
obsqsv->params.nCodecProfile =
MFX_PROFILE_HEVC_MAIN10;
}
} else if (astrcmpi(profile, "main10") == 0) {
obsqsv->params.nCodecProfile = MFX_PROFILE_HEVC_MAIN10;
}
} else if (obsqsv->codec == QSV_CODEC_AV1) {
obsqsv->params.nCodecProfile = MFX_PROFILE_AV1_MAIN;
}
@@ -733,6 +768,28 @@ static bool update_settings(struct obs_qsv *obsqsv, obs_data_t *settings)
return true;
}
static void load_hevc_headers(struct obs_qsv *obsqsv)
{
DARRAY(uint8_t) header;
DARRAY(uint8_t) sei;
da_init(header);
da_init(sei);
uint8_t *pVPS, *pSPS, *pPPS;
uint16_t nVPS, nSPS, nPPS;
qsv_hevc_encoder_headers(obsqsv->context, &pVPS, &pSPS, &pPPS, &nVPS,
&nSPS, &nPPS);
da_push_back_array(header, pVPS, nVPS);
da_push_back_array(header, pSPS, nSPS);
da_push_back_array(header, pPPS, nPPS);
obsqsv->extra_data = header.array;
obsqsv->extra_data_size = header.num;
obsqsv->sei = sei.array;
obsqsv->sei_size = sei.num;
}
static void load_headers(struct obs_qsv *obsqsv)
{
DARRAY(uint8_t) header;
@@ -819,6 +876,8 @@ static void *obs_qsv_create(enum qsv_codec codec, obs_data_t *settings,
if (obsqsv->context == NULL)
warn("qsv failed to load");
else if (obsqsv->codec == QSV_CODEC_HEVC)
load_hevc_headers(obsqsv);
else
load_headers(obsqsv);
} else {
@@ -873,6 +932,11 @@ static void *obs_qsv_create_av1(obs_data_t *settings, obs_encoder_t *encoder)
return obs_qsv_create(QSV_CODEC_AV1, settings, encoder);
}
static void *obs_qsv_create_hevc(obs_data_t *settings, obs_encoder_t *encoder)
{
return obs_qsv_create(QSV_CODEC_HEVC, settings, encoder);
}
static HANDLE get_lib(const char *lib)
{
HMODULE mod = GetModuleHandleA(lib);
@@ -909,7 +973,7 @@ static void *obs_qsv_create_tex(enum qsv_codec codec, obs_data_t *settings,
bool gpu_texture_active = obs_nv12_tex_active();
if (codec == QSV_CODEC_AV1)
if (codec != QSV_CODEC_AVC)
gpu_texture_active = gpu_texture_active ||
obs_p010_tex_active();
@@ -952,6 +1016,13 @@ static void *obs_qsv_create_tex_av1(obs_data_t *settings,
"obs_qsv11_av1_soft");
}
static void *obs_qsv_create_tex_hevc(obs_data_t *settings,
obs_encoder_t *encoder)
{
return obs_qsv_create_tex(QSV_CODEC_HEVC, settings, encoder,
"obs_qsv11_hevc_soft");
}
static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
{
struct obs_qsv *obsqsv = data;
@@ -1024,7 +1095,8 @@ static void obs_qsv_video_info(void *data, struct video_scale_info *info)
cap_resolution(obsqsv->encoder, info);
}
static void obs_qsv_av1_video_info(void *data, struct video_scale_info *info)
static void obs_qsv_video_plus_hdr_info(void *data,
struct video_scale_info *info)
{
struct obs_qsv *obsqsv = data;
enum video_format pref_format;
@@ -1204,6 +1276,77 @@ static void parse_packet_av1(struct obs_qsv *obsqsv,
g_bFirst = false;
}
static void parse_packet_hevc(struct obs_qsv *obsqsv,
struct encoder_packet *packet, mfxBitstream *pBS,
const struct video_output_info *voi,
bool *received_packet)
{
bool is_vcl_packet = false;
if (pBS == NULL || pBS->DataLength == 0) {
*received_packet = false;
return;
}
da_resize(obsqsv->packet_data, 0);
da_push_back_array(obsqsv->packet_data, &pBS->Data[pBS->DataOffset],
pBS->DataLength);
packet->data = obsqsv->packet_data.array;
packet->size = obsqsv->packet_data.num;
packet->type = OBS_ENCODER_VIDEO;
packet->pts = ts_mfx_to_obs((mfxI64)pBS->TimeStamp, voi);
packet->keyframe = (pBS->FrameType & MFX_FRAMETYPE_IDR);
uint16_t frameType = pBS->FrameType;
uint8_t priority = OBS_NAL_PRIORITY_DISPOSABLE;
if (frameType & MFX_FRAMETYPE_I)
priority = OBS_NAL_PRIORITY_HIGHEST;
else if ((frameType & MFX_FRAMETYPE_P) ||
(frameType & MFX_FRAMETYPE_REF))
priority = OBS_NAL_PRIORITY_HIGH;
packet->priority = priority;
/* ------------------------------------ */
//bool iFrame = pBS->FrameType & MFX_FRAMETYPE_I;
//bool bFrame = pBS->FrameType & MFX_FRAMETYPE_B;
bool pFrame = pBS->FrameType & MFX_FRAMETYPE_P;
// In case MSDK doesn't support automatic DecodeTimeStamp, do manual
// calculation
if (g_pts2dtsShift >= 0) {
if (g_bFirst) {
packet->dts = packet->pts - 3 * obsqsv->params.nFpsDen;
} else if (pFrame) {
packet->dts = packet->pts - 10 * obsqsv->params.nFpsDen;
g_prevDts = packet->dts;
} else {
packet->dts = g_prevDts + obsqsv->params.nFpsDen;
g_prevDts = packet->dts;
}
} else {
packet->dts = ts_mfx_to_obs(pBS->DecodeTimeStamp, voi);
}
#if 0
int iType = iFrame ? 0 : (bFrame ? 1 : (pFrame ? 2 : -1));
int64_t interval = obsqsv->params.nbFrames + 1;
info("parse packet:\n"
"\tFrameType: %d\n"
"\tpts: %d\n"
"\tdts: %d",
iType, packet->pts, packet->dts);
#endif
*received_packet = true;
pBS->DataLength = 0;
g_bFirst = false;
}
static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
struct encoder_packet *packet, bool *received_packet)
{
@@ -1244,6 +1387,8 @@ static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
parse_packet(obsqsv, packet, pBS, voi, received_packet);
else if (obsqsv->codec == QSV_CODEC_AV1)
parse_packet_av1(obsqsv, packet, pBS, voi, received_packet);
else if (obsqsv->codec == QSV_CODEC_HEVC)
parse_packet_hevc(obsqsv, packet, pBS, voi, received_packet);
ReleaseSRWLockExclusive(&g_QsvLock);
@@ -1290,6 +1435,8 @@ static bool obs_qsv_encode_tex(void *data, uint32_t handle, int64_t pts,
parse_packet(obsqsv, packet, pBS, voi, received_packet);
else if (obsqsv->codec == QSV_CODEC_AV1)
parse_packet_av1(obsqsv, packet, pBS, voi, received_packet);
else if (obsqsv->codec == QSV_CODEC_HEVC)
parse_packet_hevc(obsqsv, packet, pBS, voi, received_packet);
ReleaseSRWLockExclusive(&g_QsvLock);
@@ -1379,7 +1526,7 @@ struct obs_encoder_info obs_qsv_av1_encoder_tex = {
.get_properties = obs_qsv_props_av1,
.get_defaults = obs_qsv_defaults_av1,
.get_extra_data = obs_qsv_extra_data,
.get_video_info = obs_qsv_av1_video_info,
.get_video_info = obs_qsv_video_plus_hdr_info,
};
struct obs_encoder_info obs_qsv_av1_encoder = {
@@ -1394,6 +1541,38 @@ struct obs_encoder_info obs_qsv_av1_encoder = {
.get_properties = obs_qsv_props_av1,
.get_defaults = obs_qsv_defaults_av1,
.get_extra_data = obs_qsv_extra_data,
.get_video_info = obs_qsv_av1_video_info,
.get_video_info = obs_qsv_video_plus_hdr_info,
.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
};
struct obs_encoder_info obs_qsv_hevc_encoder_tex = {
.id = "obs_qsv11_hevc",
.type = OBS_ENCODER_VIDEO,
.codec = "hevc",
.get_name = obs_qsv_getname_hevc,
.create = obs_qsv_create_tex_hevc,
.destroy = obs_qsv_destroy,
.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
.encode_texture = obs_qsv_encode_tex,
.update = obs_qsv_update,
.get_properties = obs_qsv_props_hevc,
.get_defaults = obs_qsv_defaults_hevc,
.get_extra_data = obs_qsv_extra_data,
.get_video_info = obs_qsv_video_plus_hdr_info,
};
struct obs_encoder_info obs_qsv_hevc_encoder = {
.id = "obs_qsv11_hevc_soft",
.type = OBS_ENCODER_VIDEO,
.codec = "hevc",
.get_name = obs_qsv_getname_hevc,
.create = obs_qsv_create_hevc,
.destroy = obs_qsv_destroy,
.encode = obs_qsv_encode,
.update = obs_qsv_update,
.get_properties = obs_qsv_props_hevc,
.get_defaults = obs_qsv_defaults_hevc,
.get_extra_data = obs_qsv_extra_data,
.get_video_info = obs_qsv_video_plus_hdr_info,
.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
};