#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
\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
, 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
\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
{\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
\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
\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
}\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