]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/producer/audio/audio_decoder.cpp
[ffmpeg] Reimplemented support for playing all audio streams in a clip and treating...
[casparcg] / modules / ffmpeg / producer / audio / audio_decoder.cpp
index fe69a59cf6aa459f8667ebaf2bdf0864d99bb00e..0a1008876583afed71cbc24252315e4d5a3e6a48 100644 (file)
@@ -37,7 +37,7 @@
 #pragma warning (push)
 #pragma warning (disable : 4244)
 #endif
-extern "C" 
+extern "C"
 {
        #include <libavformat/avformat.h>
        #include <libavcodec/avcodec.h>
@@ -48,13 +48,13 @@ extern "C"
 #endif
 
 namespace caspar { namespace ffmpeg {
-       
+
 struct audio_decoder::implementation : boost::noncopyable
-{      
-       int                                                                             index_                          = -1;
+{
+       int                                                                             index_;
        const spl::shared_ptr<AVCodecContext>   codec_context_;
        const int                                                               out_samplerate_;
-       
+
        cache_aligned_vector<int32_t>                   buffer_;
 
        std::queue<spl::shared_ptr<AVPacket>>   packets_;
@@ -81,33 +81,34 @@ struct audio_decoder::implementation : boost::noncopyable
                                                                                                                                };
 
 public:
-       explicit implementation(const spl::shared_ptr<AVFormatContext>& context, int out_samplerate)
-               : codec_context_(open_codec(*context, AVMEDIA_TYPE_AUDIO, index_, false))
+       explicit implementation(int stream_index, const spl::shared_ptr<AVFormatContext>& context, int out_samplerate)
+               : index_(stream_index)
+               , codec_context_(open_codec(*context, AVMEDIA_TYPE_AUDIO, index_, false))
                , out_samplerate_(out_samplerate)
                , buffer_(10 * out_samplerate_ * codec_context_->channels) // 10 seconds of audio
-       {       
+       {
                if(!swr_)
-                       BOOST_THROW_EXCEPTION(bad_alloc());
-               
+                       CASPAR_THROW_EXCEPTION(bad_alloc());
+
                THROW_ON_ERROR2(swr_init(swr_.get()), "[audio_decoder]");
 
                codec_context_->refcounted_frames = 1;
        }
 
        void push(const std::shared_ptr<AVPacket>& packet)
-       {                       
+       {
                if(!packet)
                        return;
 
                if(packet->stream_index == index_ || packet->data == nullptr)
                        packets_.push(spl::make_shared_ptr(packet));
-       }       
-       
+       }
+
        std::shared_ptr<core::mutable_audio_buffer> poll()
        {
                if(packets_.empty())
                        return nullptr;
-                               
+
                auto packet = packets_.front();
 
                if(packet->data == nullptr)
@@ -119,7 +120,7 @@ public:
 
                auto audio = decode(*packet);
 
-               if(packet->size == 0)                                   
+               if(packet->size == 0)
                        packets_.pop();
 
                return audio;
@@ -165,17 +166,25 @@ public:
        }
 
        std::wstring print() const
-       {               
+       {
                return L"[audio-decoder] " + u16(codec_context_->codec->long_name);
        }
+
+       uint64_t ffmpeg_channel_layout() const
+       {
+               if (codec_context_->channel_layout == 0)
+                       return av_get_default_channel_layout(codec_context_->channels);
+               else
+                       return codec_context_->channel_layout;
+       }
 };
 
-audio_decoder::audio_decoder(const spl::shared_ptr<AVFormatContext>& context, int out_samplerate) : impl_(new implementation(context, out_samplerate)){}
+audio_decoder::audio_decoder(int stream_index, const spl::shared_ptr<AVFormatContext>& context, int out_samplerate) : impl_(new implementation(stream_index, context, out_samplerate)){}
 void audio_decoder::push(const std::shared_ptr<AVPacket>& packet){impl_->push(packet);}
 bool audio_decoder::ready() const{return impl_->ready();}
 std::shared_ptr<core::mutable_audio_buffer> audio_decoder::poll() { return impl_->poll(); }
 int    audio_decoder::num_channels() const { return impl_->codec_context_->channels; }
-uint64_t audio_decoder::ffmpeg_channel_layout() const { return impl_->codec_context_->channel_layout; }
+uint64_t audio_decoder::ffmpeg_channel_layout() const { return impl_->ffmpeg_channel_layout(); }
 std::wstring audio_decoder::print() const{return impl_->print();}
 
 }}