diff options
author | Rodeo <[email protected]> | 2013-09-24 13:22:19 +0000 |
---|---|---|
committer | Rodeo <[email protected]> | 2013-09-24 13:22:19 +0000 |
commit | 7be1890d2c89b31e4ef93bd92a8bb07040f082bd (patch) | |
tree | 5565c397317725df8f4c38f5c20128eaed87a8eb | |
parent | a79d60b425e588a5e2e4aff35815b8396c909895 (diff) |
QSV: libhb-based preset system.
Modeled after x264's preset system.
MMBRC and LookAhead RC are now enabled by default, whereas Trellis is disabled by default.
Please note that Windows GUI support will come later, and that preset names are not definitive.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5806 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/common.c | 1 | ||||
-rw-r--r-- | libhb/common.h | 6 | ||||
-rw-r--r-- | libhb/enc_qsv.c | 25 | ||||
-rw-r--r-- | libhb/qsv_common.c | 90 | ||||
-rw-r--r-- | libhb/qsv_common.h | 8 | ||||
-rw-r--r-- | libhb/work.c | 7 | ||||
-rw-r--r-- | test/test.c | 53 | ||||
-rw-r--r-- | win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs | 3 |
8 files changed, 157 insertions, 36 deletions
diff --git a/libhb/common.c b/libhb/common.c index 7087046b6..9df282cbc 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -2906,6 +2906,7 @@ static void job_setup( hb_job_t * job, hb_title_t * title ) #ifdef USE_QSV job->qsv.enc_info.is_init_done = 0; + job->qsv.preset = NULL; job->qsv.async_depth = AV_QSV_ASYNC_DEPTH_DEFAULT; job->qsv.decode = !!(title->video_decode_support & HB_DECODE_SUPPORT_QSV); diff --git a/libhb/common.h b/libhb/common.h index abc799ef1..42fd0a212 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -537,6 +537,7 @@ struct hb_job_s { int decode; int async_depth; + const char *preset; av_qsv_context *ctx; // shared encoding parameters // initialized by the QSV encoder, then used upstream (e.g. by filters) @@ -1238,9 +1239,12 @@ char * hb_x264_param_unparse(const char *x264_preset, const char *x264_tune, const char *x264_encopts, const char *h264_profile, const char *h264_level, int width, int height); -// x264 preset/tune & h264 profile/level helpers +// x264 preset/tune, qsv preset & h264 profile/level helpers const char * const * hb_x264_presets(); const char * const * hb_x264_tunes(); +#ifdef USE_QSV +const char * const * hb_qsv_presets(); +#endif const char * const * hb_h264_profiles(); const char * const * hb_h264_levels(); diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index 46a398c67..337befeca 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -374,9 +374,10 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) pv->next_chapter.start = INT64_MIN; // default encoding parameters - if (hb_qsv_param_default(&pv->param, &pv->enc_space.m_mfxVideoParam)) + if (hb_qsv_param_default_preset(&pv->param, &pv->enc_space.m_mfxVideoParam, + job->qsv.preset)) { - hb_error("encqsvInit: hb_qsv_param_default failed"); + hb_error("encqsvInit: hb_qsv_param_default_preset failed"); return -1; } @@ -597,31 +598,15 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) // lookahead not supported pv->param.rc.lookahead = 0; } - else if (pv->param.rc.lookahead > 0 && + else if (pv->param.rc.lookahead && pv->param.videoParam->mfx.FrameInfo.PicStruct != MFX_PICSTRUCT_PROGRESSIVE) { - // user force-enabled lookahead but we can't use it + // lookahead enabled but we can't use it hb_log("encqsvInit: MFX_RATECONTROL_LA not used (LookAhead is progressive-only)"); pv->param.rc.lookahead = 0; } - else if (pv->param.rc.lookahead < 0) - { - if (pv->param.rc.vbv_max_bitrate > 0 || - pv->param.rc.vbv_buffer_size > 0 || - pv->param.videoParam->mfx.FrameInfo.PicStruct != MFX_PICSTRUCT_PROGRESSIVE) - { - // lookahead doesn't support VBV or interlaced encoding - pv->param.rc.lookahead = 0; - } - else - { - // set automatically based on target usage - pv->param.rc.lookahead = (pv->param.videoParam->mfx.TargetUsage <= MFX_TARGETUSAGE_2); - } - } else { - // user force-enabled or force-disabled lookahead pv->param.rc.lookahead = !!pv->param.rc.lookahead; } if (pv->param.rc.lookahead) diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c index cbd427f5d..e96a715fd 100644 --- a/libhb/qsv_common.c +++ b/libhb/qsv_common.c @@ -201,7 +201,7 @@ int hb_qsv_codingoption_xlat(int val) int hb_qsv_trellisvalue_xlat(int val) { - switch (HB_QSV_CLIP3(-1, 3, val)) + switch (HB_QSV_CLIP3(0, 3, val)) { case 0: return MFX_TRELLIS_OFF; @@ -211,7 +211,6 @@ int hb_qsv_trellisvalue_xlat(int val) return MFX_TRELLIS_I|MFX_TRELLIS_P; case 3: // all frames return MFX_TRELLIS_I|MFX_TRELLIS_P|MFX_TRELLIS_B; - case -1: default: return MFX_TRELLIS_UNKNOWN; } @@ -700,6 +699,87 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, return error ? HB_QSV_PARAM_BAD_VALUE : HB_QSV_PARAM_OK; } +const char* const* hb_qsv_presets() +{ + if (hb_get_cpu_platform() >= HB_CPU_PLATFORM_INTEL_HSW) + { + return hb_qsv_preset_names2; + } + else + { + return hb_qsv_preset_names1; + } +} + +int hb_qsv_param_default_preset(hb_qsv_param_t *param, + mfxVideoParam *videoParam, const char *preset) +{ + if (param != NULL && videoParam != NULL) + { + int ret = hb_qsv_param_default(param, videoParam); + if (ret) + { + return ret; + } + } + else + { + hb_error("hb_qsv_param_default_preset: invalid pointer(s)"); + return -1; + } + if (preset != NULL && preset[0] != '\0') + { + if (!strcasecmp(preset, "quality")) + { + /* + * Haswell or later: default settings. + * Before Haswell: preset unavailable. + */ + } + else if (!strcasecmp(preset, "balanced")) + { + /* + * Haswell or later: adjust settings. + * + * The idea behind this is that we should try and get a performance + * match between platforms (so using the "balanced" preset would + * give you similar encoding speeds on Ivy Bridge and Haswell). + * + * FIXME: figure out whether this actually is a good idea. + */ + if (hb_get_cpu_platform() >= HB_CPU_PLATFORM_INTEL_HSW) + { + param->rc.lookahead = 0; + param->videoParam->mfx.GopRefDist = 1; + param->videoParam->mfx.TargetUsage = MFX_TARGETUSAGE_4; + } + else + { + /* Before Haswell: default settings */ + } + } + else if (!strcasecmp(preset, "speed")) + { + if (hb_get_cpu_platform() >= HB_CPU_PLATFORM_INTEL_HSW) + { + param->rc.lookahead = 0; + param->videoParam->mfx.GopRefDist = 1; + param->videoParam->mfx.TargetUsage = MFX_TARGETUSAGE_6; + } + else + { + param->videoParam->mfx.TargetUsage = MFX_TARGETUSAGE_4; + } + } + else + { + hb_error("hb_qsv_param_default_preset: invalid preset '%s'", preset); + return -1; + } + } + return 0; +} + int hb_qsv_param_default(hb_qsv_param_t *param, mfxVideoParam *videoParam) { if (param != NULL && videoParam != NULL) @@ -757,17 +837,17 @@ int hb_qsv_param_default(hb_qsv_param_t *param, mfxVideoParam *videoParam) param->codingOption2.IntRefQPDelta = 0; param->codingOption2.MaxFrameSize = 0; param->codingOption2.BitrateLimit = MFX_CODINGOPTION_ON; + param->codingOption2.MBBRC = MFX_CODINGOPTION_ON; param->codingOption2.ExtBRC = MFX_CODINGOPTION_OFF; - param->codingOption2.MBBRC = MFX_CODINGOPTION_UNKNOWN; // introduced in API 1.7 param->codingOption2.LookAheadDepth = 40; - param->codingOption2.Trellis = MFX_TRELLIS_UNKNOWN; + param->codingOption2.Trellis = MFX_TRELLIS_OFF; // GOP & rate control param->gop.b_pyramid = 0; param->gop.gop_pic_size = -1; // set automatically param->gop.int_ref_cycle_size = -1; // set automatically - param->rc.lookahead = -1; // set automatically + param->rc.lookahead = 1; param->rc.cqp_offsets[0] = 0; param->rc.cqp_offsets[1] = 2; param->rc.cqp_offsets[2] = 4; diff --git a/libhb/qsv_common.h b/libhb/qsv_common.h index 796d791b5..083065be6 100644 --- a/libhb/qsv_common.h +++ b/libhb/qsv_common.h @@ -106,6 +106,9 @@ typedef struct mfxVideoParam *videoParam; } hb_qsv_param_t; +static const char* const hb_qsv_preset_names1[] = { "speed", "balanced", NULL, }; +static const char* const hb_qsv_preset_names2[] = { "speed", "balanced", "quality", NULL, }; + #define HB_QSV_CLIP3(min, max, val) ((val < min) ? min : (val > max) ? max : val) int hb_qsv_codingoption_xlat (int val); const char* hb_qsv_codingoption_get_name(int val); @@ -116,8 +119,9 @@ int hb_qsv_atobool (const char *str, int *err); int hb_qsv_atoi (const char *str, int *err); float hb_qsv_atof (const char *str, int *err); -int hb_qsv_param_default(hb_qsv_param_t *param, mfxVideoParam *videoParam); -int hb_qsv_param_parse (hb_qsv_param_t *param, const char *key, const char *value, int vcodec); +int hb_qsv_param_default_preset(hb_qsv_param_t *param, mfxVideoParam *videoParam, const char *preset); +int hb_qsv_param_default (hb_qsv_param_t *param, mfxVideoParam *videoParam); +int hb_qsv_param_parse (hb_qsv_param_t *param, const char *key, const char *value, int vcodec); mfxIMPL hb_qsv_impl_get_preferred(); const char* hb_qsv_impl_get_name(int impl); diff --git a/libhb/work.c b/libhb/work.c index d44f763be..a5c3190d1 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -318,6 +318,13 @@ void hb_display_job_info(hb_job_t *job) { hb_log( " + x264 tune: %s", job->x264_tune ); } +#ifdef USE_QSV + if ((job->qsv.preset != NULL && *job->qsv.preset) && + (job->vcodec & HB_VCODEC_QSV_MASK)) + { + hb_log(" + QSV preset: %s", job->qsv.preset); + } +#endif if (job->advanced_opts != NULL && *job->advanced_opts && (job->vcodec != HB_VCODEC_THEORA)) { diff --git a/test/test.c b/test/test.c index b7f8e9ac2..b64203937 100644 --- a/test/test.c +++ b/test/test.c @@ -141,8 +141,9 @@ static uint64_t min_title_duration = 10; static int use_opencl = 0; static int use_hwd = 0; #ifdef USE_QSV -static int qsv_decode = 1; -static int qsv_async_depth = -1; +static int qsv_async_depth = -1; +static int qsv_decode = 1; +static const char *qsv_preset = NULL; #endif /* Exit cleanly on Ctrl-C */ @@ -1952,6 +1953,7 @@ static int HandleEvents( hb_handle_t * h ) job->qsv.async_depth = qsv_async_depth; } job->qsv.decode = qsv_decode; + job->qsv.preset = qsv_preset; #endif /* Grab audio tracks */ @@ -3165,6 +3167,36 @@ static void ShowHelp() } if( len ) fprintf( out, "%s\n", tmp ); +#ifdef USE_QSV +if (hb_qsv_available()) +{ + fprintf(out, + " --qsv-preset When using QSV, selects the QSV preset:\n" + " <string> "); + x264_opts = hb_qsv_presets(); + tmp[0] = 0; + len = 0; + while (x264_opts != NULL && *x264_opts != NULL) + { + strncat(tmp, *x264_opts++, sizeof(tmp) - 1 - len); + if (*x264_opts != NULL) + { + strcat(tmp, "/"); + } + len = strlen(tmp); + if (len > 40 && *x264_opts != NULL) + { + fprintf(out, "%s\n ", tmp); + tmp[0] = 0; + len = 0; + } + } + if (len > 0) + { + fprintf(out, "%s\n", tmp); + } +} +#endif fprintf(out, " -x, --encopts <string> Specify advanced encoder options in the\n"); #ifdef USE_QSV @@ -3182,7 +3214,7 @@ else fprintf(out, " option1=value1:option2=value2\n" - " --h264-profile When using x264, ensures compliance with the\n" + " --h264-profile When using H.264, ensures compliance with the\n" " <string> specified H.264 profile:\n" " "); x264_opts = hb_h264_profiles(); @@ -3204,7 +3236,7 @@ else if( len ) fprintf( out, "%s\n", tmp ); fprintf( out, - " --h264-level When using x264, ensures compliance with the\n" + " --h264-level When using H.264, ensures compliance with the\n" " <string> specified H.264 level:\n" " "); x264_opts = hb_h264_levels(); @@ -3687,6 +3719,7 @@ static int ParseOptions( int argc, char ** argv ) #define AUDIO_DITHER 289 #define QSV_BASELINE 290 #define QSV_ASYNC_DEPTH 291 + #define QSV_PRESET 292 for( ;; ) { @@ -3697,11 +3730,12 @@ static int ParseOptions( int argc, char ** argv ) { "verbose", optional_argument, NULL, 'v' }, { "no-dvdnav", no_argument, NULL, DVDNAV }, { "no-opencl", no_argument, NULL, NO_OPENCL }, - + #ifdef USE_QSV - { "qsv-baseline", no_argument, NULL, QSV_BASELINE }, - { "qsv-async-depth", required_argument, NULL, QSV_ASYNC_DEPTH }, - { "disable-qsv-decoding", no_argument, &qsv_decode, 0 }, + { "qsv-preset", required_argument, NULL, QSV_PRESET, }, + { "qsv-baseline", no_argument, NULL, QSV_BASELINE, }, + { "qsv-async-depth", required_argument, NULL, QSV_ASYNC_DEPTH, }, + { "disable-qsv-decoding", no_argument, &qsv_decode, 0, }, #endif { "format", required_argument, NULL, 'f' }, @@ -4345,6 +4379,9 @@ static int ParseOptions( int argc, char ** argv ) case QSV_ASYNC_DEPTH: qsv_async_depth = atoi(optarg); break; + case QSV_PRESET: + qsv_preset = strdup(optarg); + break; #endif default: fprintf( stderr, "unknown option (%s)\n", argv[cur_optind] ); diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs index 6d990dc67..7d0a76c68 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs @@ -217,6 +217,9 @@ namespace HandBrake.Interop.HbLib public int async_depth;
+ /// const char*
+ public IntPtr preset;
+
/// av_qsv_context*
public IntPtr ctx;
|