From: Kieran Kunhya Date: Thu, 20 May 2010 16:45:16 +0000 (+0100) Subject: Add "Fake interlaced" option X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=2b61248f4bcbb5f9df32d940732bc26d8feeda8c;p=x264 Add "Fake interlaced" option This encodes all frames progressively yet flags the stream as interlaced. This makes it possible to encode valid 25p and 30p Blu-Ray streams. Also put the pulldown help section in a more appropriate place. --- diff --git a/common/common.c b/common/common.c index ad7cf987..62bef990 100644 --- a/common/common.c +++ b/common/common.c @@ -160,6 +160,7 @@ void x264_param_default( x264_param_t *param ) param->i_nal_hrd = X264_NAL_HRD_NONE; param->b_tff = 1; param->b_pic_struct = 0; + param->b_fake_interlaced = 0; } static int x264_param_apply_preset( x264_param_t *param, const char *preset ) @@ -425,6 +426,8 @@ int x264_param_apply_profile( x264_param_t *param, const char *profile ) x264_log( NULL, X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" ); return -1; } + if( param->b_fake_interlaced ) + x264_log( NULL, X264_LOG_WARNING, "baseline profile doesn't support fake interlacing\n" ); } else if( !strcasecmp( profile, "main" ) ) { @@ -930,6 +933,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value ) b_error |= parse_enum( value, x264_nal_hrd_names, &p->i_nal_hrd ); OPT("pic-struct") p->b_pic_struct = atobool(value); + OPT("fake-interlaced") + p->b_fake_interlaced = atobool(value); else return X264_PARAM_BAD_NAME; #undef OPT diff --git a/encoder/encoder.c b/encoder/encoder.c index 76a4164d..9bf01e9b 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -784,6 +784,7 @@ static int x264_validate_parameters( x264_t *h ) BOOLIFY( b_annexb ); BOOLIFY( b_vfr_input ); BOOLIFY( b_pic_struct ); + BOOLIFY( b_fake_interlaced ); BOOLIFY( analyse.b_transform_8x8 ); BOOLIFY( analyse.b_weighted_bipred ); BOOLIFY( analyse.b_chroma_me ); diff --git a/encoder/set.c b/encoder/set.c index ce52a4b0..28de4b5a 100644 --- a/encoder/set.c +++ b/encoder/set.c @@ -149,16 +149,16 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) sps->b_gaps_in_frame_num_value_allowed = 0; sps->i_mb_width = ( param->i_width + 15 ) / 16; sps->i_mb_height= ( param->i_height + 15 ) / 16; - if( param->b_interlaced ) + sps->b_frame_mbs_only = param->b_interlaced ? 0 : !param->b_fake_interlaced; + if( !sps->b_frame_mbs_only ) sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; - sps->b_frame_mbs_only = ! param->b_interlaced; sps->b_mb_adaptive_frame_field = param->b_interlaced; sps->b_direct8x8_inference = 1; sps->crop.i_left = 0; sps->crop.i_top = 0; sps->crop.i_right = sps->i_mb_width*16 - param->i_width; - sps->crop.i_bottom = (sps->i_mb_height*16 - param->i_height) >> param->b_interlaced; + sps->crop.i_bottom = (sps->i_mb_height*16 - param->i_height) >> !sps->b_frame_mbs_only; sps->b_crop = sps->crop.i_left || sps->crop.i_top || sps->crop.i_right || sps->crop.i_bottom; @@ -685,6 +685,7 @@ int x264_validate_levels( x264_t *h, int verbose ) CHECK( "VBV buffer", (l->cpb * cbp_factor) / 4, h->param.rc.i_vbv_buffer_size ); CHECK( "MV range", l->mv_range, h->param.analyse.i_mv_range ); CHECK( "interlaced", !l->frame_only, h->param.b_interlaced ); + CHECK( "fake interlaced", !l->frame_only, h->param.b_fake_interlaced ); if( h->param.i_fps_den > 0 ) CHECK( "MB rate", l->mbps, (int64_t)mbs * h->param.i_fps_num / h->param.i_fps_den ); diff --git a/x264.c b/x264.c index 862aabb2..c4a74009 100644 --- a/x264.c +++ b/x264.c @@ -393,6 +393,11 @@ static void Help( x264_param_t *defaults, int longhelp ) H0( " --tff Enable interlaced mode (top field first)\n" ); H0( " --bff Enable interlaced mode (bottom field first)\n" ); H2( " --constrained-intra Enable constrained intra prediction.\n" ); + H0( " --pulldown Use soft pulldown to change frame rate\n" + " - none, 22, 32, 64, double, triple, euro (requires cfr input)\n" ); + H2( " --fake-interlaced Flag stream as interlaced but encode progressive.\n" + " Makes it possible to encode 25p and 30p Blu-Ray\n" + " streams. Ignored in interlaced mode.\n" ); H0( "\n" ); H0( "Ratecontrol:\n" ); H0( "\n" ); @@ -577,8 +582,6 @@ static void Help( x264_param_t *defaults, int longhelp ) H2( " --timebase Specify timebase numerator and denominator\n" " Specify timebase numerator for input timecode file\n" " or specify timebase denominator for other input\n" ); - H0( " --pulldown Use soft pulldown to change frame rate\n" - " - none, 22, 32, 64, double, triple, euro (requires cfr input)\n" ); H0( "\n" ); } @@ -747,6 +750,7 @@ static struct option long_options[] = { "pic-struct", no_argument, NULL, 0 }, { "nal-hrd", required_argument, NULL, 0 }, { "pulldown", required_argument, NULL, OPT_PULLDOWN }, + { "fake-interlaced", no_argument, NULL, 0 }, {0, 0, 0, 0} }; diff --git a/x264.h b/x264.h index f568dc5e..b11acf8a 100644 --- a/x264.h +++ b/x264.h @@ -35,7 +35,7 @@ #include -#define X264_BUILD 95 +#define X264_BUILD 96 /* x264_t: * opaque handler for encoder */ @@ -349,6 +349,14 @@ typedef struct x264_param_t int b_pic_struct; + /* Fake Interlaced. + * + * Used only when b_interlaced=0. Setting this flag to zero makes it possible to flag the stream as PAFF interlaced yet + * encode all frames progessively. It is useful for encoding 25p and 30p Blu-Ray streams. + */ + + int b_fake_interlaced; + /* Slicing parameters */ int i_slice_max_size; /* Max size per slice in bytes; includes estimated NAL overhead. */ int i_slice_max_mbs; /* Max number of MBs per slice; overrides i_slice_count. */