\r
safe_ptr<core::draw_frame> last_frame_;\r
\r
- std::queue<std::pair<safe_ptr<core::draw_frame>, uint32_t>> frame_buffer_;\r
-\r
int64_t frame_number_;\r
- uint32_t file_frame_number_;\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, uint32_t start, uint32_t length) \r
{ \r
frame_timer_.restart();\r
\r
- for(int n = 0; n < 16 && frame_buffer_.size() < 2; ++n)\r
- try_decode_frame(flags);\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
\r
- if(frame_buffer_.empty() && input_.eof())\r
- return last_frame();\r
-\r
- if(frame_buffer_.empty())\r
+ if(!frame)\r
{\r
- graph_->set_tag("underflow"); \r
- return core::draw_frame::late(); \r
+ if(!input_.eof()) \r
+ graph_->set_tag("underflow"); \r
+ return last_frame();\r
}\r
- \r
- auto frame = frame_buffer_.front(); \r
- frame_buffer_.pop();\r
- \r
+ \r
++frame_number_;\r
- file_frame_number_ = frame.second;\r
\r
graph_->set_text(print());\r
\r
- return last_frame_ = frame.first;\r
+ return last_frame_ = make_safe_ptr(frame);\r
}\r
\r
virtual safe_ptr<core::draw_frame> last_frame() const override\r
file_nb_frames = std::max(file_nb_frames, audio_decoder_ ? audio_decoder_->nb_frames() : 0);\r
return file_nb_frames;\r
}\r
+\r
+ uint32_t file_frame_number() const\r
+ {\r
+ return video_decoder_ ? video_decoder_->file_frame_number() : 0;\r
+ }\r
\r
virtual boost::unique_future<std::wstring> call(const std::wstring& param) override\r
{\r
{\r
return L"ffmpeg[" + boost::filesystem::path(filename_).filename().wstring() + L"|" \r
+ print_mode() + L"|" \r
- + boost::lexical_cast<std::wstring>(file_frame_number_) + L"/" + boost::lexical_cast<std::wstring>(file_nb_frames()) + L"]";\r
+ + boost::lexical_cast<std::wstring>(file_frame_number()) + L"/" + boost::lexical_cast<std::wstring>(file_nb_frames()) + L"]";\r
}\r
\r
boost::property_tree::wptree info() const override\r
info.add(L"frame-number", frame_number_);\r
auto nb_frames2 = nb_frames();\r
info.add(L"nb-frames", nb_frames2 == std::numeric_limits<int64_t>::max() ? -1 : nb_frames2);\r
- info.add(L"file-frame-number", file_frame_number_);\r
+ info.add(L"file-frame-number", file_frame_number());\r
info.add(L"file-nb-frames", file_nb_frames());\r
return info;\r
}\r
BOOST_THROW_EXCEPTION(invalid_argument());\r
}\r
\r
- void try_decode_frame(int flags)\r
+ std::shared_ptr<core::draw_frame> try_decode_frame(int flags)\r
{\r
- std::shared_ptr<AVPacket> pkt;\r
+ std::shared_ptr<core::draw_frame> result = muxer_->poll();\r
\r
- for(int n = 0; n < 32 && ((video_decoder_ && !video_decoder_->ready()) || (audio_decoder_ && !audio_decoder_->ready())) && input_.try_pop(pkt); ++n)\r
+ for(int n = 0; n < 32 && !result; ++n, result = muxer_->poll())\r
{\r
- if(video_decoder_)\r
- video_decoder_->push(pkt);\r
- if(audio_decoder_)\r
- audio_decoder_->push(pkt);\r
- }\r
+ std::shared_ptr<AVPacket> pkt;\r
+\r
+ for(int n = 0; n < 32 && ((video_decoder_ && !video_decoder_->ready()) || (audio_decoder_ && !audio_decoder_->ready())) && input_.try_pop(pkt); ++n)\r
+ {\r
+ if(video_decoder_)\r
+ video_decoder_->push(pkt);\r
+ if(audio_decoder_)\r
+ audio_decoder_->push(pkt);\r
+ }\r
\r
- std::shared_ptr<AVFrame> video;\r
- std::shared_ptr<core::audio_buffer> audio;\r
-\r
- tbb::parallel_invoke(\r
- [&]\r
- {\r
- if(!muxer_->video_ready() && video_decoder_) \r
- video = video_decoder_->poll(); \r
- },\r
- [&]\r
- { \r
- if(!muxer_->audio_ready() && audio_decoder_) \r
- audio = audio_decoder_->poll(); \r
- });\r
+ std::shared_ptr<AVFrame> video;\r
+ std::shared_ptr<core::audio_buffer> audio;\r
+\r
+ tbb::parallel_invoke(\r
+ [&]\r
+ {\r
+ if(!muxer_->video_ready() && video_decoder_) \r
+ video = video_decoder_->poll(); \r
+ },\r
+ [&]\r
+ { \r
+ if(!muxer_->audio_ready() && audio_decoder_) \r
+ audio = audio_decoder_->poll(); \r
+ });\r
\r
- muxer_->push(video, flags);\r
- muxer_->push(audio);\r
-\r
- if(!audio_decoder_)\r
- {\r
- if(video == flush_video())\r
- muxer_->push(flush_audio());\r
- else if(!muxer_->audio_ready())\r
- muxer_->push(empty_audio());\r
+ muxer_->push(video, flags);\r
+ muxer_->push(audio);\r
+\r
+ if(!audio_decoder_)\r
+ {\r
+ if(video == flush_video())\r
+ muxer_->push(flush_audio());\r
+ else if(!muxer_->audio_ready())\r
+ muxer_->push(empty_audio());\r
+ }\r
+\r
+ if(!video_decoder_)\r
+ {\r
+ if(audio == flush_audio())\r
+ muxer_->push(flush_video(), 0);\r
+ else if(!muxer_->video_ready())\r
+ muxer_->push(empty_video(), 0);\r
+ }\r
}\r
\r
- if(!video_decoder_)\r
- {\r
- if(audio == flush_audio())\r
- muxer_->push(flush_video(), 0);\r
- else if(!muxer_->video_ready())\r
- muxer_->push(empty_video(), 0);\r
- }\r
- \r
- uint32_t file_frame_number = 0;\r
- file_frame_number = std::max(file_frame_number, video_decoder_ ? video_decoder_->file_frame_number() : 0);\r
- //file_frame_number = std::max(file_frame_number, audio_decoder_ ? audio_decoder_->file_frame_number() : 0);\r
-\r
- for(auto frame = muxer_->poll(); frame; frame = muxer_->poll())\r
- frame_buffer_.push(std::make_pair(make_safe_ptr(frame), file_frame_number));\r
+ return result;\r
}\r
};\r
\r