summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/enc_qsv.c20
-rw-r--r--libhb/qsv_common.c274
-rw-r--r--libhb/qsv_common.h21
3 files changed, 246 insertions, 69 deletions
diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c
index 6e52edb73..27cd378e7 100644
--- a/libhb/enc_qsv.c
+++ b/libhb/enc_qsv.c
@@ -911,14 +911,16 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
memset(option1, 0, sizeof(mfxExtCodingOption));
option1->Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
option1->Header.BufferSz = sizeof(mfxExtCodingOption);
- videoParam.ExtParam[videoParam.NumExtParam++] = (mfxExtBuffer*)option1;
+ if (pv->qsv_info->capabilities & HB_QSV_CAP_OPTION1)
+ {
+ videoParam.ExtParam[videoParam.NumExtParam++] = (mfxExtBuffer*)option1;
+ }
// introduced in API 1.6
memset(option2, 0, sizeof(mfxExtCodingOption2));
option2->Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
option2->Header.BufferSz = sizeof(mfxExtCodingOption2);
- if (pv->qsv_info->capabilities & HB_QSV_CAP_MSDK_API_1_6)
+ if (pv->qsv_info->capabilities & HB_QSV_CAP_OPTION2)
{
- // attach to get the final output mfxExtCodingOption2 settings
videoParam.ExtParam[videoParam.NumExtParam++] = (mfxExtBuffer*)option2;
}
err = MFXVideoENCODE_GetVideoParam(session, &videoParam);
@@ -1099,10 +1101,16 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
videoParam.mfx.FrameInfo.PicStruct);
return -1;
}
- if (option1->CAVLC != MFX_CODINGOPTION_OFF)
+ if (pv->qsv_info->capabilities & HB_QSV_CAP_OPTION1)
{
- hb_log("encqsvInit: CAVLC %s",
- hb_qsv_codingoption_get_name(option1->CAVLC));
+ if (videoParam.mfx.CodecId == MFX_CODEC_AVC)
+ {
+ if (option1->CAVLC != MFX_CODINGOPTION_OFF)
+ {
+ hb_log("encqsvInit: CAVLC %s",
+ hb_qsv_codingoption_get_name(option1->CAVLC));
+ }
+ }
}
if (pv->qsv_info->capabilities & HB_QSV_CAP_OPTION2_EXTBRC)
{
diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c
index ac15d7856..3b8179886 100644
--- a/libhb/qsv_common.c
+++ b/libhb/qsv_common.c
@@ -167,6 +167,39 @@ static void init_video_param(mfxVideoParam *videoParam)
videoParam->IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
}
+static void init_ext_video_signal_info(mfxExtVideoSignalInfo *extVideoSignalInfo)
+{
+ if (extVideoSignalInfo == NULL)
+ {
+ return;
+ }
+
+ memset(extVideoSignalInfo, 0, sizeof(mfxExtVideoSignalInfo));
+ extVideoSignalInfo->Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
+ extVideoSignalInfo->Header.BufferSz = sizeof(mfxExtVideoSignalInfo);
+ extVideoSignalInfo->VideoFormat = 5; // undefined
+ extVideoSignalInfo->VideoFullRange = 0; // TV range
+ extVideoSignalInfo->ColourDescriptionPresent = 0; // don't write to bitstream
+ extVideoSignalInfo->ColourPrimaries = 2; // undefined
+ extVideoSignalInfo->TransferCharacteristics = 2; // undefined
+ extVideoSignalInfo->MatrixCoefficients = 2; // undefined
+}
+
+static void init_ext_coding_option(mfxExtCodingOption *extCodingOption)
+{
+ if (extCodingOption == NULL)
+ {
+ return;
+ }
+
+ memset(extCodingOption, 0, sizeof(mfxExtCodingOption));
+ extCodingOption->Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
+ extCodingOption->Header.BufferSz = sizeof(mfxExtCodingOption);
+ extCodingOption->AUDelimiter = MFX_CODINGOPTION_OFF;
+ extCodingOption->PicTimingSEI = MFX_CODINGOPTION_OFF;
+ extCodingOption->CAVLC = MFX_CODINGOPTION_OFF;
+}
+
static void init_ext_coding_option2(mfxExtCodingOption2 *extCodingOption2)
{
if (extCodingOption2 == NULL)
@@ -209,7 +242,9 @@ static int query_capabilities(mfxSession session, mfxVersion version, hb_qsv_inf
hb_list_t *mfxPluginList;
mfxExtBuffer *videoExtParam[1];
mfxVideoParam videoParam, inputParam;
- mfxExtCodingOption2 extCodingOption2;
+ mfxExtCodingOption extCodingOption;
+ mfxExtCodingOption2 extCodingOption2;
+ mfxExtVideoSignalInfo extVideoSignalInfo;
/* Reset capabilities before querying */
info->capabilities = 0;
@@ -361,7 +396,71 @@ static int query_capabilities(mfxSession session, mfxVersion version, hb_qsv_inf
}
/*
- * Check mfxExtCodingOption2 fields.
+ * Determine whether mfxExtVideoSignalInfo is supported.
+ */
+ if (HB_CHECK_MFX_VERSION(version, 1, 3))
+ {
+ init_video_param(&videoParam);
+ videoParam.mfx.CodecId = info->codec_id;
+
+ init_ext_video_signal_info(&extVideoSignalInfo);
+ videoParam.ExtParam = videoExtParam;
+ videoParam.ExtParam[0] = (mfxExtBuffer*)&extVideoSignalInfo;
+ videoParam.NumExtParam = 1;
+
+ status = MFXVideoENCODE_Query(session, NULL, &videoParam);
+ if (status >= MFX_ERR_NONE)
+ {
+ /* Encoder can be configured via mfxExtVideoSignalInfo */
+ info->capabilities |= HB_QSV_CAP_VUI_VSINFO;
+ }
+ else if (info->codec_id == MFX_CODEC_AVC)
+ {
+ /*
+ * This should not fail for AVC encoders, so we want to know
+ * about it - however, it may fail for other encoders (ignore)
+ */
+ fprintf(stderr,
+ "hb_qsv_info_init: mfxExtVideoSignalInfo check"
+ " failed (0x%"PRIX32", 0x%"PRIX32", %d)\n",
+ info->codec_id, info->implementation, status);
+ }
+ }
+
+ /*
+ * Determine whether mfxExtCodingOption is supported.
+ */
+ if (HB_CHECK_MFX_VERSION(version, 1, 0))
+ {
+ init_video_param(&videoParam);
+ videoParam.mfx.CodecId = info->codec_id;
+
+ init_ext_coding_option(&extCodingOption);
+ videoParam.ExtParam = videoExtParam;
+ videoParam.ExtParam[0] = (mfxExtBuffer*)&extCodingOption;
+ videoParam.NumExtParam = 1;
+
+ status = MFXVideoENCODE_Query(session, NULL, &videoParam);
+ if (status >= MFX_ERR_NONE)
+ {
+ /* Encoder can be configured via mfxExtCodingOption */
+ info->capabilities |= HB_QSV_CAP_OPTION1;
+ }
+ else if (info->codec_id == MFX_CODEC_AVC)
+ {
+ /*
+ * This should not fail for AVC encoders, so we want to know
+ * about it - however, it may fail for other encoders (ignore)
+ */
+ fprintf(stderr,
+ "hb_qsv_info_init: mfxExtCodingOption check"
+ " failed (0x%"PRIX32", 0x%"PRIX32", %d)\n",
+ info->codec_id, info->implementation, status);
+ }
+ }
+
+ /*
+ * Determine whether mfxExtCodingOption2 and its fields are supported.
*
* Mode 2 suffers from false negatives with some drivers, whereas mode 1
* suffers from false positives instead. The latter is probably easier
@@ -394,6 +493,9 @@ static int query_capabilities(mfxSession session, mfxVersion version, hb_qsv_inf
fprintf(stderr, "-------------------\n");
#endif
+ /* Encoder can be configured via mfxExtCodingOption2 */
+ info->capabilities |= HB_QSV_CAP_OPTION2;
+
/*
* Sanitize API 1.6 fields:
*
@@ -598,25 +700,39 @@ static void log_capabilities(int log_level, uint64_t caps, const char *prefix)
{
strcat(buffer, " icq");
}
- if (caps & HB_QSV_CAP_OPTION2_MBBRC)
- {
- strcat(buffer, " mbbrc");
- }
- if (caps & HB_QSV_CAP_OPTION2_EXTBRC)
+ if (caps & HB_QSV_CAP_VUI_VSINFO)
{
- strcat(buffer, " extbrc");
+ strcat(buffer, " vsinfo");
}
- if (caps & HB_QSV_CAP_OPTION2_TRELLIS)
+ if (caps & HB_QSV_CAP_OPTION1)
{
- strcat(buffer, " trellis");
+ strcat(buffer, " opt1");
}
- if (caps & HB_QSV_CAP_OPTION2_IB_ADAPT)
+ if (caps & HB_QSV_CAP_OPTION2)
{
- strcat(buffer, " ib_adapt");
- }
- if (caps & HB_QSV_CAP_OPTION2_NMPSLICE)
- {
- strcat(buffer, " nmpslice");
+ {
+ strcat(buffer, " opt2");
+ }
+ if (caps & HB_QSV_CAP_OPTION2_MBBRC)
+ {
+ strcat(buffer, "+mbbrc");
+ }
+ if (caps & HB_QSV_CAP_OPTION2_EXTBRC)
+ {
+ strcat(buffer, "+extbrc");
+ }
+ if (caps & HB_QSV_CAP_OPTION2_TRELLIS)
+ {
+ strcat(buffer, "+trellis");
+ }
+ if (caps & HB_QSV_CAP_OPTION2_IB_ADAPT)
+ {
+ strcat(buffer, "+ib_adapt");
+ }
+ if (caps & HB_QSV_CAP_OPTION2_NMPSLICE)
+ {
+ strcat(buffer, "+nmpslice");
+ }
}
hb_deep_log(log_level, "%s%s", prefix,
@@ -1022,13 +1138,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "cavlc") || !strcasecmp(key, "cabac"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_OPTION1)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atobool(value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atobool(value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1041,13 +1164,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "videoformat"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atoindex(hb_h264_vidformat_names, value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atoindex(hb_h264_vidformat_names, value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1056,13 +1186,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "fullrange"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atoindex(hb_h264_fullrange_names, value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atoindex(hb_h264_fullrange_names, value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1071,13 +1208,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "colorprim"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atoindex(hb_h264_colorprim_names, value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atoindex(hb_h264_colorprim_names, value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1087,13 +1231,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "transfer"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atoindex(hb_h264_transfer_names, value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atoindex(hb_h264_transfer_names, value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1103,13 +1254,20 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
}
else if (!strcasecmp(key, "colormatrix"))
{
- switch (info->codec_id)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
{
- case MFX_CODEC_AVC:
- ivalue = hb_qsv_atoindex(hb_h264_colmatrix_names, value, &error);
- break;
- default:
- return HB_QSV_PARAM_UNSUPPORTED;
+ switch (info->codec_id)
+ {
+ case MFX_CODEC_AVC:
+ ivalue = hb_qsv_atoindex(hb_h264_colmatrix_names, value, &error);
+ break;
+ default:
+ return HB_QSV_PARAM_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ return HB_QSV_PARAM_UNSUPPORTED;
}
if (!error)
{
@@ -1622,9 +1780,15 @@ int hb_qsv_param_default(hb_qsv_param_t *param, mfxVideoParam *videoParam,
// attach supported mfxExtBuffer structures to the mfxVideoParam
param->videoParam->NumExtParam = 0;
param->videoParam->ExtParam = param->ExtParamArray;
- param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->codingOption;
- param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->videoSignalInfo;
- if (info->capabilities & HB_QSV_CAP_MSDK_API_1_6)
+ if (info->capabilities & HB_QSV_CAP_VUI_VSINFO)
+ {
+ param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->videoSignalInfo;
+ }
+ if (info->capabilities & HB_QSV_CAP_OPTION1)
+ {
+ param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->codingOption;
+ }
+ if (info->capabilities & HB_QSV_CAP_OPTION2)
{
param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->codingOption2;
}
diff --git a/libhb/qsv_common.h b/libhb/qsv_common.h
index 9ac2085ec..da045422e 100644
--- a/libhb/qsv_common.h
+++ b/libhb/qsv_common.h
@@ -42,18 +42,23 @@ typedef struct hb_qsv_info_s
#define HB_QSV_CAP_MSDK_API_1_6 (1LL << 0)
// H.264, H.265: B-frames can be used as references
#define HB_QSV_CAP_B_REF_PYRAMID (1LL << 1)
+ // mfxExtVideoSignalInfo
+#define HB_QSV_CAP_VUI_VSINFO (1LL << 3)
// optional rate control methods
#define HB_QSV_CAP_RATECONTROL_LA (1LL << 10)
#define HB_QSV_CAP_RATECONTROL_LAi (1LL << 11)
#define HB_QSV_CAP_RATECONTROL_ICQ (1LL << 12)
- // mfxExtCodingOption2 fields
-#define HB_QSV_CAP_OPTION2_MBBRC (1LL << 20)
-#define HB_QSV_CAP_OPTION2_EXTBRC (1LL << 21)
-#define HB_QSV_CAP_OPTION2_TRELLIS (1LL << 22)
-#define HB_QSV_CAP_OPTION2_BREFTYPE (1LL << 23)
-#define HB_QSV_CAP_OPTION2_IB_ADAPT (1LL << 24)
-#define HB_QSV_CAP_OPTION2_LA_DOWNS (1LL << 25)
-#define HB_QSV_CAP_OPTION2_NMPSLICE (1LL << 26)
+ // mfxExtCodingOption
+#define HB_QSV_CAP_OPTION1 (1LL << 20)
+ // mfxExtCodingOption2
+#define HB_QSV_CAP_OPTION2 (1LL << 30)
+#define HB_QSV_CAP_OPTION2_MBBRC (1LL << 31)
+#define HB_QSV_CAP_OPTION2_EXTBRC (1LL << 32)
+#define HB_QSV_CAP_OPTION2_TRELLIS (1LL << 33)
+#define HB_QSV_CAP_OPTION2_BREFTYPE (1LL << 34)
+#define HB_QSV_CAP_OPTION2_IB_ADAPT (1LL << 35)
+#define HB_QSV_CAP_OPTION2_LA_DOWNS (1LL << 36)
+#define HB_QSV_CAP_OPTION2_NMPSLICE (1LL << 37)
// TODO: add maximum encode resolution, etc.
} hb_qsv_info_t;