* Author: Robert Nagy, ronag89@gmail.com
*/
-#include "../../stdafx.h"
+#include "../../StdAfx.h"
#include "audio_decoder.h"
#pragma warning (push)
#pragma warning (disable : 4244)
#endif
-extern "C"
+extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#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_;
};
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)
auto audio = decode(*packet);
- if(packet->size == 0)
+ if(packet->size == 0)
packets_.pop();
return audio;
}
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();}
}}