|
|
|
@ -2173,59 +2173,60 @@ static int tb_unreliable(AVCodecContext *c) |
|
|
|
|
int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts) |
|
|
|
|
{ |
|
|
|
|
FFStream *const sti = ffstream(st); |
|
|
|
|
int64_t last = sti->info->last_dts; |
|
|
|
|
FFStreamInfo *info = sti->info; |
|
|
|
|
int64_t last = info->last_dts; |
|
|
|
|
|
|
|
|
|
if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last |
|
|
|
|
&& ts - (uint64_t)last < INT64_MAX) { |
|
|
|
|
double dts = (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base); |
|
|
|
|
int64_t duration = ts - last; |
|
|
|
|
|
|
|
|
|
if (!sti->info->duration_error) |
|
|
|
|
sti->info->duration_error = av_mallocz(sizeof(sti->info->duration_error[0])*2); |
|
|
|
|
if (!sti->info->duration_error) |
|
|
|
|
if (!info->duration_error) |
|
|
|
|
info->duration_error = av_mallocz(sizeof(info->duration_error[0])*2); |
|
|
|
|
if (!info->duration_error) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
// if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
|
|
|
|
// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
|
|
|
|
|
for (int i = 0; i < MAX_STD_TIMEBASES; i++) { |
|
|
|
|
if (sti->info->duration_error[0][1][i] < 1e10) { |
|
|
|
|
if (info->duration_error[0][1][i] < 1e10) { |
|
|
|
|
int framerate = get_std_framerate(i); |
|
|
|
|
double sdts = dts*framerate/(1001*12); |
|
|
|
|
for (int j = 0; j < 2; j++) { |
|
|
|
|
int64_t ticks = llrint(sdts+j*0.5); |
|
|
|
|
double error = sdts - ticks + j*0.5; |
|
|
|
|
sti->info->duration_error[j][0][i] += error; |
|
|
|
|
sti->info->duration_error[j][1][i] += error*error; |
|
|
|
|
info->duration_error[j][0][i] += error; |
|
|
|
|
info->duration_error[j][1][i] += error*error; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (sti->info->rfps_duration_sum <= INT64_MAX - duration) { |
|
|
|
|
sti->info->duration_count++; |
|
|
|
|
sti->info->rfps_duration_sum += duration; |
|
|
|
|
if (info->rfps_duration_sum <= INT64_MAX - duration) { |
|
|
|
|
info->duration_count++; |
|
|
|
|
info->rfps_duration_sum += duration; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sti->info->duration_count % 10 == 0) { |
|
|
|
|
int n = sti->info->duration_count; |
|
|
|
|
if (info->duration_count % 10 == 0) { |
|
|
|
|
int n = info->duration_count; |
|
|
|
|
for (int i = 0; i < MAX_STD_TIMEBASES; i++) { |
|
|
|
|
if (sti->info->duration_error[0][1][i] < 1e10) { |
|
|
|
|
double a0 = sti->info->duration_error[0][0][i] / n; |
|
|
|
|
double error0 = sti->info->duration_error[0][1][i] / n - a0*a0; |
|
|
|
|
double a1 = sti->info->duration_error[1][0][i] / n; |
|
|
|
|
double error1 = sti->info->duration_error[1][1][i] / n - a1*a1; |
|
|
|
|
if (info->duration_error[0][1][i] < 1e10) { |
|
|
|
|
double a0 = info->duration_error[0][0][i] / n; |
|
|
|
|
double error0 = info->duration_error[0][1][i] / n - a0*a0; |
|
|
|
|
double a1 = info->duration_error[1][0][i] / n; |
|
|
|
|
double error1 = info->duration_error[1][1][i] / n - a1*a1; |
|
|
|
|
if (error0 > 0.04 && error1 > 0.04) { |
|
|
|
|
sti->info->duration_error[0][1][i] = 2e10; |
|
|
|
|
sti->info->duration_error[1][1][i] = 2e10; |
|
|
|
|
info->duration_error[0][1][i] = 2e10; |
|
|
|
|
info->duration_error[1][1][i] = 2e10; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ignore the first 4 values, they might have some random jitter
|
|
|
|
|
if (sti->info->duration_count > 3 && is_relative(ts) == is_relative(last)) |
|
|
|
|
sti->info->duration_gcd = av_gcd(sti->info->duration_gcd, duration); |
|
|
|
|
if (info->duration_count > 3 && is_relative(ts) == is_relative(last)) |
|
|
|
|
info->duration_gcd = av_gcd(info->duration_gcd, duration); |
|
|
|
|
} |
|
|
|
|
if (ts != AV_NOPTS_VALUE) |
|
|
|
|
sti->info->last_dts = ts; |
|
|
|
|
info->last_dts = ts; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|