#include <core/frame/frame_factory.h>\r
#include <core/frame/draw_frame.h>\r
#include <core/frame/frame_transform.h>\r
+#include <core/monitor/monitor.h>\r
\r
#include <boost/algorithm/string.hpp>\r
#include <common/assert.h>\r
\r
struct ffmpeg_producer : public core::frame_producer\r
{\r
+ monitor::basic_subject event_subject_;\r
const std::wstring filename_;\r
\r
const spl::shared_ptr<diagnostics::graph> graph_;\r
- boost::timer frame_timer_;\r
\r
const spl::shared_ptr<core::frame_factory> frame_factory_;\r
const core::video_format_desc format_desc_;\r
const double fps_;\r
const uint32_t start_;\r
const uint32_t length_;\r
-\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
- \r
+ \r
int64_t frame_number_;\r
\r
public:\r
explicit ffmpeg_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, uint32_t start, uint32_t length) \r
: filename_(filename)\r
, frame_factory_(frame_factory) \r
- , format_desc_(frame_factory->get_video_format_desc())\r
+ , format_desc_(frame_factory->video_format_desc())\r
, input_(graph_, filename_, loop, start, length)\r
, fps_(read_fps(*input_.context(), format_desc_.fps))\r
, start_(start)\r
, length_(length)\r
- , last_frame_(core::draw_frame::empty())\r
, frame_number_(0)\r
{\r
graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
try\r
{\r
video_decoder_.reset(new video_decoder(input_.context()));\r
+ video_decoder_->subscribe(event_subject_);\r
CASPAR_LOG(info) << print() << L" " << video_decoder_->print();\r
}\r
catch(averror_stream_not_found&)\r
\r
try\r
{\r
- audio_decoder_.reset(new audio_decoder(input_.context(), frame_factory->get_video_format_desc()));\r
+ audio_decoder_.reset(new audio_decoder(input_.context(), frame_factory->video_format_desc()));\r
+ audio_decoder_->subscribe(event_subject_);\r
CASPAR_LOG(info) << print() << L" " << audio_decoder_->print();\r
}\r
catch(averror_stream_not_found&)\r
\r
virtual spl::shared_ptr<core::draw_frame> receive(int flags) override\r
{ \r
- frame_timer_.restart();\r
+ boost::timer frame_timer;\r
\r
std::shared_ptr<core::draw_frame> frame = try_decode_frame(flags);\r
\r
- graph_->set_value("frame-time", frame_timer_.elapsed()*format_desc_.fps*0.5);\r
+ graph_->set_value("frame-time", frame_timer.elapsed()*format_desc_.fps*0.5);\r
+ \r
+ event_subject_ << monitor::event("profiler/time") % frame_timer.elapsed() % (1.0/format_desc_.fps) \r
+ << monitor::event("file/time") % monitor::duration(file_frame_number()/fps_) \r
+ % monitor::duration(file_nb_frames()/fps_)\r
+ << monitor::event("file/frame") % static_cast<int32_t>(file_frame_number())\r
+ % static_cast<int32_t>(file_nb_frames())\r
+ << monitor::event("file/fps") % fps_\r
+ << monitor::event("filename") % u8(filename_)\r
+ << monitor::event("loop") % input_.loop();\r
\r
if(!frame)\r
{\r
- if(!input_.eof()) \r
+ if(!input_.eof()) \r
graph_->set_tag("underflow"); \r
- return last_frame();\r
+ return core::draw_frame::late();\r
}\r
\r
++frame_number_;\r
\r
graph_->set_text(print());\r
\r
- return last_frame_ = spl::make_shared_ptr(frame);\r
+ return spl::make_shared_ptr(frame);\r
}\r
-\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
- {\r
- return core::draw_frame::mute(last_frame_);\r
- }\r
-\r
+ \r
virtual uint32_t nb_frames() const override\r
{\r
if(input_.loop())\r
+ boost::lexical_cast<std::wstring>(file_frame_number()) + L"/" + boost::lexical_cast<std::wstring>(file_nb_frames()) + L"]";\r
}\r
\r
+ virtual std::wstring name() const override\r
+ {\r
+ return L"ffmpeg";\r
+ }\r
+\r
boost::property_tree::wptree info() const override\r
{\r
boost::property_tree::wptree info;\r
- info.add(L"type", L"ffmpeg-producer");\r
+ info.add(L"type", L"ffmpeg");\r
info.add(L"filename", filename_);\r
info.add(L"width", video_decoder_ ? video_decoder_->width() : 0);\r
info.add(L"height", video_decoder_ ? video_decoder_->height() : 0);\r
info.add(L"file-nb-frames", file_nb_frames());\r
return info;\r
}\r
+ \r
+ virtual void subscribe(const monitor::observable::observer_ptr& o) override\r
+ {\r
+ event_subject_.subscribe(o);\r
+ }\r
+\r
+ virtual void unsubscribe(const monitor::observable::observer_ptr& o) override\r
+ {\r
+ event_subject_.unsubscribe(o);\r
+ }\r
\r
// ffmpeg_producer\r
\r
std::wstring print_mode() const\r
{\r
- return video_decoder_ ? ffmpeg::print_mode(video_decoder_->width(), video_decoder_->height(), fps_, !video_decoder_->is_progressive()) : L"";\r
+ return video_decoder_ ? ffmpeg::print_mode(video_decoder_->width(), video_decoder_->height(), fps_, !video_decoder_->is_progressive()) : L"n/a";\r
}\r
\r
std::wstring do_call(const std::wstring& param)\r