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, &timestamp, 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