With timebase denominators >= 2^30 , x264 would silently overflow and cause odd issues.
Now x264 will explicitly fail with timebase denominators >= 2^31 and work with timebase denominators 2^31 > x >= 2^30.
}
OPT("fps")
{
- if( sscanf( value, "%d/%d", &p->i_fps_num, &p->i_fps_den ) == 2 )
+ if( sscanf( value, "%u/%u", &p->i_fps_num, &p->i_fps_den ) == 2 )
;
else
{
/****************************************************************************
* x264_reduce_fraction:
****************************************************************************/
-void x264_reduce_fraction( int *n, int *d )
+void x264_reduce_fraction( uint32_t *n, uint32_t *d )
{
- int a = *n;
- int b = *d;
- int c;
+ uint32_t a = *n;
+ uint32_t b = *d;
+ uint32_t c;
if( !a || !b )
return;
c = a % b;
if( b_res )
{
s += sprintf( s, "%dx%d ", p->i_width, p->i_height );
- s += sprintf( s, "fps=%d/%d ", p->i_fps_num, p->i_fps_den );
- s += sprintf( s, "timebase=%d/%d ", p->i_timebase_num, p->i_timebase_den );
+ s += sprintf( s, "fps=%u/%u ", p->i_fps_num, p->i_fps_den );
+ s += sprintf( s, "timebase=%u/%u ", p->i_timebase_num, p->i_timebase_den );
}
s += sprintf( s, "cabac=%d", p->b_cabac );
/* log */
void x264_log( x264_t *h, int i_level, const char *psz_fmt, ... );
-void x264_reduce_fraction( int *n, int *d );
+void x264_reduce_fraction( uint32_t *n, uint32_t *d );
void x264_init_vlc_tables();
static ALWAYS_INLINE uint8_t x264_clip_uint8( int x )
int i_chroma_loc_bottom;
int b_timing_info_present;
- int i_num_units_in_tick;
- int i_time_scale;
+ uint32_t i_num_units_in_tick;
+ uint32_t i_time_scale;
int b_fixed_frame_rate;
int b_nal_hrd_parameters_present;
/* VUI */
if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )
{
- int i_w = param->vui.i_sar_width;
- int i_h = param->vui.i_sar_height;
- int old_w = h->param.vui.i_sar_width;
- int old_h = h->param.vui.i_sar_height;
+ uint32_t i_w = param->vui.i_sar_width;
+ uint32_t i_h = param->vui.i_sar_height;
+ uint32_t old_w = h->param.vui.i_sar_width;
+ uint32_t old_h = h->param.vui.i_sar_height;
x264_reduce_fraction( &i_w, &i_h );
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 )
{
- x264_log( h, X264_LOG_DEBUG, "DTS compresion changed timebase: %d/%d -> %d/%d\n",
+ new_timebase_den = h->param.i_timebase_den * h->i_dts_compress_multiplier;
+ x264_log( h, X264_LOG_DEBUG, "DTS compresion changed timebase: %u/%u -> %u/%"PRIu64"\n",
h->param.i_timebase_num, h->param.i_timebase_den,
- h->param.i_timebase_num, h->param.i_timebase_den * h->i_dts_compress_multiplier );
- h->param.i_timebase_den *= h->i_dts_compress_multiplier;
+ h->param.i_timebase_num, new_timebase_den );
}
}
else
h->i_dts_compress_multiplier = 1;
+ if( new_timebase_den * 2 > UINT32_MAX )
+ {
+ x264_log( h, X264_LOG_ERROR, "Effective timebase denominator %"PRIu64" exceeds H.264 maximum\n", new_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 );
if( !strncmp( stats_buf, "#options:", 9 ) )
{
int i, j;
+ uint32_t k, l;
char *opts = stats_buf;
stats_in = strchr( stats_buf, '\n' );
if( !stats_in )
return -1;
}
- if( ( p = strstr( opts, "timebase=" ) ) && sscanf( p, "timebase=%d/%d", &i, &j ) != 2 )
+ if( ( p = strstr( opts, "timebase=" ) ) && sscanf( p, "timebase=%u/%u", &k, &l ) != 2 )
{
x264_log( h, X264_LOG_ERROR, "timebase specified in stats file not valid\n" );
return -1;
}
- if( i != h->param.i_timebase_num || j != h->param.i_timebase_den )
+ if( k != h->param.i_timebase_num || l != h->param.i_timebase_den )
{
- x264_log( h, X264_LOG_ERROR, "timebase mismatch with 1st pass (%d/%d vs %d/%d)\n",
- h->param.i_timebase_num, h->param.i_timebase_den, i, j );
+ x264_log( h, X264_LOG_ERROR, "timebase mismatch with 1st pass (%u/%u vs %u/%u)\n",
+ h->param.i_timebase_num, h->param.i_timebase_den, k, l );
return -1;
}
typedef struct
{
int csp; /* X264_CSP_YV12 or X264_CSP_I420 */
- int fps_num;
- int fps_den;
+ uint32_t fps_num;
+ uint32_t fps_den;
int height;
int interlaced;
- int sar_width;
- int sar_height;
+ uint32_t sar_width;
+ uint32_t sar_height;
int tff;
- int timebase_num;
- int timebase_den;
+ uint32_t timebase_num;
+ uint32_t timebase_den;
int vfr;
int width;
} video_info_t;
int frame_total;
int auto_timebase_num;
int auto_timebase_den;
- int timebase_num;
- int timebase_den;
+ uint64_t timebase_num;
+ uint64_t timebase_den;
int seek;
int stored_pts_num;
int64_t *pts;
static double correct_fps( double fps, timecode_hnd_t *h )
{
- int64_t i = 1;
- int64_t fps_num, fps_den;
+ int i = 1;
+ uint64_t fps_num, fps_den;
double exponent;
double fps_sig = sigexp10( fps, &exponent );
while( 1 )
{
fps_den = i * h->timebase_num;
fps_num = round( fps_den * fps_sig ) * exponent;
- if( fps_num < 0 )
+ if( fps_num > UINT32_MAX )
{
fprintf( stderr, "timecode [error]: tcfile fps correction failed.\n"
" Specify an appropriate timebase manually or remake tcfile.\n" );
if( h->auto_timebase_den )
{
h->timebase_den = h->timebase_den ? lcm( h->timebase_den, fps_num ) : fps_num;
- if( h->timebase_den < 0 )
+ if( h->timebase_den > UINT32_MAX )
h->auto_timebase_den = 0;
}
return (double)fps_num / fps_den;
h->timebase_den = MKV_TIMEBASE_DEN;
for( int num = 0; num < loop_num; num++ )
{
- int fps_den;
+ uint64_t fps_den;
double exponent;
double fps_sig = sigexp10( fpss[num], &exponent );
fps_den = round( MKV_TIMEBASE_DEN / fps_sig ) / exponent;
- h->timebase_num = fps_den > 0 && h->timebase_num ? gcd( h->timebase_num, fps_den ) : fps_den;
- if( h->timebase_num <= 0 )
+ h->timebase_num = fps_den && h->timebase_num ? gcd( h->timebase_num, fps_den ) : fps_den;
+ if( h->timebase_num > UINT32_MAX || !h->timebase_num )
{
fprintf( stderr, "timecode [error]: automatic timebase generation failed.\n"
" Specify timebase manually.\n" );
if( h->timebase_den >= 0 )
{
int i = 1;
- int fps_num, fps_den;
+ uint64_t fps_num, fps_den;
double exponent;
double fps_sig = sigexp10( fpss[num], &exponent );
while( 1 )
{
fps_den = i * h->timebase_num;
fps_num = round( fps_den * fps_sig ) * exponent;
- if( fps_num < 0 || fabs( ((double)fps_num / fps_den) / exponent - fps_sig ) < DOUBLE_EPSILON )
+ if( fps_num > UINT32_MAX || fabs( ((double)fps_num / fps_den) / exponent - fps_sig ) < DOUBLE_EPSILON )
break;
++i;
}
- h->timebase_den = fps_num > 0 && h->timebase_den ? lcm( h->timebase_den, fps_num ) : fps_num;
- if( h->timebase_den < 0 )
+ h->timebase_den = fps_num && h->timebase_den ? lcm( h->timebase_den, fps_num ) : fps_num;
+ if( h->timebase_den > UINT32_MAX )
{
h->auto_timebase_den = 0;
continue;
if( h->auto_timebase_den || h->auto_timebase_num )
{
- x264_reduce_fraction( &h->timebase_num, &h->timebase_den );
- fprintf( stderr, "timecode [info]: automatic timebase generation %d/%d\n", h->timebase_num, h->timebase_den );
+ uint64_t i = gcd( h->timebase_num, h->timebase_den );
+ h->timebase_num /= i;
+ h->timebase_den /= i;
+ fprintf( stderr, "timecode [info]: automatic timebase generation %"PRIu64"/%"PRIu64"\n", h->timebase_num, h->timebase_den );
}
- else if( h->timebase_den <= 0 )
+ else if( h->timebase_den > UINT32_MAX || !h->timebase_den )
{
fprintf( stderr, "timecode [error]: automatic timebase generation failed.\n"
" Specify an appropriate timebase manually.\n" );
h->frame_total = input.get_frame_total( h->p_handle );
h->seek = opt->seek;
if( opt->timebase )
- ret = sscanf( opt->timebase, "%d/%d", &h->timebase_num, &h->timebase_den );
- if( ret == 1 )
- h->timebase_num = atoi( opt->timebase );
+ {
+ ret = sscanf( opt->timebase, "%"SCNu64"/%"SCNu64, &h->timebase_num, &h->timebase_den );
+ if( ret == 1 )
+ h->timebase_num = strtoul( opt->timebase, NULL, 10 );
+ if( h->timebase_num > UINT32_MAX || h->timebase_den > UINT32_MAX )
+ {
+ fprintf( stderr, "timecode [error]: timebase you specified exceeds H.264 maximum\n" );
+ return -1;
+ }
+ }
h->auto_timebase_num = !ret;
h->auto_timebase_den = ret < 2;
if( h->auto_timebase_num )
static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
{
y4m_hnd_t *h = malloc( sizeof(y4m_hnd_t) );
- int i, n, d;
+ int i;
+ uint32_t n, d;
char header[MAX_YUV4_HEADER+10];
char *tokend, *header_end;
int colorspace = X264_CSP_NONE;
int64_t i_prev_dts;
int64_t i_prev_pts;
- int i_timebase_num;
- int i_timebase_den;
+ uint32_t i_timebase_num;
+ uint32_t i_timebase_den;
int b_vfr_input;
unsigned start;
int64_t frame_duration;
char b_writing_frame;
- int i_timebase_num;
- int i_timebase_den;
+ uint32_t i_timebase_num;
+ uint32_t i_timebase_den;
} mkv_hnd_t;
GF_ISOSample *p_sample;
int i_track;
uint32_t i_descidx;
- int i_time_res;
+ uint32_t i_time_res;
int64_t i_time_inc;
int i_numframe;
int i_delay_time;
}
if( !tcfile_name && input_opt.timebase )
{
- int i_user_timebase_num;
- int i_user_timebase_den;
- int ret = sscanf( input_opt.timebase, "%d/%d", &i_user_timebase_num, &i_user_timebase_den );
+ uint64_t i_user_timebase_num;
+ uint64_t i_user_timebase_den;
+ int ret = sscanf( input_opt.timebase, "%"SCNu64"/%"SCNu64, &i_user_timebase_num, &i_user_timebase_den );
if( !ret )
{
fprintf( stderr, "x264 [error]: invalid argument: timebase = %s\n", input_opt.timebase );
else if( ret == 1 )
{
i_user_timebase_num = param->i_timebase_num;
- i_user_timebase_den = atoi( input_opt.timebase );
+ i_user_timebase_den = strtoul( input_opt.timebase, NULL, 10 );
+ }
+ if( i_user_timebase_num > UINT32_MAX || i_user_timebase_den > UINT32_MAX )
+ {
+ fprintf( stderr, "x264 [error]: timebase you specified exceeds H.264 maximum\n" );
+ return -1;
}
opt->timebase_convert_multiplier = ((double)i_user_timebase_den / param->i_timebase_den)
* ((double)param->i_timebase_num / i_user_timebase_num);
#include <stdarg.h>
-#define X264_BUILD 93
+#define X264_BUILD 94
/* x264_t:
* opaque handler for encoder */
int i_chroma_loc; /* both top & bottom */
} vui;
- int i_fps_num;
- int i_fps_den;
-
/* Bitstream parameters */
int i_frame_reference; /* Maximum number of reference frames */
int i_keyint_max; /* Force an IDR keyframe at this interval */
* otherwise place size (4 bytes) before NAL units. */
int i_sps_id; /* SPS and PPS id number */
int b_vfr_input; /* VFR input */
- int i_timebase_num; /* Timebase numerator */
- int i_timebase_den; /* Timebase denominator */
+ uint32_t i_fps_num;
+ 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! */