]> git.sesse.net Git - nageru/commitdiff
Be more resilient to video decoding errors.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 15 Apr 2023 17:03:35 +0000 (19:03 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 15 Apr 2023 17:04:03 +0000 (19:04 +0200)
In particular, hardware decoding of SRT streams that don't start
on a keyframe can throw errors the first few frames, but then
recover afterwards.

nageru/ffmpeg_capture.cpp

index 504eff24f59d5bc7bfa5ceda9345f92ffce8785f..d1b7e74102d623b54ac35c2c4ba8bc6dc6d1cb24 100644 (file)
@@ -591,6 +591,7 @@ bool FFmpegCapture::play_video(const string &pathname)
 
        // Main loop.
        bool first_frame = true;
+       int consecutive_errors = 0;
        while (!producer_thread_should_quit.should_quit()) {
                if (process_queued_commands(format_ctx.get(), pathname, last_modified, /*rewound=*/nullptr)) {
                        return true;
@@ -607,7 +608,14 @@ bool FFmpegCapture::play_video(const string &pathname)
                AVFrameWithDeleter frame = decode_frame(format_ctx.get(), video_codec_ctx.get(), audio_codec_ctx.get(),
                        pathname, video_stream_index, audio_stream_index, subtitle_stream_index, audio_frame.get(), &audio_format, &audio_pts, &error);
                if (error) {
-                       return false;
+                       if (++consecutive_errors >= 100) {
+                               fprintf(stderr, "More than 100 consecutive video frames, aborting playback.\n");
+                               return false;
+                       } else {
+                               continue;
+                       }
+               } else {
+                       consecutive_errors = 0;
                }
                if (frame == nullptr) {
                        // EOF. Loop back to the start if we can.