]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Simplified audio-chunk handling.
authorRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Jul 2011 21:30:45 +0000 (21:30 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Jul 2011 21:30:45 +0000 (21:30 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1007 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/audio/audio_mixer.cpp
core/producer/frame_muxer.cpp
modules/decklink/interop/DeckLinkAPI_h.h
modules/decklink/interop/DeckLinkAPI_i.c
modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/producer/audio/audio_decoder.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index b9e9b0b59224807723a9dd1671a9ab11ad72fe79..b93fef4873cef08f581162e9240ce43097402d2f 100644 (file)
@@ -77,10 +77,12 @@ public:
                const int n_samples = audio_data_.back().size();\r
                \r
                const auto in_size = static_cast<size_t>(audio_data.size());\r
-               CASPAR_VERIFY(in_size == 0 || in_size == audio_data_.back().size());\r
 \r
-               if(in_size > audio_data_.back().size())\r
+               if(in_size != 0 && in_size != audio_data_.back().size())\r
+               {       \r
+                       CASPAR_LOG(warning) << L" audio_mixer[] : Invalid sample count detected. Discarding audio chunk.";\r
                        return;\r
+               }\r
 \r
                tbb::parallel_for\r
                (\r
index f2d1061a74dc62e54b228c2560545f8421ea8840..10ed364b923ef7f2d1bffd620807047a47545686 100644 (file)
@@ -7,6 +7,8 @@
 #include "frame/pixel_format.h"\r
 #include "../mixer/write_frame.h"\r
 \r
+#include <boost/range/algorithm_ext/push_back.hpp>\r
+\r
 #include <common/env.h>\r
 \r
 namespace caspar { namespace core {\r
@@ -170,10 +172,10 @@ struct frame_muxer::implementation
                if(video_frames_.empty() || audio_chunks_.empty())\r
                        return;\r
 \r
-               auto frame1 = video_frames_.front();\r
+               auto frame1 = std::move(video_frames_.front());\r
                video_frames_.pop();\r
 \r
-               frame1->audio_data() = audio_chunks_.front();\r
+               frame1->audio_data() = std::move(audio_chunks_.front());\r
                audio_chunks_.pop();\r
 \r
                frame_buffer_.push(frame1);\r
@@ -181,19 +183,20 @@ struct frame_muxer::implementation
 \r
        void duplicate()\r
        {               \r
-               if(video_frames_.empty() || audio_chunks_.size() < 2)\r
+               if(video_frames_.empty() || audio_chunks_.empty())\r
                        return;\r
 \r
-               auto frame = video_frames_.front();\r
+               auto frame = std::move(video_frames_.front());\r
                video_frames_.pop();\r
 \r
-               auto frame1 = make_safe<core::write_frame>(*frame); // make a copy\r
-               frame1->audio_data() = audio_chunks_.front();\r
+               auto audio_chunk = std::move(audio_chunks_.front());\r
                audio_chunks_.pop();\r
 \r
+               auto frame1 = make_safe<core::write_frame>(*frame); // make a copy\r
+               frame1->audio_data().insert(frame1->audio_data().end(), audio_chunk.begin(), audio_chunk.begin() + audio_chunk.size()/2);\r
+\r
                auto frame2 = frame;\r
-               frame2->audio_data() = audio_chunks_.front();\r
-               audio_chunks_.pop();\r
+               frame1->audio_data().insert(frame1->audio_data().end(), audio_chunk.begin() + audio_chunk.size()/2, audio_chunk.end());\r
 \r
                frame_buffer_.push(frame1);\r
                frame_buffer_.push(frame2);\r
@@ -201,32 +204,39 @@ struct frame_muxer::implementation
 \r
        void half()\r
        {       \r
-               if(video_frames_.size() < 2 || audio_chunks_.empty())\r
+               if(video_frames_.size() < 2 || audio_chunks_.size() < 2)\r
                        return;\r
                                                \r
-               auto frame1 = video_frames_.front();\r
+               auto frame1 = std::move(video_frames_.front());\r
                video_frames_.pop();\r
-               frame1->audio_data() = audio_chunks_.front();\r
-               audio_chunks_.pop();\r
-                               \r
+\r
                video_frames_.pop(); // Throw away\r
+               \r
+               boost::range::push_back(frame1->audio_data(), std::move(audio_chunks_.front()));\r
+               audio_chunks_.pop();\r
+\r
+               boost::range::push_back(frame1->audio_data(), std::move(audio_chunks_.front()));\r
+               audio_chunks_.pop();                            \r
 \r
                frame_buffer_.push(frame1);\r
        }\r
        \r
        void interlace()\r
        {               \r
-               if(video_frames_.size() < 2 || audio_chunks_.empty())\r
+               if(video_frames_.size() < 2 || audio_chunks_.size() < 2)\r
                        return;\r
                \r
                auto frame1 = video_frames_.front();\r
                video_frames_.pop();\r
-\r
-               frame1->audio_data() = audio_chunks_.front();\r
-               audio_chunks_.pop();\r
                                \r
                auto frame2 = video_frames_.front();\r
                video_frames_.pop();\r
+               \r
+               boost::range::push_back(frame2->audio_data(), std::move(audio_chunks_.front()));\r
+               audio_chunks_.pop();\r
+\r
+               boost::range::push_back(frame2->audio_data(), std::move(audio_chunks_.front()));\r
+               audio_chunks_.pop();\r
 \r
                frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, out_mode_));            \r
        }\r
index 22eecaab4f90d2b1e8697b39e27729a50f80a14d..94e488af6c7296ddd1d8d9b3f85a20e7c1dfe365 100644 (file)
@@ -4,7 +4,7 @@
 \r
 \r
  /* File created by MIDL compiler version 7.00.0555 */\r
-/* at Wed Jul 27 12:40:52 2011\r
+/* at Wed Jul 27 22:10:40 2011\r
  */\r
 /* Compiler settings for interop\DeckLinkAPI.idl:\r
     Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
index 6bf40f36fe75f21fb32ad0ddf8c7c6fa92e8e8b4..ede7d812c3e3ee1ff712613201fbb0bdabd2ab70 100644 (file)
@@ -6,7 +6,7 @@
 \r
 \r
  /* File created by MIDL compiler version 7.00.0555 */\r
-/* at Wed Jul 27 12:40:52 2011\r
+/* at Wed Jul 27 22:10:40 2011\r
  */\r
 /* Compiler settings for interop\DeckLinkAPI.idl:\r
     Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
index de51381ca2cd2fe940e0d4086154c8b8842c8a56..d211ff16b9f4fe1a06d8c751f5d0977c8ea943ce 100644 (file)
@@ -197,17 +197,8 @@ public:
                        // It is assumed that audio is always equal or ahead of video.\r
                        if(audio && SUCCEEDED(audio->GetBytes(&bytes)))\r
                        {\r
-                               auto sample_frame_count = audio->GetSampleFrameCount();\r
                                auto audio_data = reinterpret_cast<short*>(bytes);\r
-                               audio_samples_.insert(audio_samples_.end(), audio_data, audio_data + sample_frame_count*2);\r
-\r
-                               if(audio_samples_.size() > frame_factory_->get_video_format_desc().audio_samples_per_frame)\r
-                               {\r
-                                       const auto begin = audio_samples_.begin();\r
-                                       const auto end   = begin +  frame_factory_->get_video_format_desc().audio_samples_per_frame;\r
-                                       muxer_.push(std::vector<int16_t>(begin, end));\r
-                                       audio_samples_.erase(begin, end);\r
-                               }\r
+                               muxer_.push(std::vector<int16_t>(audio_data, audio_data + audio->GetSampleFrameCount()*2));\r
                        }\r
                        else\r
                                muxer_.push(std::vector<int16_t>(frame_factory_->get_video_format_desc().audio_samples_per_frame, 0));\r
index 0092c798dfd62958b1e8b39a8f58a61d57e5d0d6..9dd7ed478dcaec104c9648ee6cf35021fc087493 100644 (file)
@@ -49,11 +49,12 @@ struct audio_decoder::implementation : boost::noncopyable
 \r
        std::vector<int8_t,  tbb::cache_aligned_allocator<int8_t>>      buffer1_;\r
        std::vector<int8_t,  tbb::cache_aligned_allocator<int8_t>>      buffer2_;\r
-       std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>>     audio_samples_; \r
        std::queue<std::shared_ptr<AVPacket>>                                           packets_;\r
+       size_t                                                                                                          sample_count_;\r
 public:\r
        explicit implementation(const std::shared_ptr<AVFormatContext>& context, const core::video_format_desc& format_desc) \r
                : format_desc_(format_desc)     \r
+               , sample_count_(0)\r
        {                          \r
                AVCodec* dec;\r
                index_ = av_find_best_stream(context.get(), AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);\r
@@ -110,27 +111,18 @@ public:
                                pkt.size = packets_.front()->size;\r
 \r
                                for(int n = 0; n < 64 && pkt.size > 0; ++n)\r
-                                       decode(pkt);\r
+                                       decode(pkt, result);\r
                        }\r
                        else\r
-                               flush();\r
+                               avcodec_flush_buffers(codec_context_.get());\r
 \r
                        packets_.pop();\r
-\r
-                       while(audio_samples_.size() > format_desc_.audio_samples_per_frame)\r
-                       {\r
-                               const auto begin = audio_samples_.begin();\r
-                               const auto end   = audio_samples_.begin() + format_desc_.audio_samples_per_frame;\r
-\r
-                               result.push_back(std::vector<int16_t>(begin, end));\r
-                               audio_samples_.erase(begin, end);\r
-                       }\r
                }\r
 \r
                return result;\r
        }\r
 \r
-       void decode(AVPacket& pkt)\r
+       void decode(AVPacket& pkt, std::vector<std::vector<int16_t>>& audio_chunks)\r
        {               \r
                buffer1_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2, 0);\r
                int written_bytes = buffer1_.size() - FF_INPUT_BUFFER_PADDING_SIZE;\r
@@ -164,18 +156,12 @@ public:
                const auto n_samples = buffer1_.size() / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);\r
                const auto samples = reinterpret_cast<int16_t*>(buffer1_.data());\r
 \r
-               audio_samples_.insert(audio_samples_.end(), samples, samples + n_samples);\r
-       }\r
+               sample_count_ = std::max(sample_count_, n_samples);\r
 \r
-       void flush()\r
-       {\r
-               auto truncate = audio_samples_.size() % format_desc_.audio_samples_per_frame;\r
-               if(truncate > 0)\r
-               {\r
-                       audio_samples_.resize(audio_samples_.size() - truncate); \r
-                       CASPAR_LOG(info) << L"Truncating " << truncate << L" audio-samples."; \r
-               }\r
-               avcodec_flush_buffers(codec_context_.get());\r
+               if(sample_count_ == 0 || n_samples == sample_count_)\r
+                       audio_chunks.push_back(std::vector<int16_t>(samples, samples + n_samples));\r
+               else\r
+                       CASPAR_LOG(warning) << L" audio_decoder: Discarding " << n_samples << L" samples.";\r
        }\r
 \r
        bool ready() const\r
index 37056a81bd42fde7d28ff772c55ec27a86d7c85d..81944871c9d1a36db0e6813b311ca92080658424 100644 (file)
@@ -130,7 +130,16 @@ public:
                        if(packet) // eof\r
                                decode(*packet, av_frames);                     \r
                        else\r
-                               flush(av_frames);\r
+                       {\r
+                               if(codec_context_->codec->capabilities | CODEC_CAP_DELAY)\r
+                               {\r
+                                       // TODO: This might cause bad performance.\r
+                                       AVPacket pkt = {0};\r
+                                       for(int n = 0; n < 8 && decode(pkt, av_frames); ++n){}\r
+                               }\r
+\r
+                               avcodec_flush_buffers(codec_context_.get());\r
+                       }\r
 \r
                        if(filter_)\r
                        {\r
@@ -154,7 +163,7 @@ public:
                return result;\r
        }\r
 \r
-       void decode(AVPacket& packet, std::vector<safe_ptr<AVFrame>>& av_frames)\r
+       bool decode(AVPacket& packet, std::vector<safe_ptr<AVFrame>>& av_frames)\r
        {\r
                std::shared_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
 \r
@@ -172,20 +181,10 @@ public:
 \r
                if(frame_finished != 0) \r
                        av_frames.push_back(make_safe(decoded_frame));\r
-       }\r
 \r
-       void flush(std::vector<safe_ptr<AVFrame>>& av_frames)\r
-       {\r
-               if(codec_context_->codec->capabilities | CODEC_CAP_DELAY)\r
-               {\r
-                       // FIXME: This might cause bad performance.\r
-                       AVPacket pkt = {0};\r
-                       decode(pkt, av_frames);\r
-               }\r
-\r
-               avcodec_flush_buffers(codec_context_.get());\r
+               return frame_finished != 0;\r
        }\r
-\r
+       \r
        bool ready() const\r
        {\r
                return !codec_context_ || !packet_buffer_.empty();\r