summaryrefslogtreecommitdiffstats
path: root/libhb/work.c
diff options
context:
space:
mode:
authorArtem Galin <[email protected]>2020-07-10 02:31:17 +0100
committerScott <[email protected]>2020-07-20 16:56:43 +0100
commitbdee4bef65609aea9f56e0a87ad3d713f62033a7 (patch)
treee272feb3b83b7f8b2d3b31f1763541eb0d60c498 /libhb/work.c
parent3fbdd5f5bef30f6180e984f578bbe7e12ba087e4 (diff)
qsv: added HW offload of resize filter
Started to close gap of filters to be offloaded for HW acceleration, when possible. Resize filter is validated and others are in the pipeline, including DX11.
Diffstat (limited to 'libhb/work.c')
-rw-r--r--libhb/work.c171
1 files changed, 25 insertions, 146 deletions
diff --git a/libhb/work.c b/libhb/work.c
index d714c988f..277e7415e 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -1226,172 +1226,49 @@ static int sanitize_audio(hb_job_t *job)
return 0;
}
+#if HB_PROJECT_FEATURE_QSV
+int num_cpu_filters = 0;
+int qsv_filters_are_enabled = 0;
+#endif
+
static int sanitize_qsv( hb_job_t * job )
{
#if HB_PROJECT_FEATURE_QSV
-#if 0 // TODO: re-implement QSV VPP filtering and QSV zerocopy path
- int i;
-
- /*
- * 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_copyframe_is_slow(job->vcodec))
- {
- if (job->list_filter != NULL)
- {
- int encode_only = 0;
- for (i = 0; i < hb_list_count(job->list_filter) && !encode_only; 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:
- case HB_FILTER_AVFILTER:
- encode_only = 1;
- break;
-
- // CPU-based deinterlace (validated)
- case HB_FILTER_DEINTERLACE:
- {
- int mode = hb_dict_get_int(filter->settings, "mode");
- if (!(mode & MODE_DEINTERLACE_QSV))
- {
- encode_only = 1;
- }
- } break;
-
- // other filters will be removed
- default:
- break;
- }
- }
- if (encode_only)
- {
- hb_log("do_job: QSV: possible CopyFrame bug, using encode-only path");
- if (hb_get_cpu_platform() >= HB_CPU_PLATFORM_INTEL_IVB)
- {
- hb_log("do_job: QSV: please update your Intel graphics driver to version 9.18.10.3257 or later");
- }
- job->qsv.decode = 0;
- }
- }
- }
-
/*
* When QSV's VPP is used for filtering, not all CPU filters
* are supported, so we need to do a little extra setup here.
*/
+ int i = 0;
+ qsv_filters_are_enabled = 0;
+ num_cpu_filters = 0;
if (job->vcodec & HB_VCODEC_QSV_MASK)
{
- int vpp_settings[7];
- int num_cpu_filters = 0;
- hb_filter_object_t *filter;
- // default values for VPP filter
- vpp_settings[0] = job->title->geometry.width;
- vpp_settings[1] = job->title->geometry.height;
- vpp_settings[2] = job->title->crop[0];
- vpp_settings[3] = job->title->crop[1];
- vpp_settings[4] = job->title->crop[2];
- vpp_settings[5] = job->title->crop[3];
- vpp_settings[6] = 0; // deinterlace: off
if (job->list_filter != NULL && hb_list_count(job->list_filter) > 0)
{
- while (hb_list_count(job->list_filter) > num_cpu_filters)
+ for (i = 0; i < hb_list_count(job->list_filter); i++)
{
- filter = hb_list_item(job->list_filter, num_cpu_filters);
+ hb_filter_object_t *filter = hb_list_item(job->list_filter, i);
+
switch (filter->id)
{
// cropping and scaling always done via VPP filter
case HB_FILTER_CROP_SCALE:
- hb_dict_extract_int(&vpp_settings[0], filter->settings,
- "width");
- hb_dict_extract_int(&vpp_settings[1], filter->settings,
- "height");
- hb_dict_extract_int(&vpp_settings[2], filter->settings,
- "crop-top");
- hb_dict_extract_int(&vpp_settings[3], filter->settings,
- "crop-bottom");
- hb_dict_extract_int(&vpp_settings[4], filter->settings,
- "crop-left");
- hb_dict_extract_int(&vpp_settings[5], filter->settings,
- "crop-right");
-
- hb_list_rem(job->list_filter, filter);
- hb_filter_close(&filter);
break;
- // pick VPP or CPU deinterlace depending on settings
case HB_FILTER_DEINTERLACE:
- {
- int mode = hb_dict_get_int(filter->settings, "mode");
- if (mode & MODE_DEINTERLACE_QSV)
- {
- // deinterlacing via VPP filter
- vpp_settings[6] = 1;
- hb_list_rem(job->list_filter, filter);
- hb_filter_close(&filter);
- }
- else
- {
- // validated
- num_cpu_filters++;
- }
- } break;
-
- // then, validated filters
- case HB_FILTER_ROTATE: // TODO: use Media SDK for this
+ case HB_FILTER_ROTATE:
case HB_FILTER_RENDER_SUB:
case HB_FILTER_AVFILTER:
num_cpu_filters++;
break;
-
- // finally, drop all unsupported filters
default:
- hb_log("do_job: QSV: full path, removing unsupported filter '%s'",
- filter->name);
- hb_list_rem(job->list_filter, filter);
- hb_filter_close(&filter);
+ num_cpu_filters++;
break;
}
}
- if (num_cpu_filters > 0)
- {
- // we need filters to copy to system memory and back
- filter = hb_filter_init(HB_FILTER_QSV_PRE);
- hb_add_filter_dict(job, filter, NULL);
- filter = hb_filter_init(HB_FILTER_QSV_POST);
- hb_add_filter_dict(job, filter, NULL);
- }
- if (vpp_settings[0] != job->title->geometry.width ||
- vpp_settings[1] != job->title->geometry.height ||
- vpp_settings[2] >= 1 /* crop */ ||
- vpp_settings[3] >= 1 /* crop */ ||
- vpp_settings[4] >= 1 /* crop */ ||
- vpp_settings[5] >= 1 /* crop */ ||
- vpp_settings[6] >= 1 /* deinterlace */)
- {
- // we need the VPP filter
- hb_dict_t * dict = hb_dict_init();
- hb_dict_set(dict, "width", hb_value_int(vpp_settings[0]));
- hb_dict_set(dict, "height", hb_value_int(vpp_settings[1]));
- hb_dict_set(dict, "crop-top", hb_value_int(vpp_settings[2]));
- hb_dict_set(dict, "crop-bottom", hb_value_int(vpp_settings[3]));
- hb_dict_set(dict, "crop-left", hb_value_int(vpp_settings[4]));
- hb_dict_set(dict, "crop-right", hb_value_int(vpp_settings[5]));
- hb_dict_set(dict, "deinterlace", hb_value_int(vpp_settings[6]));
-
- filter = hb_filter_init(HB_FILTER_QSV);
- hb_add_filter_dict(job, filter, dict);
- hb_value_free(&dict);
- }
}
+ qsv_filters_are_enabled = ((hb_list_count(job->list_filter) == 1) && hb_qsv_full_path_is_enabled(job)) ? 1 : 0;
}
-#endif // QSV VPP filtering and QSV zerocopy path
#endif // HB_PROJECT_FEATURE_QSV
return 0;
@@ -1521,15 +1398,7 @@ static void do_job(hb_job_t *job)
goto cleanup;
}
- // sanitize_qsv looks for subtitle render filter, so must happen after
- // sanitize_subtitle
- result = sanitize_qsv(job);
- if (result)
- {
- *job->done_error = HB_ERROR_WRONG_INPUT;
- *job->die = 1;
- goto cleanup;
- }
+
// Filters have an effect on settings.
// So initialize the filters and update the job.
if (job->list_filter && hb_list_count(job->list_filter))
@@ -1538,6 +1407,16 @@ static void do_job(hb_job_t *job)
sanitize_filter_list(job->list_filter, title->geometry);
+ // sanitize_qsv looks for subtitle render filter, so must happen after
+ // sanitize_subtitle
+ result = sanitize_qsv(job);
+ if (result)
+ {
+ *job->done_error = HB_ERROR_WRONG_INPUT;
+ *job->die = 1;
+ goto cleanup;
+ }
+
memset(&init, 0, sizeof(init));
init.time_base.num = 1;
init.time_base.den = 90000;