]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 24 Oct 2011 19:12:48 +0000 (19:12 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 24 Oct 2011 19:12:48 +0000 (19:12 +0000)
modules/ffmpeg/producer/frame_muxer.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index 4aa4c19c21e80744958e96bc78902df4610b4f3c..ebd22dcad6b3dcb7057f17556dd360b8203f73d0 100644 (file)
@@ -107,14 +107,8 @@ struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopya
                                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
index 06c60e242cf0065da7a5a3fb5210692b18a90497..75190cbd0da12b4cac85eee92482bd35b43e2ee5 100644 (file)
@@ -89,6 +89,27 @@ public:
        {\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
@@ -100,7 +121,21 @@ public:
                                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
@@ -109,21 +144,9 @@ public:
                                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