]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/ffmpeg_pipeline_backend_internal.cpp
[ffmpeg] Copied flush logic when seeking from 2.0, as well as current frame in clip...
[casparcg] / modules / ffmpeg / ffmpeg_pipeline_backend_internal.cpp
index 663d7dee3274edc02e589ec87f0d6c1ab57bba38..9feb2d734c147d6d7c42a7e999c9d17a94930290 100644 (file)
@@ -357,7 +357,7 @@ public:
                                {
                                        frame = (*a_decoder)();
 
-                                       if (frame && frame->data[0])
+                                       if (frame == flush() || (frame && frame->data[0]))
                                                break;
                                        else
                                                frame.reset();
@@ -376,7 +376,7 @@ public:
                        {
                                frame = (*v_decoder)();
 
-                               if (frame && frame->data[0])
+                               if (frame == flush() || (frame && frame->data[0]))
                                        return { frame };
                        }
                }
@@ -604,11 +604,12 @@ struct sink
        virtual void                                                    framerate(boost::rational<int> framerate)                                                                               { CASPAR_THROW_EXCEPTION(invalid_operation() << msg_info(print() + L" not an encoder.")); }
        virtual void                                                    start(bool has_audio, bool has_video)                                                                                   { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual void                                                    stop()                                                                                                                                                  { }
+       virtual void                                                    flush_all()                                                                                                                                             { }
        virtual std::vector<AVSampleFormat>             supported_sample_formats() const                                                                                                { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual std::vector<int>                                supported_samplerates() const                                                                                                   { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual std::vector<AVPixelFormat>              supported_pixel_formats() const                                                                                                 { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual int                                                             wanted_num_audio_streams() const                                                                                                { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
-       virtual boost::optional<int>                    wanted_num_channels_per_stream() const                                                                          { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
+       virtual boost::optional<int>                    wanted_num_channels_per_stream() const                                                                                  { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual boost::optional<AVMediaType>    try_push(AVMediaType type, int stream_index, spl::shared_ptr<AVFrame> frame)    { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
        virtual void                                                    eof()                                                                                                                                                   { CASPAR_THROW_EXCEPTION(not_implemented() << msg_info(print())); }
 };
@@ -738,6 +739,14 @@ public:
                return boost::none;
        }
 
+       void flush_all() override
+       {
+               audio_samples_.clear();
+
+               while (!video_frames_.empty())
+                       video_frames_.pop();
+       }
+
        boost::optional<AVMediaType> try_push(AVMediaType type, int stream_index, spl::shared_ptr<AVFrame> av_frame) override
        {
                if (!has_audio_ && !has_video_)
@@ -1110,8 +1119,21 @@ private:
                        {
                                auto needed                                             = *result;
                                auto input_frames_for_streams   = source_->get_input_frames_for_streams(needed);
+                               bool flush_all                                  = !input_frames_for_streams.empty() && input_frames_for_streams.at(0) == flush();
+
+                               if (flush_all)
+                               {
+                                       sink_->flush_all();
+                                       
+                                       if (source_->has_audio() && source_->has_video())
+                                               result = needed == AVMediaType::AVMEDIA_TYPE_AUDIO ? AVMediaType::AVMEDIA_TYPE_VIDEO : AVMediaType::AVMEDIA_TYPE_AUDIO;
+
+                                       continue;
+                               }
+
+                               bool got_requested_media_type   = !input_frames_for_streams.empty() && input_frames_for_streams.at(0);
 
-                               if (!input_frames_for_streams.empty() && input_frames_for_streams.at(0))
+                               if (got_requested_media_type)
                                {
                                        for (int input_stream_index = 0; input_stream_index < input_frames_for_streams.size(); ++input_stream_index)
                                        {