summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-10-02 21:28:45 +0000
committerjstebbins <[email protected]>2011-10-02 21:28:45 +0000
commitdac4f53ddacce1757351f3e96de4f2dd3ab633da (patch)
tree9646c88202cabb13543b64f94dd7d74bae3b5cb9
parent4a09a1011d8f1561c5b32a0f92274c7bf4565c4c (diff)
CLI: x264 preset, tuning, and profile support
New cli options --x264-preset, --x264-tune, and --x264-profile. x264 preset and tune are set first, followed by any custom x264 option string, and finally the profile is applied. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4265 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/common.h8
-rw-r--r--libhb/encx264.c78
-rw-r--r--libhb/work.c15
-rw-r--r--test/test.c94
4 files changed, 171 insertions, 24 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 41272b93f..2d275978f 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -257,6 +257,9 @@ struct hb_job_s
int cfr;
int pass;
char *advanced_opts;
+ char *x264_profile;
+ char *x264_preset;
+ char *x264_tune;
int areBframes;
int color_matrix_code;
int color_prim;
@@ -871,4 +874,9 @@ int hb_rgb2yuv(int rgb);
const char * hb_subsource_name( int source );
+// x264 preset/tune/profile helpers
+const char * const * hb_x264_presets();
+const char * const * hb_x264_tunes();
+const char * const * hb_x264_profiles();
+
#endif
diff --git a/libhb/encx264.c b/libhb/encx264.c
index 3d55c2ee3..9af954d97 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -83,7 +83,12 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
memset( pv->filename, 0, 1024 );
hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
- x264_param_default( &param );
+ if( x264_param_default_preset( &param, job->x264_preset, job->x264_tune ) < 0 )
+ {
+ free( pv );
+ pv = NULL;
+ return 1;
+ }
/* Enable metrics */
param.analyse.b_psnr = 1;
@@ -209,7 +214,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
}
free(x264opts_start);
}
-
+
/* Reload colorimetry settings in case custom values were set
* in the advanced_opts string */
job->color_matrix_code = 3;
@@ -217,26 +222,6 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
job->color_transfer = param.vui.i_transfer;
job->color_matrix = param.vui.i_colmatrix;
- /* B-frames are on by default.*/
- job->areBframes = 1;
-
- if( param.i_bframe && param.i_bframe_pyramid )
- {
- /* Note b-pyramid here, so the initial delay can be doubled */
- job->areBframes = 2;
- }
- else if( !param.i_bframe )
- {
- /*
- When B-frames are enabled, the max frame count increments
- by 1 (regardless of the number of B-frames). If you don't
- change the duration of the video track when you mux, libmp4
- barfs. So, check if the x264opts aren't using B-frames, and
- when they aren't, set the boolean job->areBframes as false.
- */
- job->areBframes = 0;
- }
-
/* For 25 fps sources, HandBrake's explicit keyints will match the x264 defaults:
min-keyint 25 (same as auto), keyint 250 */
if( param.i_keyint_min != 25 || param.i_keyint_max != 250 )
@@ -295,11 +280,44 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
}
}
+ /* Apply profile settings after explicit settings, if present. */
+ if( job->x264_profile )
+ {
+ if( x264_param_apply_profile( &param, job->x264_profile ) < 0 )
+ {
+ free( pv );
+ pv = NULL;
+ return 1;
+ }
+ }
+
+ /* B-frames are on by default.*/
+ job->areBframes = 1;
+
+ if( param.i_bframe && param.i_bframe_pyramid )
+ {
+ /* Note b-pyramid here, so the initial delay can be doubled */
+ job->areBframes = 2;
+ }
+ else if( !param.i_bframe )
+ {
+ /*
+ When B-frames are enabled, the max frame count increments
+ by 1 (regardless of the number of B-frames). If you don't
+ change the duration of the video track when you mux, libmp4
+ barfs. So, check if the x264opts aren't using B-frames, and
+ when they aren't, set the boolean job->areBframes as false.
+ */
+ job->areBframes = 0;
+ }
+
hb_deep_log( 2, "encx264: opening libx264 (pass %d)", job->pass );
pv->x264 = x264_encoder_open( &param );
if ( pv->x264 == NULL )
{
hb_error("encx264: x264_encoder_open failed.");
+ free( pv );
+ pv = NULL;
return 1;
}
@@ -608,3 +626,19 @@ int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
*buf_out = x264_encode( w, in );
return HB_WORK_OK;
}
+
+const char * const * hb_x264_presets()
+{
+ return x264_preset_names;
+}
+
+const char * const * hb_x264_tunes()
+{
+ return x264_tune_names;
+}
+
+const char * const * hb_x264_profiles()
+{
+ return x264_profile_names;
+}
+
diff --git a/libhb/work.c b/libhb/work.c
index c9e5ee205..d8cb7b919 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -288,12 +288,27 @@ void hb_display_job_info( hb_job_t * job )
}
}
+ if( job->x264_preset && *job->x264_preset &&
+ job->vcodec == HB_VCODEC_X264 )
+ {
+ 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);
+ }
if( job->advanced_opts && *job->advanced_opts &&
( ( job->vcodec & HB_VCODEC_FFMPEG_MASK ) ||
( job->vcodec == HB_VCODEC_X264 ) ) )
{
hb_log( " + options: %s", job->advanced_opts);
}
+ if( job->x264_profile && *job->x264_profile &&
+ job->vcodec == HB_VCODEC_X264 )
+ {
+ hb_log( " + x264 profile: %s", job->x264_profile);
+ }
if( job->vquality >= 0 )
{
diff --git a/test/test.c b/test/test.c
index c91b59b30..fac25e8bc 100644
--- a/test/test.c
+++ b/test/test.c
@@ -114,6 +114,9 @@ static int chapter_markers = 0;
static char * marker_file = NULL;
static char *advanced_opts = NULL;
static char *advanced_opts2 = NULL;
+static char *x264_profile = NULL;
+static char *x264_preset = NULL;
+static char *x264_tune = NULL;
static int maxHeight = 0;
static int maxWidth = 0;
static int turbo_opts_enabled = 0;
@@ -361,6 +364,9 @@ int main( int argc, char ** argv )
if (preset_name) free (preset_name);
if( stop_at_string ) free( stop_at_string );
if( start_at_string ) free( start_at_string );
+ free( x264_profile );
+ free( x264_preset );
+ free( x264_tune );
// write a carriage return to stdout - avoids overlap / line wrapping when stderr is redirected
fprintf( stdout, "\n" );
@@ -2319,6 +2325,9 @@ static int HandleEvents( hb_handle_t * h )
{
job->advanced_opts = NULL;
}
+ job->x264_profile = x264_profile;
+ job->x264_preset = x264_preset;
+ job->x264_tune = x264_tune;
if (maxWidth)
job->maxWidth = maxWidth;
if (maxHeight)
@@ -2541,8 +2550,10 @@ void SigHandler( int i_signal )
****************************************************************************/
static void ShowHelp()
{
- int i, j;
+ int i, j, len;
FILE* const out = stdout;
+ const char * const *x264_opts;
+ char tmp[80];
fprintf( out,
"Syntax: HandBrakeCLI [options] -i <device> -o <file>\n"
@@ -2614,9 +2625,73 @@ static void ShowHelp()
}
}
fprintf( out,
+ " --x264-preset When using x264, selects the x264 preset:\n"
+ " <string> ");
+ x264_opts = hb_x264_presets();
+ 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"
+ " <string> ");
+ x264_opts = hb_x264_tunes();
+ 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,
" -x, --encopts <string> Specify advanced encoder options in the\n"
" same style as mencoder (x264 and ffmpeg only):\n"
" option1=value1:option2=value2\n"
+ " --x264-profile When using x264, ensures compliance with the\n"
+ " <string> specified h.264 profile:\n"
+ " ");
+ x264_opts = hb_x264_profiles();
+ 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,
" -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"
@@ -2974,7 +3049,10 @@ static int ParseOptions( int argc, char ** argv )
#define ALLOWED_AUDIO_COPY 280
#define AUDIO_FALLBACK 281
#define LOOSE_CROP 282
-
+ #define X264_PROFILE 283
+ #define X264_PRESET 284
+ #define X264_TUNE 285
+
for( ;; )
{
static struct option long_options[] =
@@ -3042,6 +3120,9 @@ static int ParseOptions( int argc, char ** argv )
{ "rate", required_argument, NULL, 'r' },
{ "arate", required_argument, NULL, 'R' },
{ "encopts", required_argument, NULL, 'x' },
+ { "x264-profile", required_argument, NULL, X264_PROFILE },
+ { "x264-preset", required_argument, NULL, X264_PRESET },
+ { "x264-tune", required_argument, NULL, X264_TUNE },
{ "turbo", no_argument, NULL, 'T' },
{ "maxHeight", required_argument, NULL, 'Y' },
{ "maxWidth", required_argument, NULL, 'X' },
@@ -3451,6 +3532,15 @@ static int ParseOptions( int argc, char ** argv )
case 'x':
advanced_opts = strdup( optarg );
break;
+ case X264_PROFILE:
+ x264_profile = strdup( optarg );
+ break;
+ case X264_PRESET:
+ x264_preset = strdup( optarg );
+ break;
+ case X264_TUNE:
+ x264_tune = strdup( optarg );
+ break;
case 'T':
turbo_opts_enabled = 1;
break;