Tidying.
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index e5685f6611d60665367b46b97e5f66a06634d113..30a4b1823e8873193051ec2c6e91f9bbfe68f4c8 100644 (file)
@@ -144,7 +144,7 @@ FFmpegDecoder::flush ()
                auto const f = full_length.frames_round (vfr);
                auto v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
                while (v < f) {
-                       video->emit (film(), shared_ptr<const ImageProxy> (new RawImageProxy (_black_image)), v);
+                       video->emit (film(), make_shared<const RawImageProxy>(_black_image), v);
                        ++v;
                }
        }
@@ -533,23 +533,38 @@ FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
 
        auto context = video_codec_context();
 
-       int r = avcodec_send_packet (context, packet);
-       if (r < 0) {
-               LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r);
-       }
+       bool pending = false;
+       do {
+               int r = avcodec_send_packet (context, packet);
+               if (r < 0) {
+                       LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r);
+               }
 
-       r = avcodec_receive_frame (context, _video_frame);
-       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);
-       }
+               /* EAGAIN means we should call avcodec_receive_frame and then re-send the same packet */
+               pending = r == AVERROR(EAGAIN);
+
+               while (true) {
+                       r = avcodec_receive_frame (context, _video_frame);
+                       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 */
+                       process_video_frame ();
+               }
+       } while (pending);
 
+       return true;
+}
+
+
+void
+FFmpegDecoder::process_video_frame ()
+{
        boost::mutex::scoped_lock lm (_filter_graphs_mutex);
 
        shared_ptr<VideoFilterGraph> graph;
@@ -587,8 +602,6 @@ FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
                        LOG_WARNING_NC ("Dropping frame without PTS");
                }
        }
-
-       return true;
 }