瀏覽代碼

obs-qsv11: Add codec enum

(Jim description: Adding a codec enum will add support for other codecs)
Gale 3 年之前
父節點
當前提交
9dd70910cb

+ 2 - 2
plugins/obs-qsv11/QSV_Encoder.cpp

@@ -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
plugins/obs-qsv11/QSV_Encoder.h

@@ -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
plugins/obs-qsv11/QSV_Encoder_Internal.cpp

@@ -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
plugins/obs-qsv11/QSV_Encoder_Internal.h

@@ -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
plugins/obs-qsv11/obs-qsv11-plugin-main.c

@@ -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;

+ 88 - 48
plugins/obs-qsv11/obs-qsv11.c

@@ -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"));
-
-	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);
-
+	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);
+	}
 	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,