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