\r
struct write_frame::impl : boost::noncopyable\r
{ \r
- std::shared_ptr<context> ogl_;\r
+ std::shared_ptr<context> ogl_;\r
std::vector<spl::shared_ptr<ogl::host_buffer>> buffers_;\r
core::audio_buffer audio_data_;\r
const core::pixel_format_desc desc_;\r
, desc_(desc)\r
, tag_(tag)\r
{\r
- if(desc.format != core::pixel_format::invalid)\r
+ std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
{\r
- std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
- {\r
- return ogl_->create_host_buffer(plane.size, ogl::host_buffer::usage::write_only);\r
- });\r
- }\r
+ return ogl_->create_host_buffer(plane.size, ogl::host_buffer::usage::write_only);\r
+ });\r
}\r
\r
void accept(write_frame& self, core::frame_visitor& visitor)\r
}, task_priority::high_priority);\r
}\r
\r
- void load(int index, const spl::shared_ptr<frame_producer>& producer, int auto_play_delta)\r
+ void load(int index, const spl::shared_ptr<frame_producer>& producer, const boost::optional<int32_t>& auto_play_delta)\r
{\r
executor_.begin_invoke([=]\r
{\r
void stage::apply_transform(int index, const std::function<core::frame_transform(core::frame_transform)>& transform, unsigned int mix_duration, const tweener& tween){impl_->apply_transform(index, transform, mix_duration, tween);}\r
void stage::clear_transforms(int index){impl_->clear_transforms(index);}\r
void stage::clear_transforms(){impl_->clear_transforms();}\r
-void stage::load(int index, const spl::shared_ptr<frame_producer>& producer, int auto_play_delta){impl_->load(index, producer, auto_play_delta);}\r
+void stage::load(int index, const spl::shared_ptr<frame_producer>& producer, const boost::optional<int32_t>& auto_play_delta){impl_->load(index, producer, auto_play_delta);}\r
void stage::pause(int index){impl_->pause(index);}\r
void stage::play(int index){impl_->play(index);}\r
void stage::stop(int index){impl_->stop(index);}\r
void clear_transforms(int index);\r
void clear_transforms();\r
\r
- void load(int index, const spl::shared_ptr<struct frame_producer>& producer, int auto_play_delta = -1);\r
+ void load(int index, const spl::shared_ptr<struct frame_producer>& producer, const boost::optional<int32_t>& auto_play_delta = nullptr);\r
void pause(int index);\r
void play(int index);\r
void stop(int index);\r
{\r
const std::wstring filename_;\r
\r
- const spl::shared_ptr<diagnostics::graph> graph_;\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 spl::shared_ptr<core::frame_factory> frame_factory_;\r
const core::video_format_desc format_desc_;\r
\r
input input_; \r
const uint32_t start_;\r
const uint32_t length_;\r
\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ spl::shared_ptr<core::draw_frame> last_frame_;\r
\r
int64_t frame_number_;\r
\r
\r
try\r
{\r
- video_decoder_.reset(new video_decoder(input_.context()));\r
+ video_decoder_.reset(new video_decoder(input_.context(), frame_factory_));\r
CASPAR_LOG(info) << print() << L" " << video_decoder_->print();\r
}\r
catch(averror_stream_not_found&)\r
\r
static const int CASPAR_PIX_FMT_LUMA = 10; // Just hijack some unual pixel format.\r
\r
-core::field_mode get_mode(const AVFrame& frame);\r
-int make_alpha_format(int format); // NOTE: Be careful about CASPAR_PIX_FMT_LUMA, change it to PIX_FMT_GRAY8 if you want to use the frame inside some ffmpeg function.\r
-spl::shared_ptr<core::write_frame> make_write_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags);\r
+core::field_mode get_mode(const AVFrame& frame);\r
+int make_alpha_format(int format); // NOTE: Be careful about CASPAR_PIX_FMT_LUMA, change it to PIX_FMT_GRAY8 if you want to use the frame inside some ffmpeg function.\r
+spl::shared_ptr<core::write_frame> make_write_frame(const void* tag, const spl::shared_ptr<AVFrame>& decoded_frame, const spl::shared_ptr<core::frame_factory>& frame_factory, int flags);\r
+core::pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, int width, int height);\r
\r
spl::shared_ptr<AVPacket> create_packet();\r
\r
struct video_decoder::impl : boost::noncopyable\r
{\r
int index_;\r
- const spl::shared_ptr<AVCodecContext> codec_context_;\r
+ const spl::shared_ptr<AVCodecContext> codec_context_;\r
\r
- std::queue<spl::shared_ptr<AVPacket>> packets_;\r
+ std::queue<spl::shared_ptr<AVPacket>> packets_;\r
\r
const uint32_t nb_frames_;\r
\r
tbb::atomic<uint32_t> file_frame_number_;\r
\r
public:\r
- explicit impl(const spl::shared_ptr<AVFormatContext>& context) \r
+ explicit impl(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory) \r
: codec_context_(open_codec(*context, AVMEDIA_TYPE_VIDEO, index_))\r
, nb_frames_(static_cast<uint32_t>(context->streams[index_]->nb_frames))\r
, width_(codec_context_->width)\r
, height_(codec_context_->height)\r
{\r
file_frame_number_ = 0;\r
+\r
+ // Reserve some frames\r
+ std::vector<spl::shared_ptr<core::write_frame>> frames;\r
+ for(int n = 0; n < 3; ++n)\r
+ frames.push_back(frame_factory->create_frame(this, get_pixel_format_desc(codec_context_->pix_fmt, codec_context_->width, codec_context_->height)));\r
}\r
\r
void push(const std::shared_ptr<AVPacket>& packet)\r
}\r
};\r
\r
-video_decoder::video_decoder(const spl::shared_ptr<AVFormatContext>& context) : impl_(new impl(context)){}\r
+video_decoder::video_decoder(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory) : impl_(new impl(context, frame_factory)){}\r
void video_decoder::push(const std::shared_ptr<AVPacket>& packet){impl_->push(packet);}\r
std::shared_ptr<AVFrame> video_decoder::poll(){return impl_->poll();}\r
bool video_decoder::ready() const{return impl_->ready();}\r
class video_decoder : boost::noncopyable\r
{\r
public:\r
- explicit video_decoder(const spl::shared_ptr<AVFormatContext>& context);\r
+ explicit video_decoder(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory);\r
\r
bool ready() const;\r
void push(const std::shared_ptr<AVPacket>& packet);\r
bool auto_play = std::find(_parameters.begin(), _parameters.end(), L"AUTO") != _parameters.end();\r
\r
auto pFP2 = create_transition_producer(GetChannel()->get_video_format_desc().field_mode, pFP, transitionInfo);\r
- GetChannel()->stage()->load(GetLayerIndex(), pFP2, auto_play ? transitionInfo.duration : -1); // TODO: LOOP\r
+ if(auto_play)\r
+ GetChannel()->stage()->load(GetLayerIndex(), pFP2, transitionInfo.duration); // TODO: LOOP\r
+ else\r
+ GetChannel()->stage()->load(GetLayerIndex(), pFP2); // TODO: LOOP\r
\r
SetReplyString(TEXT("202 LOADBG OK\r\n"));\r
\r