]> granicus.if.org Git - handbrake/commitdiff
QSV: support of MSDK 2013 R2/API 1.7 release and new features, RB541
authorhandbrake <no-reply@handbrake.fr>
Mon, 22 Jul 2013 19:24:04 +0000 (19:24 +0000)
committerhandbrake <no-reply@handbrake.fr>
Mon, 22 Jul 2013 19:24:04 +0000 (19:24 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/qsv@5658 b64f7644-9d1e-0410-96f1-a4d463321fa5

16 files changed:
contrib/libmfx/module.defs
libhb/decavcodec.c
libhb/enc_qsv.c
libhb/enc_qsv.h
libhb/hb.c
libhb/hb.h
libhb/qsv_filter.c
test/test.c
win/CS/HandBrake.ApplicationServices/Factories/PlistPresetFactory.cs
win/CS/HandBrake.ApplicationServices/Services/PresetService.cs
win/CS/HandBrake.ApplicationServices/Utilities/PlistUtility.cs
win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs
win/CS/HandBrakeWPF/ViewModels/Interfaces/IMainViewModel.cs
win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
win/CS/HandBrakeWPF/Views/VideoView.xaml
win/CS/HandBrakeWPF/Views/VideoView.xaml.cs

index a83d32b7f41bf086a42bdae2d41d57ebe37663de..4377123b90370471bbf3d30304ef1441c9586a90 100644 (file)
@@ -1,6 +1,6 @@
 $(eval $(call import.MODULE.defs,LIBMFX,libmfx))
 $(eval $(call import.CONTRIB.defs,LIBMFX))
 
-LIBMFX.FETCH.url = http://download.handbrake.fr/contrib/mfx_dispatcher_2013_4.0.tar.bz2
+LIBMFX.FETCH.url = http://download.handbrake.fr/contrib/libmfx_intel_msdk_2013r2.tar.bz2
 
 LIBMFX.CONFIGURE.bootstrap = rm -fr aclocal.m4 autom4te.cache; autoreconf -fiv;
index 47536ca41a32443f243a1678cf0346a39c333965..8e6e0bfb0f0984ce81be0d778f8d66f92851cffe 100644 (file)
@@ -880,6 +880,9 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen
             pv->job->vcodec == HB_VCODEC_QSV_H264 && pv->job->title->video_codec_param == AV_CODEC_ID_H264 ){
             pv->context->hwaccel_context          = &pv->qsv_config;
             pv->qsv_config.io_pattern             = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+            if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_LOOKAHEAD)
+                pv->qsv_config.additional_buffers     = 160; // LA might need more surfaces
+            else
             pv->qsv_config.additional_buffers     = 64; // FIFO_LARGE for now
             // decode is async, sync only at encode
             pv->qsv_config.sync_need              = 0;
@@ -1204,7 +1207,7 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
             int ret;
             hb_dict_t *qsv_opts = NULL;
             hb_dict_entry_t *entry = NULL;
-            qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
+            qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info,job);
             if (job->advanced_opts != NULL && *job->advanced_opts != '\0')
             {
                 qsv_opts = hb_encopts_to_dict(job->advanced_opts, job->vcodec);
@@ -1240,6 +1243,9 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
         if(job && job->vcodec == HB_VCODEC_QSV_H264 ){
             pv->context->hwaccel_context          = &pv->qsv_config;
             pv->qsv_config.io_pattern             = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+            if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_LOOKAHEAD)
+                pv->qsv_config.additional_buffers     = 160;
+            else
             pv->qsv_config.additional_buffers     = 64;
             pv->qsv_config.sync_need              = 0;
             pv->qsv_config.usage_threaded         = 1;
@@ -1290,6 +1296,9 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
         if(job && job->vcodec == HB_VCODEC_QSV_H264 ){
             pv->context->hwaccel_context              = &pv->qsv_config;
             pv->qsv_config.io_pattern             = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+            if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_LOOKAHEAD)
+                pv->qsv_config.additional_buffers     = 160;
+            else
             pv->qsv_config.additional_buffers     = 64;
             pv->qsv_config.sync_need              = 0;
             pv->qsv_config.usage_threaded         = 1;
index f9976c78946b94912d7e3f67777765916127ba73..4b490fafbb813d45b5b9d493fd59d7049198681d 100644 (file)
@@ -139,6 +139,9 @@ struct hb_work_private_s
     mfxExtCodingOption2  qsv_coding_option2_config;
     mfxExtCodingOption   qsv_coding_option_config;
     int     mbbrx_param_idx;
+
+    // lookahead
+    mfxU16  la_depth;
 };
 
 extern char* get_codec_id(hb_work_private_t *pv);
@@ -278,17 +281,20 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     AV_QSV_ZERO_MEMORY(qsv_encode->m_mfxVideoParam);
     AV_QSV_ZERO_MEMORY(qsv_encode->m_mfxVideoParam.mfx);
 
-    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
+    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info,job);
 
     hb_dict_t *qsv_opts_dict = NULL;
     if( job->advanced_opts != NULL && *job->advanced_opts != '\0' )
         qsv_opts_dict = hb_encopts_to_dict( job->advanced_opts, job->vcodec );
 
+    int gop_pic_size_force = 0;
     int ret;
     hb_dict_entry_t *entry = NULL;
     while( ( entry = hb_dict_next( qsv_opts_dict, entry ) ) )
     {
         ret = qsv_param_parse( &pv->qsv_config, entry->key, entry->value );
+        if(!strcmp(entry->key,QSV_NAME_gop_pic_size))
+            gop_pic_size_force = 1;
         if( ret == QSV_PARAM_BAD_NAME )
             hb_log( "QSV options: Unknown suboption %s", entry->key );
         else
@@ -307,6 +313,8 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     qsv_encode->m_mfxVideoParam.mfx.TargetKbps              = 2000;
     qsv_encode->m_mfxVideoParam.mfx.RateControlMethod       = MFX_RATECONTROL_VBR;
 
+    int old_TargetKbps = qsv_encode->m_mfxVideoParam.mfx.TargetKbps;
+
     if (job->vquality >= 0)
     {
         int cqp_offset_i,cqp_offset_p,cqp_offset_b;
@@ -349,6 +357,7 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
         //
         qsv_encode->m_mfxVideoParam.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
         qsv_encode->m_mfxVideoParam.mfx.TargetKbps        = job->vbitrate;
+        old_TargetKbps = qsv_encode->m_mfxVideoParam.mfx.TargetKbps;
 
         // make it work like x264 for ease of use
         // (more convenient if switching back and forth)
@@ -392,24 +401,56 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
         hb_error("wrong parameters setting");
     }
 
+    if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_LOOKAHEAD)
+    {
+        int use_la = 0;
+
+        if (qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_VBR ||
+            qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_AVBR)
+        {
+            if ((entry = hb_dict_get(qsv_opts_dict, QSV_NAME_lookahead)) != NULL && entry->value != NULL)
+                use_la |= atoi(entry->value);
+            else
+            if (qsv_encode->m_mfxVideoParam.mfx.TargetUsage < 3)
+                use_la = 1; // sort of default value
+        }
+        if (use_la)
+        {
+            qsv_encode->m_mfxVideoParam.mfx.RateControlMethod = MFX_RATECONTROL_LA;
+            qsv_encode->m_mfxVideoParam.mfx.TargetKbps        = old_TargetKbps;
+        }
+    }
+
+    if (!gop_pic_size_force && qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_CQP)
+    {
+        pv->qsv_config.gop_pic_size = 32; // default for CQP, if not forced
+    }
+
     // version-specific encoder options
-    if (hb_qsv_info->capabilities & HB_QSV_CAP_MSDK_1_6)
+    if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_BRC)
     {
         if ((entry = hb_dict_get(qsv_opts_dict, QSV_NAME_mbbrc)) != NULL && entry->value != NULL)
         {
             pv->mbbrc =atoi(entry->value);
         }
         else
-            pv->mbbrc = 1; // MFX_CODINGOPTION_ON
+            pv->mbbrc = 1; // default: MFX_CODINGOPTION_ON
 
         if ((entry = hb_dict_get(qsv_opts_dict, QSV_NAME_extbrc)) != NULL && entry->value != NULL)
         {
             pv->extbrc =atoi(entry->value);
         }
         else
-            pv->extbrc = 2; //MFX_CODINGOPTION_OFF
+            pv->extbrc = 2; // default: MFX_CODINGOPTION_OFF
     }
 
+
+    if (hb_qsv_info->capabilities & HB_QSV_CAP_OPTION2_LOOKAHEAD)
+        if ((entry = hb_dict_get(qsv_opts_dict, QSV_NAME_lookaheaddepth)) != NULL && entry->value != NULL)
+            pv->la_depth = atoi(entry->value);
+        else
+            pv->la_depth = 40; // default: value
+
     hb_dict_free( &qsv_opts_dict );
 
     if(pv->qsv_config.async_depth)
@@ -428,12 +469,17 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
                                       break;
         case MFX_RATECONTROL_CQP    : rc_method = "MFX_RATECONTROL_CQP";
                                       break;
+        case MFX_RATECONTROL_LA     : rc_method = "MFX_RATECONTROL_LA";
+                                      break;
         default                     : rc_method = "unknown";
     };
 
     if( qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_CQP )
         hb_log("qsv: RateControlMethod:%s(I:%d/P:%d/B:%d)",rc_method,
                                                 qsv_encode->m_mfxVideoParam.mfx.QPI, qsv_encode->m_mfxVideoParam.mfx.QPP, qsv_encode->m_mfxVideoParam.mfx.QPB );
+    else
+    if( qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_LA )
+        hb_log("qsv: RateControlMethod:%s LookAheadDepth:%d TargetKbps:%d",rc_method , pv->la_depth, qsv_encode->m_mfxVideoParam.mfx.TargetKbps  );
     else
         hb_log("qsv: RateControlMethod:%s TargetKbps:%d",rc_method , qsv_encode->m_mfxVideoParam.mfx.TargetKbps );
 
@@ -517,7 +563,8 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     if(!pv->is_sys_mem)
         qsv_encode->p_ext_param_num = 1; // for MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
 
-    if(pv->mbbrc || pv->extbrc){
+    if (pv->mbbrc || pv->extbrc || qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_LA)
+    {
         qsv_encode->p_ext_param_num++;
     }
 
@@ -525,7 +572,8 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
 
     qsv_encode->m_mfxVideoParam.NumExtParam = qsv_encode->p_ext_param_num;
 
-    if(qsv_encode->m_mfxVideoParam.NumExtParam){
+    if (qsv_encode->m_mfxVideoParam.NumExtParam)
+    {
         int cur_idx = 0;
         qsv_encode->p_ext_params = av_mallocz(sizeof(mfxExtBuffer *)*qsv_encode->p_ext_param_num);
         AV_QSV_CHECK_POINTER(qsv_encode->p_ext_params, MFX_ERR_MEMORY_ALLOC);
@@ -537,7 +585,8 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
         pv->qsv_coding_option_config.PicTimingSEI     = MFX_CODINGOPTION_OFF;
         qsv_encode->p_ext_params[cur_idx++]            = (mfxExtBuffer*)&pv->qsv_coding_option_config;
 
-        if(!pv->is_sys_mem){
+        if (!pv->is_sys_mem)
+        {
             memset(&qsv_encode->ext_opaque_alloc, 0, sizeof(mfxExtOpaqueSurfaceAlloc));
             qsv_encode->ext_opaque_alloc.Header.BufferId    = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
             qsv_encode->ext_opaque_alloc.Header.BufferSz    = sizeof(mfxExtOpaqueSurfaceAlloc);
@@ -555,12 +604,14 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
             qsv_encode->ext_opaque_alloc.In.Type        = qsv_encode->request[0].Type;
         }
 
-        if(pv->mbbrc || pv->extbrc){
+        if (pv->mbbrc || pv->extbrc || qsv_encode->m_mfxVideoParam.mfx.RateControlMethod == MFX_RATECONTROL_LA)
+        {
             pv->qsv_coding_option2_config.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION2;
             pv->qsv_coding_option2_config.Header.BufferSz  = sizeof(mfxExtCodingOption2);
             pv->qsv_coding_option2_config.MBBRC            = pv->mbbrc << 4;
                                                             // default is off
             pv->qsv_coding_option2_config.ExtBRC           = pv->extbrc == 0 ? MFX_CODINGOPTION_OFF : pv->extbrc << 4;
+            pv->qsv_coding_option2_config.LookAheadDepth   = pv->la_depth;
 
             // reset if out of the ranges
             if(pv->qsv_coding_option2_config.MBBRC > MFX_CODINGOPTION_ADAPTIVE)
@@ -581,6 +632,7 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
             if( pv->mbbrx_param_idx ){
                 pv->qsv_coding_option2_config.MBBRC     = MFX_CODINGOPTION_UNKNOWN;
                 pv->qsv_coding_option2_config.ExtBRC    = MFX_CODINGOPTION_OFF;
+                pv->qsv_coding_option2_config.LookAheadDepth    = 0;
                     pv->mbbrx_param_idx = 0;
             }
         }
@@ -635,7 +687,7 @@ int qsv_enc_init( av_qsv_context* qsv, hb_work_private_t * pv ){
     pv->bfrm_delay = FFMAX(pv->bfrm_delay, 0);
     // check whether we need to generate DTS ourselves (MSDK API < 1.6 or VFR)
     pv->bfrm_workaround = job->cfr != 1 || !(hb_qsv_info->capabilities &
-                                             HB_QSV_CAP_MSDK_1_6);
+                                             HB_QSV_CAP_BITSTREAM_DTS);
     if (pv->bfrm_delay && pv->bfrm_workaround)
     {
         pv->bfrm_workaround = 1;
@@ -1093,8 +1145,8 @@ int encqsvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
                 {
                     // MSDK API < 1.6 or VFR, so generate our own DTS
                     if ((pv->frames_out == 0)                             &&
-                        (hb_qsv_info->capabilities & HB_QSV_CAP_MSDK_1_6) &&
-                        (hb_qsv_info->capabilities & HB_QSV_CAP_BPYRAMID))
+                        (hb_qsv_info->capabilities & HB_QSV_CAP_BITSTREAM_DTS) &&
+                        (hb_qsv_info->capabilities & HB_QSV_CAP_H264_BPYRAMID))
                     {
                         // with B-pyramid, the delay may be more than 1 frame,
                         // so compute the actual delay based on the initial DTS
@@ -1302,7 +1354,9 @@ int qsv_param_parse( av_qsv_config* config, const char *name, const char *value)
        !strcmp(name,QSV_NAME_extbrc)      ||
        !strcmp(name,QSV_NAME_cqp_offset_i)      ||
        !strcmp(name,QSV_NAME_cqp_offset_p)      ||
-       !strcmp(name,QSV_NAME_cqp_offset_b)
+       !strcmp(name,QSV_NAME_cqp_offset_b)      ||
+       !strcmp(name,QSV_NAME_lookaheaddepth)    ||
+       !strcmp(name,QSV_NAME_lookahead)
        )
         ret = QSV_PARAM_OK;
     else
@@ -1311,12 +1365,15 @@ int qsv_param_parse( av_qsv_config* config, const char *name, const char *value)
     return ret;
 }
 
-void qsv_param_set_defaults( av_qsv_config* config, hb_qsv_info_t *qsv_info ){
+void qsv_param_set_defaults( av_qsv_config* config, hb_qsv_info_t *qsv_info, hb_job_t *job ){
     if(!config)
         return;
 
     config->async_depth     = AV_QSV_ASYNC_DEPTH_DEFAULT;
     config->target_usage    = MFX_TARGETUSAGE_BEST_QUALITY + 1;
+    config->num_ref_frame   = 0;
     config->gop_ref_dist    = 4;
-    config->gop_pic_size    = 32;
+
+    int used_rate = round((float)job->vrate/(float)job->vrate_base);
+    config->gop_pic_size    = (used_rate * 5) + 1;
 }
index c5c5fc735b480b667f68ce990bf4fa786242bfad..5f5d8d4b35171f9bb2627452095e4e7907c940f7 100644 (file)
@@ -50,6 +50,8 @@ void parse_nalus( uint8_t *nal_inits, size_t length, hb_buffer_t *buf, uint32_t
 #define QSV_NAME_cqp_offset_i   "cqp-offset-i"
 #define QSV_NAME_cqp_offset_p   "cqp-offset-p"
 #define QSV_NAME_cqp_offset_b   "cqp-offset-b"
+#define QSV_NAME_lookaheaddepth "lookahead-depth"
+#define QSV_NAME_lookahead      "lookahead"
 
 typedef enum {
     QSV_PARAM_OK            = 0,
@@ -59,6 +61,6 @@ typedef enum {
 } qsv_param_errors;
 
 int qsv_param_parse( av_qsv_config* config, const char *name, const char *value);
-void qsv_param_set_defaults( av_qsv_config* config, hb_qsv_info_t *qsv_info );
+void qsv_param_set_defaults( av_qsv_config* config, hb_qsv_info_t *qsv_info, hb_job_t *job );
 
 #endif //ENC_QSV_H
index 4b0a348241bd0c0fd2626b15b214f6a6d965bd90..162dbe0e86c82974915b5f33a36939d03e326de9 100644 (file)
@@ -370,7 +370,7 @@ static int hb_qsv_info_init()
         return (hb_qsv_info == NULL);
     init_done = 1;
 
-    hb_qsv_info = malloc(sizeof(*hb_qsv_info));
+    hb_qsv_info = calloc(sizeof(*hb_qsv_info),1);
     if (hb_qsv_info == NULL)
     {
         hb_error("hb_qsv_info_init: malloc failure");
@@ -440,7 +440,6 @@ static int hb_qsv_info_init()
     }
 
     mfxSession session;
-    hb_qsv_info->capabilities          = 0;
     hb_qsv_info->minimum_version.Major = HB_QSV_MINVERSION_MAJOR;
     hb_qsv_info->minimum_version.Minor = HB_QSV_MINVERSION_MINOR;
     hb_qsv_info->software_available    = hb_qsv_info->hardware_available = 0;
@@ -475,19 +474,28 @@ static int hb_qsv_info_init()
     {
         if (HB_QSV_MIN_HARDWARE(1, 6))
         {
-            hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_1_6;
+            hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_BRC;
+            hb_qsv_info->capabilities |= HB_QSV_CAP_BITSTREAM_DTS;
         }
+        if (HB_QSV_MIN_HARDWARE(1, 7))
+        {
         if (hb_qsv_info->cpu_platform == HB_CPU_PLATFORM_INTEL_HSW)
         {
-            hb_qsv_info->capabilities |= HB_QSV_CAP_BPYRAMID;
+                hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_LOOKAHEAD;
         }
     }
-    else
+        if (hb_qsv_info->cpu_platform == HB_CPU_PLATFORM_INTEL_HSW)
+    {
+            hb_qsv_info->capabilities |= HB_QSV_CAP_H264_BPYRAMID;
+        }
+    }
+    else if (hb_qsv_info->software_available)
     {
         if (HB_QSV_MIN_SOFTWARE(1, 6))
         {
-            hb_qsv_info->capabilities |= HB_QSV_CAP_MSDK_1_6;
-            hb_qsv_info->capabilities |= HB_QSV_CAP_BPYRAMID;
+            hb_qsv_info->capabilities |= HB_QSV_CAP_OPTION2_BRC;
+            hb_qsv_info->capabilities |= HB_QSV_CAP_BITSTREAM_DTS;
+            hb_qsv_info->capabilities |= HB_QSV_CAP_H264_BPYRAMID;
         }
     }
 
index 42a1755de95b29338bf97c971a8a2135147db020..34bd93530a512b52c4f0c1ba839e3cd729c40db8 100644 (file)
@@ -162,8 +162,10 @@ typedef struct hb_qsv_info_s
 
     // supported version-specific or hardware-specific capabilities
     int capabilities;
-#define HB_QSV_CAP_MSDK_1_6 0x0000001
-#define HB_QSV_CAP_BPYRAMID 0x0000010
+#define HB_QSV_CAP_H264_BPYRAMID     1 << 0 // H.264: reference B-frames
+#define HB_QSV_CAP_BITSTREAM_DTS     1 << 1 // mfxBitStream: DecodeTimeStamp
+#define HB_QSV_CAP_OPTION2_BRC       1 << 2 // mfxExtCodingOption2: MBBRC/ExtBRC
+#define HB_QSV_CAP_OPTION2_LOOKAHEAD 1 << 3 // mfxExtCodingOption2: LookAhead
 
     // if a feature depends on the cpu generation
     enum
index 9b5a5e0f8a34fd69265bdde01a951ac437987419..ad9cd3fc27da2a51c31b5db9b01423023ca4045f 100644 (file)
@@ -111,7 +111,7 @@ static int filter_init( av_qsv_context* qsv, hb_filter_private_t * pv ){
     av_qsv_add_context_usage(qsv,HAVE_THREADS);
 
 
-    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info);
+    qsv_param_set_defaults(&pv->qsv_config, hb_qsv_info,pv->job);
     hb_dict_t * qsv_opts = NULL;
     if( pv->job->advanced_opts != NULL && *pv->job->advanced_opts != '\0' )
         qsv_opts = hb_encopts_to_dict( pv->job->advanced_opts, pv->job->vcodec );
index 5566ec313b5742964e2bbc3018e75f7266e9ca6f..23e36c40ed27a57845614817dd612868d339a44c 100644 (file)
@@ -3473,17 +3473,44 @@ if (hb_qsv_available())
     "### QSV Options, via --encopts=\"option1=value1:option2=value2\" -----------\n\n"
     "        - target-usage  A range of numbers that indicate trade-offs between\n"
     "          <number>          quality and speed, from 1 to 7 inclusive.\n"
-    "        - num-ref-frame Number of reference frames; if equal to 0, this parameter is\n"
-    "          <number>          not specified.\n"
-    "        - gop-pic-size  Number of pictures within the current GOP (Group of Pictures);\n"
-    "          <number>          if equal to 0, then the GOP size is unspecified.\n"
+    "                            Default is 2\n"
+    "        - num-ref-frame Number of reference frames; if equal to 0,\n"
+    "          <number>          this parameter is not specified.\n"
+    "        - gop-pic-size  Number of pictures within the current GOP.\n"
+    "          <number>          If equal to 0, then the GOP size is unspecified.\n"
     "                            If equal to 1, only I-frames are used.\n"
     "        - gop-ref-dist  Distance between I- or P- key frames; if it is zero,\n"
     "          <number>          the GOP structure is unspecified.\n"
     "                            Note: If GopRefDist = 1, there are no B-frames used.\n"
-    "        - async-depth   Specifies how many asynchronous operations an application performs\n"
-    "          <number>          before the application explicitly synchronizes the result.\n"
+    "        - async-depth   Specifies how many asynchronous operations an\n"
+    "          <number>          application performsbefore the application\n"
+    "                            explicitly synchronizes the result.\n"
     "                            If zero, the value is not specified. Default is 4\n"
+    "        - mbbrc         Setting this flag enables macroblock level bitrate\n"
+    "          <number>          control that generally improves subjective\n"
+    "                            visual quality.\n"
+    "                            Enabling this flag may have negative impact on\n"
+    "                            performance and objective visual quality metric.\n"
+    "                            Default is ON\n"
+    "        - extbrc        Setting this flag instructs encoder to use extended\n"
+    "          <number>          bitrate control algorithms. It generally improves\n"
+    "                            objective and subjective visual quality, but it\n"
+    "                            also leads to violation of HRD conformance and may\n"
+    "                            significantly reduce performance.\n"
+    "                            Default is OFF\n"
+    "        - cqp-offset-i\n"
+    "        - cqp-offset-p\n"
+    "        - cqp-offset-b  Specify shift/offset for QP(CQP) mode and each\n"
+    "                            Default is \"0:2:4\"\n"
+    "          <number>          I, P and B frames respectively.\n"
+    "        - lookahead     Use the look ahead bitrate control algorithm.\n"
+    "          <number>          Value more than 0 - enables the feature,\n"
+    "                            if supported by runtime hardware and driver\n"
+    "        - lookahead-depth   Specifies the depth of look ahead rate control\n"
+    "          <number>          algorithm. It is number of frames that SDK\n"
+    "                            encoder analyzes before encoding. Valid value\n"
+    "                            range is from 10 to 100 inclusive.\n"
+    "                            Default is 40\n"
     "\n"
     );
 }
@@ -4268,7 +4295,9 @@ static int ParseOptions( int argc, char ** argv )
                 if (hb_qsv_available())
                 {
                     /* XXX: for testing workarounds */
-                    hb_qsv_info->capabilities &= ~HB_QSV_CAP_MSDK_1_6;
+                    hb_qsv_info->capabilities &= ~HB_QSV_CAP_BITSTREAM_DTS;
+                    hb_qsv_info->capabilities &= ~HB_QSV_CAP_OPTION2_BRC;
+                    hb_qsv_info->capabilities &= ~HB_QSV_CAP_OPTION2_LOOKAHEAD;
                 }
 #endif
                 break;
index 6e738351a3799e3687e103c49a0d0d696711bfed..00b41398a71542a8041ee538ccdd85d72ceceaf1 100644 (file)
@@ -238,7 +238,9 @@ namespace HandBrake.ApplicationServices.Factories
                 case "h264Level":\r
                     preset.Task.H264Level = kvp.Value;\r
                     break;\r
-\r
+                case "QsvPreset":\r
+                    preset.Task.QsvPreset = EnumHelper<QsvPreset>.GetValue(kvp.Value, true);\r
+                    break;\r
                 // Chapter Markers Tab\r
                 case "ChapterMarkers":\r
                     preset.Task.IncludeChapterMarkers = kvp.Value == 1;\r
index e40c440335f46c3ba48179d9afb5cbe2b0c4ec5a..0b528b5ee2f4d8637876bda8e96053b9dcf69a2d 100644 (file)
@@ -522,8 +522,7 @@ namespace HandBrake.ApplicationServices.Services
 \r
             preset.Task.VideoEncoder = VideoEncoder.QuickSync;\r
             preset.Task.Quality = 20;\r
-            preset.Task.AdvancedEncoderOptions =\r
-                "gop-ref-dist=4:gop-pic-size=32:async-depth=4";\r
+            preset.Task.AdvancedEncoderOptions = "async-depth=4";\r
             preset.Task.AudioTracks = new ObservableCollection<AudioTrack>();\r
             preset.Task.AudioTracks.Add(new AudioTrack { Bitrate = 224, Encoder = AudioEncoder.ffaac, MixDown = Mixdown.DolbyProLogicII});\r
             preset.Task.Anamorphic = Anamorphic.Loose;\r
index a6a91cce7bec10b1e9fd31bd9a753c0c6b3474ac..9017ee93dd326c5db16bcbe725dc52e51b36b41e 100644 (file)
@@ -273,6 +273,7 @@ namespace HandBrake.ApplicationServices.Utilities
             AddEncodeElement(xmlWriter, "x264OptionExtra", "string", parsed.AdvancedEncoderOptions);\r
             AddEncodeElement(xmlWriter, "x264Preset", "string", parsed.X264Preset.ToString().ToLower());\r
             AddEncodeElement(xmlWriter, "h264Profile", "string", parsed.H264Profile.ToString().ToLower());\r
+            AddEncodeElement(xmlWriter, "QsvPreset", "string", parsed.QsvPreset.ToString());\r
             string tune = parsed.X264Tune.ToString().ToLower();\r
             if (parsed.FastDecode)\r
             {\r
index 2dbaa37950ac880b9d263bfbce99805e6f351f7b..9931caf865981e63a65dd3db2a232e5ae6edc423 100644 (file)
@@ -33,7 +33,7 @@ namespace HandBrakeWPF.ViewModels
         public EncoderOptionsViewModel()\r
         {\r
             this.Task = new EncodeTask();\r
-            cachedOptions.Add(VideoEncoder.QuickSync, "gop-ref-dist=4:gop-pic-size=32:async-depth=4");\r
+            cachedOptions.Add(VideoEncoder.QuickSync, "async-depth=4");\r
         }\r
 \r
         /// <summary>\r
index 67dcf4c0930aceba30468c4a26ca097b13c2079e..e6cf6ce61f653068cecf1d2f2b9e50bf07eec307 100644 (file)
@@ -84,5 +84,7 @@ namespace HandBrakeWPF.ViewModels.Interfaces
         /// Shutdown this View\r
         /// </summary>\r
         void Shutdown();\r
+\r
+        EncodeTask GetCurrentTask();\r
     }\r
 }
\ No newline at end of file
index 81ac6a688dd2f78a231b730e843f72d647b0bca2..4202dd7d76c344998f686019b9faba95c5afe4f3 100644 (file)
@@ -1313,6 +1313,11 @@ namespace HandBrakeWPF.ViewModels
             this.scanService.Scan(task.Source, task.Title, this.UserSettingService.GetUserSetting<int>(ASUserSettingConstants.PreviewScanCount), QueueEditAction);\r
         }\r
 \r
+        public EncodeTask GetCurrentTask()\r
+        {\r
+            return this.CurrentTask;\r
+        }\r
+\r
         /// <summary>\r
         /// Pause an Encode\r
         /// </summary>\r
index bb5f666917e15a93f5a1ef8052f0d930f705479f..a3b740568e13ca28899d6146089db38eea4b472e 100644 (file)
@@ -94,7 +94,7 @@
                 <TextBlock Text="Quality" FontWeight="Bold" Margin="0,0,0,10"/>\r
 \r
                 <StackPanel Orientation="Horizontal" Margin="0,0,0,10" >\r
-                    <RadioButton Content="Constant Quality:" IsChecked="{Binding IsConstantQuantity}"  Margin="0,0,10,0"/>\r
+                    <RadioButton Content="Constant Quality:" IsChecked="{Binding IsConstantQuantity}"  Margin="0,0,10,0" Checked="qsv_preset_radiobutton"/>\r
                     <TextBlock Text="{Binding DisplayRF}" MinWidth="30" />\r
                     <TextBlock Text="{Binding Rfqp}" FontWeight="Bold" Margin="5,0,0,0" />\r
 \r
                 </Grid>\r
 \r
                 <StackPanel Orientation="Horizontal" Margin="0,0,0,10">\r
-                    <RadioButton Content="Avg Bitrate (kbps):" IsChecked="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="0,0,10,0"/>\r
+                    <RadioButton Content="Avg Bitrate (kbps):" IsChecked="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="0,0,10,0" Checked="qsv_preset_radiobutton"/>\r
                     <TextBox Width="75" Text="{Binding Task.VideoBitrate, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" />\r
                 </StackPanel>\r
 \r
                     <StackPanel Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal"\r
                                 Visibility="{Binding DisplayQSVOptions, Converter={StaticResource boolToVisConverter}}" >\r
                         <Slider Minimum="0" Maximum="{Binding QsvSliderMax}" Width="150" Value="{Binding QsvPresetValue, Mode=Default, UpdateSourceTrigger=PropertyChanged}" \r
-                            IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight" />\r
+                            IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight" ValueChanged="qsv_preset_ValueChanged"/>\r
                         <TextBlock Text="{Binding QsvPreset, Converter={StaticResource enumComboConverter}}" Margin="5,0,0,0" />\r
                     </StackPanel>\r
 \r
index 8a0842a96bdc0304e17d651906fa379912404db8..b653dfc415c142237f21c033760ed3b0bb82ed50 100644 (file)
 namespace HandBrakeWPF.Views\r
 {\r
     using System.Windows.Controls;\r
+    using System.Collections.Generic;\r
+    using System.Windows;\r
+    using Caliburn.Micro;\r
+    using HandBrake.ApplicationServices.Model;\r
+    using HandBrake.ApplicationServices.Utilities;\r
+    using HandBrake.Interop.Model.Encoding;\r
+\r
+    using HandBrakeWPF.ViewModels.Interfaces;\r
 \r
     /// <summary>\r
     /// Interaction logic for VideoView.xaml\r
@@ -23,5 +31,78 @@ namespace HandBrakeWPF.Views
         {\r
             InitializeComponent();\r
         }\r
+\r
+        private void qsv_preset_radiobutton(object sender, System.Windows.RoutedEventArgs e)\r
+        {\r
+            qsv_preset_ValueChanged(sender,null);\r
+    }\r
+\r
+        private void qsv_preset_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)\r
+        {\r
+            IMainViewModel mvm = IoC.Get<IMainViewModel>();\r
+            EncodeTask task = mvm.GetCurrentTask();\r
+            string addon = "";\r
+\r
+            if (SystemInfo.IsHswOrNewer)\r
+            {\r
+                if (task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality)\r
+                {\r
+                if (task.QsvPreset == QsvPreset.Balanced ||\r
+                    task.QsvPreset == QsvPreset.Speed)\r
+                    addon = "num-ref-frame=1";\r
+}\r
+                if (task.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate)\r
+                {\r
+                    if (task.QsvPreset == QsvPreset.Quality) \r
+                        addon = "lookahead=1:gop-ref-dist=3";\r
+                    else\r
+                    if (task.QsvPreset == QsvPreset.Balanced)\r
+                    {\r
+                        addon = "num-ref-frame=1:gop-ref-dist=1";\r
+                    }\r
+                    else\r
+                    if (task.QsvPreset == QsvPreset.Speed)\r
+                        addon = "gop-ref-dist=1";\r
+                }\r
+            }\r
+\r
+\r
+            string full_string = addon + ":";\r
+\r
+            IDictionary<string, string> newOptions = new Dictionary<string, string>();\r
+            string[] existingSegments = full_string.Split(':');\r
+            foreach (string existingSegment in existingSegments)\r
+            {\r
+                string optionName  = existingSegment;\r
+                string optionValue = string.Empty; \r
+                int equalsIndex = existingSegment.IndexOf('=');\r
+                if (equalsIndex >= 0)\r
+                {\r
+                    optionName = existingSegment.Substring(\r
+                        0, existingSegment.IndexOf("=", System.StringComparison.Ordinal));\r
+                    optionValue = existingSegment.Substring(equalsIndex);\r
+                }\r
+\r
+                if (optionName != string.Empty)\r
+                {\r
+                    if (newOptions.ContainsKey(optionName)) \r
+                        newOptions.Remove(optionName);\r
+                    newOptions.Add(optionName, optionValue);\r
+                }\r
+            }\r
+\r
+            full_string = "";\r
+            foreach (KeyValuePair<string, string> entry in newOptions)\r
+            {\r
+                full_string += entry.Key;\r
+                if (entry.Value != string.Empty) \r
+                    full_string += entry.Value;\r
+                full_string += ":";\r
+            }\r
+            full_string = full_string.TrimEnd(':');\r
+\r
+            task.AdvancedEncoderOptions = full_string;\r
+            task.NotifyOfPropertyChange(() => task.AdvancedEncoderOptions);\r
+        }\r
     }\r
 }\r