#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
\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
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
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