]> granicus.if.org Git - handbrake/commitdiff
QSV: use encode-only path when we have CPU filters enabled and CopyFrame is unavailable.
authorRodeo <tdskywalker@gmail.com>
Fri, 11 Oct 2013 13:17:17 +0000 (13:17 +0000)
committerRodeo <tdskywalker@gmail.com>
Fri, 11 Oct 2013 13:17:17 +0000 (13:17 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5831 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/qsv_common.c
libhb/qsv_common.h
libhb/work.c

index d191fadf17fbe4671cf8f68795ffc83efaa902f8..704a6e86a483a87c191a60ddc597614e6e5a2886 100644 (file)
@@ -93,6 +93,10 @@ int hb_qsv_info_init()
             hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_API_1_6;
             hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_EXTBRC;
         }
+        if (HB_CHECK_MFX_VERSION(qsv_hardware_version, 1, 7))
+        {
+            hb_qsv_info->capabilities |= HB_QSV_CAP_COPYFRAME;
+        }
         if (hb_get_cpu_platform() == HB_CPU_PLATFORM_INTEL_HSW)
         {
             if (HB_CHECK_MFX_VERSION(qsv_hardware_version, 1, 6))
@@ -114,6 +118,10 @@ int hb_qsv_info_init()
             hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_API_1_6;
             hb_qsv_info->capabilities |= HB_QSV_CAP_H264_BPYRAMID;
         }
+        if (HB_CHECK_MFX_VERSION(qsv_software_version, 1, 7))
+        {
+            hb_qsv_info->capabilities |= HB_QSV_CAP_COPYFRAME;
+        }
     }
 
     // note: we pass a pointer to MFXInit but it never gets modified
index 083065be64b05fa18b7c4ddee5dde8595a073a0e..ab9ca902486fd89a5e5a9dc2358c17b680012d3d 100644 (file)
@@ -36,6 +36,7 @@ typedef struct hb_qsv_info_s
 #define HB_QSV_CAP_OPTION2_MBBRC     (1 << 3) // mfxExtCodingOption2: MBBRC
 #define HB_QSV_CAP_OPTION2_LOOKAHEAD (1 << 4) // mfxExtCodingOption2: LookAhead
 #define HB_QSV_CAP_OPTION2_TRELLIS   (1 << 5) // mfxExtCodingOption2: Trellis
+#define HB_QSV_CAP_COPYFRAME         (1 << 6) // mfxCoreInterface: CopyFrame
 
     // TODO: add available decoders, filters, encoders,
     //       maximum decode and encode resolution, etc.
index a5c3190d180c29d6697b8ae7c45bb7e46d06234e..bd5b66529d8fb5e49a9b93e6ce7993c6e93c7bec 100644 (file)
@@ -699,6 +699,48 @@ static void do_job(hb_job_t *job)
     }
 
 #ifdef USE_QSV
+    /*
+     * XXX: mfxCoreInterface's CopyFrame doesn't work in old drivers, and our
+     *      workaround is really slow. If we have validated CPU-based filters in
+     *      the list and we can't use CopyFrame, disable QSV decoding until a
+     *      better solution is implemented.
+     */
+    if (!(hb_qsv_info->capabilities & HB_QSV_CAP_COPYFRAME))
+    {
+        if (job->list_filter != NULL)
+        {
+            for (i = 0;
+                 i < hb_list_count(job->list_filter) && hb_qsv_decode_is_enabled(job);
+                 i++)
+            {
+                hb_filter_object_t *filter = hb_list_item(job->list_filter, i);
+                switch (filter->id)
+                {
+                    // validated, CPU-based filters
+                    case HB_FILTER_ROTATE:
+                    case HB_FILTER_RENDER_SUB:
+                        hb_log("do_job: QSV: CopyFrame unavailable, using encode-only path");
+                        job->qsv.decode = 0;
+                        break;
+
+                    // CPU-based deinterlace (validated)
+                    case HB_FILTER_DEINTERLACE:
+                        if (filter->settings != NULL &&
+                            strcasecmp(filter->settings, "qsv") != 0)
+                        {
+                            hb_log("do_job: QSV: CopyFrame unavailable, using encode-only path");
+                            job->qsv.decode = 0;
+                        }
+                        break;
+
+                    // other filters will be removed
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
     /*
      * When QSV is used for decoding, not all CPU-based filters are supported,
      * so we need to do a little extra setup here.
@@ -744,7 +786,8 @@ static void do_job(hb_job_t *job)
 
                     // pick VPP or CPU deinterlace depending on settings
                     case HB_FILTER_DEINTERLACE:
-                        if (filter->settings == NULL || !strcmp(filter->settings, "qsv"))
+                        if (filter->settings == NULL ||
+                            strcasecmp(filter->settings, "qsv") == 0)
                         {
                             // deinterlacing via VPP filter
                             vpp_settings[6] = 1;
@@ -766,7 +809,7 @@ static void do_job(hb_job_t *job)
 
                     // finally, drop all unsupported filters
                     default:
-                        hb_log("do_job: full QSV path, removing unsupported filter '%s'",
+                        hb_log("do_job: QSV: full path, removing unsupported filter '%s'",
                                filter->name);
                         hb_list_rem(job->list_filter, filter);
                         hb_filter_close(&filter);