Ignore errors from avcodec_receive_frame when flushing video (#2035).
authorCarl Hetherington <cth@carlh.net>
Thu, 3 Jun 2021 18:40:16 +0000 (20:40 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 3 Jun 2021 18:40:16 +0000 (20:40 +0200)
The test fails if we don't do this; it doesn't really seem 100%
convincing but we are already doing this for audio.

src/lib/ffmpeg_decoder.cc
test/ffmpeg_decoder_error_test.cc [new file with mode: 0644]
test/wscript

index db88562ea09b2bb05001d14b2c031ad018c19f6f..c5c41fdac86b09608fc09cf4be32c7af4b5cec20 100644 (file)
@@ -548,9 +548,13 @@ FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
        }
 
        r = avcodec_receive_frame (context, _frame);
        }
 
        r = avcodec_receive_frame (context, _frame);
-       if (r == AVERROR(EAGAIN) || r == AVERROR_EOF) {
-               /* More input is required, or no more frames are coming */
+       if (r == AVERROR(EAGAIN) || r == AVERROR_EOF || (r < 0 && !packet)) {
+               /* More input is required, no more frames are coming, or we are flushing and there was
+                * some error which we just want to ignore.
+                */
                return false;
                return false;
+       } else if (r < 0) {
+               throw DecodeError (N_("avcodec_receive_frame"), N_("FFmpeg::decode_and_process_video_packet"), r);
        }
 
        /* We assume we'll only get one frame here, which I think is safe */
        }
 
        /* We assume we'll only get one frame here, which I think is safe */
diff --git a/test/ffmpeg_decoder_error_test.cc b/test/ffmpeg_decoder_error_test.cc
new file mode 100644 (file)
index 0000000..b3e9e42
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright (C) 2021 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/content.h"
+#include "lib/content_factory.h"
+#include "lib/dcpomatic_time.h"
+#include "test.h"
+#include <boost/test/unit_test.hpp>
+
+
+/** @defgroup regression Tests to make sure that old bugs do not reappear */
+
+/** @file  test/ffmpeg_decoder_erro_test.cc
+ *  @brief Check some bugs in the FFmpegDecoder
+ *  @ingroup regression
+ */
+
+
+BOOST_AUTO_TEST_CASE (check_exception_during_flush)
+{
+       auto content = content_factory(TestPaths::private_data() / "3d_thx_broadway_2010_lossless.m2ts").front();
+       auto film = new_test_film2 ("check_exception_during_flush", { content });
+
+       content->set_trim_start (dcpomatic::ContentTime(2310308));
+       content->set_trim_end (dcpomatic::ContentTime(116020));
+
+       make_and_verify_dcp (film);
+}
+
+
index 6ef9ac7528f442020a9e394bd7aac6bc82495599..5774ffebf919d15b4e78699cefb05aec3b7f23fd 100644 (file)
@@ -73,6 +73,7 @@ def build(bld):
                  ffmpeg_audio_only_test.cc
                  ffmpeg_audio_test.cc
                  ffmpeg_dcp_test.cc
                  ffmpeg_audio_only_test.cc
                  ffmpeg_audio_test.cc
                  ffmpeg_dcp_test.cc
+                 ffmpeg_decoder_error_test.cc
                  ffmpeg_decoder_seek_test.cc
                  ffmpeg_decoder_sequential_test.cc
                  ffmpeg_encoder_test.cc
                  ffmpeg_decoder_seek_test.cc
                  ffmpeg_decoder_sequential_test.cc
                  ffmpeg_encoder_test.cc