15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decoder_buffer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/video_frame.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// padded. Check here to ensure FFmpeg only receives data padded to its
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifications.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               decoder_buffer_padding_size_does_not_fit_ffmpeg_requirement);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Alignment requirement by FFmpeg for input and output buffers. This need to
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be updated to match FFmpeg when it changes.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ARCH_CPU_ARM_FAMILY)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kFFmpegBufferAddressAlignment = 16;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kFFmpegBufferAddressAlignment = 32;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check here to ensure FFmpeg only receives data aligned to its specifications.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decoder_buffer_alignment_size_does_not_fit_ffmpeg_requirement);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See video_get_buffer() in libavcodec/utils.c.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kFFmpegOutputBufferPaddingSize = 16;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               video_frame_padding_size_does_not_fit_ffmpeg_requirement);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    video_frame_address_alignment_does_not_fit_ffmpeg_requirement);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta ConvertFromTimeBase(const AVRational& time_base,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 timestamp) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 microseconds = av_rescale_q(timestamp, time_base, kMicrosBase);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::TimeDelta::FromMicroseconds(microseconds);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 ConvertToTimeBase(const AVRational& time_base,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const base::TimeDelta& timestamp) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Converts an FFmpeg audio codec ID into its corresponding supported codec id.
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)static AudioCodec CodecIDToAudioCodec(AVCodecID codec_id) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (codec_id) {
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_AAC:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecAAC;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_MP3:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecMP3;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_VORBIS:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecVorbis;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_U8:
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_S16LE:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_S24LE:
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_F32LE:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecPCM;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_S16BE:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecPCM_S16BE;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_S24BE:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecPCM_S24BE;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_FLAC:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecFLAC;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_AMR_NB:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecAMR_NB;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_AMR_WB:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecAMR_WB;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_GSM_MS:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecGSM_MS;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_PCM_MULAW:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecPCM_MULAW;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_OPUS:
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kCodecOpus;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown audio CodecID: " << codec_id;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kUnknownAudioCodec;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static AVCodecID AudioCodecToCodecID(AudioCodec audio_codec,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     SampleFormat sample_format) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (audio_codec) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecAAC:
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_AAC;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecMP3:
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_MP3;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecPCM:
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      switch (sample_format) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case kSampleFormatU8:
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return AV_CODEC_ID_PCM_U8;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case kSampleFormatS16:
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return AV_CODEC_ID_PCM_S16LE;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case kSampleFormatS32:
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return AV_CODEC_ID_PCM_S24LE;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case kSampleFormatF32:
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return AV_CODEC_ID_PCM_F32LE;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          DVLOG(1) << "Unsupported sample format: " << sample_format;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecPCM_S16BE:
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_PCM_S16BE;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecPCM_S24BE:
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_PCM_S24BE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecVorbis:
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_VORBIS;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecFLAC:
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_FLAC;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecAMR_NB:
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_AMR_NB;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecAMR_WB:
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_AMR_WB;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecGSM_MS:
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_GSM_MS;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecPCM_MULAW:
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_PCM_MULAW;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kCodecOpus:
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_OPUS;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown AudioCodec: " << audio_codec;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return AV_CODEC_ID_NONE;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Converts an FFmpeg video codec ID into its corresponding supported codec id.
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)static VideoCodec CodecIDToVideoCodec(AVCodecID codec_id) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (codec_id) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_H264:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecH264;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_THEORA:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecTheora;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_MPEG4:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecMPEG4;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case AV_CODEC_ID_VP8:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kCodecVP8;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_CODEC_ID_VP9:
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kCodecVP9;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown video CodecID: " << codec_id;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kUnknownVideoCodec;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static AVCodecID VideoCodecToCodecID(VideoCodec video_codec) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (video_codec) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecH264:
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_H264;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecTheora:
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_THEORA;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecMPEG4:
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_MPEG4;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCodecVP8:
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return AV_CODEC_ID_VP8;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kCodecVP9:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_CODEC_ID_VP9;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown VideoCodec: " << video_codec;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return AV_CODEC_ID_NONE;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static VideoCodecProfile ProfileIDToVideoCodecProfile(int profile) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear out the CONSTRAINED & INTRA flags which are strict subsets of the
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // corresponding profiles with which they're used.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile &= ~FF_PROFILE_H264_CONSTRAINED;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile &= ~FF_PROFILE_H264_INTRA;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (profile) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_BASELINE:
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_BASELINE;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_MAIN:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_MAIN;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_EXTENDED:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_EXTENDED;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_HIGH:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_HIGH;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_HIGH_10:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_HIGH10PROFILE;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_HIGH_422:
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_HIGH422PROFILE;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return H264PROFILE_HIGH444PREDICTIVEPROFILE;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown profile id: " << profile;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VIDEO_CODEC_PROFILE_UNKNOWN;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (profile) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_BASELINE:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_BASELINE;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_MAIN:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_MAIN;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_EXTENDED:
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_EXTENDED;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_HIGH:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_HIGH;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_HIGH10PROFILE:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_HIGH_10;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_HIGH422PROFILE:
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_HIGH_422;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case H264PROFILE_HIGH444PREDICTIVEPROFILE:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unknown VideoCodecProfile: " << profile;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FF_PROFILE_UNKNOWN;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format) {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (sample_format) {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_U8:
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatU8;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_S16:
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatS16;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_S32:
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatS32;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_FLT:
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatF32;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_S16P:
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatPlanarS16;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case AV_SAMPLE_FMT_FLTP:
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return kSampleFormatPlanarF32;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << "Unknown AVSampleFormat: " << sample_format;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kUnknownSampleFormat;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (sample_format) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatU8:
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_U8;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatS16:
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_S16;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatS32:
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_S32;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatF32:
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_FLT;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatPlanarS16:
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_S16P;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kSampleFormatPlanarF32:
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return AV_SAMPLE_FMT_FLTP;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << "Unknown SampleFormat: " << sample_format;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AV_SAMPLE_FMT_NONE;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void AVCodecContextToAudioDecoderConfig(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AVCodecContext* codec_context,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_encrypted,
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    AudioDecoderConfig* config,
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bool record_stats) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SampleFormat sample_format =
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AVSampleFormatToSampleFormat(codec_context->sample_fmt);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      codec_context->channel_layout, codec_context->channels);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (codec == kCodecOpus) {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |codec_context->sample_fmt| is not set by FFmpeg because Opus decoding is
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // not enabled in FFmpeg, so we need to manually set the sample format.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sample_format = kSampleFormatS16;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config->Initialize(codec,
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     sample_format,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     channel_layout,
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     codec_context->sample_rate,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     codec_context->extradata,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     codec_context->extradata_size,
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     is_encrypted,
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                     record_stats);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (codec != kCodecOpus) {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              config->bits_per_channel());
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AVStreamToAudioDecoderConfig(
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AVStream* stream,
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    AudioDecoderConfig* config,
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bool record_stats) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_encrypted = false;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (key)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_encrypted = true;
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return AVCodecContextToAudioDecoderConfig(
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      stream->codec, is_encrypted, config, record_stats);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        AVCodecContext* codec_context) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->codec_id = AudioCodecToCodecID(config.codec(),
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                config.sample_format());
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  codec_context->sample_fmt = SampleFormatToAVSampleFormat(
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      config.sample_format());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // said information to decode.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->channels =
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChannelLayoutToChannelCount(config.channel_layout());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->sample_rate = config.samples_per_second();
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (config.extra_data()) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata_size = config.extra_data_size();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata = reinterpret_cast<uint8_t*>(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(codec_context->extradata, config.extra_data(),
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           config.extra_data_size());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(codec_context->extradata + config.extra_data_size(), '\0',
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           FF_INPUT_BUFFER_PADDING_SIZE);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata = NULL;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata_size = 0;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AVStreamToVideoDecoderConfig(
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AVStream* stream,
343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    VideoDecoderConfig* config,
344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bool record_stats) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size coded_size(stream->codec->coded_width, stream->codec->coded_height);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for now, but may not always be true forever. Fix this in the future.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect visible_rect(stream->codec->width, stream->codec->height);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AVRational aspect_ratio = { 1, 1 };
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream->sample_aspect_ratio.num)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aspect_ratio = stream->sample_aspect_ratio;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (stream->codec->sample_aspect_ratio.num)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aspect_ratio = stream->codec->sample_aspect_ratio;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VideoCodec codec = CodecIDToVideoCodec(stream->codec->codec_id);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (codec == kCodecVP8)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile = VP8PROFILE_MAIN;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (codec == kCodecVP9)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile = VP9PROFILE_MAIN;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile = ProfileIDToVideoCodecProfile(stream->codec->profile);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size natural_size = GetNaturalSize(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      visible_rect.size(), aspect_ratio.num, aspect_ratio.den);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VideoFrame::Format format = PixelFormatToVideoFormat(stream->codec->pix_fmt);
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (codec == kCodecVP9) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(tomfinegan): libavcodec doesn't know about VP9.
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    format = VideoFrame::YV12;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    coded_size = natural_size;
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_encrypted = false;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (key)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_encrypted = true;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AVDictionaryEntry* webm_alpha =
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      av_dict_get(stream->metadata, "alpha_mode", NULL, 0);
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (webm_alpha && !strcmp(webm_alpha->value, "1")) {
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    format = VideoFrame::YV12A;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config->Initialize(codec,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     profile,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     format,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     coded_size, visible_rect, natural_size,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     stream->codec->extradata, stream->codec->extradata_size,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     is_encrypted,
394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                     record_stats);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VideoDecoderConfigToAVCodecContext(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const VideoDecoderConfig& config,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AVCodecContext* codec_context) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->codec_id = VideoCodecToCodecID(config.codec());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->profile = VideoCodecProfileToProfileID(config.profile());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->coded_width = config.coded_size().width();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->coded_height = config.coded_size().height();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codec_context->pix_fmt = VideoFormatToPixelFormat(config.format());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (config.extra_data()) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata_size = config.extra_data_size();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata = reinterpret_cast<uint8_t*>(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(codec_context->extradata, config.extra_data(),
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           config.extra_data_size());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(codec_context->extradata + config.extra_data_size(), '\0',
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           FF_INPUT_BUFFER_PADDING_SIZE);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata = NULL;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    codec_context->extradata_size = 0;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (layout) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_MONO:
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_MONO;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_STEREO:
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_STEREO;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_2_1:
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_2_1;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_SURROUND:
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_SURROUND;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_4POINT0:
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_4_0;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_2_2:
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_2_2;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_QUAD:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_QUAD;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_5POINT0:
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_5_0;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_5POINT1:
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_5_1;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_5POINT0_BACK:
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_5_0_BACK;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_5POINT1_BACK:
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_5_1_BACK;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_7POINT0:
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_7_0;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_7POINT1:
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_7_1;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_7POINT1_WIDE:
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_7_1_WIDE;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_STEREO_DOWNMIX:
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_STEREO_DOWNMIX;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_2POINT1:
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_2POINT1;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_3POINT1:
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_3_1;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_4POINT1:
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_4_1;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_6POINT0:
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_6_0;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_6POINT0_FRONT:
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_6_0_FRONT;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_HEXAGONAL:
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_HEXAGONAL;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_6POINT1:
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_6_1;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_6POINT1_BACK:
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_6_1_BACK;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_6POINT1_FRONT:
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_6_1_FRONT;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_7POINT0_FRONT:
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_7_0_FRONT;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_7_1_WIDE_BACK;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AV_CH_LAYOUT_OCTAGONAL:
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return CHANNEL_LAYOUT_OCTAGONAL;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // FFmpeg channel_layout is 0 for .wav and .mp3.  Attempt to guess layout
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // based on the channel count.
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GuessChannelLayout(channels);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoFrame::Format PixelFormatToVideoFormat(PixelFormat pixel_format) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (pixel_format) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PIX_FMT_YUV422P:
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return VideoFrame::YV16;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(scherkus): We should be paying attention to the color range of each
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // format and scaling as appropriate when rendering. Regular YUV has a range
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // of 16-239 where as YUVJ has a range of 0-255.
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PIX_FMT_YUV420P:
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case PIX_FMT_YUVJ420P:
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return VideoFrame::YV12;
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case PIX_FMT_YUVA420P:
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return VideoFrame::YV12A;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unsupported PixelFormat: " << pixel_format;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VideoFrame::INVALID;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PixelFormat VideoFormatToPixelFormat(VideoFrame::Format video_format) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (video_format) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case VideoFrame::YV16:
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PIX_FMT_YUV422P;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case VideoFrame::YV12:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PIX_FMT_YUV420P;
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case VideoFrame::YV12A:
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return PIX_FMT_YUVA420P;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Unsupported VideoFrame::Format: " << video_format;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PIX_FMT_NONE;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
519