\r
std::shared_ptr<filter> filter_;\r
size_t filter_delay_;\r
- size_t filter_skip_;\r
+ int eof_count_;\r
\r
- std::shared_ptr<AVFrame> last_frame_;\r
- std::shared_ptr<AVFrame> decoded_frame_;\r
std::string filter_str_;\r
\r
public:\r
, codec_context_(*input_.get_video_codec_context())\r
, frame_number_(0)\r
, filter_(filter_str.empty() ? nullptr : new filter(filter_str))\r
- , filter_delay_(0)\r
- , filter_skip_(0)\r
- , last_frame_(avcodec_alloc_frame(), av_free)\r
+ , filter_delay_(1)\r
, filter_str_(filter_str)\r
+ , eof_count_(std::numeric_limits<int>::max())\r
{\r
}\r
\r
\r
std::deque<std::pair<int, safe_ptr<core::write_frame>>> decode(const std::shared_ptr<AVPacket>& video_packet)\r
{ \r
- std::deque<std::pair<int, safe_ptr<core::write_frame>>> result;\r
- \r
if(!video_packet) // eof\r
return flush();\r
-\r
+ \r
+ std::deque<std::pair<int, safe_ptr<core::write_frame>>> result;\r
+ \r
+ frame_number_ = frame_number_ % eof_count_;\r
+ \r
if(filter_)\r
- {\r
- if(decoded_frame_)\r
- push_filter_frames(make_safe(decoded_frame_)); \r
- \r
+ { \r
std::shared_ptr<AVFrame> frame;\r
\r
tbb::parallel_invoke(\r
},\r
[&]\r
{\r
- if(decoded_frame_)\r
- result = poll_filter_frames();\r
+ result = poll_filter_frames();\r
}); \r
\r
- decoded_frame_ = frame;\r
- if(frame)\r
- last_frame_ = frame; \r
+ push_filter_frames(make_safe(frame)); \r
}\r
else\r
{\r
{\r
std::deque<std::pair<int, safe_ptr<core::write_frame>>> result;\r
\r
- if(filter_)\r
- {\r
- // Get all buffered frames\r
- if(decoded_frame_)\r
- { \r
- push_filter_frames(make_safe(decoded_frame_)); \r
- boost::range::push_back(result, poll_filter_frames());\r
- }\r
-\r
- for(size_t n = 0; n < filter_delay_; ++n)\r
- { \r
- push_filter_frames(make_safe(last_frame_)); \r
- boost::range::push_back(result, poll_filter_frames());\r
- }\r
+ eof_count_ = frame_number_;\r
\r
- // FIXME: Unnecessary reinitialization\r
- filter_skip_ = filter_delay_;\r
- decoded_frame_ = nullptr;\r
- }\r
+ if(filter_)\r
+ eof_count_ += filter_delay_; \r
\r
- frame_number_ = 0;\r
avcodec_flush_buffers(&codec_context_);\r
\r
return result;\r
std::deque<std::pair<int, safe_ptr<core::write_frame>>> poll_filter_frames()\r
{\r
std::deque<std::pair<int, safe_ptr<core::write_frame>>> result;\r
- \r
- if(filter_skip_ > 0)\r
- {\r
- --filter_skip_;\r
- filter_->skip();\r
+ \r
+ if(!filter_->is_ready())\r
return result;\r
- }\r
-\r
+ \r
auto frames = filter_->poll(); \r
\r
boost::range::transform(frames, std::back_inserter(result), [&](const safe_ptr<AVFrame>& frame)\r