Commit e54ea0c8 authored by Fiona Glaser's avatar Fiona Glaser

Consolidate Blu-ray hacks into --bluray-compat

This option is now required for Blu-ray compatibility.
--open-gop bluray is now gone (using bluray-compat and open-gop implies a Blu-ray compatible open-gop).
This option doesn't automatically enforce every aspect of Blu-ray compatibility (e.g. resolution, framerate, level, etc).
parent bdb88277
......@@ -621,6 +621,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
else
p->i_level_idc = atoi(value);
}
OPT("bluray-compat")
p->b_bluray_compat = atobool(value);
OPT("sar")
{
b_error = ( 2 != sscanf( value, "%d:%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) &&
......@@ -705,14 +707,7 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
}
}
OPT("open-gop")
{
b_error |= parse_enum( value, x264_open_gop_names, &p->i_open_gop );
if( b_error )
{
b_error = 0;
p->i_open_gop = atoi(value);
}
}
p->b_open_gop = atobool(value);
OPT("nf")
p->b_deblocking_filter = !atobool(value);
OPT2("filter", "deblock")
......@@ -1240,6 +1235,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
s += sprintf( s, " nr=%d", p->analyse.i_noise_reduction );
s += sprintf( s, " decimate=%d", p->analyse.b_dct_decimate );
s += sprintf( s, " interlaced=%s", p->b_interlaced ? p->b_tff ? "tff" : "bff" : p->b_fake_interlaced ? "fake" : "0" );
s += sprintf( s, " bluray_compat=%d", p->b_bluray_compat );
s += sprintf( s, " constrained_intra=%d", p->b_constrained_intra );
......@@ -1248,7 +1244,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
{
s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d weightb=%d open_gop=%d",
p->i_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias,
p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred, p->i_open_gop );
p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred, p->b_open_gop );
}
s += sprintf( s, " weightp=%d", p->analyse.i_weighted_pred > 0 ? p->analyse.i_weighted_pred : 0 );
......
......@@ -595,6 +595,21 @@ static int x264_validate_parameters( x264_t *h )
h->param.i_slice_count = 0;
}
if( h->param.b_bluray_compat )
{
h->param.i_bframe_pyramid = X264_MIN( X264_B_PYRAMID_STRICT, h->param.i_bframe_pyramid );
h->param.i_bframe = X264_MIN( h->param.i_bframe, 3 );
h->param.b_aud = 1;
h->param.i_nal_hrd = X264_MAX( h->param.i_nal_hrd, X264_NAL_HRD_VBR );
h->param.i_slice_max_size = 0;
h->param.i_slice_max_mbs = 0;
h->param.b_intra_refresh = 0;
h->param.i_frame_reference = X264_MIN( h->param.i_frame_reference, 6 );
h->param.i_dpb_size = X264_MIN( h->param.i_dpb_size, 6 );
/* Due to the proliferation of broken players that don't handle dupes properly. */
h->param.analyse.i_weighted_pred = X264_MIN( h->param.analyse.i_weighted_pred, X264_WEIGHTP_SIMPLE );
}
h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, X264_REF_MAX );
h->param.i_dpb_size = x264_clip3( h->param.i_dpb_size, 1, X264_REF_MAX );
if( h->param.i_scenecut_threshold < 0 )
......@@ -605,7 +620,6 @@ static int x264_validate_parameters( x264_t *h )
h->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
}
h->param.i_bframe = x264_clip3( h->param.i_bframe, 0, X264_MIN( X264_BFRAME_MAX, h->param.i_keyint_max-1 ) );
h->param.i_open_gop = x264_clip3( h->param.i_open_gop, X264_OPEN_GOP_NONE, X264_OPEN_GOP_BLURAY );
h->param.i_bframe_bias = x264_clip3( h->param.i_bframe_bias, -90, 100 );
if( h->param.i_bframe <= 1 )
h->param.i_bframe_pyramid = X264_B_PYRAMID_NONE;
......@@ -615,7 +629,7 @@ static int x264_validate_parameters( x264_t *h )
h->param.i_bframe_adaptive = X264_B_ADAPT_NONE;
h->param.analyse.i_direct_mv_pred = 0;
h->param.analyse.b_weighted_bipred = 0;
h->param.i_open_gop = X264_OPEN_GOP_NONE;
h->param.b_open_gop = 0;
}
if( h->param.b_intra_refresh && h->param.i_bframe_pyramid == X264_B_PYRAMID_NORMAL )
{
......@@ -628,10 +642,10 @@ static int x264_validate_parameters( x264_t *h )
h->param.i_frame_reference = 1;
h->param.i_dpb_size = 1;
}
if( h->param.b_intra_refresh && h->param.i_open_gop )
if( h->param.b_intra_refresh && h->param.b_open_gop )
{
x264_log( h, X264_LOG_WARNING, "intra-refresh is not compatible with open-gop\n" );
h->param.i_open_gop = X264_OPEN_GOP_NONE;
h->param.b_open_gop = 0;
}
float fps = h->param.i_fps_num > 0 && h->param.i_fps_den > 0 ? (float) h->param.i_fps_num / h->param.i_fps_den : 25.0;
if( h->param.i_keyint_min == X264_KEYINT_MIN_AUTO )
......@@ -867,6 +881,7 @@ static int x264_validate_parameters( x264_t *h )
BOOLIFY( b_vfr_input );
BOOLIFY( b_pic_struct );
BOOLIFY( b_fake_interlaced );
BOOLIFY( b_open_gop );
BOOLIFY( analyse.b_transform_8x8 );
BOOLIFY( analyse.b_weighted_bipred );
BOOLIFY( analyse.b_chroma_me );
......@@ -2557,7 +2572,7 @@ int x264_encoder_encode( x264_t *h,
i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/
h->sh.i_type = SLICE_TYPE_I;
x264_reference_hierarchy_reset( h );
if( h->param.i_open_gop )
if( h->param.b_open_gop )
h->frames.i_poc_last_open_gop = h->fenc->b_keyframe ? h->fenc->i_poc : -1;
}
else if( h->fenc->i_type == X264_TYPE_P )
......@@ -2732,7 +2747,7 @@ int x264_encoder_encode( x264_t *h,
if( h->fenc->i_type != X264_TYPE_IDR )
{
int time_to_recovery = h->param.i_open_gop ? 0 : X264_MIN( h->mb.i_mb_width - 1, h->param.i_keyint_max ) + h->param.i_bframe - 1;
int time_to_recovery = h->param.b_open_gop ? 0 : X264_MIN( h->mb.i_mb_width - 1, h->param.i_keyint_max ) + h->param.i_bframe - 1;
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
x264_sei_recovery_point_write( h, &h->out.bs, time_to_recovery );
if( x264_nal_end( h ) )
......
......@@ -735,7 +735,8 @@ int x264_ratecontrol_new( x264_t *h )
CMP_OPT_FIRST_PASS( "bframes", h->param.i_bframe );
CMP_OPT_FIRST_PASS( "b_pyramid", h->param.i_bframe_pyramid );
CMP_OPT_FIRST_PASS( "intra_refresh", h->param.b_intra_refresh );
CMP_OPT_FIRST_PASS( "open_gop", h->param.i_open_gop );
CMP_OPT_FIRST_PASS( "open_gop", h->param.b_open_gop );
CMP_OPT_FIRST_PASS( "bluray_compat", h->param.b_bluray_compat );
if( (p = strstr( opts, "keyint=" )) )
{
......@@ -1208,8 +1209,7 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
int mincr = l->mincr;
/* Blu-ray requires this */
if( l->level_idc == 41 && h->param.i_nal_hrd )
if( h->param.b_bluray_compat )
mincr = 4;
/* High 10 doesn't require minCR, so just set the maximum to a large value. */
......
......@@ -1377,7 +1377,7 @@ void x264_slicetype_analyse( x264_t *h, int keyframe )
{
frames[i]->i_type = X264_TYPE_I;
reset_start = X264_MIN( reset_start, i+1 );
if( h->param.i_open_gop == X264_OPEN_GOP_BLURAY )
if( h->param.b_open_gop && h->param.b_bluray_compat )
while( IS_X264_TYPE_B( frames[i-1]->i_type ) )
i--;
}
......@@ -1465,25 +1465,25 @@ void x264_slicetype_decide( x264_t *h )
}
if( frm->i_type == X264_TYPE_KEYFRAME )
frm->i_type = h->param.i_open_gop ? X264_TYPE_I : X264_TYPE_IDR;
frm->i_type = h->param.b_open_gop ? X264_TYPE_I : X264_TYPE_IDR;
/* Limit GOP size */
if( (!h->param.b_intra_refresh || frm->i_frame == 0) && frm->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_max )
{
if( frm->i_type == X264_TYPE_AUTO || frm->i_type == X264_TYPE_I )
frm->i_type = h->param.i_open_gop && h->lookahead->i_last_keyframe >= 0 ? X264_TYPE_I : X264_TYPE_IDR;
frm->i_type = h->param.b_open_gop && h->lookahead->i_last_keyframe >= 0 ? X264_TYPE_I : X264_TYPE_IDR;
int warn = frm->i_type != X264_TYPE_IDR;
if( warn && h->param.i_open_gop )
if( warn && h->param.b_open_gop )
warn &= frm->i_type != X264_TYPE_I;
if( warn )
x264_log( h, X264_LOG_WARNING, "specified frame type (%d) at %d is not compatible with keyframe interval\n", frm->i_type, frm->i_frame );
}
if( frm->i_type == X264_TYPE_I && frm->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_min )
{
if( h->param.i_open_gop )
if( h->param.b_open_gop )
{
h->lookahead->i_last_keyframe = frm->i_frame; // Use display order
if( h->param.i_open_gop == X264_OPEN_GOP_BLURAY )
if( h->param.b_bluray_compat )
h->lookahead->i_last_keyframe -= bframes; // Use bluray order
frm->b_keyframe = 1;
}
......
......@@ -541,11 +541,7 @@ static void help( x264_param_t *defaults, int longhelp )
" - strict: Strictly hierarchical pyramid\n"
" - normal: Non-strict (not Blu-ray compatible)\n",
strtable_lookup( x264_b_pyramid_names, defaults->i_bframe_pyramid ) );
H1( " --open-gop <string> Use recovery points to close GOPs [none]\n"
" - none: closed GOPs only\n"
" - normal: standard open GOPs\n"
" (not Blu-ray compatible)\n"
" - bluray: Blu-ray-compatible open GOPs\n"
H1( " --open-gop Use recovery points to close GOPs\n"
" Only available with b-frames\n" );
H1( " --no-cabac Disable CABAC\n" );
H1( " -r, --ref <integer> Number of reference frames [%d]\n", defaults->i_frame_reference );
......@@ -741,6 +737,7 @@ static void help( x264_param_t *defaults, int longhelp )
H0( " --seek <integer> First frame to encode\n" );
H0( " --frames <integer> Maximum number of frames to encode\n" );
H0( " --level <string> Specify level (as defined by Annex A)\n" );
H1( " --bluray-compat Enable compatibility hacks for Blu-ray support\n" );
H1( "\n" );
H1( " -v, --verbose Print stats for each frame\n" );
H1( " --no-progress Don't show the progress indicator while encoding\n" );
......@@ -831,7 +828,8 @@ static struct option long_options[] =
{ "no-b-adapt", no_argument, NULL, 0 },
{ "b-bias", required_argument, NULL, 0 },
{ "b-pyramid", required_argument, NULL, 0 },
{ "open-gop", required_argument, NULL, 0 },
{ "open-gop", no_argument, NULL, 0 },
{ "bluray-compat", no_argument, NULL, 0 },
{ "min-keyint", required_argument, NULL, 'i' },
{ "keyint", required_argument, NULL, 'I' },
{ "intra-refresh", no_argument, NULL, 0 },
......
......@@ -41,7 +41,7 @@
#include "x264_config.h"
#define X264_BUILD 114
#define X264_BUILD 115
/* x264_t:
* opaque handler for encoder */
......@@ -162,9 +162,6 @@ typedef struct
#define X264_B_PYRAMID_NORMAL 2
#define X264_KEYINT_MIN_AUTO 0
#define X264_KEYINT_MAX_INFINITE (1<<30)
#define X264_OPEN_GOP_NONE 0
#define X264_OPEN_GOP_NORMAL 1
#define X264_OPEN_GOP_BLURAY 2
static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", "tesa", 0 };
......@@ -176,7 +173,6 @@ static const char * const x264_colorprim_names[] = { "", "bt709", "undef", "", "
static const char * const x264_transfer_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", "log316", 0 };
static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", 0 };
static const char * const x264_nal_hrd_names[] = { "none", "vbr", "cbr", 0 };
static const char * const x264_open_gop_names[] = { "none", "normal", "bluray", 0 };
/* Colorspace type */
#define X264_CSP_MASK 0x00ff /* */
......@@ -281,7 +277,8 @@ typedef struct x264_param_t
int i_bframe_adaptive;
int i_bframe_bias;
int i_bframe_pyramid; /* Keep some B-frames as references: 0=off, 1=strict hierarchical, 2=normal */
int i_open_gop; /* Open gop: 1=display order, 2=bluray compatibility braindamage mode */
int b_open_gop;
int b_bluray_compat;
int b_deblocking_filter;
int i_deblocking_filter_alphac0; /* [-6, 6] -6 light filter, 6 strong */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment