]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: ffmpeg-producer: Fixed audio-resampling.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Jul 2011 08:20:18 +0000 (08:20 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Jul 2011 08:20:18 +0000 (08:20 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@998 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/ffmpeg/producer/audio/audio_decoder.cpp

index fee090509ae1f51ab9219c014bfdc71a6bf12bac..9c1bfc818302a8d7f2da66622296164693189e41 100644 (file)
@@ -45,11 +45,12 @@ struct audio_decoder::implementation : boost::noncopyable
        std::shared_ptr<AVCodecContext>                                                         codec_context_;         \r
        const core::video_format_desc                                                           format_desc_;\r
        int                                                                                                                     index_;\r
-       std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>       buffer1_;               // avcodec_decode_audio3 needs 4 byte alignment\r
-       std::vector<int8_t, tbb::cache_aligned_allocator<int8_t>>       buffer2_;               // avcodec_decode_audio3 needs 4 byte alignment\r
-       std::vector<int16_t, tbb::cache_aligned_allocator<int16_t>>     audio_samples_;         // avcodec_decode_audio3 needs 4 byte alignment\r
-       std::queue<std::shared_ptr<AVPacket>>                                           packets_;\r
        std::shared_ptr<ReSampleContext>                                                        resampler_;\r
+\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
 public:\r
        explicit implementation(const std::shared_ptr<AVFormatContext>& context, const core::video_format_desc& format_desc) \r
                : format_desc_(format_desc)     \r
@@ -101,8 +102,7 @@ public:
                        result.push_back(std::vector<int16_t>(format_desc_.audio_samples_per_frame, 0));\r
                else if(!packets_.empty())\r
                {\r
-                       decode(packets_.front());\r
-                       packets_.pop();\r
+                       decode();\r
 \r
                        while(audio_samples_.size() > format_desc_.audio_samples_per_frame)\r
                        {\r
@@ -117,10 +117,15 @@ public:
                return result;\r
        }\r
 \r
-       void decode(const std::shared_ptr<AVPacket>& packet)\r
-       {                                                                                       \r
-               if(!packet) // eof\r
+       void decode()\r
+       {                       \r
+               if(packets_.empty())\r
+                       return;\r
+\r
+               if(!packets_.front()) // eof\r
                {\r
+                       packets_.pop();\r
+\r
                        auto truncate = audio_samples_.size() % format_desc_.audio_samples_per_frame;\r
                        if(truncate > 0)\r
                        {\r
@@ -133,16 +138,22 @@ public:
                {\r
                        buffer1_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2, 0);\r
                        int written_bytes = buffer1_.size() - FF_INPUT_BUFFER_PADDING_SIZE;\r
-                       // TODO: Packet might contain multiple frames\r
-                       const int errn = avcodec_decode_audio3(codec_context_.get(), reinterpret_cast<int16_t*>(buffer1_.data()), &written_bytes, packet.get());\r
-                       if(errn < 0)\r
+\r
+                       const int ret = avcodec_decode_audio3(codec_context_.get(), reinterpret_cast<int16_t*>(buffer1_.data()), &written_bytes, packets_.front().get());\r
+                       if(ret < 0)\r
                        {       \r
                                BOOST_THROW_EXCEPTION(\r
                                        invalid_operation() <<\r
                                        boost::errinfo_api_function("avcodec_decode_audio2") <<\r
-                                       boost::errinfo_errno(AVUNERROR(errn)));\r
+                                       boost::errinfo_errno(AVUNERROR(ret)));\r
                        }\r
 \r
+                       packets_.front()->size -= ret;\r
+                       packets_.front()->data += ret;\r
+\r
+                       if(packets_.front()->size <= 0)\r
+                               packets_.pop();\r
+\r
                        buffer1_.resize(written_bytes);\r
 \r
                        if(resampler_)\r
@@ -151,8 +162,8 @@ public:
                                auto ret = audio_resample(resampler_.get(),\r
                                                                                  reinterpret_cast<short*>(buffer2_.data()), \r
                                                                                  reinterpret_cast<short*>(buffer1_.data()), \r
-                                                                                 buffer1_.size() / av_get_bytes_per_sample(codec_context_->sample_fmt)); \r
-                               buffer2_.resize(ret);\r
+                                                                                 buffer1_.size() / (av_get_bytes_per_sample(codec_context_->sample_fmt) * codec_context_->channels)); \r
+                               buffer2_.resize(ret * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * format_desc_.audio_channels);\r
                                std::swap(buffer1_, buffer2_);\r
                        }\r
 \r