initialize_display_mode(*video);\r
\r
filter_.value()->push(video);\r
- while(true)\r
- {\r
- auto frame = filter_.value()->poll();\r
- if(!frame)\r
- break; \r
-\r
- video_frames_.push(write_element_t(make_write_frame(this, video, frame_factory_, 0), element.second));\r
- }\r
+ for(auto frame = filter_.value()->poll(); frame; frame = filter_.value()->poll()) \r
+ video_frames_.push(write_element_t(make_write_frame(this, video, frame_factory_, 0), element.second)); \r
}\r
\r
return receive_video();\r
{\r
agent::wait(this);\r
}\r
+ \r
+ std::shared_ptr<AVFrame> decode(AVPacket& packet)\r
+ {\r
+ std::shared_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
+\r
+ int frame_finished = 0;\r
+ THROW_ON_ERROR2(avcodec_decode_video2(codec_context_.get(), decoded_frame.get(), &frame_finished, &packet), "[video_decocer]");\r
+\r
+ // 1 packet <=> 1 frame.\r
+ // If a decoder consumes less then the whole packet then something is wrong\r
+ // that might be just harmless padding at the end, or a problem with the\r
+ // AVParser or demuxer which puted more then one frame in a AVPacket.\r
+\r
+ if(frame_finished == 0) \r
+ return nullptr;\r
+ \r
+ if(decoded_frame->repeat_pict > 0)\r
+ CASPAR_LOG(warning) << "[video_decoder]: Field repeat_pict not implemented.";\r
+\r
+ return decoded_frame;\r
+ }\r
\r
virtual void run()\r
{\r
auto packet = element.first;\r
\r
if(packet == loop_packet(index_))\r
- {\r
+ { \r
+ if(codec_context_->codec->capabilities & CODEC_CAP_DELAY)\r
+ {\r
+ AVPacket pkt;\r
+ av_init_packet(&pkt);\r
+ pkt.data = nullptr;\r
+ pkt.size = 0;\r
+\r
+ for(auto decoded_frame = decode(pkt); decoded_frame; decoded_frame = decode(pkt))\r
+ {\r
+ send(target_, target_element_t(dup_frame(make_safe_ptr(decoded_frame)), element.second));\r
+ Context::Yield();\r
+ }\r
+ }\r
+\r
avcodec_flush_buffers(codec_context_.get());\r
send(target_, target_element_t(loop_video(), ticket_t()));\r
continue;\r
if(packet == eof_packet(index_))\r
break;\r
\r
- std::shared_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
-\r
- int frame_finished = 0;\r
- THROW_ON_ERROR2(avcodec_decode_video2(codec_context_.get(), decoded_frame.get(), &frame_finished, packet.get()), "[video_decocer]");\r
-\r
- // 1 packet <=> 1 frame.\r
- // If a decoder consumes less then the whole packet then something is wrong\r
- // that might be just harmless padding at the end, or a problem with the\r
- // AVParser or demuxer which puted more then one frame in a AVPacket.\r
-\r
- if(frame_finished == 0) \r
+ auto decoded_frame = decode(*packet);\r
+ if(!decoded_frame)\r
continue;\r
- \r
- if(decoded_frame->repeat_pict > 0)\r
- CASPAR_LOG(warning) << "[video_decoder]: Field repeat_pict not implemented.";\r
\r
is_progressive_ = decoded_frame->interlaced_frame == 0;\r
\r