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
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
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
{\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
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