]> git.sesse.net Git - casparcg/blob - core/producer/ffmpeg/audio/audio_decoder.cpp
2.0.0.2:
[casparcg] / core / producer / ffmpeg / audio / audio_decoder.cpp
1 #include "../../../stdafx.h"\r
2 \r
3 #include "audio_decoder.h"\r
4 \r
5 #include "../../../../common/utility/memory.h"\r
6 \r
7 #include <queue>\r
8                 \r
9 namespace caspar{ namespace ffmpeg{\r
10 \r
11 struct audio_decoder::implementation : boost::noncopyable\r
12 {\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
14         {\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
18         }\r
19                 \r
20         audio_packet_ptr execute(const audio_packet_ptr& audio_packet)\r
21         {                       \r
22                 int max_chunk_length = std::min(audio_packet->audio_frame_size, audio_packet->src_audio_frame_size);\r
23 \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
26 \r
27                 if(result <= 0)\r
28                         return audio_packet;\r
29 \r
30                 unsigned char* pDecomp = aligned_audio_decomp_addr_;\r
31 \r
32                 //if there are bytes to discard, do that first\r
33                 while(written_bytes > 0 && discard_bytes_ != 0)\r
34                 {\r
35                         int bytesToDiscard = std::min(written_bytes, static_cast<int>(discard_bytes_));\r
36                         pDecomp += bytesToDiscard;\r
37 \r
38                         discard_bytes_ -= bytesToDiscard;\r
39                         written_bytes -= bytesToDiscard;\r
40                 }\r
41 \r
42                 while(written_bytes > 0)\r
43                 {\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
48 \r
49                         current_audio_chunk_offset_ += targetLength;\r
50                         pDecomp += targetLength;\r
51 \r
52                         if(current_audio_chunk_offset_ >= max_chunk_length) \r
53                         {\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
58                                 \r
59                                 current_audio_chunk_offset_ = 0;\r
60                                 audio_packet->audio_chunks.push_back(current_chunk_);\r
61                         }\r
62                 }\r
63 \r
64                 return audio_packet;\r
65         }\r
66                         \r
67         int                                                                     discard_bytes_;\r
68                 \r
69         std::vector<unsigned char>                      audio_decomp_buffer_;\r
70         unsigned char*                                          aligned_audio_decomp_addr_;\r
71         \r
72         std::vector<short>                                      current_chunk_;\r
73         char*                                                           current_chunk_data_;\r
74         int                                                                     current_audio_chunk_offset_;\r
75 };\r
76 \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
79 }}