]> git.sesse.net Git - nageru/commitdiff
Serve a better frame rate from streams (especially SRT streams) with packet length...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 11 May 2020 18:07:20 +0000 (20:07 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 11 May 2020 18:14:31 +0000 (20:14 +0200)
This fixes issues when a Larix SRT client becomes the master card, at least.

nageru/ffmpeg_capture.cpp

index 0c3aa57bcfde150a221ec86bcc72a253ee606e37..cda801a240d7e81147465fe37050d8ea50c31e7f 100644 (file)
@@ -589,6 +589,22 @@ bool FFmpegCapture::play_video(const string &pathname)
                }
 
                VideoFormat video_format = construct_video_format(frame.get(), video_timebase);
+               if (video_format.frame_rate_nom == 0 || video_format.frame_rate_den == 0) {
+                       // Invalid frame rate; try constructing it from the previous frame length.
+                       // (This is especially important if we are the master card, for SRT,
+                       // since it affects audio. Not all senders have good timebases
+                       // (e.g., Larix rounds first to timebase 1000 and then multiplies by
+                       // 90 from there, it seems), but it's much better to have an oscillating
+                       // value than just locking at 60.
+                       if (last_pts != 0 && frame->pts > last_pts) {
+                               int64_t pts_diff = frame->pts - last_pts;
+                               video_format.frame_rate_nom = video_timebase.den;
+                               video_format.frame_rate_den = video_timebase.num * pts_diff;
+                       } else {
+                               video_format.frame_rate_nom = 60;
+                               video_format.frame_rate_den = 1;
+                       }
+               }
                UniqueFrame video_frame = make_video_frame(frame.get(), pathname, &error);
                if (error) {
                        return false;
@@ -932,11 +948,6 @@ VideoFormat FFmpegCapture::construct_video_format(const AVFrame *frame, AVRation
        }
        video_format.frame_rate_nom = video_timebase.den;
        video_format.frame_rate_den = frame->pkt_duration * video_timebase.num;
-       if (video_format.frame_rate_nom == 0 || video_format.frame_rate_den == 0) {
-               // Invalid frame rate.
-               video_format.frame_rate_nom = 60;
-               video_format.frame_rate_den = 1;
-       }
        video_format.has_signal = true;
        video_format.is_connected = true;
        return video_format;