Use dcp::file_to_string().
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index db88562ea09b2bb05001d14b2c031ad018c19f6f..31fbde773b3ab86df610edb9eb801141a48e9a11 100644 (file)
@@ -427,6 +427,12 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
        for (auto& i: _next_time) {
                i.second = boost::optional<dcpomatic::ContentTime>();
        }
+
+       /* 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);
        }
 
@@ -548,9 +560,13 @@ FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
        }
 
        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;
+       } 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 */