+\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
+\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
+\r
+ muxer_->push(video, hints);\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
+ for(auto frame = muxer_->poll(); frame; frame = muxer_->poll())\r
+ frame_buffer_.push(make_safe_ptr(frame));\r
+ }\r