]> 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 d916b1dccbf2fdd287488bde22c4f5c8d7727b0f..e30f0a694ba01c67a94b772ee55617bc7e005122 100644 (file)
@@ -45,6 +45,7 @@
 #include <boost/filesystem.hpp>\r
 #include <boost/range/algorithm/find_if.hpp>\r
 #include <boost/range/algorithm/find.hpp>\r
+#include <boost/regex.hpp>\r
 \r
 #include <tbb/parallel_invoke.h>\r
 \r
@@ -125,8 +126,10 @@ public:
 \r
                muxer_.reset(new frame_muxer(video_decoder_ ? video_decoder_->fps() : frame_factory->get_video_format_desc().fps, frame_factory, filter));\r
        }\r
+\r
+       // frame_producer\r
        \r
-       virtual safe_ptr<core::basic_frame> receive(int hints)\r
+       virtual safe_ptr<core::basic_frame> receive(int hints) override\r
        {               \r
                frame_timer_.restart();\r
                \r
@@ -152,11 +155,76 @@ public:
                return last_frame_;\r
        }\r
 \r
-       virtual safe_ptr<core::basic_frame> last_frame() const\r
+       virtual safe_ptr<core::basic_frame> last_frame() const override\r
        {\r
                return disable_audio(last_frame_);\r
        }\r
-       \r
+\r
+       virtual int64_t nb_frames() const override\r
+       {\r
+               if(loop_)\r
+                       return std::numeric_limits<int64_t>::max();\r
+\r
+               // This function estimates nb_frames until input has read all packets for one loop, at which point the count should be accurate.\r
+\r
+               int64_t nb_frames = input_.nb_frames();\r
+               if(input_.nb_loops() < 1) // input still hasn't counted all frames\r
+               {\r
+                       auto video_nb_frames = video_decoder_ ? video_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
+                       auto audio_nb_frames = audio_decoder_ ? audio_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
+\r
+                       nb_frames = std::max(nb_frames, std::max(video_nb_frames, audio_nb_frames));\r
+               }\r
+\r
+               nb_frames = std::min(static_cast<int64_t>(length_), nb_frames);\r
+               nb_frames = muxer_->calc_nb_frames(nb_frames);\r
+               \r
+               return nb_frames - start_;\r
+       }\r
+\r
+       virtual boost::unique_future<std::wstring> call(const std::wstring& param) override\r
+       {\r
+               boost::promise<std::wstring> promise;\r
+               promise.set_value(do_call(param));\r
+               return promise.get_future();\r
+       }\r
+                               \r
+       virtual std::wstring print() const override\r
+       {\r
+               if(video_decoder_)\r
+               {\r
+                       return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"|" \r
+                                                         + boost::lexical_cast<std::wstring>(video_decoder_->width()) + L"x" + boost::lexical_cast<std::wstring>(video_decoder_->height())\r
+                                                         + (video_decoder_->is_progressive() ? L"p" : L"i")  + boost::lexical_cast<std::wstring>(video_decoder_->is_progressive() ? video_decoder_->fps() : 2.0 * video_decoder_->fps())\r
+                                                         + L"]";\r
+               }\r
+               \r
+               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
+       }\r
+\r
+       // ffmpeg_producer\r
+                               \r
+       std::wstring do_call(const std::wstring& param)\r
+       {\r
+               static const boost::wregex loop_exp(L"LOOP\\s*(?<VALUE>\\d?)");\r
+               static const boost::wregex seek_exp(L"SEEK\\s+(?<VALUE>\\d+)");\r
+               \r
+               boost::wsmatch what;\r
+               if(boost::regex_match(param, what, loop_exp))\r
+               {\r
+                       if(!what["VALUE"].str().empty())\r
+                               input_.loop(boost::lexical_cast<bool>(what["VALUE"].str()));\r
+                       return boost::lexical_cast<std::wstring>(input_.loop());\r
+               }\r
+               if(boost::regex_match(param, what, seek_exp))\r
+               {\r
+                       input_.seek(boost::lexical_cast<int64_t>(what["VALUE"].str()));\r
+                       return L"";\r
+               }\r
+\r
+               BOOST_THROW_EXCEPTION(invalid_argument());\r
+       }\r
+\r
        void try_decode_frame(int hints)\r
        {\r
                std::shared_ptr<AVPacket> pkt;\r
@@ -206,44 +274,6 @@ public:
                for(auto frame = muxer_->poll(); frame; frame = muxer_->poll())\r
                        frame_buffer_.push(make_safe_ptr(frame));\r
        }\r
-\r
-       virtual int64_t nb_frames() const \r
-       {\r
-               if(loop_)\r
-                       return std::numeric_limits<int64_t>::max();\r
-\r
-               // This function estimates nb_frames until input has read all packets for one loop, at which point the count should be accurate.\r
-\r
-               int64_t nb_frames = input_.nb_frames();\r
-               if(input_.nb_loops() < 1) // input still hasn't counted all frames\r
-               {\r
-                       auto video_nb_frames = video_decoder_ ? video_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
-                       auto audio_nb_frames = audio_decoder_ ? audio_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
-\r
-                       nb_frames = std::max(nb_frames, std::max(video_nb_frames, audio_nb_frames));\r
-               }\r
-\r
-               nb_frames = std::min(static_cast<int64_t>(length_), nb_frames);\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
-               return nb_frames - start_;\r
-       }\r
-                               \r
-       virtual std::wstring print() const\r
-       {\r
-               if(video_decoder_)\r
-               {\r
-                       return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"|" \r
-                                                         + boost::lexical_cast<std::wstring>(video_decoder_->width()) + L"x" + boost::lexical_cast<std::wstring>(video_decoder_->height())\r
-                                                         + (video_decoder_->is_progressive() ? L"p" : L"i")  + boost::lexical_cast<std::wstring>(video_decoder_->is_progressive() ? video_decoder_->fps() : 2.0 * video_decoder_->fps())\r
-                                                         + L"]";\r
-               }\r
-               \r
-               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
-       }\r
 };\r
 \r
 safe_ptr<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)\r