Commit e4b44c2e authored by Yusuke Nakamura's avatar Yusuke Nakamura Committed by Fiona Glaser

Move DTS compression from libx264 to x264cli

DTS compression is an ugly stupid hack and starting to encroach on unrelated areas like VBV.
Some people want it in the mp4 muxer for devices and/or splitters that don't support Edit Boxes.
We just say "throw these broken devices out the window".
DTS compression will remain as a muxer option, --dts-compress, at the user's own risk.
This option is disabled by default.
parent 2eb4139f
......@@ -161,7 +161,6 @@ void x264_param_default( x264_param_t *param )
param->b_annexb = 1;
param->b_aud = 0;
param->b_vfr_input = 1;
param->b_dts_compress = 0;
param->i_nal_hrd = X264_NAL_HRD_NONE;
param->b_tff = 1;
param->b_pic_struct = 0;
......
......@@ -443,9 +443,6 @@ struct x264_t
x264_pps_t *pps;
int i_idr_pic_id;
/* Timebase multiplier for DTS compression */
int i_dts_compress_multiplier;
/* quantization matrix for decoding, [cqm][qp%6][coef] */
int (*dequant4_mf[4])[16]; /* [4][6][16] */
int (*dequant8_mf[2])[64]; /* [2][6][64] */
......@@ -500,7 +497,6 @@ struct x264_t
int i_bframe_delay;
int64_t i_bframe_delay_time;
int64_t i_first_pts;
int64_t i_init_delta;
int64_t i_prev_reordered_pts[2];
int64_t i_largest_pts;
int64_t i_second_largest_pts;
......
......@@ -935,28 +935,12 @@ x264_t *x264_encoder_open( x264_param_t *param )
h->i_frame = -1;
h->i_frame_num = 0;
h->i_idr_pic_id = 0;
uint64_t new_timebase_den = h->param.i_timebase_den;
if( h->param.b_dts_compress )
{
/* h->i_dts_compress_multiplier == h->frames.i_bframe_delay + 1 */
h->i_dts_compress_multiplier = h->param.i_bframe ? (h->param.i_bframe_pyramid ? 3 : 2) : 1;
if( h->i_dts_compress_multiplier != 1 )
{
new_timebase_den = h->param.i_timebase_den * h->i_dts_compress_multiplier;
x264_log( h, X264_LOG_DEBUG, "DTS compression changed timebase: %u/%u -> %u/%"PRIu64"\n",
h->param.i_timebase_num, h->param.i_timebase_den,
h->param.i_timebase_num, new_timebase_den );
}
}
else
h->i_dts_compress_multiplier = 1;
if( new_timebase_den * 2 > UINT32_MAX )
if( (uint64_t)h->param.i_timebase_den * 2 > UINT32_MAX )
{
x264_log( h, X264_LOG_ERROR, "Effective timebase denominator %"PRIu64" exceeds H.264 maximum\n", new_timebase_den );
x264_log( h, X264_LOG_ERROR, "Effective timebase denominator %u exceeds H.264 maximum\n", h->param.i_timebase_den );
goto fail;
}
h->param.i_timebase_den = new_timebase_den;
h->sps = &h->sps_array[0];
x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
......@@ -2506,25 +2490,14 @@ int x264_encoder_encode( x264_t *h,
h->fenc->b_kept_as_ref =
h->fdec->b_kept_as_ref = i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE && h->param.i_keyint_max > 1;
h->fdec->i_pts = h->fenc->i_pts *= h->i_dts_compress_multiplier;
h->fdec->i_pts = h->fenc->i_pts;
if( h->frames.i_bframe_delay )
{
int64_t *prev_reordered_pts = thread_current->frames.i_prev_reordered_pts;
if( h->i_frame <= h->frames.i_bframe_delay )
{
if( h->i_dts_compress_multiplier == 1 )
h->fdec->i_dts = h->fenc->i_reordered_pts - h->frames.i_bframe_delay_time;
else
{
/* DTS compression */
if( h->i_frame == 1 )
thread_current->frames.i_init_delta = (h->fenc->i_reordered_pts - h->frames.i_first_pts) * h->i_dts_compress_multiplier;
h->fdec->i_dts = h->i_frame * thread_current->frames.i_init_delta / h->i_dts_compress_multiplier + h->frames.i_first_pts * h->i_dts_compress_multiplier;
}
}
else
h->fdec->i_dts = prev_reordered_pts[ (h->i_frame - h->frames.i_bframe_delay) % h->frames.i_bframe_delay ];
prev_reordered_pts[ h->i_frame % h->frames.i_bframe_delay ] = h->fenc->i_reordered_pts * h->i_dts_compress_multiplier;
h->fdec->i_dts = h->i_frame > h->frames.i_bframe_delay
? prev_reordered_pts[ (h->i_frame - h->frames.i_bframe_delay) % h->frames.i_bframe_delay ]
: h->fenc->i_reordered_pts - h->frames.i_bframe_delay_time;
prev_reordered_pts[ h->i_frame % h->frames.i_bframe_delay ] = h->fenc->i_reordered_pts;
}
else
h->fdec->i_dts = h->fenc->i_reordered_pts;
......@@ -3137,7 +3110,7 @@ void x264_encoder_close ( x264_t *h )
else
{
float duration = (float)(2 * h->frames.i_largest_pts - h->frames.i_second_largest_pts - h->frames.i_first_pts)
* h->i_dts_compress_multiplier * h->param.i_timebase_num / h->param.i_timebase_den;
* h->param.i_timebase_num / h->param.i_timebase_den;
f_bitrate = SUM3(h->stat.i_frame_size) / duration / 125;
}
......
......@@ -1260,12 +1260,12 @@ void x264_slicetype_decide( x264_t *h )
if( h->param.b_vfr_input )
{
if( lookahead_size-- > 1 )
h->lookahead->next.list[i]->i_duration = 2 * (h->lookahead->next.list[i+1]->i_pts - h->lookahead->next.list[i]->i_pts) * h->i_dts_compress_multiplier;
h->lookahead->next.list[i]->i_duration = 2 * (h->lookahead->next.list[i+1]->i_pts - h->lookahead->next.list[i]->i_pts);
else
h->lookahead->next.list[i]->i_duration = h->i_prev_duration;
}
else
h->lookahead->next.list[i]->i_duration = delta_tfi_divisor[h->lookahead->next.list[i]->i_pic_struct] * h->i_dts_compress_multiplier;
h->lookahead->next.list[i]->i_duration = delta_tfi_divisor[h->lookahead->next.list[i]->i_pic_struct];
h->i_prev_duration = h->lookahead->next.list[i]->i_duration;
if( h->lookahead->next.list[i]->i_frame > h->i_disp_fields_last_frame && lookahead_size > 0 )
......
......@@ -50,11 +50,14 @@ typedef struct
uint8_t b_write_length;
int64_t i_prev_dts;
int64_t i_prev_pts;
int64_t i_prev_cts;
int64_t i_delay_time;
int64_t i_init_delta;
int i_delay_frames;
uint32_t i_timebase_num;
uint32_t i_timebase_den;
double d_timebase;
int b_vfr_input;
int b_dts_compress;
unsigned start;
} flv_hnd_t;
......@@ -70,7 +73,7 @@ static int write_header( flv_buffer *c )
return flv_flush_data( c );
}
static int open_file( char *psz_filename, hnd_t *p_handle )
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
{
flv_hnd_t *p_flv = malloc( sizeof(*p_flv) );
*p_handle = NULL;
......@@ -78,6 +81,8 @@ static int open_file( char *psz_filename, hnd_t *p_handle )
return -1;
memset( p_flv, 0, sizeof(*p_flv) );
p_flv->b_dts_compress = opt->use_dts_compress;
p_flv->c = flv_create_writer( psz_filename );
if( !p_flv->c )
return -1;
......@@ -147,9 +152,9 @@ static int set_param( hnd_t handle, x264_param_t *p_param )
p_flv->i_fps_num = p_param->i_fps_num;
p_flv->i_fps_den = p_param->i_fps_den;
p_flv->i_timebase_num = p_param->i_timebase_num;
p_flv->i_timebase_den = p_param->i_timebase_den;
p_flv->d_timebase = (double)p_param->i_timebase_num / p_param->i_timebase_den;
p_flv->b_vfr_input = p_param->b_vfr_input;
p_flv->i_delay_frames = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0;
return 0;
}
......@@ -217,29 +222,47 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_
flv_hnd_t *p_flv = handle;
flv_buffer *c = p_flv->c;
int64_t dts = (int64_t)( (p_picture->i_dts * 1000 * ((double)p_flv->i_timebase_num / p_flv->i_timebase_den)) + 0.5 );
int64_t cts = (int64_t)( (p_picture->i_pts * 1000 * ((double)p_flv->i_timebase_num / p_flv->i_timebase_den)) + 0.5 );
int64_t offset = cts - dts;
#define convert_timebase_ms( timestamp, timebase ) (int64_t)((timestamp) * (timebase) * 1000 + 0.5)
if( !p_flv->i_framenum )
{
p_flv->i_delay_time = p_picture->i_dts * -1;
if( !p_flv->b_dts_compress && p_flv->i_delay_time )
x264_cli_log( "flv", X264_LOG_INFO, "initial delay %"PRId64" ms\n",
convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase ) );
}
int64_t dts;
int64_t cts;
int64_t offset;
if( p_flv->b_dts_compress )
{
if( p_flv->i_framenum == 1 )
p_flv->i_init_delta = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
dts = p_flv->i_framenum > p_flv->i_delay_frames
? convert_timebase_ms( p_picture->i_dts, p_flv->d_timebase )
: p_flv->i_framenum * p_flv->i_init_delta / (p_flv->i_delay_frames + 1);
cts = convert_timebase_ms( p_picture->i_pts, p_flv->d_timebase );
}
else
{
dts = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
cts = convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase );
}
offset = cts - dts;
if( p_flv->i_framenum )
{
int64_t prev_dts = (int64_t)( (p_flv->i_prev_dts * 1000 * ((double)p_flv->i_timebase_num / p_flv->i_timebase_den)) + 0.5 );
int64_t prev_cts = (int64_t)( (p_flv->i_prev_pts * 1000 * ((double)p_flv->i_timebase_num / p_flv->i_timebase_den)) + 0.5 );
if( prev_dts == dts )
{
double fps = ((double)p_flv->i_timebase_den / p_flv->i_timebase_num) / (p_picture->i_dts - p_flv->i_prev_dts);
if( p_flv->i_prev_dts == dts )
x264_cli_log( "flv", X264_LOG_WARNING, "duplicate DTS %"PRId64" generated by rounding\n"
" current internal decoding framerate: %.6f fps\n", dts, fps );
}
if( prev_cts == cts )
{
double fps = ((double)p_flv->i_timebase_den / p_flv->i_timebase_num) / (p_picture->i_pts - p_flv->i_prev_pts);
" decoding framerate cannot exceed 1000fps\n", dts );
if( p_flv->i_prev_cts == cts )
x264_cli_log( "flv", X264_LOG_WARNING, "duplicate CTS %"PRId64" generated by rounding\n"
" current internal composition framerate: %.6f fps\n", cts, fps );
}
" composition framerate cannot exceed 1000fps\n", cts );
}
p_flv->i_prev_dts = p_picture->i_dts;
p_flv->i_prev_pts = p_picture->i_pts;
p_flv->i_prev_dts = dts;
p_flv->i_prev_cts = cts;
// A new frame - write packet header
x264_put_byte( c, FLV_TAG_TYPE_VIDEO );
......@@ -285,7 +308,7 @@ static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest
CHECK( flv_flush_data( c ) );
double total_duration = (double)(2 * largest_pts - second_largest_pts) * p_flv->i_timebase_num / p_flv->i_timebase_den;
double total_duration = (2 * largest_pts - second_largest_pts) * p_flv->d_timebase;
if( x264_is_regular_file( c->fp ) )
{
......
......@@ -42,7 +42,7 @@ typedef struct
} mkv_hnd_t;
static int open_file( char *psz_filename, hnd_t *p_handle )
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
{
mkv_hnd_t *p_mkv;
......
......@@ -41,10 +41,14 @@ typedef struct
GF_ISOSample *p_sample;
int i_track;
uint32_t i_descidx;
uint32_t i_time_res;
uint64_t i_time_res;
int64_t i_time_inc;
int64_t i_delay_time;
int64_t i_init_delta;
int i_numframe;
int i_delay_time;
int i_delay_frames;
int b_dts_compress;
int i_dts_compress_multiplier;
} mp4_hnd_t;
static void recompute_bitrate_mp4( GF_ISOFile *p_file, int i_track )
......@@ -158,7 +162,7 @@ static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest
return 0;
}
static int open_file( char *psz_filename, hnd_t *p_handle )
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
{
mp4_hnd_t *p_mp4;
......@@ -175,6 +179,8 @@ static int open_file( char *psz_filename, hnd_t *p_handle )
memset( p_mp4, 0, sizeof(mp4_hnd_t) );
p_mp4->p_file = gf_isom_open( psz_filename, GF_ISOM_OPEN_WRITE, NULL );
p_mp4->b_dts_compress = opt->use_dts_compress;
if( !(p_mp4->p_sample = gf_isom_sample_new()) )
{
close_file( p_mp4, 0, 0 );
......@@ -192,8 +198,12 @@ static int set_param( hnd_t handle, x264_param_t *p_param )
{
mp4_hnd_t *p_mp4 = handle;
p_mp4->i_time_res = p_param->i_timebase_den;
p_mp4->i_time_inc = p_param->i_timebase_num;
p_mp4->i_delay_frames = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0;
p_mp4->i_dts_compress_multiplier = p_mp4->b_dts_compress * p_mp4->i_delay_frames + 1;
p_mp4->i_time_res = p_param->i_timebase_den * p_mp4->i_dts_compress_multiplier;
p_mp4->i_time_inc = p_param->i_timebase_num * p_mp4->i_dts_compress_multiplier;
FAIL_IF_ERR( p_mp4->i_time_res > UINT32_MAX, "mp4", "MP4 media timescale %"PRIu64" exceeds maximum\n", p_mp4->i_time_res )
p_mp4->i_track = gf_isom_new_track( p_mp4->p_file, 0, GF_ISOM_MEDIA_VISUAL,
p_mp4->i_time_res );
......@@ -276,6 +286,7 @@ static int write_headers( hnd_t handle, x264_nal_t *p_nal )
return sei_size + sps_size + pps_size;
}
static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_t *p_picture )
{
mp4_hnd_t *p_mp4 = handle;
......@@ -288,8 +299,20 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_
if( !p_mp4->i_numframe )
p_mp4->i_delay_time = p_picture->i_dts * -1;
dts = (p_picture->i_dts + p_mp4->i_delay_time) * p_mp4->i_time_inc;
cts = (p_picture->i_pts + p_mp4->i_delay_time) * p_mp4->i_time_inc;
if( p_mp4->b_dts_compress )
{
if( p_mp4->i_numframe == 1 )
p_mp4->i_init_delta = (p_picture->i_dts + p_mp4->i_delay_time) * p_mp4->i_time_inc;
dts = p_mp4->i_numframe > p_mp4->i_delay_frames
? p_picture->i_dts * p_mp4->i_time_inc
: p_mp4->i_numframe * (p_mp4->i_init_delta / p_mp4->i_dts_compress_multiplier);
cts = p_picture->i_pts * p_mp4->i_time_inc;
}
else
{
dts = (p_picture->i_dts + p_mp4->i_delay_time) * p_mp4->i_time_inc;
cts = (p_picture->i_pts + p_mp4->i_delay_time) * p_mp4->i_time_inc;
}
p_mp4->p_sample->IsRAP = p_picture->b_keyframe;
p_mp4->p_sample->DTS = dts;
......
......@@ -31,7 +31,12 @@
typedef struct
{
int (*open_file)( char *psz_filename, hnd_t *p_handle );
int use_dts_compress;
} cli_output_opt_t;
typedef struct
{
int (*open_file)( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt );
int (*set_param)( hnd_t handle, x264_param_t *p_param );
int (*write_headers)( hnd_t handle, x264_nal_t *p_nal );
int (*write_frame)( hnd_t handle, uint8_t *p_nal, int i_size, x264_picture_t *p_picture );
......
......@@ -26,7 +26,7 @@
#include "output.h"
static int open_file( char *psz_filename, hnd_t *p_handle )
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
{
if( !strcmp( psz_filename, "-" ) )
*p_handle = stdout;
......
......@@ -725,6 +725,7 @@ static void help( x264_param_t *defaults, int longhelp )
H2( " --timebase <int/int> Specify timebase numerator and denominator\n"
" <integer> Specify timebase numerator for input timecode file\n"
" or specify timebase denominator for other input\n" );
H2( " --dts-compress Eliminate initial delay with container DTS hack\n" );
H0( "\n" );
H0( "Filtering:\n" );
H0( "\n" );
......@@ -766,7 +767,8 @@ enum
OPT_VIDEO_FILTER,
OPT_INPUT_RES,
OPT_INPUT_CSP,
OPT_INPUT_DEPTH
OPT_INPUT_DEPTH,
OPT_DTS_COMPRESSION
} OptionsOPT;
static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw";
......@@ -919,6 +921,7 @@ static struct option long_options[] =
{ "input-res", required_argument, NULL, OPT_INPUT_RES },
{ "input-csp", required_argument, NULL, OPT_INPUT_CSP },
{ "input-depth", required_argument, NULL, OPT_INPUT_DEPTH },
{ "dts-compress", no_argument, NULL, OPT_DTS_COMPRESSION },
{0, 0, 0, 0}
};
......@@ -933,7 +936,6 @@ static int select_output( const char *muxer, char *filename, x264_param_t *param
#if HAVE_GPAC
output = mp4_output;
param->b_annexb = 0;
param->b_dts_compress = 0;
param->b_repeat_headers = 0;
if( param->i_nal_hrd == X264_NAL_HRD_CBR )
{
......@@ -949,14 +951,12 @@ static int select_output( const char *muxer, char *filename, x264_param_t *param
{
output = mkv_output;
param->b_annexb = 0;
param->b_dts_compress = 0;
param->b_repeat_headers = 0;
}
else if( !strcasecmp( ext, "flv" ) )
{
output = flv_output;
param->b_annexb = 0;
param->b_dts_compress = 1;
param->b_repeat_headers = 0;
}
else
......@@ -1131,6 +1131,7 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
int b_user_fps = 0;
int b_user_interlaced = 0;
cli_input_opt_t input_opt;
cli_output_opt_t output_opt;
char *preset = NULL;
char *tune = NULL;
......@@ -1139,6 +1140,7 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
memset( opt, 0, sizeof(cli_opt_t) );
memset( &input_opt, 0, sizeof(cli_input_opt_t) );
memset( &output_opt, 0, sizeof(cli_output_opt_t) );
input_opt.bit_depth = 8;
opt->b_progress = 1;
......@@ -1288,6 +1290,9 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
case OPT_INPUT_DEPTH:
input_opt.bit_depth = atoi( optarg );
break;
case OPT_DTS_COMPRESSION:
output_opt.use_dts_compress = 1;
break;
default:
generic_option:
{
......@@ -1332,7 +1337,7 @@ generic_option:
if( select_output( muxer, output_filename, param ) )
return -1;
FAIL_IF_ERROR( output.open_file( output_filename, &opt->hout ), "could not open output file `%s'\n", output_filename )
FAIL_IF_ERROR( output.open_file( output_filename, &opt->hout, &output_opt ), "could not open output file `%s'\n", output_filename )
input_filename = argv[optind++];
video_info_t info = {0};
......@@ -1585,8 +1590,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
int64_t second_largest_pts = -1;
int64_t ticks_per_frame;
double duration;
int prev_timebase_den;
int dts_compress_multiplier;
double pulldown_pts = 0;
opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;
......@@ -1605,8 +1608,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
param->i_timebase_den = param->i_fps_num * pulldown->fps_factor;
}
prev_timebase_den = param->i_timebase_den / gcd( param->i_timebase_num, param->i_timebase_den );
if( ( h = x264_encoder_open( param ) ) == NULL )
{
x264_cli_log( "x264", X264_LOG_ERROR, "x264_encoder_open failed\n" );
......@@ -1616,8 +1617,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
x264_encoder_parameters( h, param );
dts_compress_multiplier = param->i_timebase_den / prev_timebase_den;
if( output.set_param( opt->hout, param ) )
{
x264_cli_log( "x264", X264_LOG_ERROR, "can't set outfile param\n" );
......@@ -1664,24 +1663,21 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
else if( opt->timebase_convert_multiplier )
pic.i_pts = (int64_t)( pic.i_pts * opt->timebase_convert_multiplier + 0.5 );
int64_t output_pts = pic.i_pts * dts_compress_multiplier; /* pts libx264 returns */
if( pic.i_pts <= largest_pts )
{
if( cli_log_level >= X264_LOG_DEBUG || pts_warning_cnt < MAX_PTS_WARNING )
x264_cli_log( "x264", X264_LOG_WARNING, "non-strictly-monotonic pts at frame %d (%"PRId64" <= %"PRId64")\n",
i_frame, output_pts, largest_pts * dts_compress_multiplier );
i_frame, pic.i_pts, largest_pts );
else if( pts_warning_cnt == MAX_PTS_WARNING )
x264_cli_log( "x264", X264_LOG_WARNING, "too many nonmonotonic pts warnings, suppressing further ones\n" );
pts_warning_cnt++;
pic.i_pts = largest_pts + ticks_per_frame;
output_pts = pic.i_pts * dts_compress_multiplier;
}
second_largest_pts = largest_pts;
largest_pts = pic.i_pts;
if( opt->tcfile_out )
fprintf( opt->tcfile_out, "%.6f\n", output_pts * ((double)param->i_timebase_num / param->i_timebase_den) * 1e3 );
fprintf( opt->tcfile_out, "%.6f\n", pic.i_pts * ((double)param->i_timebase_num / param->i_timebase_den) * 1e3 );
if( opt->qpfile )
parse_qpfile( opt, &pic, i_frame + opt->i_seek );
......@@ -1731,8 +1727,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
if( pts_warning_cnt >= MAX_PTS_WARNING && cli_log_level < X264_LOG_DEBUG )
x264_cli_log( "x264", X264_LOG_WARNING, "%d suppressed nonmonotonic pts warnings\n", pts_warning_cnt-MAX_PTS_WARNING );
largest_pts *= dts_compress_multiplier;
second_largest_pts *= dts_compress_multiplier;
/* duration algorithm fails when only 1 frame is output */
if( i_frame_output == 1 )
duration = (double)param->i_fps_den / param->i_fps_num;
......
......@@ -39,7 +39,7 @@
#include <stdarg.h>
#define X264_BUILD 106
#define X264_BUILD 107
/* x264_t:
* opaque handler for encoder */
......@@ -391,9 +391,6 @@ typedef struct x264_param_t
uint32_t i_fps_den;
uint32_t i_timebase_num; /* Timebase numerator */
uint32_t i_timebase_den; /* Timebase denominator */
int b_dts_compress; /* DTS compression: this algorithm eliminates negative DTS
* by compressing them to be less than the second PTS.
* Warning: this will change the timebase! */
int b_tff;
......
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