lavf: consider codec framerate for framerate detection
authorwm4 <nfxjfg@googlemail.com>
Tue, 23 May 2017 11:36:38 +0000 (13:36 +0200)
committerwm4 <nfxjfg@googlemail.com>
Wed, 7 Jun 2017 09:08:06 +0000 (11:08 +0200)
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.

libavformat/internal.h
libavformat/mpegts.c
libavformat/utils.c

index c856945..d136c79 100644 (file)
@@ -145,6 +145,11 @@ struct AVFormatInternal {
      * ID3v2 tag useful for MP3 demuxing
      */
     AVDictionary *id3v2_meta;
+
+    /*
+     * Prefer the codec framerate for avg_frame_rate computation.
+     */
+    int prefer_codec_framerate;
 };
 
 struct AVStreamInternal {
index 3eff152..4d2f5c6 100644 (file)
@@ -2616,6 +2616,8 @@ static int mpegts_read_header(AVFormatContext *s)
     int len;
     int64_t pos, probesize = s->probesize;
 
+    s->internal->prefer_codec_framerate = 1;
+
     if (ffio_ensure_seekback(pb, probesize) < 0)
         av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");
 
index c641377..38d247c 100644 (file)
@@ -3904,6 +3904,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
                 st->info->codec_info_duration) {
                 int best_fps      = 0;
                 double best_error = 0.01;
+                AVRational codec_frame_rate = avctx->framerate;
 
                 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 ||
@@ -3924,6 +3925,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
                         best_error = error;
                         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)
                     av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,