]> granicus.if.org Git - handbrake/commitdiff
libhb: make encoder options less x264-centric.
authorRodeo <tdskywalker@gmail.com>
Thu, 13 Feb 2014 15:18:15 +0000 (15:18 +0000)
committerRodeo <tdskywalker@gmail.com>
Thu, 13 Feb 2014 15:18:15 +0000 (15:18 +0000)
profile/level control and, to a lesser extent,
encoder presets and tunes are becoming more common.

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6031 b64f7644-9d1e-0410-96f1-a4d463321fa5

14 files changed:
gtk/src/hb-backend.c
libhb/common.c
libhb/common.h
libhb/enc_qsv.c
libhb/encavcodec.c
libhb/encx264.c
libhb/encx265.c
libhb/hb.c
libhb/work.c
macosx/Controller.m
macosx/HBPreviewGenerator.m
macosx/module.defs
test/module.defs
test/test.c

index 2c1e568cbc5f373873720ec2af06d920f11cf9d3..393aad0e521ed776aefec2ba9801d91707b6c6d3 100644 (file)
@@ -3174,7 +3174,7 @@ void ghb_set_video_encoder_opts(hb_job_t *job, GValue *js)
             if (ghb_settings_get_boolean(js, "x264UseAdvancedOptions"))
             {
                 char *opts = ghb_settings_get_string(js, "x264Option");
-                hb_job_set_advanced_opts(job, opts);
+                hb_job_set_encoder_options(job, opts);
                 g_free(opts);
             }
             else
@@ -3198,18 +3198,18 @@ void ghb_set_video_encoder_opts(hb_job_t *job, GValue *js)
                 }
                 tunes = g_string_free(str, FALSE);
 
-                hb_job_set_x264_preset(job, preset);
+                hb_job_set_encoder_preset(job, preset);
 
                 if (tunes != NULL && strcasecmp(tune, "none"))
-                    hb_job_set_x264_tune(job, tunes);
+                    hb_job_set_encoder_tune(job, tunes);
 
                 if (profile != NULL && strcasecmp(profile, "auto"))
-                    hb_job_set_h264_profile(job, profile);
+                    hb_job_set_encoder_profile(job, profile);
 
                 if (level != NULL && strcasecmp(level, "auto"))
-                    hb_job_set_h264_level(job, level);
+                    hb_job_set_encoder_level(job, level);
 
-                hb_job_set_advanced_opts(job, opts);
+                hb_job_set_encoder_options(job, opts);
 
                 g_free(preset);
                 g_free(tune);
@@ -3226,7 +3226,7 @@ void ghb_set_video_encoder_opts(hb_job_t *job, GValue *js)
             gchar *opts = ghb_settings_get_string(js, "lavcOption");
             if (opts != NULL && opts[0])
             {
-                hb_job_set_advanced_opts(job, opts);
+                hb_job_set_encoder_options(job, opts);
             }
             g_free(opts);
         } break;
@@ -5233,7 +5233,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
          */
         job->pass = -1;
         job->indepth_scan = 1;
-        hb_job_set_advanced_opts(job, NULL);
+        hb_job_set_encoder_options(job, NULL);
 
         /*
          * Add the pre-scan job
index bcbff39aa4718b548a228a51fe4f0569a9dc4467..6dbdde75c70162fd1d5600b163dbb2b07e49404e 100644 (file)
@@ -3067,18 +3067,18 @@ static void job_clean( hb_job_t * job )
         hb_filter_object_t *filter;
         hb_attachment_t *attachment;
 
+        free(job->encoder_preset);
+        job->encoder_preset = NULL;
+        free(job->encoder_tune);
+        job->encoder_tune = NULL;
+        free(job->encoder_options);
+        job->encoder_options = NULL;
+        free(job->encoder_profile);
+        job->encoder_profile = NULL;
+        free(job->encoder_level);
+        job->encoder_level = NULL;
         free(job->file);
         job->file = NULL;
-        free(job->advanced_opts);
-        job->advanced_opts = NULL;
-        free(job->x264_preset);
-        job->x264_preset = NULL;
-        free(job->x264_tune);
-        job->x264_tune = NULL;
-        free(job->h264_profile);
-        job->h264_profile = NULL;
-        free(job->h264_level);
-        job->h264_level = NULL;
 
         // clean up chapter list
         while( ( chapter = hb_list_item( job->list_chapter, 0 ) ) )
@@ -3184,54 +3184,81 @@ void hb_job_close( hb_job_t ** _j )
     }
 }
 
-void hb_job_set_file( hb_job_t *job, const char *file )
+void hb_job_set_encoder_preset(hb_job_t *job, const char *preset)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->file, file );
+        hb_update_str(&job->encoder_preset, preset);
     }
 }
 
-void hb_job_set_advanced_opts( hb_job_t *job, const char *advanced_opts )
+void hb_job_set_encoder_tune(hb_job_t *job, const char *tune)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->advanced_opts, advanced_opts );
+        hb_update_str(&job->encoder_tune, tune);
     }
 }
 
-void hb_job_set_x264_preset( hb_job_t *job, const char *preset )
+void hb_job_set_encoder_options(hb_job_t *job, const char *options)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->x264_preset, preset );
+        hb_update_str(&job->encoder_options, options);
     }
 }
 
-void hb_job_set_x264_tune( hb_job_t *job, const char *tune )
+void hb_job_set_encoder_profile(hb_job_t *job, const char *profile)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->x264_tune, tune );
+        hb_update_str(&job->encoder_profile, profile);
     }
 }
 
-void hb_job_set_h264_profile( hb_job_t *job, const char *profile )
+void hb_job_set_encoder_level(hb_job_t *job, const char *level)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->h264_profile, profile );
+        hb_update_str(&job->encoder_level, level);
     }
 }
 
-void hb_job_set_h264_level( hb_job_t *job, const char *level )
+void hb_job_set_file(hb_job_t *job, const char *file)
 {
-    if ( job )
+    if (job != NULL)
     {
-        hb_update_str( &job->h264_level, level );
+        hb_update_str(&job->file, file);
     }
 }
 
+#ifdef HB_API_OLD_PRESET_SETTERS
+void hb_job_set_x264_preset(hb_job_t *job, const char *preset)
+{
+    hb_job_set_encoder_preset(job, preset);
+}
+
+void hb_job_set_x264_tune(hb_job_t *job, const char *tune)
+{
+    hb_job_set_encoder_tune(job, tune);
+}
+
+void hb_job_set_advanced_opts(hb_job_t *job, const char *opts)
+{
+    hb_job_set_encoder_options(job, opts);
+}
+
+void hb_job_set_h264_profile(hb_job_t *job, const char *profile)
+{
+    hb_job_set_encoder_profile(job, profile);
+}
+
+void hb_job_set_h264_level(hb_job_t *job, const char *level)
+{
+    hb_job_set_encoder_level(job, level);
+}
+#endif
+
 hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter )
 {
     if( filter == NULL )
index 87c6f8904a3f6e84dc8cd47a52bf95964fe27140..7544740dd539909a3f2bcb3167f647a9e09d7204 100644 (file)
@@ -137,12 +137,21 @@ void hb_limit_rational64( int64_t *x, int64_t *y, int64_t num, int64_t den, int6
 #define HB_KEEP_HEIGHT 1
 void hb_fix_aspect( hb_job_t * job, int keep );
 
-void hb_job_set_advanced_opts( hb_job_t *job, const char *advanced_opts );
-void hb_job_set_x264_preset( hb_job_t *job, const char *preset );
-void hb_job_set_x264_tune( hb_job_t *job, const char *tune );
-void hb_job_set_h264_profile( hb_job_t *job, const char *profile );
-void hb_job_set_h264_level( hb_job_t *job, const char *level );
-void hb_job_set_file( hb_job_t *job, const char *file );
+void hb_job_set_encoder_preset (hb_job_t *job, const char *preset);
+void hb_job_set_encoder_tune   (hb_job_t *job, const char *tune);
+void hb_job_set_encoder_options(hb_job_t *job, const char *options);
+void hb_job_set_encoder_profile(hb_job_t *job, const char *profile);
+void hb_job_set_encoder_level  (hb_job_t *job, const char *level);
+void hb_job_set_file           (hb_job_t *job, const char *file);
+// TODO: legacy functions, remove once UIs are updated
+#define HB_API_OLD_PRESET_SETTERS
+#ifdef  HB_API_OLD_PRESET_SETTERS
+void hb_job_set_x264_preset  (hb_job_t *job, const char *preset);
+void hb_job_set_x264_tune    (hb_job_t *job, const char *tune);
+void hb_job_set_advanced_opts(hb_job_t *job, const char *opts);
+void hb_job_set_h264_profile (hb_job_t *job, const char *profile);
+void hb_job_set_h264_level   (hb_job_t *job, const char *level);
+#endif
 
 hb_audio_t *hb_audio_copy(const hb_audio_t *src);
 hb_list_t *hb_audio_list_copy(const hb_list_t *src);
@@ -441,8 +450,7 @@ struct hb_job_s
          vrate, vrate_base: output framerate is vrate / vrate_base
          cfr:               0 (vfr), 1 (cfr), 2 (pfr) [see render.c]
          pass:              0, 1 or 2 (or -1 for scan)
-         advanced_opts:     string of extra advanced encoder options
-         areBframes:        boolean to note if b-frames are included in advanced_opts */
+         areBframes:        boolean to note if b-frames are used */
 #define HB_VCODEC_MASK         0x0000FFF
 #define HB_VCODEC_X264         0x0000001
 #define HB_VCODEC_THEORA       0x0000002
@@ -462,11 +470,41 @@ struct hb_job_s
     int             cfr;
     int             pass;
     int             fastfirstpass;
-    char            *x264_preset;
-    char            *x264_tune;
-    char            *advanced_opts;
-    char            *h264_profile;
-    char            *h264_level;
+    union
+    {
+#ifdef HB_API_OLD_PRESET_SETTERS
+        char *x264_preset;     // TODO: legacy name, remove once UIs are updated
+#endif
+        char *encoder_preset;
+    };
+    union
+    {
+#ifdef HB_API_OLD_PRESET_SETTERS
+        char *x264_tune;       // TODO: legacy name, remove once UIs are updated
+#endif
+        char *encoder_tune;
+    };
+    union
+    {
+#ifdef HB_API_OLD_PRESET_SETTERS
+        char *advanced_opts;   // TODO: legacy name, remove once UIs are updated
+#endif
+        char *encoder_options;
+    };
+    union
+    {
+#ifdef HB_API_OLD_PRESET_SETTERS
+        char *h264_profile;    // TODO: legacy name, remove once UIs are updated
+#endif
+        char *encoder_profile;
+    };
+    union
+    {
+#ifdef HB_API_OLD_PRESET_SETTERS
+        char *h264_level;      // TODO: legacy name, remove once UIs are updated
+#endif
+        char *encoder_level;
+    };
     int             areBframes;
 
     int             color_matrix_code;
@@ -556,7 +594,11 @@ struct hb_job_s
     {
         int decode;
         int async_depth;
-        const char *preset;
+#ifdef HB_API_OLD_PRESET_SETTERS
+        const char *preset;   // TODO: deprecated, remove once UIs are updated
+#else
+        const char *reserved; // keep around until Interop is updated
+#endif
         av_qsv_context *ctx;
         // shared encoding parameters
         // initialized by the QSV encoder, then used upstream (e.g. by filters)
index e0becb81cc9917cae97ff36c3f0a8fde6b8b1feb..3b745744a82d0522611f00dc0ff26d07a524fb94 100644 (file)
@@ -381,7 +381,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
 
     // default encoding parameters
     if (hb_qsv_param_default_preset(&pv->param, &pv->enc_space.m_mfxVideoParam,
-                                    job->qsv.preset))
+                                    job->encoder_preset))
     {
         hb_error("encqsvInit: hb_qsv_param_default_preset failed");
         return -1;
@@ -426,12 +426,12 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
             break;
     }
 
-    // parse user-specified advanced options, if present
-    if (job->advanced_opts != NULL && job->advanced_opts[0] != '\0')
+    // parse user-specified encoder options, if present
+    if (job->encoder_options != NULL && *job->encoder_options)
     {
         hb_dict_t *options_list;
         hb_dict_entry_t *option = NULL;
-        options_list = hb_encopts_to_dict(job->advanced_opts, job->vcodec);
+        options_list = hb_encopts_to_dict(job->encoder_options, job->vcodec);
         while ((option = hb_dict_next(options_list, option)) != NULL)
         {
             switch (hb_qsv_param_parse(&pv->param,
@@ -462,7 +462,7 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
         hb_dict_free(&options_list);
     }
 
-    // reload colorimetry in case values were set in advanced_opts
+    // reload colorimetry in case values were set in encoder_options
     if (pv->param.videoSignalInfo.ColourDescriptionPresent)
     {
         job->color_matrix_code = 4;
@@ -519,36 +519,36 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job)
     pv->param.videoParam->mfx.FrameInfo.Height        = job->qsv.enc_info.align_height;
 
     // set H.264 profile and level
-    if (job->h264_profile != NULL && job->h264_profile[0] != '\0' &&
-        strcasecmp(job->h264_profile, "auto"))
+    if (job->encoder_profile != NULL && *job->encoder_profile &&
+        strcasecmp(job->encoder_profile, "auto"))
     {
-        if (!strcasecmp(job->h264_profile, "baseline"))
+        if (!strcasecmp(job->encoder_profile, "baseline"))
         {
             pv->param.videoParam->mfx.CodecProfile = MFX_PROFILE_AVC_BASELINE;
         }
-        else if (!strcasecmp(job->h264_profile, "main"))
+        else if (!strcasecmp(job->encoder_profile, "main"))
         {
             pv->param.videoParam->mfx.CodecProfile = MFX_PROFILE_AVC_MAIN;
         }
-        else if (!strcasecmp(job->h264_profile, "high"))
+        else if (!strcasecmp(job->encoder_profile, "high"))
         {
             pv->param.videoParam->mfx.CodecProfile = MFX_PROFILE_AVC_HIGH;
         }
         else
         {
-            hb_error("encqsvInit: bad profile %s", job->h264_profile);
+            hb_error("encqsvInit: bad profile %s", job->encoder_profile);
             return -1;
         }
     }
-    if (job->h264_level != NULL && job->h264_level[0] != '\0' &&
-        strcasecmp(job->h264_level, "auto"))
+    if (job->encoder_level != NULL && *job->encoder_level &&
+        strcasecmp(job->encoder_level, "auto"))
     {
         int err;
-        int i = hb_qsv_atoindex(hb_h264_level_names, job->h264_level, &err);
+        int i = hb_qsv_atoindex(hb_h264_level_names, job->encoder_level, &err);
         if (err || i >= (sizeof(hb_h264_level_values) /
                          sizeof(hb_h264_level_values[0])))
         {
-            hb_error("encqsvInit: bad level %s", job->h264_level);
+            hb_error("encqsvInit: bad level %s", job->encoder_level);
             return -1;
         }
         else if (hb_qsv_info->capabilities & HB_QSV_CAP_MSDK_API_1_6)
index f75e4493e828185f37dadf4f1a8c347fc0e15223..3cc2db52329286cdb97d3efc3eca7c303a0e0630 100644 (file)
@@ -159,11 +159,11 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
     context->time_base.num = fps.den;
     context->gop_size  = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
 
-    /* place job->advanced_opts in an hb_dict_t for convenience */
+    /* place job->encoder_options in an hb_dict_t for convenience */
     hb_dict_t * lavc_opts = NULL;
-    if( job->advanced_opts != NULL && *job->advanced_opts != '\0' )
+    if (job->encoder_options != NULL && *job->encoder_options)
     {
-        lavc_opts = hb_encopts_to_dict( job->advanced_opts, job->vcodec );
+        lavc_opts = hb_encopts_to_dict(job->encoder_options, job->vcodec);
     }
     /* iterate through lavc_opts and have avutil parse the options for us */
     AVDictionary * av_opts = NULL;
index ad0ed655a1316baaf8e74b4b0b2fb389ebd04b04..011fbc8f45827e93c6b24e68efb9aa6e3eb91cdc 100644 (file)
@@ -91,7 +91,8 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     pv->next_chapter_pts = AV_NOPTS_VALUE;
     pv->delayed_chapters = hb_list_init();
 
-    if( x264_param_default_preset( &param, job->x264_preset, job->x264_tune ) < 0 )
+    if (x264_param_default_preset(&param,
+                                  job->encoder_preset, job->encoder_tune) < 0)
     {
         free( pv );
         pv = NULL;
@@ -99,9 +100,9 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     }
 
     /* If the PSNR or SSIM tunes are in use, enable the relevant metric */
-    if (job->x264_tune != NULL && job->x264_tune[0] != '\0')
+    if (job->encoder_tune != NULL && *job->encoder_tune)
     {
-        char *tmp = strdup(job->x264_tune);
+        char *tmp = strdup(job->encoder_tune);
         char *tok = strtok(tmp,   ",./-+");
         do
         {
@@ -121,7 +122,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     }
 
     /* Some HandBrake-specific defaults; users can override them
-     * using the advanced_opts string. */
+     * using the encoder_options string. */
     if( job->pass == 2 && job->cfr != 1 )
     {
         hb_interjob_t * interjob = hb_interjob_get( job->h );
@@ -191,11 +192,11 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
         param.vui.i_colmatrix = job->title->color_matrix;
     }
 
-    /* place job->advanced_opts in an hb_dict_t for convenience */
+    /* place job->encoder_options in an hb_dict_t for convenience */
     hb_dict_t * x264_opts = NULL;
-    if( job->advanced_opts != NULL && *job->advanced_opts != '\0' )
+    if (job->encoder_options != NULL && *job->encoder_options)
     {
-        x264_opts = hb_encopts_to_dict( job->advanced_opts, job->vcodec );
+        x264_opts = hb_encopts_to_dict(job->encoder_options, job->vcodec);
     }
     /* iterate through x264_opts and have libx264 parse the options for us */
     int ret;
@@ -213,7 +214,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     hb_dict_free( &x264_opts );
 
     /* Reload colorimetry settings in case custom values were set
-     * in the advanced_opts string */
+     * in the encoder_options string */
     job->color_matrix_code = 4;
     job->color_prim = param.vui.i_colorprim;
     job->color_transfer = param.vui.i_transfer;
@@ -242,7 +243,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
         hb_log( "encx264: min-keyint: %s, keyint: %s", min, max );
     }
 
-    /* Settings which can't be overriden in the advanced_opts string
+    /* Settings which can't be overriden in the encoder_options string
      * (muxer-specific settings, resolution, ratecontrol, etc.). */
 
     /* Disable annexb. Inserts size into nal header instead of start code. */
@@ -291,19 +292,19 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     }
 
     /* Apply profile and level settings last, if present. */
-    if (job->h264_profile != NULL && *job->h264_profile)
+    if (job->encoder_profile != NULL && *job->encoder_profile)
     {
-        if (hb_apply_h264_profile(&param, job->h264_profile, 1))
+        if (hb_apply_h264_profile(&param, job->encoder_profile, 1))
         {
             free(pv);
             pv = NULL;
             return 1;
         }
     }
-    if (job->h264_level != NULL && *job->h264_level)
+    if (job->encoder_level != NULL && *job->encoder_level)
     {
-        if (hb_apply_h264_level(&param, job->h264_level,
-                                job->h264_profile, 1) < 0)
+        if (hb_apply_h264_level(&param, job->encoder_level,
+                                job->encoder_profile, 1) < 0)
         {
             free(pv);
             pv = NULL;
@@ -330,12 +331,12 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     }
     
     /* Log the unparsed x264 options string. */
-    char *x264_opts_unparsed = hb_x264_param_unparse( job->x264_preset,
-                                                      job->x264_tune,
-                                                      job->advanced_opts,
-                                                      job->h264_profile,
-                                                      job->h264_level,
-                                                      job->width, job->height );
+    char *x264_opts_unparsed = hb_x264_param_unparse(job->encoder_preset,
+                                                     job->encoder_tune,
+                                                     job->encoder_options,
+                                                     job->encoder_profile,
+                                                     job->encoder_level,
+                                                     job->width, job->height);
     if( x264_opts_unparsed != NULL )
     {
         hb_log( "encx264: unparsed options: %s", x264_opts_unparsed );
index 6b58be84966ac0609012a59dbb12e340c1708797..89360e5bceb0fac7ca3bc44b2cc67f34e2530a3d 100644 (file)
@@ -90,7 +90,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
     x265_param *param = pv->param = x265_param_alloc();
 
     if (x265_param_default_preset(param,
-                                  job->x264_preset, job->x264_tune) < 0)
+                                  job->encoder_preset, job->encoder_tune) < 0)
     {
         free(pv);
         pv = NULL;
@@ -99,9 +99,9 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
 
     /* If the PSNR or SSIM tunes are in use, enable the relevant metric */
     param->bEnablePsnr = param->bEnableSsim = 0;
-    if (job->x264_tune != NULL && *job->x264_tune)
+    if (job->encoder_tune != NULL && *job->encoder_tune)
     {
-        char *tmp = strdup(job->x264_tune);
+        char *tmp = strdup(job->encoder_tune);
         char *tok = strtok(tmp,   ",./-+");
         do
         {
@@ -122,7 +122,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
 
     /*
      * Some HandBrake-specific defaults; users can override them
-     * using the advanced_opts string.
+     * using the encoder_options string.
      */
     param->frameRate   = (int)((double)job->vrate / (double)job->vrate_base + 0.5); // yes, this is an int
     param->keyframeMax = param->frameRate * 10;
@@ -130,7 +130,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
 
     /* iterate through x265_opts and parse the options */
     hb_dict_entry_t *entry = NULL;
-    hb_dict_t *x265_opts = hb_encopts_to_dict(job->advanced_opts, job->vcodec);
+    hb_dict_t *x265_opts = hb_encopts_to_dict(job->encoder_options, job->vcodec);
     while ((entry = hb_dict_next(x265_opts, entry)) != NULL)
     {
         // here's where the strings are passed to libx265 for parsing
@@ -152,7 +152,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
     hb_dict_free(&x265_opts);
 
     /*
-     * Settings which can't be overriden in the advanced_opts string
+     * Settings which can't be overriden in the encodeer_options string
      * (muxer-specific settings, resolution, ratecontrol, etc.).
      */
     param->sourceWidth  = job->width;
@@ -185,7 +185,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job)
     }
 
     /* Apply profile and level settings last. */
-    if (x265_param_apply_profile(param, job->h264_profile) < 0)
+    if (x265_param_apply_profile(param, job->encoder_profile) < 0)
     {
         free(pv);
         pv = NULL;
index 6149acd87a634abf909077d444eb42002c6bf8a2..68ac9f0a9c1d81d2981d403b80cba6852be902ed 100644 (file)
@@ -1398,18 +1398,18 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     job_copy->list_attachment = hb_attachment_list_copy( job->list_attachment );
     job_copy->metadata = hb_metadata_copy( job->metadata );
 
-    if ( job->file )
-        job_copy->file  = strdup( job->file );
-    if ( job->advanced_opts )
-        job_copy->advanced_opts  = strdup( job->advanced_opts );
-    if ( job->x264_preset )
-        job_copy->x264_preset  = strdup( job->x264_preset );
-    if ( job->x264_tune )
-        job_copy->x264_tune  = strdup( job->x264_tune );
-    if ( job->h264_profile )
-        job_copy->h264_profile  = strdup( job->h264_profile );
-    if ( job->h264_level )
-        job_copy->h264_level  = strdup( job->h264_level );
+    if (job->encoder_preset != NULL)
+        job_copy->encoder_preset = strdup(job->encoder_preset);
+    if (job->encoder_tune != NULL)
+        job_copy->encoder_tune = strdup(job->encoder_tune);
+    if (job->encoder_options != NULL)
+        job_copy->encoder_options = strdup(job->encoder_options);
+    if (job->encoder_profile != NULL)
+        job_copy->encoder_profile = strdup(job->encoder_profile);
+    if (job->encoder_level != NULL)
+        job_copy->encoder_level = strdup(job->encoder_level);
+    if (job->file != NULL)
+        job_copy->file = strdup(job->file);
 
     job_copy->h     = h;
     job_copy->pause = h->pause_lock;
index 5739951e5bfbe4488b19baa9666ff05487b3b541..96f5016f07c11aef76476f55a1806d4239702a2e 100644 (file)
@@ -309,37 +309,70 @@ void hb_display_job_info(hb_job_t *job)
         hb_log("   + encoder: %s",
                hb_video_encoder_get_long_name(job->vcodec));
 
-        if( job->x264_preset && *job->x264_preset &&
-            job->vcodec == HB_VCODEC_X264 )
+        if (job->encoder_preset && *job->encoder_preset)
         {
-            hb_log( "     + x264 preset: %s", job->x264_preset );
-        }
-        if( job->x264_tune && *job->x264_tune &&
-            job->vcodec == HB_VCODEC_X264 )
-        {
-            hb_log( "     + x264 tune: %s", job->x264_tune );
-        }
+            switch (job->vcodec)
+            {
+                case HB_VCODEC_X264:
+                    hb_log("     + x264 preset: %s", job->encoder_preset);
+                    break;
+                case HB_VCODEC_X265:
+                    hb_log("     + x265 preset: %s", job->encoder_preset);
+                    break;
 #ifdef USE_QSV
-        if ((job->qsv.preset != NULL && *job->qsv.preset) &&
-            (job->vcodec & HB_VCODEC_QSV_MASK))
+                case HB_VCODEC_QSV_H264:
+                    hb_log("     + QSV preset: %s", job->encoder_preset);
+                    break;
+#endif
+                default:
+                    break;
+            }
+        }
+        if (job->encoder_tune && *job->encoder_tune)
         {
-            hb_log("     + QSV preset: %s", job->qsv.preset);
+            switch (job->vcodec)
+            {
+                case HB_VCODEC_X264:
+                    hb_log("     + x264 tune: %s", job->encoder_tune);
+                    break;
+                case HB_VCODEC_X265:
+                    hb_log("     + x265 tune: %s", job->encoder_tune);
+                    break;
+                default:
+                    break;
+            }
         }
-#endif
-        if (job->advanced_opts != NULL && *job->advanced_opts &&
-            (job->vcodec != HB_VCODEC_THEORA))
+        if (job->encoder_options != NULL && *job->encoder_options &&
+            job->vcodec != HB_VCODEC_THEORA)
         {
-            hb_log("     + options: %s", job->advanced_opts);
+            hb_log("     + options: %s", job->encoder_options);
         }
-        if (job->h264_profile != NULL && *job->h264_profile &&
-            (job->vcodec & HB_VCODEC_H264_MASK))
+        if (job->encoder_profile && *job->encoder_profile)
         {
-            hb_log("     + h264 profile: %s", job->h264_profile);
+            switch (job->vcodec)
+            {
+                case HB_VCODEC_X264:
+                case HB_VCODEC_QSV_H264:
+                    hb_log("     + H.264 profile: %s", job->encoder_profile);
+                    break;
+                case HB_VCODEC_X265:
+                    hb_log("     + H.265 profile: %s", job->encoder_profile);
+                    break;
+                default:
+                    break;
+            }
         }
-        if (job->h264_level != NULL && *job->h264_level &&
-            (job->vcodec & HB_VCODEC_H264_MASK))
+        if (job->encoder_level && *job->encoder_level)
         {
-            hb_log("     + h264 level: %s", job->h264_level);
+            switch (job->vcodec)
+            {
+                case HB_VCODEC_X264:
+                case HB_VCODEC_QSV_H264:
+                    hb_log("     + H.264 level: %s", job->encoder_level);
+                    break;
+                default:
+                    break;
+            }
         }
 
         if (job->vquality >= 0)
index a999b15260ad3571e78100b98a99a188df2d4aaf..ca3d6aa6941ad03d7da903242a0552e13cd47f1d 100644 (file)
@@ -2974,35 +2974,35 @@ fWorkingCount = 0;
      */
     if (job->indepth_scan == 1)
     {
-        char *x264_preset_tmp   = job->x264_preset   != NULL ? strdup(job->x264_preset)   : NULL;
-        char *x264_tune_tmp     = job->x264_tune     != NULL ? strdup(job->x264_tune)     : NULL;
-        char *advanced_opts_tmp = job->advanced_opts != NULL ? strdup(job->advanced_opts) : NULL;
-        char *h264_profile_tmp  = job->h264_profile  != NULL ? strdup(job->h264_profile)  : NULL;
-        char *h264_level_tmp    = job->h264_level    != NULL ? strdup(job->h264_level)    : NULL;
+        char *encoder_preset_tmp  = job->encoder_preset  != NULL ? strdup(job->encoder_preset)  : NULL;
+        char *encoder_tune_tmp    = job->encoder_tune    != NULL ? strdup(job->encoder_tune)    : NULL;
+        char *encoder_options_tmp = job->encoder_options != NULL ? strdup(job->encoder_options) : NULL;
+        char *encoder_profile_tmp = job->encoder_profile != NULL ? strdup(job->encoder_profile) : NULL;
+        char *encoder_level_tmp   = job->encoder_level   != NULL ? strdup(job->encoder_level)   : NULL;
         /*
          * When subtitle scan is enabled do a fast pre-scan job
          * which will determine which subtitles to enable, if any.
          */
-        hb_job_set_x264_preset  (job, NULL);
-        hb_job_set_x264_tune    (job, NULL);
-        hb_job_set_advanced_opts(job, NULL);
-        hb_job_set_h264_profile (job, NULL);
-        hb_job_set_h264_level   (job, NULL);
+        hb_job_set_encoder_preset (job, NULL);
+        hb_job_set_encoder_tune   (job, NULL);
+        hb_job_set_encoder_options(job, NULL);
+        hb_job_set_encoder_profile(job, NULL);
+        hb_job_set_encoder_level  (job, NULL);
         job->pass = -1;
         hb_add(fQueueEncodeLibhb, job);
         /*
          * reset the advanced settings
          */
-        hb_job_set_x264_preset  (job, x264_preset_tmp);
-        hb_job_set_x264_tune    (job, x264_tune_tmp);
-        hb_job_set_advanced_opts(job, advanced_opts_tmp);
-        hb_job_set_h264_profile (job, h264_profile_tmp);
-        hb_job_set_h264_level   (job, h264_level_tmp);
-        free(x264_preset_tmp);
-        free(x264_tune_tmp);
-        free(advanced_opts_tmp);
-        free(h264_profile_tmp);
-        free(h264_level_tmp);
+        hb_job_set_encoder_preset (job, encoder_preset_tmp);
+        hb_job_set_encoder_tune   (job, encoder_tune_tmp);
+        hb_job_set_encoder_options(job, encoder_options_tmp);
+        hb_job_set_encoder_profile(job, encoder_profile_tmp);
+        hb_job_set_encoder_level  (job, encoder_level_tmp);
+        free(encoder_preset_tmp);
+        free(encoder_tune_tmp);
+        free(encoder_options_tmp);
+        free(encoder_profile_tmp);
+        free(encoder_level_tmp);
     }
 
     
@@ -3422,17 +3422,17 @@ fWorkingCount = 0;
         /* advanced x264 options */
         NSString   *tmpString;
         // translate zero-length strings to NULL for libhb
-        const char *x264_preset   = NULL;
-        const char *x264_tune     = NULL;
-        const char *advanced_opts = NULL;
-        const char *h264_profile  = NULL;
-        const char *h264_level    = NULL;
+        const char *encoder_preset  = NULL;
+        const char *encoder_tune    = NULL;
+        const char *encoder_options = NULL;
+        const char *encoder_profile = NULL;
+        const char *encoder_level   = NULL;
         if ([fX264UseAdvancedOptionsCheck state])
         {
             // we are using the advanced panel
             if ([(tmpString = [fAdvancedOptions optionsString]) length])
             {
-                advanced_opts = [tmpString UTF8String];
+                encoder_options = [tmpString UTF8String];
             }
         }
         else
@@ -3440,33 +3440,33 @@ fWorkingCount = 0;
             // we are using the x264 preset system
             if ([(tmpString = [self x264Tune]) length])
             {
-                x264_tune = [tmpString UTF8String];
+                encoder_tune = [tmpString UTF8String];
             }
             if ([(tmpString = [self x264OptionExtra]) length])
             {
-                advanced_opts = [tmpString UTF8String];
+                encoder_options = [tmpString UTF8String];
             }
             if ([(tmpString = [self h264Profile]) length])
             {
-                h264_profile = [tmpString UTF8String];
+                encoder_profile = [tmpString UTF8String];
             }
             if ([(tmpString = [self h264Level]) length])
             {
-                h264_level = [tmpString UTF8String];
+                encoder_level = [tmpString UTF8String];
             }
-            x264_preset = [[self x264Preset] UTF8String];
+            encoder_preset = [[self x264Preset] UTF8String];
         }
-        hb_job_set_x264_preset  (job, x264_preset);
-        hb_job_set_x264_tune    (job, x264_tune);
-        hb_job_set_advanced_opts(job, advanced_opts);
-        hb_job_set_h264_profile (job, h264_profile);
-        hb_job_set_h264_level   (job, h264_level);
+        hb_job_set_encoder_preset (job, encoder_preset);
+        hb_job_set_encoder_tune   (job, encoder_tune);
+        hb_job_set_encoder_options(job, encoder_options);
+        hb_job_set_encoder_profile(job, encoder_profile);
+        hb_job_set_encoder_level  (job, encoder_level);
     }
     else if (job->vcodec & HB_VCODEC_FFMPEG_MASK)
     {
-        hb_job_set_advanced_opts(job,
-                                 [[fAdvancedOptions optionsStringLavc]
-                                  UTF8String]);
+        hb_job_set_encoder_options(job,
+                                   [[fAdvancedOptions optionsStringLavc]
+                                    UTF8String]);
     }
 
     /* Video settings */
@@ -3947,17 +3947,17 @@ bool one_burned = FALSE;
         /* advanced x264 options */
         NSString   *tmpString;
         // translate zero-length strings to NULL for libhb
-        const char *x264_preset   = NULL;
-        const char *x264_tune     = NULL;
-        const char *advanced_opts = NULL;
-        const char *h264_profile  = NULL;
-        const char *h264_level    = NULL;
+        const char *encoder_preset  = NULL;
+        const char *encoder_tune    = NULL;
+        const char *encoder_options = NULL;
+        const char *encoder_profile = NULL;
+        const char *encoder_level   = NULL;
         if ([[queueToApply objectForKey:@"x264UseAdvancedOptions"] intValue])
         {
             // we are using the advanced panel
             if ([(tmpString = [queueToApply objectForKey:@"x264Option"]) length])
             {
-                advanced_opts = [tmpString UTF8String];
+                encoder_options = [tmpString UTF8String];
             }
         }
         else
@@ -3965,33 +3965,33 @@ bool one_burned = FALSE;
             // we are using the x264 preset system
             if ([(tmpString = [queueToApply objectForKey:@"x264Tune"]) length])
             {
-                x264_tune = [tmpString UTF8String];
+                encoder_tune = [tmpString UTF8String];
             }
             if ([(tmpString = [queueToApply objectForKey:@"x264OptionExtra"]) length])
             {
-                advanced_opts = [tmpString UTF8String];
+                encoder_options = [tmpString UTF8String];
             }
             if ([(tmpString = [queueToApply objectForKey:@"h264Profile"]) length])
             {
-                h264_profile = [tmpString UTF8String];
+                encoder_profile = [tmpString UTF8String];
             }
             if ([(tmpString = [queueToApply objectForKey:@"h264Level"]) length])
             {
-                h264_level = [tmpString UTF8String];
+                encoder_level = [tmpString UTF8String];
             }
-            x264_preset = [[queueToApply objectForKey:@"x264Preset"] UTF8String];
+            encoder_preset = [[queueToApply objectForKey:@"x264Preset"] UTF8String];
         }
-        hb_job_set_x264_preset  (job, x264_preset);
-        hb_job_set_x264_tune    (job, x264_tune);
-        hb_job_set_advanced_opts(job, advanced_opts);
-        hb_job_set_h264_profile (job, h264_profile);
-        hb_job_set_h264_level   (job, h264_level);
+        hb_job_set_encoder_preset (job, encoder_preset);
+        hb_job_set_encoder_tune   (job, encoder_tune);
+        hb_job_set_encoder_options(job, encoder_options);
+        hb_job_set_encoder_profile(job, encoder_profile);
+        hb_job_set_encoder_level  (job, encoder_level);
     }
     else if (job->vcodec & HB_VCODEC_FFMPEG_MASK)
     {
-        hb_job_set_advanced_opts(job,
-                                 [[queueToApply objectForKey:@"lavcOption"]
-                                  UTF8String]);
+        hb_job_set_encoder_options(job,
+                                   [[queueToApply objectForKey:@"lavcOption"]
+                                    UTF8String]);
     }
     
     
index 25a7ec3448c9e815648db928066838d10b2817e7..45c4571a009b1a50737a58877bd9cc44480d3763 100644 (file)
@@ -254,21 +254,40 @@ typedef enum EncodeState : NSUInteger {
     int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue];
     self.privateHandle = hb_init(loggingLevel, 0);
 
-    /* If scanning we need to do some extra setup of the job. */
+    /*
+     * If scanning we need to do some extra setup of the job.
+     */
     if (job->indepth_scan == 1)
     {
-        char *x264opts_tmp;
-        /* When subtitle scan is enabled do a fast pre-scan job
-         * which will determine which subtitles to enable, if any. */
+        char *encoder_preset_tmp  = job->encoder_preset  != NULL ? strdup(job->encoder_preset)  : NULL;
+        char *encoder_tune_tmp    = job->encoder_tune    != NULL ? strdup(job->encoder_tune)    : NULL;
+        char *encoder_options_tmp = job->encoder_options != NULL ? strdup(job->encoder_options) : NULL;
+        char *encoder_profile_tmp = job->encoder_profile != NULL ? strdup(job->encoder_profile) : NULL;
+        char *encoder_level_tmp   = job->encoder_level   != NULL ? strdup(job->encoder_level)   : NULL;
+        /*
+         * When subtitle scan is enabled do a fast pre-scan job
+         * which will determine which subtitles to enable, if any.
+         */
+        hb_job_set_encoder_preset (job, NULL);
+        hb_job_set_encoder_tune   (job, NULL);
+        hb_job_set_encoder_options(job, NULL);
+        hb_job_set_encoder_profile(job, NULL);
+        hb_job_set_encoder_level  (job, NULL);
         job->pass = -1;
-        x264opts_tmp = job->advanced_opts;
-
-        job->advanced_opts = NULL;
-        job->indepth_scan = 1;
-
-        /* Add the pre-scan job */
         hb_add(self.privateHandle, job);
-        job->advanced_opts = x264opts_tmp;
+        /*
+         * reset the advanced settings
+         */
+        hb_job_set_encoder_preset (job, encoder_preset_tmp);
+        hb_job_set_encoder_tune   (job, encoder_tune_tmp);
+        hb_job_set_encoder_options(job, encoder_options_tmp);
+        hb_job_set_encoder_profile(job, encoder_profile_tmp);
+        hb_job_set_encoder_level  (job, encoder_level_tmp);
+        free(encoder_preset_tmp);
+        free(encoder_tune_tmp);
+        free(encoder_options_tmp);
+        free(encoder_profile_tmp);
+        free(encoder_level_tmp);
     }
 
     /* Go ahead and perform the actual encoding preview scan */
index 9c785090188cdf8cfc55003b4bfefb3f4789bdf5..d864b7ff4f083138862b697a93e3bd0564107c52 100644 (file)
@@ -31,6 +31,14 @@ MACOSX.map.g.max  = debug
 MACOSX.xcconfig = $(foreach x,$(XCODE.xcconfig),-xcconfig $(MACOSX.src/)xcconfig/$(x))
 MACOSX.sdk      = $(foreach sdk,$(GCC.sysroot),-sdk $(sdk))
 
+## some optional features use ifdef directives outside of libhb (e.g. CLI)
+ifeq (1,$(FEATURE.x265))
+    MACOSX.GCC.D += -DUSE_X265
+endif
+
+## extra CFLAGS: macro definitions
+MACOSX.extra_cflags = OTHER_CFLAGS='$(MACOSX.GCC.D)'
+
 ## launch a build thru xcode; which in turn will do a nested make against
 ## this build system with normal build rules enabled.
 ##
index ce60e0d46d963fd200a910680fa67ea1c488d408..bac482b6d0330ba751f20bd53c2bdc22db1a1c42 100644 (file)
@@ -23,6 +23,10 @@ ifeq (1,$(FEATURE.qsv))
     TEST.GCC.D += USE_QSV HAVE_THREADS=1
 endif
 
+ifeq (1,$(FEATURE.x265))
+    TEST.GCC.D += USE_X265
+endif
+
 TEST.GCC.l += $(foreach m,$(MODULES.NAMES),$($m.OSL.libs))
 
 TEST.install.exe = $(DESTDIR)$(PREFIX/)bin/$(notdir $(TEST.exe))
index c74bf9491145919e8fa89182a63399623cbc755c..cd414e22130d9be226ff7f8389281a4ee2dd4f95 100644 (file)
@@ -145,7 +145,6 @@ static int use_hwd = 0;
 #ifdef USE_QSV
 static int         qsv_async_depth = -1;
 static int         qsv_decode      =  1;
-static const char *qsv_preset      = NULL;
 #endif
 
 /* Exit cleanly on Ctrl-C */
@@ -172,6 +171,8 @@ static int  HandleEvents( hb_handle_t * h );
 static void str_vfree( char **strv );
 static char** str_split( char *str, char delem );
 
+static void print_preset_list(FILE *out, const char* const *list, const char *indent);
+
 #ifdef __APPLE_CC__
 static char* bsd_name_for_path(char *path);
 static int device_is_dvd(char *device);
@@ -1974,7 +1975,6 @@ 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 */
@@ -2868,10 +2868,10 @@ static int HandleEvents( hb_handle_t * h )
                 job->color_matrix_code = color_matrix_code;
             }
 
-            hb_job_set_x264_preset(job, x264_preset);
-            hb_job_set_x264_tune(job, x264_tune);
-            hb_job_set_h264_profile(job, h264_profile);
-            hb_job_set_h264_level(job, h264_level);
+            hb_job_set_encoder_preset (job, x264_preset);
+            hb_job_set_encoder_tune   (job, x264_tune);
+            hb_job_set_encoder_profile(job, h264_profile);
+            hb_job_set_encoder_level  (job, h264_level);
 
             if (maxWidth)
                 job->maxWidth = maxWidth;
@@ -2919,7 +2919,7 @@ static int HandleEvents( hb_handle_t * h )
                  */
                 job->pass = -1;
 
-                hb_job_set_advanced_opts(job, NULL);
+                hb_job_set_encoder_options(job, NULL);
 
                 job->indepth_scan = subtitle_scan;
                 fprintf( stderr, "Subtitle Scan Enabled - enabling "
@@ -2931,7 +2931,7 @@ static int HandleEvents( hb_handle_t * h )
                 hb_add( h, job );
             }
 
-            hb_job_set_advanced_opts(job, advanced_opts);
+            hb_job_set_encoder_options(job, advanced_opts);
 
             if( twoPass )
             {
@@ -3071,7 +3071,7 @@ void SigHandler( int i_signal )
  ****************************************************************************/
 static void ShowHelp()
 {
-    int i, len;
+    int i;
     const char *name;
     const hb_rate_t *rate;
     const hb_dither_t *dither;
@@ -3079,8 +3079,6 @@ static void ShowHelp()
     const hb_encoder_t *encoder;
     const hb_container_t *container;
     FILE* const out = stdout;
-    const char * const *x264_opts;
-    char tmp[80];
 
     fprintf( out,
     "Syntax: HandBrakeCLI [options] -i <device> -o <file>\n"
@@ -3169,139 +3167,64 @@ static void ShowHelp()
         }
     }
     fprintf(out, "                            (default: %s)\n", name);
-    fprintf( out,
+    fprintf(out,
     "        --x264-preset       When using x264, selects the x264 preset:\n"
     "          <string>          ");
-    x264_opts = hb_video_encoder_get_presets(HB_VCODEC_X264);
-    tmp[0] = 0;
-    len = 0;
-    while( x264_opts && *x264_opts )
-    {
-        strncat( tmp, *x264_opts++, 79 - len );
-        if( *x264_opts )
-            strcat( tmp, "/" );
-        len = strlen( tmp );
-        if( len > 40 && *x264_opts )
-        {
-            fprintf( out, "%s\n                            ", tmp );
-            len = 0;
-            tmp[0] = 0;
-        }
-    }
-    if( len )
-        fprintf( out, "%s\n", tmp );
-    fprintf( out,
-    "        --x264-tune         When using x264, selects the x264 tuning:\n"
+    print_preset_list(out, hb_video_encoder_get_presets(HB_VCODEC_X264),
+    "                            ");
+#ifdef USE_X265
+    fprintf(out,
+    "        --x265-preset       When using x265, selects the x265 preset:\n"
     "          <string>          ");
-    x264_opts = hb_video_encoder_get_tunes(HB_VCODEC_X264);
-    tmp[0] = 0;
-    len = 0;
-    while( x264_opts && *x264_opts )
-    {
-        strncat( tmp, *x264_opts++, 79 - len );
-        if( *x264_opts )
-            strcat( tmp, "/" );
-        len = strlen( tmp );
-        if( len > 40 && *x264_opts )
-        {
-            fprintf( out, "%s\n                            ", tmp );
-            len = 0;
-            tmp[0] = 0;
-        }
-    }
-    if( len )
-        fprintf( out, "%s\n", tmp );
+    print_preset_list(out, hb_video_encoder_get_presets(HB_VCODEC_X265),
+    "                            ");
+#endif
 #ifdef USE_QSV
-if (hb_qsv_available())
-{
-    fprintf(out,
-            "        --qsv-preset        When using QSV, selects the QSV preset:\n"
-            "          <string>          ");
-    x264_opts = hb_video_encoder_get_presets(HB_VCODEC_QSV_H264);
-    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)
+    if (hb_qsv_available())
     {
-        fprintf(out, "%s\n", tmp);
+        fprintf(out,
+        "        --qsv-preset        When using QSV, selects the QSV preset:\n"
+        "          <string>          ");
+        print_preset_list(out, hb_video_encoder_get_presets(HB_VCODEC_QSV_H264),
+        "                            ");
     }
-}
 #endif
+    fprintf( out,
+    "        --x264-tune         When using x264, selects the x264 tuning:\n"
+    "          <string>          ");
+    print_preset_list(out, hb_video_encoder_get_tunes(HB_VCODEC_X264),
+    "                            ");
+#ifdef USE_X265
     fprintf(out,
-    "    -x, --encopts <string>  Specify advanced encoder options in the\n");
-#ifdef USE_QSV
-if (hb_qsv_available())
-{
-    fprintf(out,
-    "                            same style as mencoder (x264/qsv/ffmpeg only):\n");
-}
-else
+    "        --x265-tune         When using x265, selects the x265 tuning:\n"
+    "          <string>          ");
+    print_preset_list(out, hb_video_encoder_get_tunes(HB_VCODEC_X265),
+    "                            ");
 #endif
-{
-    fprintf(out,
-    "                            same style as mencoder (x264 and ffmpeg only):\n");
-}
-    
     fprintf(out,
+    "    -x, --encopts <string>  Specify advanced encoder options in the\n"
+    "                            same style as mencoder (all except theora):\n"
     "                            option1=value1:option2=value2\n"
     "        --h264-profile      When using H.264, ensures compliance with the\n"
     "          <string>          specified H.264 profile:\n"
     "                            ");
-    x264_opts = hb_video_encoder_get_profiles(HB_VCODEC_X264);
-    tmp[0] = 0;
-    len = 0;
-    while( x264_opts && *x264_opts )
-    {
-        strncat( tmp, *x264_opts++, 79 - len );
-        if( *x264_opts )
-            strcat( tmp, "/" );
-        len = strlen( tmp );
-        if( len > 40 && *x264_opts )
-        {
-            fprintf( out, "%s\n                            ", tmp );
-            len = 0;
-            tmp[0] = 0;
-        }
-    }
-    if( len )
-        fprintf( out, "%s\n", tmp );
-    fprintf( out,
+    print_preset_list(out, hb_video_encoder_get_profiles(HB_VCODEC_X264),
+    "                            ");
+#ifdef USE_X265
+    fprintf(out,
+    "        --h265-profile      When using H.265, ensures compliance with the\n"
+    "          <string>          specified H.265 profile:\n"
+    "                            ");
+    print_preset_list(out, hb_video_encoder_get_profiles(HB_VCODEC_X265),
+    "                            ");
+#endif
+    fprintf(out,
     "        --h264-level        When using H.264, ensures compliance with the\n"
     "          <string>          specified H.264 level:\n"
     "                            ");
-    x264_opts = hb_video_encoder_get_levels(HB_VCODEC_X264);
-    tmp[0] = 0;
-    len = 0;
-    while( x264_opts && *x264_opts )
-    {
-        strncat( tmp, *x264_opts++, 79 - len );
-        if( *x264_opts )
-            strcat( tmp, "/" );
-        len = strlen( tmp );
-        if( len > 40 && *x264_opts )
-        {
-            fprintf( out, "%s\n                            ", tmp );
-            len = 0;
-            tmp[0] = 0;
-        }
-    }
-    if( len )
-        fprintf( out, "%s\n", tmp );
-    fprintf( out,
+    print_preset_list(out, hb_video_encoder_get_levels(HB_VCODEC_X264),
+    "                            ");
+    fprintf(out,
     "    -q, --quality <number>  Set video quality\n"
     "    -b, --vb <kb/s>         Set video bitrate (default: 1000)\n"
     "    -2, --two-pass          Use two-pass mode\n"
@@ -3755,16 +3678,15 @@ static int ParseOptions( int argc, char ** argv )
     #define ALLOWED_AUDIO_COPY  280
     #define AUDIO_FALLBACK      281
     #define LOOSE_CROP          282
-    #define X264_PRESET         283
-    #define X264_TUNE           284
-    #define H264_PROFILE        285
-    #define H264_LEVEL          286
+    #define ENCODER_PRESET      283
+    #define ENCODER_TUNE        284
+    #define ENCODER_PROFILE     285
+    #define ENCODER_LEVEL       286
     #define NO_OPENCL           287
     #define NORMALIZE_MIX       288
     #define AUDIO_DITHER        289
     #define QSV_BASELINE        290
     #define QSV_ASYNC_DEPTH     291
-    #define QSV_PRESET          292
 
     for( ;; )
     {
@@ -3777,7 +3699,7 @@ static int ParseOptions( int argc, char ** argv )
             { "no-opencl",   no_argument,       NULL,    NO_OPENCL },
 
 #ifdef USE_QSV
-            { "qsv-preset",           required_argument, NULL,        QSV_PRESET,      },
+            { "qsv-preset",           required_argument, NULL,        ENCODER_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,               },
@@ -3846,12 +3768,18 @@ static int ParseOptions( int argc, char ** argv )
             { "ac",          required_argument, NULL,    'C' },
             { "rate",        required_argument, NULL,    'r' },
             { "arate",       required_argument, NULL,    'R' },
-            { "x264-preset", required_argument, NULL,    X264_PRESET },
-            { "x264-tune",   required_argument, NULL,    X264_TUNE },
+            { "x264-preset", required_argument, NULL,    ENCODER_PRESET },
+            { "x264-tune",   required_argument, NULL,    ENCODER_TUNE },
             { "encopts",     required_argument, NULL,    'x' },
-            { "x264-profile", required_argument, NULL,   H264_PROFILE },
-            { "h264-profile", required_argument, NULL,   H264_PROFILE },
-            { "h264-level",  required_argument, NULL,    H264_LEVEL },
+            { "x264-profile", required_argument, NULL,   ENCODER_PROFILE },
+            { "h264-profile", required_argument, NULL,   ENCODER_PROFILE },
+            { "h264-level",  required_argument, NULL,    ENCODER_LEVEL },
+#ifdef USE_X265
+            { "x265-preset",  required_argument, NULL,   ENCODER_PRESET },
+            { "x265-tune",    required_argument, NULL,   ENCODER_TUNE },
+            { "h265-profile", required_argument, NULL,   ENCODER_PROFILE },
+            { "h265-level",   required_argument, NULL,   ENCODER_LEVEL },
+#endif
             { "turbo",       no_argument,       NULL,    'T' },
             { "maxHeight",   required_argument, NULL,    'Y' },
             { "maxWidth",    required_argument, NULL,    'X' },
@@ -4279,19 +4207,19 @@ static int ParseOptions( int argc, char ** argv )
             case 'C':
                 acompressions = str_split( optarg, ',' );
                 break;
-            case X264_PRESET:
+            case ENCODER_PRESET:
                 x264_preset = strdup( optarg );
                 break;
-            case X264_TUNE:
+            case ENCODER_TUNE:
                 x264_tune = strdup( optarg );
                 break;
             case 'x':
                 advanced_opts = strdup( optarg );
                 break;
-            case H264_PROFILE:
+            case ENCODER_PROFILE:
                 h264_profile = strdup( optarg );
                 break;
-            case H264_LEVEL:
+            case ENCODER_LEVEL:
                 h264_level = strdup( optarg );
                 break;
             case 'T':
@@ -4424,9 +4352,6 @@ 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] );
@@ -4508,6 +4433,34 @@ static int CheckOptions( int argc, char ** argv )
     return 0;
 }
 
+static void print_preset_list(FILE *out, const char* const *list, const char *indent)
+{
+    if (out != NULL && list != NULL && indent != NULL)
+    {
+        int len = 0;
+        char tmp[80];
+        tmp[0] = '\0';
+        while (list != NULL && *list != NULL)
+        {
+            strncat(tmp, *list++, sizeof(tmp) - 1  - len);
+            if (*list != NULL)
+            {
+                strcat(tmp, "/");
+            }
+            if ((len = strlen(tmp)) > 40 && *list != NULL)
+            {
+                fprintf(out, "%s\n%s", tmp, indent);
+                tmp[0] = '\0';
+                len = 0;
+            }
+        }
+        if (len)
+        {
+            fprintf(out, "%s\n", tmp);
+        }
+    }
+}
+
 #ifdef __APPLE_CC__
 /****************************************************************************
  * bsd_name_for_path