]> granicus.if.org Git - handbrake/commitdiff
QSV: add new capability guards for some extended video parameter buffers.
authorRodeo <tdskywalker@gmail.com>
Sat, 27 Jun 2015 22:10:00 +0000 (22:10 +0000)
committerRodeo <tdskywalker@gmail.com>
Sat, 27 Jun 2015 22:10:00 +0000 (22:10 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@7326 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/enc_qsv.c
libhb/qsv_common.c
libhb/qsv_common.h

index 6e52edb73b843b3876ec51adfa2ab2a0ec9b9bcd..27cd378e7f27a16f340d8e3457170c9cd8754e11 100644 (file)
@@ -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)
     {
index ac15d78561cc6857131208d4fae3da7cbbee5a42..3b8179886122011de8d6d9663c74962ef1e91634 100644 (file)
@@ -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;
         }
index 9ac2085ec2f989c1206d66a503b1b9b472d3cb43..da045422e0e591d045de0d1b49379c4fef5ee4c2 100644 (file)
@@ -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;