\r
void visit(core::write_frame& frame)\r
{ \r
+ if(frame.get_textures().empty())\r
+ return;\r
+\r
render_item item = {frame.get_pixel_format_desc(), frame.get_textures(), transform_stack_.top()*frame.get_image_transform(), frame.tag()}; \r
\r
auto& layer = render_queue_.back();\r
\r
struct write_frame::implementation\r
{ \r
- ogl_device* ogl_;\r
- std::vector<std::shared_ptr<host_buffer>> buffers_;\r
- std::array<std::shared_ptr<device_buffer>, 4> textures_;\r
- std::vector<int16_t> audio_data_;\r
- const core::pixel_format_desc desc_;\r
- int tag_;\r
- core::video_mode::type mode_;\r
+ ogl_device* ogl_;\r
+ std::vector<std::shared_ptr<host_buffer>> buffers_;\r
+ std::vector<safe_ptr<device_buffer>> textures_;\r
+ std::vector<int16_t> audio_data_;\r
+ const core::pixel_format_desc desc_;\r
+ int tag_;\r
+ core::video_mode::type mode_;\r
\r
implementation()\r
{\r
void accept(write_frame& self, core::frame_visitor& visitor)\r
{\r
visitor.begin(self);\r
- if(!desc_.planes().empty())\r
- visitor.visit(self);\r
+ visitor.visit(self);\r
visitor.end();\r
}\r
\r
if(!buffer)\r
return;\r
\r
- auto texture\r
+ auto texture = textures_.at(plane_index);\r
\r
ogl_->begin_invoke([=]\r
- {\r
- auto plane = desc_.planes[plane_index];\r
- textures_[plane_index] = ogl_->create_device_buffer(plane.width, plane.height, plane.channels); \r
- textures_[plane_index]->read(*buffer);\r
+ { \r
+ texture->read(*buffer);\r
}, high_priority);\r
}\r
};\r
}\r
int write_frame::tag() const {return impl_->tag_;}\r
const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
-const std::vector<safe_ptr<device_buffer>> write_frame::get_textures() const\r
-{\r
- std::vector<safe_ptr<device_buffer>> textures;\r
- BOOST_FOREACH(auto texture, impl_->textures_)\r
- {\r
- if(texture)\r
- textures.push_back(make_safe(texture));\r
- }\r
-\r
- return textures;\r
-}\r
+const std::vector<safe_ptr<device_buffer>>& write_frame::get_textures() const{return impl_->textures_;}\r
void write_frame::commit(size_t plane_index){impl_->commit(plane_index);}\r
void write_frame::commit(){impl_->commit();}\r
void write_frame::set_type(const video_mode::type& mode){impl_->mode_ = mode;}\r
start = boost::lexical_cast<int>(*seek_it);\r
}\r
\r
- return make_safe<ffmpeg_producer>(frame_factory, path, L"", loop, start, length);\r
+ std::wstring filter = L"";\r
+ auto filter_it = std::find(params.begin(), params.end(), L"FILTER");\r
+ if(filter_it != params.end())\r
+ {\r
+ if(++filter_it != params.end())\r
+ filter = *filter_it;\r
+ }\r
+\r
+ return make_safe<ffmpeg_producer>(frame_factory, path, filter, loop, start, length);\r
}\r
\r
}
\ No newline at end of file
std::transform(filters_.begin(), filters_.end(), filters_.begin(), ::tolower);\r
}\r
\r
- void push(const safe_ptr<AVFrame>& frame)\r
+ void push(const std::shared_ptr<AVFrame>& frame)\r
{ \r
int errn = 0; \r
\r
};\r
\r
filter::filter(const std::wstring& filters) : impl_(new implementation(filters)){}\r
-void filter::push(const safe_ptr<AVFrame>& frame) {impl_->push(frame);}\r
+void filter::push(const std::shared_ptr<AVFrame>& frame) {impl_->push(frame);}\r
std::vector<safe_ptr<AVFrame>> filter::poll() {return impl_->poll();}\r
}
\ No newline at end of file
public:\r
filter(const std::wstring& filters);\r
\r
- void push(const safe_ptr<AVFrame>& frame);\r
+ void push(const std::shared_ptr<AVFrame>& frame);\r
std::vector<safe_ptr<AVFrame>> poll();\r
\r
private:\r
std::queue<std::shared_ptr<AVPacket>> packet_buffer_;\r
\r
std::unique_ptr<filter> filter_;\r
+ tbb::task_group filter_tasks_;\r
\r
double fps_;\r
public:\r
codec_context_->time_base.num = static_cast<int>(std::pow(10.0, static_cast<int>(std::log10(static_cast<float>(codec_context_->time_base.den)))-1)); \r
\r
fps_ = static_cast<double>(codec_context_->time_base.den) / static_cast<double>(codec_context_->time_base.num);\r
- //if(double_rate(filter))\r
- // fps_ *= 2;\r
+ if(double_rate(filter))\r
+ fps_ *= 2;\r
}\r
\r
void push(const std::shared_ptr<AVPacket>& packet)\r
result.push_back(make_safe<core::write_frame>());\r
else if(!packet_buffer_.empty())\r
{\r
+ std::vector<std::shared_ptr<AVFrame>> av_frames;\r
+\r
auto packet = std::move(packet_buffer_.front());\r
packet_buffer_.pop();\r
\r
{\r
// FIXME: This might cause bad performance.\r
AVPacket pkt = {0};\r
- auto frame = decode_frame(pkt);\r
- if(frame)\r
- result.push_back(make_write_frame(this, make_safe(frame), frame_factory_));\r
+ av_frames.push_back(decode_frame(pkt));\r
}\r
\r
avcodec_flush_buffers(codec_context_.get());\r
}\r
else\r
{\r
- auto frame = decode_frame(*packet);\r
- if(frame)\r
+ av_frames.push_back(decode_frame(*packet)); \r
+ }\r
+\r
+ if(filter_)\r
+ {\r
+ filter_tasks_.wait();\r
+ \r
+ av_frames.clear();\r
+ boost::range::push_back(av_frames, filter_->poll());\r
+\r
+ filter_tasks_.run([=]\r
{\r
- auto frame2 = make_write_frame(this, make_safe(frame), frame_factory_); \r
- mode_ = frame2->get_type();\r
- result.push_back(std::move(frame2));\r
- }\r
+ BOOST_FOREACH(auto& frame, av_frames) \r
+ filter_->push(frame);\r
+ });\r
}\r
+ \r
+ BOOST_FOREACH(auto& frame, av_frames)\r
+ result.push_back(make_write_frame(this, make_safe(frame), frame_factory_));\r
}\r
\r
return result;\r