From: Carl Hetherington Date: Thu, 3 Jun 2021 20:55:44 +0000 (+0200) Subject: Fix errors when seeking FFmpeg for some formats. X-Git-Tag: v2.15.154~2 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=9f4cb3b340376d93be39dc97c2e0c631e9cf73c4 Fix errors when seeking FFmpeg for some formats. The comments discuss this in a bit more depth, but basically we see errors from avcodec_send_packet after seek. ffplay etc. seem basically to ignore all errors from avcodec_send_packet, and I can't find a "proper" fix, so here's a half-way house hack: ignore some errors after seek. Nasty. --- diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index c5c41fdac..31fbde773 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -427,6 +427,12 @@ FFmpegDecoder::seek (ContentTime time, bool accurate) for (auto& i: _next_time) { i.second = boost::optional(); } + + /* We find that we get some errors from av_send_packet after a seek. Perhaps we should ignore + * all of them (which seems risky), or perhaps we should have some proper fix. But instead + * let's ignore the next 2 errors. + */ + _errors_to_ignore = 2; } @@ -513,6 +519,12 @@ FFmpegDecoder::decode_and_process_audio_packet (AVPacket* packet) /* We could cope with AVERROR(EAGAIN) and re-send the packet but I think it should never happen. * Likewise I think AVERROR_EOF should not happen. */ + if (_errors_to_ignore > 0) { + /* We see errors here after a seek, which is hopefully to be nothing to worry about */ + --_errors_to_ignore; + LOG_GENERAL("Ignoring error %1 avcodec_send_packet after seek; will ignore %2 more", r, _errors_to_ignore); + return; + } throw DecodeError (N_("avcodec_send_packet"), N_("FFmpegDecoder::decode_and_process_audio_packet"), r); } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index fce3fcae9..def824feb 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -79,6 +79,9 @@ private: /** true if we have a subtitle which has not had emit_stop called for it yet */ bool _have_current_subtitle = false; + /** number of errors from avcodec_send_packet to ignore */ + int _errors_to_ignore = 0; + std::shared_ptr _black_image; std::map, boost::optional> _next_time; diff --git a/test/ffmpeg_decoder_seek_test.cc b/test/ffmpeg_decoder_seek_test.cc index f8ce256cf..4dceae86b 100644 --- a/test/ffmpeg_decoder_seek_test.cc +++ b/test/ffmpeg_decoder_seek_test.cc @@ -100,4 +100,5 @@ BOOST_AUTO_TEST_CASE (ffmpeg_decoder_seek_test) test ("boon_telly.mkv", frames); test ("Sintel_Trailer1.480p.DivX_Plus_HD.mkv", frames); test ("prophet_long_clip.mkv", { 15, 42, 999, 15 }); + test ("dolby_aurora.vob", { 0, 125, 250, 41 }); }