1 #include "../../../stdafx.h"
\r
3 #include "audio_decoder.h"
\r
5 #include "../../../../common/utility/memory.h"
\r
9 namespace caspar { namespace core { namespace ffmpeg{
\r
11 struct audio_decoder::implementation : boost::noncopyable
\r
13 implementation() : discard_bytes_(0), current_audio_chunk_offset_(0), current_chunk_(1920*2), current_chunk_data_(reinterpret_cast<char*>(current_chunk_.data()))
\r
15 audio_decomp_buffer_.resize(audio_decoder::AUDIO_DECOMP_BUFFER_SIZE);
\r
16 int alignment_offset_ = static_cast<unsigned char>(audio_decoder::ALIGNMENT - (reinterpret_cast<size_t>(&audio_decomp_buffer_.front()) % audio_decoder::ALIGNMENT));
\r
17 aligned_audio_decomp_addr_ = &audio_decomp_buffer_.front() + alignment_offset_;
\r
20 audio_packet_ptr execute(const audio_packet_ptr& audio_packet)
\r
22 int max_chunk_length = std::min(audio_packet->audio_frame_size, audio_packet->src_audio_frame_size);
\r
24 int written_bytes = audio_decoder::AUDIO_DECOMP_BUFFER_SIZE - audio_decoder::ALIGNMENT;
\r
25 int result = avcodec_decode_audio2(audio_packet->codec_context, reinterpret_cast<int16_t*>(aligned_audio_decomp_addr_), &written_bytes, audio_packet->data, audio_packet->size);
\r
28 return audio_packet;
\r
30 unsigned char* pDecomp = aligned_audio_decomp_addr_;
\r
32 //if there are bytes to discard, do that first
\r
33 while(written_bytes > 0 && discard_bytes_ != 0)
\r
35 int bytesToDiscard = std::min(written_bytes, static_cast<int>(discard_bytes_));
\r
36 pDecomp += bytesToDiscard;
\r
38 discard_bytes_ -= bytesToDiscard;
\r
39 written_bytes -= bytesToDiscard;
\r
42 while(written_bytes > 0)
\r
44 //either fill what's left of the chunk or copy all written_bytes that are left
\r
45 int targetLength = std::min((max_chunk_length - current_audio_chunk_offset_), written_bytes);
\r
46 common::copy(current_chunk_data_ + current_audio_chunk_offset_, pDecomp, targetLength);
\r
47 written_bytes -= targetLength;
\r
49 current_audio_chunk_offset_ += targetLength;
\r
50 pDecomp += targetLength;
\r
52 if(current_audio_chunk_offset_ >= max_chunk_length)
\r
54 if(max_chunk_length < static_cast<int>(audio_packet->audio_frame_size))
\r
55 common::clear(current_chunk_data_ + max_chunk_length, audio_packet->audio_frame_size-max_chunk_length);
\r
56 else if(audio_packet->audio_frame_size < audio_packet->src_audio_frame_size)
\r
57 discard_bytes_ = audio_packet->src_audio_frame_size-audio_packet->audio_frame_size;
\r
59 current_audio_chunk_offset_ = 0;
\r
60 audio_packet->audio_chunks.push_back(current_chunk_);
\r
64 return audio_packet;
\r
69 std::vector<unsigned char> audio_decomp_buffer_;
\r
70 unsigned char* aligned_audio_decomp_addr_;
\r
72 std::vector<short> current_chunk_;
\r
73 char* current_chunk_data_;
\r
74 int current_audio_chunk_offset_;
\r
77 audio_decoder::audio_decoder() : impl_(new implementation()){}
\r
78 audio_packet_ptr audio_decoder::execute(const audio_packet_ptr& audio_packet){return impl_->execute(audio_packet);}
\r