]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/producer/ffmpeg_producer.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / modules / ffmpeg / producer / ffmpeg_producer.cpp
index 956648131357df18790b056ffccf594adbc8a47d..96187ec6cdbfec113fcb861a2deac110203ecbaa 100644 (file)
 #include <boost/range/algorithm/find.hpp>\r
 \r
 #include <agents.h>\r
-#include <agents_extras.h>\r
-#include <connect.h>\r
-#include <concrt.h>\r
-#include <ppl.h>\r
 \r
 using namespace Concurrency;\r
 \r
@@ -57,25 +53,25 @@ namespace caspar { namespace ffmpeg {
                \r
 struct ffmpeg_producer : public core::frame_producer\r
 {      \r
-       const std::wstring                                              filename_;\r
-       const int                                                               start_;\r
-       const bool                                                              loop_;\r
-       const size_t                                                    length_;\r
+       const std::wstring                                                                                              filename_;\r
+       const int                                                                                                               start_;\r
+       const bool                                                                                                              loop_;\r
+       const size_t                                                                                                    length_;\r
        \r
-       Concurrency::unbounded_buffer<std::shared_ptr<AVPacket>>                        packets_;\r
-       Concurrency::unbounded_buffer<std::shared_ptr<AVFrame>>                         video_;\r
-       Concurrency::unbounded_buffer<std::shared_ptr<core::audio_buffer>>      audio_;\r
-       Concurrency::bounded_buffer<safe_ptr<core::basic_frame>>                        frames_;\r
+       call<input::target_element_t>                                                                   throw_away_;\r
+       unbounded_buffer<input::target_element_t>                                               packets_;\r
+       std::shared_ptr<unbounded_buffer<frame_muxer2::video_source_element_t>> video_;\r
+       std::shared_ptr<unbounded_buffer<frame_muxer2::audio_source_element_t>> audio_;\r
+       unbounded_buffer<frame_muxer2::target_element_t>                                frames_;\r
                \r
-       const safe_ptr<diagnostics::graph>              graph_;\r
+       const safe_ptr<diagnostics::graph>                                                              graph_;\r
                                        \r
-       input                                                                                   input_; \r
-       std::shared_ptr<video_decoder>                                  video_decoder_;\r
-       std::shared_ptr<audio_decoder>                                  audio_decoder_; \r
-       Concurrency::call<std::shared_ptr<AVPacket>>    throw_away_;\r
-       std::unique_ptr<frame_muxer2>                                   muxer_;\r
+       input                                                                                                                   input_; \r
+       std::unique_ptr<frame_muxer2>                                                                   muxer_;\r
+       std::shared_ptr<video_decoder>                                                                  video_decoder_;\r
+       std::shared_ptr<audio_decoder>                                                                  audio_decoder_; \r
 \r
-       safe_ptr<core::basic_frame>                             last_frame_;\r
+       safe_ptr<core::basic_frame>                                                                             last_frame_;\r
        \r
 public:\r
        explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, int start, size_t length) \r
@@ -83,21 +79,18 @@ public:
                , start_(start)\r
                , loop_(loop)\r
                , length_(length)\r
-               , throw_away_([](const std::shared_ptr<AVPacket>&){})\r
-               , frames_(2)\r
+               , throw_away_([](const input::target_element_t&){})\r
                , graph_(diagnostics::create_graph("", false))\r
                , input_(packets_, graph_, filename_, loop, start, length)\r
                , last_frame_(core::basic_frame::empty())\r
-       {\r
-               frame_muxer2::video_source_t* video_source = nullptr;\r
-               frame_muxer2::audio_source_t* audio_source = nullptr;\r
-\r
+       {               \r
                try\r
                {\r
-                       video_decoder_.reset(new video_decoder(packets_, video_, *input_.context()));\r
-                       video_source = &video_;\r
+                       auto video = std::make_shared<unbounded_buffer<frame_muxer2::video_source_element_t>>();\r
+                       video_decoder_.reset(new video_decoder(packets_, *video, *input_.context()));\r
+                       video_ = video;\r
                }\r
-               catch(ffmpeg_stream_not_found&)\r
+               catch(averror_stream_not_found&)\r
                {\r
                        CASPAR_LOG(warning) << "No video-stream found. Running without video."; \r
                }\r
@@ -109,10 +102,11 @@ public:
 \r
                try\r
                {\r
-                       audio_decoder_.reset(new audio_decoder(packets_, audio_, *input_.context(), frame_factory->get_video_format_desc()));\r
-                       audio_source = &audio_;\r
+                       auto audio = std::make_shared<unbounded_buffer<frame_muxer2::audio_source_element_t>>();\r
+                       audio_decoder_.reset(new audio_decoder(packets_, *audio, *input_.context(), frame_factory->get_video_format_desc()));\r
+                       audio_ = audio;\r
                }\r
-               catch(ffmpeg_stream_not_found&)\r
+               catch(averror_stream_not_found&)\r
                {\r
                        CASPAR_LOG(warning) << "No audio-stream found. Running without video."; \r
                }\r
@@ -120,13 +114,12 @@ public:
                {\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                        CASPAR_LOG(warning) << "Failed to open audio-stream. Running without audio.";           \r
-               }\r
-               \r
-               Concurrency::connect(packets_, throw_away_);\r
+               }               \r
 \r
                CASPAR_VERIFY(video_decoder_ || audio_decoder_, ffmpeg_error());\r
-\r
-               muxer_.reset(new frame_muxer2(video_source, audio_source, frames_, video_decoder_ ? video_decoder_->fps() : frame_factory->get_video_format_desc().fps, frame_factory));\r
+               \r
+               packets_.link_target(&throw_away_);\r
+               muxer_.reset(new frame_muxer2(video_.get(), audio_.get(), frames_, video_decoder_ ? video_decoder_->fps() : frame_factory->get_video_format_desc().fps, frame_factory));\r
                                \r
                graph_->set_color("underflow", diagnostics::color(0.6f, 0.3f, 0.9f));   \r
                graph_->start();\r
@@ -136,10 +129,7 @@ public:
 \r
        ~ffmpeg_producer()\r
        {\r
-               input_.stop();                  \r
-               while(Concurrency::receive(frames_) != core::basic_frame::eof())\r
-               {\r
-               }\r
+               input_.stop();  \r
        }\r
                                                \r
        virtual safe_ptr<core::basic_frame> receive(int hints)\r
@@ -148,10 +138,11 @@ public:
                \r
                try\r
                {               \r
-                       frame = last_frame_ = safe_ptr<core::basic_frame>(Concurrency::receive(frames_, 10));\r
+                       auto frame_element = Concurrency::receive(frames_, 10);\r
+                       frame = last_frame_ = frame_element.first;\r
                        graph_->update_text(narrow(print()));\r
                }\r
-               catch(Concurrency::operation_timed_out&)\r
+               catch(operation_timed_out&)\r
                {               \r
                        graph_->add_tag("underflow");   \r
                }\r
@@ -181,9 +172,7 @@ public:
                }\r
 \r
                nb_frames = muxer_->calc_nb_frames(nb_frames);\r
-\r
-               // TODO: Might need to scale nb_frames av frame_muxer transformations.\r
-\r
+               \r
                return nb_frames - start_;\r
        }\r
                                \r