]> 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>
Fri, 29 Jul 2011 07:03:19 +0000 (07:03 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 29 Jul 2011 07:03:19 +0000 (07:03 +0000)
core/mixer/audio/audio_mixer.cpp
core/producer/frame_muxer.cpp
modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/producer/audio/audio_decoder.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index b93fef4873cef08f581162e9240ce43097402d2f..b9e9b0b59224807723a9dd1671a9ab11ad72fe79 100644 (file)
@@ -77,12 +77,10 @@ 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 != 0 && in_size != audio_data_.back().size())\r
-               {       \r
-                       CASPAR_LOG(warning) << L" audio_mixer[] : Invalid sample count detected. Discarding audio chunk.";\r
+               if(in_size > audio_data_.back().size())\r
                        return;\r
-               }\r
 \r
                tbb::parallel_for\r
                (\r
index 10ed364b923ef7f2d1bffd620807047a47545686..f2d1061a74dc62e54b228c2560545f8421ea8840 100644 (file)
@@ -7,8 +7,6 @@
 #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
@@ -172,10 +170,10 @@ struct frame_muxer::implementation
                if(video_frames_.empty() || audio_chunks_.empty())\r
                        return;\r
 \r
-               auto frame1 = std::move(video_frames_.front());\r
+               auto frame1 = video_frames_.front();\r
                video_frames_.pop();\r
 \r
-               frame1->audio_data() = std::move(audio_chunks_.front());\r
+               frame1->audio_data() = audio_chunks_.front();\r
                audio_chunks_.pop();\r
 \r
                frame_buffer_.push(frame1);\r
@@ -183,20 +181,19 @@ struct frame_muxer::implementation
 \r
        void duplicate()\r
        {               \r
-               if(video_frames_.empty() || audio_chunks_.empty())\r
+               if(video_frames_.empty() || audio_chunks_.size() < 2)\r
                        return;\r
 \r
-               auto frame = std::move(video_frames_.front());\r
+               auto frame = video_frames_.front();\r
                video_frames_.pop();\r
 \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
+               frame1->audio_data() = audio_chunks_.front();\r
+               audio_chunks_.pop();\r
 \r
                auto frame2 = frame;\r
-               frame1->audio_data().insert(frame1->audio_data().end(), audio_chunk.begin() + audio_chunk.size()/2, audio_chunk.end());\r
+               frame2->audio_data() = audio_chunks_.front();\r
+               audio_chunks_.pop();\r
 \r
                frame_buffer_.push(frame1);\r
                frame_buffer_.push(frame2);\r
@@ -204,39 +201,32 @@ struct frame_muxer::implementation
 \r
        void half()\r
        {       \r
-               if(video_frames_.size() < 2 || audio_chunks_.size() < 2)\r
+               if(video_frames_.size() < 2 || audio_chunks_.empty())\r
                        return;\r
                                                \r
-               auto frame1 = std::move(video_frames_.front());\r
+               auto frame1 = video_frames_.front();\r
                video_frames_.pop();\r
-\r
-               video_frames_.pop(); // Throw away\r
-               \r
-               boost::range::push_back(frame1->audio_data(), std::move(audio_chunks_.front()));\r
+               frame1->audio_data() = 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
+               video_frames_.pop(); // Throw away\r
 \r
                frame_buffer_.push(frame1);\r
        }\r
        \r
        void interlace()\r
        {               \r
-               if(video_frames_.size() < 2 || audio_chunks_.size() < 2)\r
+               if(video_frames_.size() < 2 || audio_chunks_.empty())\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 d211ff16b9f4fe1a06d8c751f5d0977c8ea943ce..de51381ca2cd2fe940e0d4086154c8b8842c8a56 100644 (file)
@@ -197,8 +197,17 @@ 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
-                               muxer_.push(std::vector<int16_t>(audio_data, audio_data + audio->GetSampleFrameCount()*2));\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
                        }\r
                        else\r
                                muxer_.push(std::vector<int16_t>(frame_factory_->get_video_format_desc().audio_samples_per_frame, 0));\r
index 9dd7ed478dcaec104c9648ee6cf35021fc087493..0dbbe4aa2c6aee32cbc32bd61a7d69e6877cdfd9 100644 (file)
@@ -49,16 +49,18 @@ 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
 \r
+               if(index_ < 0)\r
+                       return;\r
+\r
                int errn = avcodec_open(context->streams[index_]->codec, dec);\r
                if(errn < 0)\r
                        return;\r
@@ -111,18 +113,27 @@ public:
                                pkt.size = packets_.front()->size;\r
 \r
                                for(int n = 0; n < 64 && pkt.size > 0; ++n)\r
-                                       decode(pkt, result);\r
+                                       decode(pkt);\r
                        }\r
                        else\r
-                               avcodec_flush_buffers(codec_context_.get());\r
+                               flush();\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, std::vector<std::vector<int16_t>>& audio_chunks)\r
+       void decode(AVPacket& pkt)\r
        {               \r
                buffer1_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2, 0);\r
                int written_bytes = buffer1_.size() - FF_INPUT_BUFFER_PADDING_SIZE;\r
@@ -156,12 +167,18 @@ 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
-               sample_count_ = std::max(sample_count_, n_samples);\r
+               audio_samples_.insert(audio_samples_.end(), samples, samples + n_samples);\r
+       }\r
 \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
+       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
        }\r
 \r
        bool ready() const\r
index 81944871c9d1a36db0e6813b311ca92080658424..37056a81bd42fde7d28ff772c55ec27a86d7c85d 100644 (file)
@@ -130,16 +130,7 @@ public:
                        if(packet) // eof\r
                                decode(*packet, av_frames);                     \r
                        else\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
+                               flush(av_frames);\r
 \r
                        if(filter_)\r
                        {\r
@@ -163,7 +154,7 @@ public:
                return result;\r
        }\r
 \r
-       bool decode(AVPacket& packet, std::vector<safe_ptr<AVFrame>>& av_frames)\r
+       void 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
@@ -181,10 +172,20 @@ public:
 \r
                if(frame_finished != 0) \r
                        av_frames.push_back(make_safe(decoded_frame));\r
+       }\r
 \r
-               return frame_finished != 0;\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
        }\r
-       \r
+\r
        bool ready() const\r
        {\r
                return !codec_context_ || !packet_buffer_.empty();\r