From c101bd6f4bba6b74c82ad4d62b78f7f484ee89db Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 11 May 2020 20:07:20 +0200 Subject: [PATCH] Serve a better frame rate from streams (especially SRT streams) with packet length zero. This fixes issues when a Larix SRT client becomes the master card, at least. --- nageru/ffmpeg_capture.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/nageru/ffmpeg_capture.cpp b/nageru/ffmpeg_capture.cpp index 0c3aa57..cda801a 100644 --- a/nageru/ffmpeg_capture.cpp +++ b/nageru/ffmpeg_capture.cpp @@ -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; -- 2.39.2