obs-qsv11: Add codec enum

(Jim description: Adding a codec enum will add support for other codecs)
This commit is contained in:
Gale
2022-11-21 19:08:02 -08:00
committed by Jim
parent 4b6af813dc
commit 9dd70910cb
6 changed files with 107 additions and 59 deletions
+2 -2
View File
@@ -80,7 +80,7 @@ void qsv_encoder_version(unsigned short *major, unsigned short *minor)
*minor = ver.Minor;
}
qsv_t *qsv_encoder_open(qsv_param_t *pParams)
qsv_t *qsv_encoder_open(qsv_param_t *pParams, enum qsv_codec codec)
{
mfxIMPL impl_list[4] = {MFX_IMPL_HARDWARE, MFX_IMPL_HARDWARE2,
MFX_IMPL_HARDWARE3, MFX_IMPL_HARDWARE4};
@@ -102,7 +102,7 @@ qsv_t *qsv_encoder_open(qsv_param_t *pParams)
impl = impl_list[adapter_idx];
QSV_Encoder_Internal *pEncoder = new QSV_Encoder_Internal(impl, ver);
mfxStatus sts = pEncoder->Open(pParams);
mfxStatus sts = pEncoder->Open(pParams, codec);
if (sts != MFX_ERR_NONE) {
#define WARN_ERR_IMPL(err, str, err_name) \
+5 -1
View File
@@ -87,6 +87,10 @@ struct adapter_info {
bool is_dgpu;
};
enum qsv_codec {
QSV_CODEC_AVC,
};
#define MAX_ADAPTERS 10
extern struct adapter_info adapters[MAX_ADAPTERS];
extern size_t adapter_count;
@@ -141,7 +145,7 @@ int qsv_param_default_preset(qsv_param_t *, const char *preset,
const char *tune);
int qsv_encoder_reconfig(qsv_t *, qsv_param_t *);
void qsv_encoder_version(unsigned short *major, unsigned short *minor);
qsv_t *qsv_encoder_open(qsv_param_t *);
qsv_t *qsv_encoder_open(qsv_param_t *, enum qsv_codec codec);
int qsv_encoder_encode(qsv_t *, uint64_t, uint8_t *, uint8_t *, uint32_t,
uint32_t, mfxBitstream **pBS);
int qsv_encoder_encode_tex(qsv_t *, uint64_t, uint32_t, uint64_t, uint64_t *,
+10 -6
View File
@@ -148,7 +148,7 @@ QSV_Encoder_Internal::~QSV_Encoder_Internal()
ClearData();
}
mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams)
mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec)
{
mfxStatus sts = MFX_ERR_NONE;
@@ -167,7 +167,7 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams)
m_pmfxENC = new MFXVideoENCODE(m_session);
InitParams(pParams);
InitParams(pParams, codec);
sts = m_pmfxENC->Query(&m_mfxEncParams, &m_mfxEncParams);
MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
@@ -191,11 +191,14 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams)
return sts;
}
bool QSV_Encoder_Internal::InitParams(qsv_param_t *pParams)
bool QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
enum qsv_codec codec)
{
memset(&m_mfxEncParams, 0, sizeof(m_mfxEncParams));
m_mfxEncParams.mfx.CodecId = MFX_CODEC_AVC;
if (codec == QSV_CODEC_AVC)
m_mfxEncParams.mfx.CodecId = MFX_CODEC_AVC;
m_mfxEncParams.mfx.GopOptFlag = MFX_GOP_STRICT;
m_mfxEncParams.mfx.NumSlice = 1;
m_mfxEncParams.mfx.TargetUsage = pParams->nTargetUsage;
@@ -746,12 +749,13 @@ mfxStatus QSV_Encoder_Internal::ClearData()
return sts;
}
mfxStatus QSV_Encoder_Internal::Reset(qsv_param_t *pParams)
mfxStatus QSV_Encoder_Internal::Reset(qsv_param_t *pParams,
enum qsv_codec codec)
{
mfxStatus sts = ClearData();
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
sts = Open(pParams);
sts = Open(pParams, codec);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
return sts;
+3 -3
View File
@@ -64,7 +64,7 @@ public:
QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version);
~QSV_Encoder_Internal();
mfxStatus Open(qsv_param_t *pParams);
mfxStatus Open(qsv_param_t *pParams, enum qsv_codec codec);
void GetSPSPPS(mfxU8 **pSPSBuf, mfxU8 **pPPSBuf, mfxU16 *pnSPSBuf,
mfxU16 *pnPPSBuf);
mfxStatus Encode(uint64_t ts, uint8_t *pDataY, uint8_t *pDataUV,
@@ -74,12 +74,12 @@ public:
uint64_t lock_key, uint64_t *next_key,
mfxBitstream **pBS);
mfxStatus ClearData();
mfxStatus Reset(qsv_param_t *pParams);
mfxStatus Reset(qsv_param_t *pParams, enum qsv_codec codec);
mfxStatus ReconfigureEncoder();
bool UpdateParams(qsv_param_t *pParams);
protected:
bool InitParams(qsv_param_t *pParams);
bool InitParams(qsv_param_t *pParams, enum qsv_codec codec);
mfxStatus AllocateSurfaces();
mfxStatus GetVideoParam();
mfxStatus InitBitstream();
+1 -1
View File
@@ -64,7 +64,7 @@ OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("obs-qsv11", "en-US")
MODULE_EXPORT const char *obs_module_description(void)
{
return "Intel Quick Sync Video H.264 encoder support for Windows";
return "Intel Quick Sync Video support for Windows";
}
extern struct obs_encoder_info obs_qsv_encoder;
+86 -46
View File
@@ -145,7 +145,7 @@ static void obs_qsv_destroy(void *data)
}
}
static void obs_qsv_defaults(obs_data_t *settings)
static void obs_qsv_defaults_h264(obs_data_t *settings)
{
obs_data_set_default_string(settings, "target_usage", "balanced");
obs_data_set_default_int(settings, "bitrate", 2500);
@@ -337,7 +337,7 @@ static inline void add_rate_controls(obs_property_t *list,
}
}
static obs_properties_t *obs_qsv_props(void *unused)
static obs_properties_t *obs_qsv_props(enum qsv_codec codec, void *unused)
{
UNUSED_PARAMETER(unused);
@@ -352,7 +352,9 @@ static obs_properties_t *obs_qsv_props(void *unused)
prop = obs_properties_add_list(props, "profile", TEXT_PROFILE,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
add_strings(prop, qsv_profile_names);
if (codec == QSV_CODEC_AVC)
add_strings(prop, qsv_profile_names);
obs_property_set_modified_callback(prop, profile_modified);
@@ -363,7 +365,9 @@ static obs_properties_t *obs_qsv_props(void *unused)
prop = obs_properties_add_list(props, "rate_control", TEXT_RATE_CONTROL,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
add_rate_controls(prop, qsv_ratecontrols);
if (codec == QSV_CODEC_AVC)
add_rate_controls(prop, qsv_ratecontrols);
obs_property_set_modified_callback(prop, rate_control_modified);
prop = obs_properties_add_int(props, "bitrate", TEXT_TARGET_BITRATE, 50,
@@ -374,30 +378,38 @@ static obs_properties_t *obs_qsv_props(void *unused)
50, 10000000, 50);
obs_property_int_set_suffix(prop, " Kbps");
obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0, 10000, 1);
obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE, 0, 10,
1);
obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1);
obs_properties_add_int(props, "qpp", "QPP", 1, 51, 1);
obs_properties_add_int(props, "qpb", "QPB", 1, 51, 1);
obs_properties_add_int(props, "icq_quality", TEXT_ICQ_QUALITY, 1, 51,
1);
prop = obs_properties_add_list(props, "latency", TEXT_LATENCY,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
add_strings(prop, qsv_latency_names);
obs_property_set_long_description(prop,
obs_module_text("Latency.ToolTip"));
if (codec == QSV_CODEC_AVC) {
obs_properties_add_int(props, "accuracy", TEXT_ACCURACY, 0,
10000, 1);
obs_properties_add_int(props, "convergence", TEXT_CONVERGENCE,
0, 10, 1);
obs_properties_add_int(props, "qpi", "QPI", 1, 51, 1);
obs_properties_add_int(props, "qpp", "QPP", 1, 51, 1);
obs_properties_add_int(props, "qpb", "QPB", 1, 51, 1);
obs_properties_add_int(props, "icq_quality", TEXT_ICQ_QUALITY,
1, 51, 1);
prop = obs_properties_add_list(props, "latency", TEXT_LATENCY,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
add_strings(prop, qsv_latency_names);
obs_property_set_long_description(
prop, obs_module_text("Latency.ToolTip"));
obs_properties_add_int(props, "bframes", TEXT_BFRAMES, 0, 3, 1);
if (is_skl_or_greater_platform())
obs_properties_add_bool(props, "enhancements",
TEXT_PERCEPTUAL_ENHANCEMENTS);
obs_properties_add_int(props, "bframes", TEXT_BFRAMES, 0, 3, 1);
if (is_skl_or_greater_platform())
obs_properties_add_bool(props, "enhancements",
TEXT_PERCEPTUAL_ENHANCEMENTS);
}
return props;
}
static obs_properties_t *obs_qsv_props_h264(void *unused)
{
UNUSED_PARAMETER(unused);
return obs_qsv_props(QSV_CODEC_AVC, unused);
}
static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings)
{
video_t *video = obs_encoder_video(obsqsv->encoder);
@@ -613,21 +625,27 @@ static bool obs_qsv_update(void *data, obs_data_t *settings)
return true;
}
static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder)
static void *obs_qsv_create(enum qsv_codec codec, obs_data_t *settings,
obs_encoder_t *encoder)
{
struct obs_qsv *obsqsv = bzalloc(sizeof(struct obs_qsv));
obsqsv->encoder = encoder;
obsqsv->codec = codec;
video_t *video = obs_encoder_video(encoder);
const struct video_output_info *voi = video_output_get_info(video);
switch (voi->format) {
case VIDEO_FORMAT_I010:
case VIDEO_FORMAT_P010:
const char *const text = obs_module_text("10bitUnsupportedAvc");
obs_encoder_set_last_error(encoder, text);
error("%s", text);
bfree(obsqsv);
return NULL;
if (codec == QSV_CODEC_AVC) {
const char *const text =
obs_module_text("10bitUnsupportedAvc");
obs_encoder_set_last_error(encoder, text);
error("%s", text);
bfree(obsqsv);
return NULL;
}
break;
default:
switch (voi->colorspace) {
case VIDEO_CS_2100_PQ:
@@ -643,7 +661,7 @@ static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder)
if (update_settings(obsqsv, settings)) {
AcquireSRWLockExclusive(&g_QsvLock);
obsqsv->context = qsv_encoder_open(&obsqsv->params);
obsqsv->context = qsv_encoder_open(&obsqsv->params, codec);
ReleaseSRWLockExclusive(&g_QsvLock);
if (obsqsv->context == NULL)
@@ -692,6 +710,11 @@ static void *obs_qsv_create(obs_data_t *settings, obs_encoder_t *encoder)
return obsqsv;
}
static void *obs_qsv_create_h264(obs_data_t *settings, obs_encoder_t *encoder)
{
return obs_qsv_create(QSV_CODEC_AVC, settings, encoder);
}
static HANDLE get_lib(const char *lib)
{
HMODULE mod = GetModuleHandleA(lib);
@@ -714,29 +737,44 @@ static bool is_intel_gpu_primary(void)
return adapters[ovi.adapter].is_intel;
}
static void *obs_qsv_create_tex(obs_data_t *settings, obs_encoder_t *encoder)
static void *obs_qsv_create_tex(enum qsv_codec codec, obs_data_t *settings,
obs_encoder_t *encoder)
{
char *encoder_id;
if (codec == QSV_CODEC_AVC)
encoder_id = "obs_qsv11_soft";
if (!is_intel_gpu_primary()) {
blog(LOG_INFO,
">>> app not on intel GPU, fall back to old qsv encoder");
return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
return obs_encoder_create_rerouted(encoder,
(const char *)encoder_id);
}
if (!obs_nv12_tex_active()) {
bool gpu_texture_active = obs_nv12_tex_active();
if (!gpu_texture_active) {
blog(LOG_INFO,
">>> nv12 tex not active, fall back to old qsv encoder");
return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
">>> gpu tex not active, fall back to old qsv encoder");
return obs_encoder_create_rerouted(encoder,
(const char *)encoder_id);
}
if (obs_encoder_scaling_enabled(encoder)) {
blog(LOG_INFO,
">>> encoder scaling active, fall back to old qsv encoder");
return obs_encoder_create_rerouted(encoder, "obs_qsv11_soft");
return obs_encoder_create_rerouted(encoder,
(const char *)encoder_id);
}
blog(LOG_INFO, ">>> new qsv encoder");
return obs_qsv_create(settings, encoder);
return obs_qsv_create(codec, settings, encoder);
}
static void *obs_qsv_create_tex_h264(obs_data_t *settings,
obs_encoder_t *encoder)
{
return obs_qsv_create_tex(QSV_CODEC_AVC, settings, encoder);
}
static bool obs_qsv_extra_data(void *data, uint8_t **extra_data, size_t *size)
@@ -954,7 +992,8 @@ static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
return false;
}
parse_packet(obsqsv, packet, pBS, voi, received_packet);
if (obsqsv->codec == QSV_CODEC_AVC)
parse_packet(obsqsv, packet, pBS, voi, received_packet);
ReleaseSRWLockExclusive(&g_QsvLock);
@@ -997,7 +1036,8 @@ static bool obs_qsv_encode_tex(void *data, uint32_t handle, int64_t pts,
return false;
}
parse_packet(obsqsv, packet, pBS, voi, received_packet);
if (obsqsv->codec == QSV_CODEC_AVC)
parse_packet(obsqsv, packet, pBS, voi, received_packet);
ReleaseSRWLockExclusive(&g_QsvLock);
@@ -1009,12 +1049,12 @@ struct obs_encoder_info obs_qsv_encoder = {
.type = OBS_ENCODER_VIDEO,
.codec = "h264",
.get_name = obs_qsv_getname,
.create = obs_qsv_create,
.create = obs_qsv_create_h264,
.destroy = obs_qsv_destroy,
.encode = obs_qsv_encode,
.update = obs_qsv_update,
.get_properties = obs_qsv_props,
.get_defaults = obs_qsv_defaults,
.get_properties = obs_qsv_props_h264,
.get_defaults = obs_qsv_defaults_h264,
.get_extra_data = obs_qsv_extra_data,
.get_sei_data = obs_qsv_sei,
.get_video_info = obs_qsv_video_info,
@@ -1026,13 +1066,13 @@ struct obs_encoder_info obs_qsv_encoder_tex = {
.type = OBS_ENCODER_VIDEO,
.codec = "h264",
.get_name = obs_qsv_getname,
.create = obs_qsv_create_tex,
.create = obs_qsv_create_tex_h264,
.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,
.get_defaults = obs_qsv_defaults,
.get_properties = obs_qsv_props_h264,
.get_defaults = obs_qsv_defaults_h264,
.get_extra_data = obs_qsv_extra_data,
.get_sei_data = obs_qsv_sei,
.get_video_info = obs_qsv_video_info,