]> 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>
Sat, 13 Aug 2011 14:41:13 +0000 (14:41 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 13 Aug 2011 14:41:13 +0000 (14:41 +0000)
modules/ffmpeg/producer/audio/audio_decoder.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/frame_muxer.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index 8bb629be80e5fe614ede23e4bea7591fc7263cf5..a9316080981ed6ec24ce140ff35880e463527ebe 100644 (file)
@@ -115,37 +115,34 @@ public:
        \r
        std::vector<std::shared_ptr<std::vector<int16_t>>> poll()\r
        {\r
+               std::vector<std::shared_ptr<std::vector<int16_t>>> result;\r
+\r
+               if(packets_.empty())\r
+                       return result;\r
+\r
                if(!codec_context_)\r
                        return empty_poll();\r
+               \r
+               auto packet = packets_.front();\r
 \r
-               std::vector<std::shared_ptr<std::vector<int16_t>>> result;\r
-\r
-               while(!packets_.empty() && result.empty())\r
-               {                                               \r
-                       auto packet = packets_.front();\r
-\r
-                       if(packet)              \r
-                       {\r
-                               result.push_back(decode(*packet));\r
-                               if(packet->size == 0)                                   \r
-                                       packets_.pop();\r
-                       }\r
-                       else                    \r
-                       {       \r
-                               avcodec_flush_buffers(codec_context_.get());\r
-                               result.push_back(nullptr);\r
+               if(packet)              \r
+               {\r
+                       result.push_back(decode(*packet));\r
+                       if(packet->size == 0)                                   \r
                                packets_.pop();\r
-                       }               \r
                }\r
+               else                    \r
+               {       \r
+                       avcodec_flush_buffers(codec_context_.get());\r
+                       result.push_back(nullptr);\r
+                       packets_.pop();\r
+               }               \r
 \r
                return result;\r
        }\r
 \r
        std::vector<std::shared_ptr<std::vector<int16_t>>> empty_poll()\r
        {\r
-               if(packets_.empty())\r
-                       return std::vector<std::shared_ptr<std::vector<int16_t>>>();\r
-               \r
                auto packet = packets_.front();\r
                packets_.pop();\r
 \r
@@ -183,7 +180,7 @@ public:
 \r
        bool ready() const\r
        {\r
-               return !codec_context_ || packets_.size() > 2;\r
+               return !packets_.empty();\r
        }\r
 };\r
 \r
index fa696549e38f0aff0cf18e09a9d3e0131b341d38..0b6128b117705c7971a6d1af83a9b208e945fe8e 100644 (file)
@@ -89,11 +89,9 @@ public:
        {\r
                graph_->add_guide("frame-time", 0.5);\r
                graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
-               graph_->set_color("video-time", diagnostics::color(1.0f, 1.0f, 0.0f));\r
-               graph_->set_color("audio-time", diagnostics::color(0.2f, 1.0f, 0.2f));\r
                graph_->set_color("underflow", diagnostics::color(0.6f, 0.3f, 0.9f));           \r
                \r
-               for(int n = 0; n < 32 && muxer_.size() < 2; ++n)\r
+               for(int n = 0; n < 32 && muxer_.empty(); ++n)\r
                        decode_frame(0);\r
        }\r
                        \r
@@ -108,6 +106,8 @@ public:
                \r
                for(int n = 0; n < 64 && muxer_.empty(); ++n)\r
                        decode_frame(hints);\r
+               \r
+               graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
 \r
                if(!muxer_.empty())\r
                        frame = last_frame_ = muxer_.pop();     \r
@@ -125,8 +125,6 @@ public:
                        }\r
                }\r
                \r
-               graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
-               \r
                return frame;\r
        }\r
 \r
@@ -150,29 +148,21 @@ public:
                tbb::parallel_invoke(\r
                [&]\r
                {\r
-                       if(!muxer_.video_ready())\r
-                       {\r
-                               video_timer_.restart();\r
+                       if(muxer_.video_ready())\r
+                               return;\r
 \r
-                               auto video_frames = video_decoder_.poll();\r
-                               BOOST_FOREACH(auto& video, video_frames)                \r
-                                       muxer_.push(video, hints);      \r
-\r
-                               graph_->update_value("video-time", static_cast<float>(video_timer_.elapsed()*format_desc_.fps*0.5));\r
-                       }\r
+                       auto video_frames = video_decoder_.poll();\r
+                       BOOST_FOREACH(auto& video, video_frames)                \r
+                               muxer_.push(video, hints);      \r
                },\r
                [&]\r
                {\r
-                       if(!muxer_.audio_ready())\r
-                       {\r
-                               audio_timer_.restart();\r
+                       if(muxer_.audio_ready())\r
+                               return;\r
                                        \r
-                               auto audio_samples = audio_decoder_.poll();\r
-                               BOOST_FOREACH(auto& audio, audio_samples)\r
-                                       muxer_.push(audio);                             \r
-\r
-                               graph_->update_value("audio-time", static_cast<float>(audio_timer_.elapsed()*format_desc_.fps*0.5));\r
-                       }\r
+                       auto audio_samples = audio_decoder_.poll();\r
+                       BOOST_FOREACH(auto& audio, audio_samples)\r
+                               muxer_.push(audio);                             \r
                });\r
 \r
                muxer_.commit();\r
index 29c3de9bc3e841d2aee98847dc2cbeb77f394f1d..abf8c60f3eb66f73808901573971e06c4db471c5 100644 (file)
@@ -261,30 +261,43 @@ struct frame_muxer::implementation : boost::noncopyable
 \r
                return samples;\r
        }\r
-\r
+       \r
        bool video_ready() const\r
-       {\r
-               return video_frames() > 1 && video_streams_.size() >= audio_streams_.size();\r
+       {               \r
+               return video_streams_.size() >= audio_streams_.size() && video_ready2();\r
        }\r
        \r
        bool audio_ready() const\r
        {\r
-               return audio_chunks() > 1 && audio_streams_.size() >= video_streams_.size();\r
+               return audio_streams_.size() >= video_streams_.size() && audio_ready2();\r
        }\r
 \r
-       size_t video_frames() const\r
-       {\r
-               return video_streams_.back().size();\r
+       bool video_ready2() const\r
+       {               \r
+               switch(display_mode_)\r
+               {\r
+               case display_mode::deinterlace_bob_reinterlace:                                 \r
+               case display_mode::interlace:                                   \r
+                       return video_streams_.front().size() >= 2;\r
+               default:                                                                                \r
+                       return !video_streams_.front().empty();\r
+               }\r
        }\r
-\r
-       size_t audio_chunks() const\r
+       \r
+       bool audio_ready2() const\r
        {\r
-               return audio_streams_.back().size() / format_desc_.audio_samples_per_frame;\r
+               switch(display_mode_)\r
+               {\r
+               case display_mode::duplicate:                                   \r
+                       return audio_streams_.front().size()/2 >= format_desc_.audio_samples_per_frame;\r
+               default:                                                                                \r
+                       return audio_streams_.front().size() >= format_desc_.audio_samples_per_frame;\r
+               }\r
        }\r
-       \r
+               \r
        void commit()\r
        {\r
-               if(video_streams_.size() > 1 && audio_streams_.size() > 1 && !ready())\r
+               if(video_streams_.size() > 1 && audio_streams_.size() > 1 && (!video_ready2() || !audio_ready2()))\r
                {\r
                        if(!video_streams_.front().empty() || !audio_streams_.front().empty())\r
                                CASPAR_LOG(debug) << "Truncating: " << video_streams_.front().size() << L" video-frames, " << audio_streams_.front().size() << L" audio-samples.";\r
@@ -293,7 +306,7 @@ struct frame_muxer::implementation : boost::noncopyable
                        audio_streams_.pop_front();\r
                }\r
 \r
-               if(!ready())\r
+               if(!video_ready2() || !audio_ready2())\r
                        return;\r
                \r
                switch(display_mode_)\r
@@ -308,22 +321,7 @@ struct frame_muxer::implementation : boost::noncopyable
                default:                                                                                BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("invalid display-mode"));\r
                }\r
        }\r
-\r
-       bool ready()\r
-       {\r
-               switch(display_mode_)\r
-               {\r
-               case display_mode::deinterlace_bob:\r
-               case display_mode::deinterlace:\r
-               case display_mode::simple:                                              return !video_streams_.front().empty() && audio_streams_.front().size() >= format_desc_.audio_samples_per_frame;\r
-               case display_mode::duplicate:                                   return !video_streams_.front().empty() && audio_streams_.front().size()/2 >= format_desc_.audio_samples_per_frame;\r
-               case display_mode::half:        \r
-               case display_mode::deinterlace_bob_reinterlace:                                 \r
-               case display_mode::interlace:                                   return video_streams_.front().size() >= 2 && audio_streams_.front().size() >= format_desc_.audio_samples_per_frame;\r
-               default:                                                                                return false;\r
-               }\r
-       }\r
-\r
+       \r
        void simple(std::deque<safe_ptr<basic_frame>>& dest)\r
        {               \r
                auto frame1 = pop_video();\r
index 770614e1356fdc763193f64ae0b43a39f640d715..a15da2bd482a9d77837a50773d3b369e631d0c86 100644 (file)
@@ -110,40 +110,42 @@ public:
 \r
        std::vector<std::shared_ptr<AVFrame>> poll()\r
        {               \r
+               std::vector<std::shared_ptr<AVFrame>> result;\r
+\r
+               if(packets_.empty())\r
+                       return result;\r
+\r
                if(!codec_context_)\r
                        return empty_poll();\r
 \r
-               std::vector<std::shared_ptr<AVFrame>> result;\r
-\r
-               while(!packets_.empty() && result.empty())\r
-               {\r
-                       auto packet = packets_.front();\r
+               auto packet = packets_.front();\r
                                        \r
-                       if(packet)\r
-                       {\r
-                               auto frame = decode(*packet);\r
+               if(packet)\r
+               {                       \r
+                       BOOST_FOREACH(auto& frame, decode(*packet))\r
                                boost::range::push_back(result, filter_.execute(frame));\r
-                               if(packet->size == 0)\r
-                                       packets_.pop();\r
-                       }\r
-                       else\r
+\r
+                       if(packet->size == 0)\r
+                               packets_.pop();\r
+               }\r
+               else\r
+               {\r
+                       if(codec_context_->codec->capabilities & CODEC_CAP_DELAY)\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
-                                       auto frame = decode(pkt);\r
+                               AVPacket pkt;\r
+                               av_init_packet(&pkt);\r
+                               pkt.data = nullptr;\r
+                               pkt.size = 0;\r
+\r
+                               BOOST_FOREACH(auto& frame, decode(pkt))\r
                                        boost::range::push_back(result, filter_.execute(frame));        \r
-                               }\r
-\r
-                               if(result.empty())\r
-                               {                                       \r
-                                       packets_.pop();\r
-                                       avcodec_flush_buffers(codec_context_.get());\r
-                                       result.push_back(nullptr);\r
-                               }\r
+                       }\r
+\r
+                       if(result.empty())\r
+                       {                                       \r
+                               packets_.pop();\r
+                               avcodec_flush_buffers(codec_context_.get());\r
+                               result.push_back(nullptr);\r
                        }\r
                }\r
                \r
@@ -151,10 +153,7 @@ public:
        }\r
 \r
        std::vector<std::shared_ptr<AVFrame>> empty_poll()\r
-       {               \r
-               if(packets_.empty())\r
-                       return std::vector<std::shared_ptr<AVFrame>>();\r
-               \r
+       {                               \r
                auto packet = packets_.front();\r
                packets_.pop();\r
 \r
@@ -167,7 +166,7 @@ public:
                return boost::assign::list_of(frame);                                   \r
        }\r
 \r
-       std::shared_ptr<AVFrame> decode(AVPacket& pkt)\r
+       std::vector<std::shared_ptr<AVFrame>> decode(AVPacket& pkt)\r
        {\r
                std::shared_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
 \r
@@ -180,19 +179,18 @@ public:
                pkt.data = nullptr;\r
                pkt.size = 0;\r
 \r
-               if(frame_finished != 0) \r
-               {\r
-                       if(decoded_frame->repeat_pict != 0)\r
-                               CASPAR_LOG(warning) << "video_decoder: repeat_pict not implemented.";\r
-                       return decoded_frame;\r
-               }\r
+               if(frame_finished == 0) \r
+                       return std::vector<std::shared_ptr<AVFrame>>();\r
 \r
-               return nullptr;\r
+               if(decoded_frame->repeat_pict % 2 > 0)\r
+                               CASPAR_LOG(warning) << "[video_decoder]: Field repeat_pict not implemented.";\r
+               \r
+               return std::vector<std::shared_ptr<AVFrame>>(1 + decoded_frame->repeat_pict/2, decoded_frame);\r
        }\r
        \r
        bool ready() const\r
        {\r
-               return !codec_context_ || packets_.size() > 2;\r
+               return !packets_.empty();\r
        }\r
        \r
        double fps() const\r