lavf: consider codec framerate for framerate detection

Fixes detection of some TV sample as 24.5 FPS. With the patch applied,
it's detected as 25 FPS.

This is enabled for mpegts only.
This commit is contained in:
wm4 2017-05-23 13:36:38 +02:00
parent 34c5200560
commit 66cf78e932
3 changed files with 17 additions and 0 deletions

View File

@ -145,6 +145,11 @@ struct AVFormatInternal {
* ID3v2 tag useful for MP3 demuxing * ID3v2 tag useful for MP3 demuxing
*/ */
AVDictionary *id3v2_meta; AVDictionary *id3v2_meta;
/*
* Prefer the codec framerate for avg_frame_rate computation.
*/
int prefer_codec_framerate;
}; };
struct AVStreamInternal { struct AVStreamInternal {

View File

@ -2616,6 +2616,8 @@ static int mpegts_read_header(AVFormatContext *s)
int len; int len;
int64_t pos, probesize = s->probesize; int64_t pos, probesize = s->probesize;
s->internal->prefer_codec_framerate = 1;
if (ffio_ensure_seekback(pb, probesize) < 0) if (ffio_ensure_seekback(pb, probesize) < 0)
av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n"); av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");

View File

@ -3904,6 +3904,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
st->info->codec_info_duration) { st->info->codec_info_duration) {
int best_fps = 0; int best_fps = 0;
double best_error = 0.01; double best_error = 0.01;
AVRational codec_frame_rate = avctx->framerate;
if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2||
st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den ||
@ -3924,6 +3925,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
best_error = error; best_error = error;
best_fps = std_fps.num; best_fps = std_fps.num;
} }
if (ic->internal->prefer_codec_framerate && codec_frame_rate.num > 0 && codec_frame_rate.den > 0) {
error = fabs(av_q2d(codec_frame_rate) /
av_q2d(std_fps) - 1);
if (error < best_error) {
best_error = error;
best_fps = std_fps.num;
}
}
} }
if (best_fps) if (best_fps)
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,