1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_bus.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_timestamp_helper.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/buffers.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/data_buffer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/limits.h" 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include FFmpeg header files. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Temporarily disable possible loss of data warning. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_PUSH_DISABLE_WARNING(4244); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libavcodec/avcodec.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_POP_WARNING(); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // extern "C" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace media { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum number of channels with defined layout in src/media. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMaxChannels = 8; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static AVCodecID CdmAudioCodecToCodecID( 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cdm::AudioDecoderConfig::AudioCodec audio_codec) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (audio_codec) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case cdm::AudioDecoderConfig::kCodecVorbis: 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return AV_CODEC_ID_VORBIS; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case cdm::AudioDecoderConfig::kCodecAac: 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return AV_CODEC_ID_AAC; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case cdm::AudioDecoderConfig::kUnknownAudioCodec: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported cdm::AudioCodec: " << audio_codec; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return AV_CODEC_ID_NONE; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CdmAudioDecoderConfigToAVCodecContext( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const cdm::AudioDecoderConfig& config, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AVCodecContext* codec_context) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->codec_type = AVMEDIA_TYPE_AUDIO; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->codec_id = CdmAudioCodecToCodecID(config.codec); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (config.bits_per_channel) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->sample_fmt = AV_SAMPLE_FMT_U8; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->sample_fmt = AV_SAMPLE_FMT_S16; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 32: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->sample_fmt = AV_SAMPLE_FMT_S32; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "CdmAudioDecoderConfigToAVCodecContext() Unsupported bits " 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "per channel: " << config.bits_per_channel; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->sample_fmt = AV_SAMPLE_FMT_NONE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->channels = config.channel_count; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->sample_rate = config.samples_per_second; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config.extra_data) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->extradata_size = config.extra_data_size; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->extradata = reinterpret_cast<uint8_t*>( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) av_malloc(config.extra_data_size + FF_INPUT_BUFFER_PADDING_SIZE)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(codec_context->extradata, config.extra_data, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.extra_data_size); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(codec_context->extradata + config.extra_data_size, '\0', 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FF_INPUT_BUFFER_PADDING_SIZE); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->extradata = NULL; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codec_context->extradata_size = 0; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static cdm::AudioFormat AVSampleFormatToCdmAudioFormat( 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AVSampleFormat sample_format) { 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (sample_format) { 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_U8: 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatU8; 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_S16: 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatS16; 901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_S32: 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatS32; 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_FLT: 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatF32; 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_S16P: 951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatPlanarS16; 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case AV_SAMPLE_FMT_FLTP: 971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kAudioFormatPlanarF32; 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DVLOG(1) << "Unknown AVSampleFormat: " << sample_format; 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kUnknownAudioFormat; 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static void CopySamples(cdm::AudioFormat cdm_format, 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int decoded_audio_size, 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const AVFrame& av_frame, 1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint8_t* output_buffer) { 1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (cdm_format) { 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatU8: 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatS16: 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatS32: 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatF32: 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(output_buffer, av_frame.data[0], decoded_audio_size); 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatPlanarS16: 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case cdm::kAudioFormatPlanarF32: { 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int decoded_size_per_channel = 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) decoded_audio_size / av_frame.channels; 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (int i = 0; i < av_frame.channels; ++i) { 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(output_buffer, 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) av_frame.extended_data[i], 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) decoded_size_per_channel); 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_buffer += decoded_size_per_channel; 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTREACHED() << "Unsupported CDM Audio Format!"; 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memset(output_buffer, 0, decoded_audio_size); 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)FFmpegCdmAudioDecoder::FFmpegCdmAudioDecoder(ClearKeyCdmHost* host) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : is_initialized_(false), 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_(host), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples_per_second_(0), 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channels_(0), 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) av_sample_format_(0), 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_per_frame_(0), 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_input_timestamp_(kNoTimestamp()), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_bytes_to_drop_(0) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FFmpegCdmAudioDecoder::~FFmpegCdmAudioDecoder() { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseFFmpegResources(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FFmpegCdmAudioDecoder::Initialize(const cdm::AudioDecoderConfig& config) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Initialize()"; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValidConfig(config)) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Initialize(): invalid audio decoder configuration."; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_initialized_) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Initialize(): Already initialized."; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize AVCodecContext structure. 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) codec_context_.reset(avcodec_alloc_context3(NULL)); 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CdmAudioDecoderConfigToAVCodecContext(config, codec_context_.get()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // MP3 decodes to S16P which we don't support, tell it to use S16 instead. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) codec_context_->request_sample_fmt = AV_SAMPLE_FMT_S16; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Could not initialize audio decoder: " 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << codec_context_->codec_id; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure avcodec_open2() respected our format request. 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Unable to configure a supported sample format: " 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << codec_context_->sample_fmt; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Success! 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) av_frame_.reset(av_frame_alloc()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples_per_second_ = config.samples_per_second; 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bytes_per_frame_ = codec_context_->channels * config.bits_per_channel / 8; 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch output_timestamp_helper_.reset( 187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch new AudioTimestampHelper(config.samples_per_second)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_initialized_ = true; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store initial values to guard against midstream configuration changes. 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channels_ = codec_context_->channels; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) av_sample_format_ = codec_context_->sample_fmt; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FFmpegCdmAudioDecoder::Deinitialize() { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Deinitialize()"; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseFFmpegResources(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_initialized_ = false; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetTimestampState(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FFmpegCdmAudioDecoder::Reset() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Reset()"; 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) avcodec_flush_buffers(codec_context_.get()); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetTimestampState(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FFmpegCdmAudioDecoder::IsValidConfig( 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const cdm::AudioDecoderConfig& config) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config.codec != cdm::AudioDecoderConfig::kUnknownAudioCodec && 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.channel_count > 0 && 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.channel_count <= kMaxChannels && 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.bits_per_channel > 0 && 217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch config.bits_per_channel <= limits::kMaxBitsPerSample && 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.samples_per_second > 0 && 219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch config.samples_per_second <= limits::kMaxSampleRate; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cdm::Status FFmpegCdmAudioDecoder::DecodeBuffer( 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8_t* compressed_buffer, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t compressed_buffer_size, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t input_timestamp, 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cdm::AudioFrames* decoded_frames) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "DecodeBuffer()"; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_end_of_stream = !compressed_buffer; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp = 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMicroseconds(input_timestamp); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_vorbis = codec_context_->codec_id == AV_CODEC_ID_VORBIS; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_end_of_stream) { 234ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (last_input_timestamp_ == kNoTimestamp()) { 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_vorbis && timestamp < base::TimeDelta()) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dropping frames for negative timestamps as outlined in section A.2 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_to_drop = floor( 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0.5 + -timestamp.InSecondsF() * samples_per_second_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_bytes_to_drop_ = bytes_per_frame_ * frames_to_drop; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_input_timestamp_ = timestamp; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (timestamp != kNoTimestamp()) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timestamp < last_input_timestamp_) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta diff = timestamp - last_input_timestamp_; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Input timestamps are not monotonically increasing! " 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " ts " << timestamp.InMicroseconds() << " us" 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " diff " << diff.InMicroseconds() << " us"; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kDecodeError; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_input_timestamp_ = timestamp; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AVPacket packet; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) av_init_packet(&packet); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet.data = const_cast<uint8_t*>(compressed_buffer); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet.size = compressed_buffer_size; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Tell the CDM what AudioFormat we're using. 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const cdm::AudioFormat cdm_format = AVSampleFormatToCdmAudioFormat( 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static_cast<AVSampleFormat>(av_sample_format_)); 2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(cdm_format, cdm::kUnknownAudioFormat); 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) decoded_frames->SetFormat(cdm_format); 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each audio packet may contain several frames, so we must call the decoder 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // until we've exhausted the packet. Regardless of the packet size we always 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to hand it to the decoder at least once, otherwise we would end up 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // skipping end of stream packets since they have a size of zero. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset frame to default values. 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) av_frame_unref(av_frame_.get()); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_decoded = 0; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = avcodec_decode_audio4( 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) codec_context_.get(), av_frame_.get(), &frame_decoded, &packet); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_end_of_stream) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "End of stream buffer produced an error! " 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "This is quite possibly a bug in the audio decoder not handling " 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "end of stream AVPackets correctly."; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Error decoding an audio frame with timestamp: " 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << timestamp.InMicroseconds() << " us, duration: " 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << timestamp.InMicroseconds() << " us, packet size: " 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << compressed_buffer_size << " bytes"; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kDecodeError; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update packet size and data pointer in case we need to call the decoder 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the remaining bytes from this packet. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet.size -= result; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet.data += result; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !is_end_of_stream) { 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(timestamp != kNoTimestamp()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output_bytes_to_drop_ > 0) { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Currently Vorbis is the only codec that causes us to drop samples. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have to drop samples it always means the timeline starts at 0. 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(codec_context_->codec_id, AV_CODEC_ID_VORBIS); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_timestamp_helper_->SetBaseTimestamp(timestamp); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int decoded_audio_size = 0; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame_decoded) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (av_frame_->sample_rate != samples_per_second_ || 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) av_frame_->channels != channels_ || 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) av_frame_->format != av_sample_format_) { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Unsupported midstream configuration change!" 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " Sample Rate: " << av_frame_->sample_rate << " vs " 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << samples_per_second_ 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", Channels: " << av_frame_->channels << " vs " 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << channels_ 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", Sample Format: " << av_frame_->format << " vs " 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << av_sample_format_; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kDecodeError; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoded_audio_size = av_samples_get_buffer_size( 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, codec_context_->channels, av_frame_->nb_samples, 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) codec_context_->sample_fmt, 1); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoded_audio_size > 0 && output_bytes_to_drop_ > 0) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(decoded_audio_size % bytes_per_frame_, 0) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Decoder didn't output full frames"; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dropped_size = std::min(decoded_audio_size, output_bytes_to_drop_); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_audio_size -= dropped_size; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_bytes_to_drop_ -= dropped_size; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoded_audio_size > 0) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(decoded_audio_size % bytes_per_frame_, 0) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Decoder didn't output full frames"; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::TimeDelta output_timestamp = 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_timestamp_helper_->GetTimestamp(); 3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_timestamp_helper_->AddFrames(decoded_audio_size / 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bytes_per_frame_); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If we've exhausted the packet in the first decode we can write directly 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // into the frame buffer instead of a multistep serialization approach. 3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (serialized_audio_frames_.empty() && !packet.size) { 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const uint32_t buffer_size = decoded_audio_size + sizeof(int64) * 2; 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) decoded_frames->SetFrameBuffer(host_->Allocate(buffer_size)); 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!decoded_frames->FrameBuffer()) { 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(ERROR) << "DecodeBuffer() ClearKeyCdmHost::Allocate failed."; 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kDecodeError; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) decoded_frames->FrameBuffer()->SetSize(buffer_size); 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint8_t* output_buffer = decoded_frames->FrameBuffer()->Data(); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int64 timestamp = output_timestamp.InMicroseconds(); 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(output_buffer, ×tamp, sizeof(timestamp)); 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_buffer += sizeof(timestamp); 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int64 output_size = decoded_audio_size; 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(output_buffer, &output_size, sizeof(output_size)); 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_buffer += sizeof(output_size); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Copy the samples and return success. 3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CopySamples( 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cdm_format, decoded_audio_size, *av_frame_, output_buffer); 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cdm::kSuccess; 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // There are still more frames to decode, so we need to serialize them in 3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // a secondary buffer since we don't know their sizes ahead of time (which 3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // is required to allocate the FrameBuffer object). 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializeInt64(output_timestamp.InMicroseconds()); 3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SerializeInt64(decoded_audio_size); 3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const size_t previous_size = serialized_audio_frames_.size(); 3841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) serialized_audio_frames_.resize(previous_size + decoded_audio_size); 3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint8_t* output_buffer = &serialized_audio_frames_[0] + previous_size; 3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CopySamples( 3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cdm_format, decoded_audio_size, *av_frame_, output_buffer); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (packet.size > 0); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!serialized_audio_frames_.empty()) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoded_frames->SetFrameBuffer( 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_->Allocate(serialized_audio_frames_.size())); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!decoded_frames->FrameBuffer()) { 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG(ERROR) << "DecodeBuffer() ClearKeyCdmHost::Allocate failed."; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kDecodeError; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(decoded_frames->FrameBuffer()->Data(), 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &serialized_audio_frames_[0], 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serialized_audio_frames_.size()); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoded_frames->FrameBuffer()->SetSize(serialized_audio_frames_.size()); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serialized_audio_frames_.clear(); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kSuccess; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cdm::kNeedMoreData; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FFmpegCdmAudioDecoder::ResetTimestampState() { 411ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); 412ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_input_timestamp_ = kNoTimestamp(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_bytes_to_drop_ = 0; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FFmpegCdmAudioDecoder::ReleaseFFmpegResources() { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "ReleaseFFmpegResources()"; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) codec_context_.reset(); 42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) av_frame_.reset(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FFmpegCdmAudioDecoder::SerializeInt64(int64 value) { 4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const size_t previous_size = serialized_audio_frames_.size(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serialized_audio_frames_.resize(previous_size + sizeof(value)); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&serialized_audio_frames_[0] + previous_size, &value, sizeof(value)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 429ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace media 430