1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/ffmpeg/ffmpeg_common.h"
7 #include "base/hash/sha1.h"
8 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "build/build_config.h"
13 #include "media/base/audio_decoder_config.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/encryption_scheme.h"
16 #include "media/base/media_util.h"
17 #include "media/base/video_aspect_ratio.h"
18 #include "media/base/video_decoder_config.h"
19 #include "media/base/video_util.h"
20 #include "media/formats/mp4/box_definitions.h"
21 #include "media/media_buildflags.h"
23 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
24 #include "media/formats/mp4/aac.h"
25 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
26 #include "media/formats/mp4/hevc.h"
34 EncryptionScheme GetEncryptionScheme(const AVStream* stream) {
35 AVDictionaryEntry* key =
36 av_dict_get(stream->metadata, "enc_key_id", nullptr, 0);
37 return key ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted;
40 VideoDecoderConfig::AlphaMode GetAlphaMode(const AVStream* stream) {
41 AVDictionaryEntry* alpha_mode =
42 av_dict_get(stream->metadata, "alpha_mode", nullptr, 0);
43 return alpha_mode && !strcmp(alpha_mode->value, "1")
44 ? VideoDecoderConfig::AlphaMode::kHasAlpha
45 : VideoDecoderConfig::AlphaMode::kIsOpaque;
50 // Why AV_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
51 // padded. Check here to ensure FFmpeg only receives data padded to its
53 static_assert(DecoderBuffer::kPaddingSize >= AV_INPUT_BUFFER_PADDING_SIZE,
54 "DecoderBuffer padding size does not fit ffmpeg requirement");
56 // Alignment requirement by FFmpeg for input and output buffers. This need to
57 // be updated to match FFmpeg when it changes.
58 #if defined(ARCH_CPU_ARM_FAMILY)
59 static const int kFFmpegBufferAddressAlignment = 16;
61 static const int kFFmpegBufferAddressAlignment = 32;
64 // Check here to ensure FFmpeg only receives data aligned to its specifications.
66 DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
67 DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
68 "DecoderBuffer alignment size does not fit ffmpeg requirement");
70 // Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
71 // See video_get_buffer() in libavcodec/utils.c.
72 static const int kFFmpegOutputBufferPaddingSize = 16;
74 static_assert(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
75 "VideoFrame padding size does not fit ffmpeg requirement");
78 VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
79 VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
80 "VideoFrame frame address alignment does not fit ffmpeg requirement");
82 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
84 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base,
86 int64_t microseconds = av_rescale_q(timestamp, time_base, kMicrosBase);
87 return base::Microseconds(microseconds);
90 int64_t ConvertToTimeBase(const AVRational& time_base,
91 const base::TimeDelta& timestamp) {
92 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base);
95 AudioCodec CodecIDToAudioCodec(AVCodecID codec_id) {
98 return AudioCodec::kAAC;
99 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
100 case AV_CODEC_ID_AC3:
101 return AudioCodec::kAC3;
102 case AV_CODEC_ID_EAC3:
103 return AudioCodec::kEAC3;
105 case AV_CODEC_ID_MP3:
106 return AudioCodec::kMP3;
107 case AV_CODEC_ID_VORBIS:
108 return AudioCodec::kVorbis;
109 case AV_CODEC_ID_PCM_U8:
110 case AV_CODEC_ID_PCM_S16LE:
111 case AV_CODEC_ID_PCM_S24LE:
112 case AV_CODEC_ID_PCM_S32LE:
113 case AV_CODEC_ID_PCM_F32LE:
114 return AudioCodec::kPCM;
115 case AV_CODEC_ID_PCM_S16BE:
116 return AudioCodec::kPCM_S16BE;
117 case AV_CODEC_ID_PCM_S24BE:
118 return AudioCodec::kPCM_S24BE;
119 case AV_CODEC_ID_FLAC:
120 return AudioCodec::kFLAC;
121 case AV_CODEC_ID_AMR_NB:
122 return AudioCodec::kAMR_NB;
123 case AV_CODEC_ID_AMR_WB:
124 return AudioCodec::kAMR_WB;
125 case AV_CODEC_ID_GSM_MS:
126 return AudioCodec::kGSM_MS;
127 case AV_CODEC_ID_PCM_ALAW:
128 return AudioCodec::kPCM_ALAW;
129 case AV_CODEC_ID_PCM_MULAW:
130 return AudioCodec::kPCM_MULAW;
131 case AV_CODEC_ID_OPUS:
132 return AudioCodec::kOpus;
133 case AV_CODEC_ID_ALAC:
134 return AudioCodec::kALAC;
135 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
136 case AV_CODEC_ID_MPEGH_3D_AUDIO:
137 return AudioCodec::kMpegHAudio;
140 DVLOG(1) << "Unknown audio CodecID: " << codec_id;
142 return AudioCodec::kUnknown;
145 AVCodecID AudioCodecToCodecID(AudioCodec audio_codec,
146 SampleFormat sample_format) {
147 switch (audio_codec) {
148 case AudioCodec::kAAC:
149 return AV_CODEC_ID_AAC;
150 case AudioCodec::kALAC:
151 return AV_CODEC_ID_ALAC;
152 case AudioCodec::kMP3:
153 return AV_CODEC_ID_MP3;
154 case AudioCodec::kPCM:
155 switch (sample_format) {
156 case kSampleFormatU8:
157 return AV_CODEC_ID_PCM_U8;
158 case kSampleFormatS16:
159 return AV_CODEC_ID_PCM_S16LE;
160 case kSampleFormatS24:
161 return AV_CODEC_ID_PCM_S24LE;
162 case kSampleFormatS32:
163 return AV_CODEC_ID_PCM_S32LE;
164 case kSampleFormatF32:
165 return AV_CODEC_ID_PCM_F32LE;
167 DVLOG(1) << "Unsupported sample format: " << sample_format;
170 case AudioCodec::kPCM_S16BE:
171 return AV_CODEC_ID_PCM_S16BE;
172 case AudioCodec::kPCM_S24BE:
173 return AV_CODEC_ID_PCM_S24BE;
174 case AudioCodec::kVorbis:
175 return AV_CODEC_ID_VORBIS;
176 case AudioCodec::kFLAC:
177 return AV_CODEC_ID_FLAC;
178 case AudioCodec::kAMR_NB:
179 return AV_CODEC_ID_AMR_NB;
180 case AudioCodec::kAMR_WB:
181 return AV_CODEC_ID_AMR_WB;
182 case AudioCodec::kGSM_MS:
183 return AV_CODEC_ID_GSM_MS;
184 case AudioCodec::kPCM_ALAW:
185 return AV_CODEC_ID_PCM_ALAW;
186 case AudioCodec::kPCM_MULAW:
187 return AV_CODEC_ID_PCM_MULAW;
188 case AudioCodec::kOpus:
189 return AV_CODEC_ID_OPUS;
190 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
191 case AudioCodec::kMpegHAudio:
192 return AV_CODEC_ID_MPEGH_3D_AUDIO;
195 DVLOG(1) << "Unknown AudioCodec: " << audio_codec;
197 return AV_CODEC_ID_NONE;
200 // Converts an FFmpeg video codec ID into its corresponding supported codec id.
201 static VideoCodec CodecIDToVideoCodec(AVCodecID codec_id) {
203 case AV_CODEC_ID_H264:
204 return VideoCodec::kH264;
205 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
206 case AV_CODEC_ID_HEVC:
207 return VideoCodec::kHEVC;
209 case AV_CODEC_ID_THEORA:
210 return VideoCodec::kTheora;
211 case AV_CODEC_ID_MPEG4:
212 return VideoCodec::kMPEG4;
213 case AV_CODEC_ID_VP8:
214 return VideoCodec::kVP8;
215 case AV_CODEC_ID_VP9:
216 return VideoCodec::kVP9;
217 case AV_CODEC_ID_AV1:
218 return VideoCodec::kAV1;
220 DVLOG(1) << "Unknown video CodecID: " << codec_id;
222 return VideoCodec::kUnknown;
225 AVCodecID VideoCodecToCodecID(VideoCodec video_codec) {
226 switch (video_codec) {
227 case VideoCodec::kH264:
228 return AV_CODEC_ID_H264;
229 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
230 case VideoCodec::kHEVC:
231 return AV_CODEC_ID_HEVC;
233 case VideoCodec::kTheora:
234 return AV_CODEC_ID_THEORA;
235 case VideoCodec::kMPEG4:
236 return AV_CODEC_ID_MPEG4;
237 case VideoCodec::kVP8:
238 return AV_CODEC_ID_VP8;
239 case VideoCodec::kVP9:
240 return AV_CODEC_ID_VP9;
241 case VideoCodec::kAV1:
242 return AV_CODEC_ID_AV1;
244 DVLOG(1) << "Unknown VideoCodec: " << video_codec;
246 return AV_CODEC_ID_NONE;
249 static VideoCodecProfile ProfileIDToVideoCodecProfile(int profile) {
250 // Clear out the CONSTRAINED & INTRA flags which are strict subsets of the
251 // corresponding profiles with which they're used.
252 profile &= ~FF_PROFILE_H264_CONSTRAINED;
253 profile &= ~FF_PROFILE_H264_INTRA;
255 case FF_PROFILE_H264_BASELINE:
256 return H264PROFILE_BASELINE;
257 case FF_PROFILE_H264_MAIN:
258 return H264PROFILE_MAIN;
259 case FF_PROFILE_H264_EXTENDED:
260 return H264PROFILE_EXTENDED;
261 case FF_PROFILE_H264_HIGH:
262 return H264PROFILE_HIGH;
263 case FF_PROFILE_H264_HIGH_10:
264 return H264PROFILE_HIGH10PROFILE;
265 case FF_PROFILE_H264_HIGH_422:
266 return H264PROFILE_HIGH422PROFILE;
267 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
268 return H264PROFILE_HIGH444PREDICTIVEPROFILE;
270 DVLOG(1) << "Unknown profile id: " << profile;
272 return VIDEO_CODEC_PROFILE_UNKNOWN;
275 static int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
277 case H264PROFILE_BASELINE:
278 return FF_PROFILE_H264_BASELINE;
279 case H264PROFILE_MAIN:
280 return FF_PROFILE_H264_MAIN;
281 case H264PROFILE_EXTENDED:
282 return FF_PROFILE_H264_EXTENDED;
283 case H264PROFILE_HIGH:
284 return FF_PROFILE_H264_HIGH;
285 case H264PROFILE_HIGH10PROFILE:
286 return FF_PROFILE_H264_HIGH_10;
287 case H264PROFILE_HIGH422PROFILE:
288 return FF_PROFILE_H264_HIGH_422;
289 case H264PROFILE_HIGH444PREDICTIVEPROFILE:
290 return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
292 DVLOG(1) << "Unknown VideoCodecProfile: " << profile;
294 return FF_PROFILE_UNKNOWN;
297 SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format,
298 AVCodecID codec_id) {
299 switch (sample_format) {
300 case AV_SAMPLE_FMT_U8:
301 return kSampleFormatU8;
302 case AV_SAMPLE_FMT_S16:
303 return kSampleFormatS16;
304 case AV_SAMPLE_FMT_S32:
305 if (codec_id == AV_CODEC_ID_PCM_S24LE)
306 return kSampleFormatS24;
308 return kSampleFormatS32;
309 case AV_SAMPLE_FMT_FLT:
310 return kSampleFormatF32;
311 case AV_SAMPLE_FMT_S16P:
312 return kSampleFormatPlanarS16;
313 case AV_SAMPLE_FMT_S32P:
314 return kSampleFormatPlanarS32;
315 case AV_SAMPLE_FMT_FLTP:
316 return kSampleFormatPlanarF32;
318 DVLOG(1) << "Unknown AVSampleFormat: " << sample_format;
320 return kUnknownSampleFormat;
323 static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) {
324 switch (sample_format) {
325 case kSampleFormatU8:
326 return AV_SAMPLE_FMT_U8;
327 case kSampleFormatS16:
328 return AV_SAMPLE_FMT_S16;
329 // pcm_s24le is treated as a codec with sample format s32 in ffmpeg
330 case kSampleFormatS24:
331 case kSampleFormatS32:
332 return AV_SAMPLE_FMT_S32;
333 case kSampleFormatF32:
334 return AV_SAMPLE_FMT_FLT;
335 case kSampleFormatPlanarS16:
336 return AV_SAMPLE_FMT_S16P;
337 case kSampleFormatPlanarF32:
338 return AV_SAMPLE_FMT_FLTP;
340 DVLOG(1) << "Unknown SampleFormat: " << sample_format;
342 return AV_SAMPLE_FMT_NONE;
345 bool AVCodecContextToAudioDecoderConfig(const AVCodecContext* codec_context,
346 EncryptionScheme encryption_scheme,
347 AudioDecoderConfig* config) {
348 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO);
350 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
352 SampleFormat sample_format = AVSampleFormatToSampleFormat(
353 codec_context->sample_fmt, codec_context->codec_id);
355 ChannelLayout channel_layout =
356 codec_context->ch_layout.nb_channels > 8
357 ? CHANNEL_LAYOUT_DISCRETE
358 : ChannelLayoutToChromeChannelLayout(
359 codec_context->ch_layout.u.mask,
360 codec_context->ch_layout.nb_channels);
363 // For AC3/EAC3 we enable only demuxing, but not decoding, so FFmpeg does
364 // not fill |sample_fmt|.
365 case AudioCodec::kAC3:
366 case AudioCodec::kEAC3:
367 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
368 // The spec for AC3/EAC3 audio is ETSI TS 102 366. According to sections
369 // F.3.1 and F.5.1 in that spec the sample_format for AC3/EAC3 must be 16.
370 sample_format = kSampleFormatS16;
375 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
376 case AudioCodec::kMpegHAudio:
377 channel_layout = CHANNEL_LAYOUT_BITSTREAM;
378 sample_format = kSampleFormatMpegHAudio;
386 base::TimeDelta seek_preroll;
387 if (codec_context->seek_preroll > 0) {
388 seek_preroll = base::Microseconds(codec_context->seek_preroll * 1000000.0 /
389 codec_context->sample_rate);
392 // AVStream occasionally has invalid extra data. See http://crbug.com/517163
393 if ((codec_context->extradata_size == 0) !=
394 (codec_context->extradata == nullptr)) {
395 LOG(ERROR) << __func__
396 << (codec_context->extradata == nullptr ? " NULL" : " Non-NULL")
397 << " extra data cannot have size of "
398 << codec_context->extradata_size << ".";
402 std::vector<uint8_t> extra_data;
403 if (codec_context->extradata_size > 0) {
404 extra_data.assign(codec_context->extradata,
405 codec_context->extradata + codec_context->extradata_size);
408 #if defined(EWK_BRINGUP) && defined(TIZEN_MULTIMEDIA)
409 // TODO: Address the hardcoding.
410 sample_format = kSampleFormatS16;
413 config->Initialize(codec, sample_format, channel_layout, codec_context->sample_rate,
414 extra_data, encryption_scheme, seek_preroll,
415 codec_context->delay);
416 if (channel_layout == CHANNEL_LAYOUT_DISCRETE)
417 config->SetChannelsForDiscrete(codec_context->ch_layout.nb_channels);
419 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
420 // These are bitstream formats unknown to ffmpeg, so they don't have
421 // a known sample format size.
422 if (codec == AudioCodec::kAC3 || codec == AudioCodec::kEAC3)
425 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
426 if (codec == AudioCodec::kMpegHAudio)
430 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
431 if (codec == AudioCodec::kAAC) {
432 config->set_aac_extra_data(extra_data);
434 // TODO(dalecurtis): Just use the profile from the codec context if ffmpeg
435 // ever starts supporting xHE-AAC.
436 if (codec_context->profile == FF_PROFILE_UNKNOWN) {
437 // Errors aren't fatal here, so just drop any MediaLog messages.
438 NullMediaLog media_log;
440 if (aac_parser.Parse(extra_data, &media_log))
441 config->set_profile(aac_parser.GetProfile());
446 // Verify that AudioConfig.bits_per_channel was calculated correctly for
447 // codecs that have |sample_fmt| set by FFmpeg.
448 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
449 config->bits_per_channel());
453 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext>
454 AVStreamToAVCodecContext(const AVStream* stream) {
455 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
456 avcodec_alloc_context3(nullptr));
457 if (avcodec_parameters_to_context(codec_context.get(), stream->codecpar) <
462 return codec_context;
465 bool AVStreamToAudioDecoderConfig(const AVStream* stream,
466 AudioDecoderConfig* config) {
467 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
468 AVStreamToAVCodecContext(stream));
472 return AVCodecContextToAudioDecoderConfig(
473 codec_context.get(), GetEncryptionScheme(stream), config);
476 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
477 AVCodecContext* codec_context) {
478 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
479 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
480 config.sample_format());
481 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
482 config.sample_format());
484 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
485 // said information to decode.
486 codec_context->ch_layout.nb_channels = config.channels();
487 codec_context->sample_rate = config.samples_per_second();
489 if (config.extra_data().empty()) {
490 codec_context->extradata = nullptr;
491 codec_context->extradata_size = 0;
493 codec_context->extradata_size = config.extra_data().size();
494 codec_context->extradata = reinterpret_cast<uint8_t*>(
495 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
496 memcpy(codec_context->extradata, &config.extra_data()[0],
497 config.extra_data().size());
498 memset(codec_context->extradata + config.extra_data().size(), '\0',
499 AV_INPUT_BUFFER_PADDING_SIZE);
503 bool AVStreamToVideoDecoderConfig(const AVStream* stream,
504 VideoDecoderConfig* config) {
505 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
506 AVStreamToAVCodecContext(stream));
510 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
511 // for now, but may not always be true forever. Fix this in the future.
512 gfx::Rect visible_rect(codec_context->width, codec_context->height);
513 gfx::Size coded_size = visible_rect.size();
514 gfx::HDRMetadata hdr_metadata;
516 // In some cases a container may have a DAR but no PAR, but FFmpeg translates
517 // everything to PAR. It is possible to get the render width and height, but I
518 // didn't find a way to determine whether that should be preferred to the PAR.
519 VideoAspectRatio aspect_ratio;
520 if (stream->sample_aspect_ratio.num) {
521 aspect_ratio = VideoAspectRatio::PAR(stream->sample_aspect_ratio.num,
522 stream->sample_aspect_ratio.den);
523 } else if (codec_context->sample_aspect_ratio.num) {
525 VideoAspectRatio::PAR(codec_context->sample_aspect_ratio.num,
526 codec_context->sample_aspect_ratio.den);
529 // Used to guess color space and to create the config. The first use should
530 // probably change to coded size, and the second should be removed as part of
531 // crbug.com/1214061.
532 gfx::Size natural_size = aspect_ratio.GetNaturalSize(visible_rect);
534 VideoCodec codec = CodecIDToVideoCodec(codec_context->codec_id);
536 // Without the ffmpeg decoder configured, libavformat is unable to get the
537 // profile, format, or coded size. So choose sensible defaults and let
538 // decoders fail later if the configuration is actually unsupported.
540 // TODO(chcunningham): We need real profiles for all of the codecs below to
541 // actually handle capabilities requests correctly. http://crbug.com/784610
542 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
544 // Prefer the color space found by libavcodec if available
545 VideoColorSpace color_space =
546 VideoColorSpace(codec_context->color_primaries, codec_context->color_trc,
547 codec_context->colorspace,
548 codec_context->color_range == AVCOL_RANGE_JPEG
549 ? gfx::ColorSpace::RangeID::FULL
550 : gfx::ColorSpace::RangeID::LIMITED);
552 VideoDecoderConfig::AlphaMode alpha_mode = GetAlphaMode(stream);
555 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
556 case VideoCodec::kH264: {
557 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
558 // if the profile is still unknown, try to extract it from
559 // the extradata using the internal parser
560 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN && codec_context->extradata &&
561 codec_context->extradata_size) {
562 mp4::AVCDecoderConfigurationRecord avc_config;
563 if (avc_config.Parse(codec_context->extradata,
564 codec_context->extradata_size)) {
565 profile = ProfileIDToVideoCodecProfile(avc_config.profile_indication);
568 // All the heuristics failed, let's assign a default profile
569 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN)
570 profile = H264PROFILE_BASELINE;
573 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
574 case VideoCodec::kHEVC: {
575 int hevc_profile = -1;
576 // We need to parse extradata each time, because we wont add ffmpeg
577 // hevc decoder & parser to chromium and codec_context->profile
578 // should always be FF_PROFILE_UNKNOWN (-99) here
579 if (codec_context->extradata && codec_context->extradata_size) {
580 mp4::HEVCDecoderConfigurationRecord hevc_config;
581 if (hevc_config.Parse(codec_context->extradata,
582 codec_context->extradata_size)) {
583 hevc_profile = hevc_config.general_profile_idc;
584 #if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
585 if (!color_space.IsSpecified()) {
586 // We should try to parsed color space from SPS if the
587 // result from libavcodec is not specified in case
588 // that some encoder not write extra colorspace info to
590 color_space = hevc_config.GetColorSpace();
592 hdr_metadata = hevc_config.GetHDRMetadata();
593 alpha_mode = hevc_config.GetAlphaMode();
594 #endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
597 // The values of general_profile_idc are taken from the HEVC standard, see
598 // the latest https://www.itu.int/rec/T-REC-H.265/en
599 switch (hevc_profile) {
601 profile = HEVCPROFILE_MAIN;
604 profile = HEVCPROFILE_MAIN10;
607 profile = HEVCPROFILE_MAIN_STILL_PICTURE;
610 profile = HEVCPROFILE_REXT;
613 profile = HEVCPROFILE_HIGH_THROUGHPUT;
616 profile = HEVCPROFILE_MULTIVIEW_MAIN;
619 profile = HEVCPROFILE_SCALABLE_MAIN;
622 profile = HEVCPROFILE_3D_MAIN;
625 profile = HEVCPROFILE_SCREEN_EXTENDED;
628 profile = HEVCPROFILE_SCALABLE_REXT;
631 profile = HEVCPROFILE_HIGH_THROUGHPUT_SCREEN_EXTENDED;
634 // Always assign a default if all heuristics fail.
635 profile = HEVCPROFILE_MAIN;
640 #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
641 #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
642 case VideoCodec::kVP8:
643 profile = VP8PROFILE_ANY;
645 case VideoCodec::kVP9:
646 switch (codec_context->profile) {
647 case FF_PROFILE_VP9_0:
648 profile = VP9PROFILE_PROFILE0;
650 case FF_PROFILE_VP9_1:
651 profile = VP9PROFILE_PROFILE1;
653 case FF_PROFILE_VP9_2:
654 profile = VP9PROFILE_PROFILE2;
656 case FF_PROFILE_VP9_3:
657 profile = VP9PROFILE_PROFILE3;
660 profile = VP9PROFILE_MIN;
664 case VideoCodec::kAV1:
665 profile = AV1PROFILE_PROFILE_MAIN;
667 case VideoCodec::kTheora:
668 profile = THEORAPROFILE_ANY;
671 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
674 void* display_matrix =
675 av_stream_get_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, nullptr);
677 VideoTransformation video_transformation = VideoTransformation();
678 if (display_matrix) {
679 video_transformation = VideoTransformation::FromFFmpegDisplayMatrix(
680 static_cast<int32_t*>(display_matrix));
683 if (!color_space.IsSpecified()) {
684 // VP9 frames may have color information, but that information cannot
685 // express new color spaces, like HDR. For that reason, color space
686 // information from the container should take precedence over color space
687 // information from the VP9 stream. However, if we infer the color space
688 // based on resolution here, it looks as if it came from the container.
689 // Since this inference causes color shifts and is slated to go away
690 // we just skip it for VP9 and leave the color space undefined, which
691 // will make the VP9 decoder behave correctly..
692 // We also ignore the resolution for AV1, since it's new and it's easy
693 // to make it behave correctly from the get-go.
694 // TODO(hubbe): Skip this inference for all codecs.
695 if (codec_context->codec_id != AV_CODEC_ID_VP9 &&
696 codec_context->codec_id != AV_CODEC_ID_AV1) {
697 // Otherwise, assume that SD video is usually Rec.601, and HD is usually
699 color_space = (natural_size.height() < 720) ? VideoColorSpace::REC601()
700 : VideoColorSpace::REC709();
702 } else if (codec_context->codec_id == AV_CODEC_ID_H264 &&
703 codec_context->colorspace == AVCOL_SPC_RGB &&
704 AVPixelFormatToVideoPixelFormat(codec_context->pix_fmt) ==
706 // Some H.264 videos contain a VUI that specifies a color matrix of GBR,
707 // when they are actually ordinary YUV. Only 4:2:0 formats are checked,
708 // because GBR is reasonable for 4:4:4 content. See crbug.com/1067377.
709 color_space = VideoColorSpace::REC709();
712 // AVCodecContext occasionally has invalid extra data. See
713 // http://crbug.com/517163
714 if (codec_context->extradata != nullptr &&
715 codec_context->extradata_size == 0) {
716 DLOG(ERROR) << __func__ << " Non-Null extra data cannot have size of 0.";
720 std::vector<uint8_t> extra_data;
721 if (codec_context->extradata_size > 0) {
722 extra_data.assign(codec_context->extradata,
723 codec_context->extradata + codec_context->extradata_size);
725 // TODO(tmathmeyer) ffmpeg can't provide us with an actual video rotation yet.
726 config->Initialize(codec, profile, alpha_mode, color_space,
727 video_transformation, coded_size, visible_rect,
728 natural_size, extra_data, GetEncryptionScheme(stream));
729 // Set the aspect ratio explicitly since our version hasn't been rounded.
730 config->set_aspect_ratio(aspect_ratio);
732 if (stream->nb_side_data) {
733 for (int i = 0; i < stream->nb_side_data; ++i) {
734 AVPacketSideData side_data = stream->side_data[i];
735 if (side_data.type != AV_PKT_DATA_MASTERING_DISPLAY_METADATA)
738 AVMasteringDisplayMetadata* metadata =
739 reinterpret_cast<AVMasteringDisplayMetadata*>(side_data.data);
740 if (metadata->has_primaries) {
741 hdr_metadata.color_volume_metadata.primary_r =
742 gfx::PointF(av_q2d(metadata->display_primaries[0][0]),
743 av_q2d(metadata->display_primaries[0][1]));
744 hdr_metadata.color_volume_metadata.primary_g =
745 gfx::PointF(av_q2d(metadata->display_primaries[1][0]),
746 av_q2d(metadata->display_primaries[1][1]));
747 hdr_metadata.color_volume_metadata.primary_b =
748 gfx::PointF(av_q2d(metadata->display_primaries[2][0]),
749 av_q2d(metadata->display_primaries[2][1]));
750 hdr_metadata.color_volume_metadata.white_point = gfx::PointF(
751 av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
753 if (metadata->has_luminance) {
754 hdr_metadata.color_volume_metadata.luminance_max =
755 av_q2d(metadata->max_luminance);
756 hdr_metadata.color_volume_metadata.luminance_min =
757 av_q2d(metadata->min_luminance);
762 if (hdr_metadata.IsValid()) {
763 config->set_hdr_metadata(hdr_metadata);
769 void VideoDecoderConfigToAVCodecContext(
770 const VideoDecoderConfig& config,
771 AVCodecContext* codec_context) {
772 codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
773 codec_context->codec_id = VideoCodecToCodecID(config.codec());
774 codec_context->profile = VideoCodecProfileToProfileID(config.profile());
775 codec_context->coded_width = config.coded_size().width();
776 codec_context->coded_height = config.coded_size().height();
777 if (config.color_space_info().range == gfx::ColorSpace::RangeID::FULL)
778 codec_context->color_range = AVCOL_RANGE_JPEG;
780 if (config.extra_data().empty()) {
781 codec_context->extradata = nullptr;
782 codec_context->extradata_size = 0;
784 codec_context->extradata_size = config.extra_data().size();
785 codec_context->extradata = reinterpret_cast<uint8_t*>(
786 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
787 memcpy(codec_context->extradata, &config.extra_data()[0],
788 config.extra_data().size());
789 memset(codec_context->extradata + config.extra_data().size(), '\0',
790 AV_INPUT_BUFFER_PADDING_SIZE);
794 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
796 case AV_CH_LAYOUT_MONO:
797 return CHANNEL_LAYOUT_MONO;
798 case AV_CH_LAYOUT_STEREO:
799 return CHANNEL_LAYOUT_STEREO;
800 case AV_CH_LAYOUT_2_1:
801 return CHANNEL_LAYOUT_2_1;
802 case AV_CH_LAYOUT_SURROUND:
803 return CHANNEL_LAYOUT_SURROUND;
804 case AV_CH_LAYOUT_4POINT0:
805 return CHANNEL_LAYOUT_4_0;
806 case AV_CH_LAYOUT_2_2:
807 return CHANNEL_LAYOUT_2_2;
808 case AV_CH_LAYOUT_QUAD:
809 return CHANNEL_LAYOUT_QUAD;
810 case AV_CH_LAYOUT_5POINT0:
811 return CHANNEL_LAYOUT_5_0;
812 case AV_CH_LAYOUT_5POINT1:
813 return CHANNEL_LAYOUT_5_1;
814 case AV_CH_LAYOUT_5POINT0_BACK:
815 return CHANNEL_LAYOUT_5_0_BACK;
816 case AV_CH_LAYOUT_5POINT1_BACK:
817 return CHANNEL_LAYOUT_5_1_BACK;
818 case AV_CH_LAYOUT_7POINT0:
819 return CHANNEL_LAYOUT_7_0;
820 case AV_CH_LAYOUT_7POINT1:
821 return CHANNEL_LAYOUT_7_1;
822 case AV_CH_LAYOUT_7POINT1_WIDE:
823 return CHANNEL_LAYOUT_7_1_WIDE;
824 case AV_CH_LAYOUT_STEREO_DOWNMIX:
825 return CHANNEL_LAYOUT_STEREO_DOWNMIX;
826 case AV_CH_LAYOUT_2POINT1:
827 return CHANNEL_LAYOUT_2POINT1;
828 case AV_CH_LAYOUT_3POINT1:
829 return CHANNEL_LAYOUT_3_1;
830 case AV_CH_LAYOUT_4POINT1:
831 return CHANNEL_LAYOUT_4_1;
832 case AV_CH_LAYOUT_6POINT0:
833 return CHANNEL_LAYOUT_6_0;
834 case AV_CH_LAYOUT_6POINT0_FRONT:
835 return CHANNEL_LAYOUT_6_0_FRONT;
836 case AV_CH_LAYOUT_HEXAGONAL:
837 return CHANNEL_LAYOUT_HEXAGONAL;
838 case AV_CH_LAYOUT_6POINT1:
839 return CHANNEL_LAYOUT_6_1;
840 case AV_CH_LAYOUT_6POINT1_BACK:
841 return CHANNEL_LAYOUT_6_1_BACK;
842 case AV_CH_LAYOUT_6POINT1_FRONT:
843 return CHANNEL_LAYOUT_6_1_FRONT;
844 case AV_CH_LAYOUT_7POINT0_FRONT:
845 return CHANNEL_LAYOUT_7_0_FRONT;
846 #ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
847 case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
848 return CHANNEL_LAYOUT_7_1_WIDE_BACK;
850 case AV_CH_LAYOUT_OCTAGONAL:
851 return CHANNEL_LAYOUT_OCTAGONAL;
853 // FFmpeg channel_layout is 0 for .wav and .mp3. Attempt to guess layout
854 // based on the channel count.
855 return GuessChannelLayout(channels);
859 #if !defined(ARCH_CPU_LITTLE_ENDIAN)
860 #error The code below assumes little-endianness.
863 VideoPixelFormat AVPixelFormatToVideoPixelFormat(AVPixelFormat pixel_format) {
864 // The YUVJ alternatives are FFmpeg's (deprecated, but still in use) way to
865 // specify a pixel format and full range color combination.
866 switch (pixel_format) {
867 case AV_PIX_FMT_YUV444P:
868 case AV_PIX_FMT_YUVJ444P:
869 return PIXEL_FORMAT_I444;
871 case AV_PIX_FMT_YUV420P:
872 case AV_PIX_FMT_YUVJ420P:
873 return PIXEL_FORMAT_I420;
875 case AV_PIX_FMT_YUV422P:
876 case AV_PIX_FMT_YUVJ422P:
877 return PIXEL_FORMAT_I422;
879 case AV_PIX_FMT_YUVA420P:
880 return PIXEL_FORMAT_I420A;
882 case AV_PIX_FMT_YUV420P9LE:
883 return PIXEL_FORMAT_YUV420P9;
884 case AV_PIX_FMT_YUV420P10LE:
885 return PIXEL_FORMAT_YUV420P10;
886 case AV_PIX_FMT_YUV420P12LE:
887 return PIXEL_FORMAT_YUV420P12;
889 case AV_PIX_FMT_YUV422P9LE:
890 return PIXEL_FORMAT_YUV422P9;
891 case AV_PIX_FMT_YUV422P10LE:
892 return PIXEL_FORMAT_YUV422P10;
893 case AV_PIX_FMT_YUV422P12LE:
894 return PIXEL_FORMAT_YUV422P12;
896 case AV_PIX_FMT_YUV444P9LE:
897 return PIXEL_FORMAT_YUV444P9;
898 case AV_PIX_FMT_YUV444P10LE:
899 return PIXEL_FORMAT_YUV444P10;
900 case AV_PIX_FMT_YUV444P12LE:
901 return PIXEL_FORMAT_YUV444P12;
903 case AV_PIX_FMT_P016LE:
904 return PIXEL_FORMAT_P016LE;
907 DVLOG(1) << "Unsupported AVPixelFormat: " << pixel_format;
909 return PIXEL_FORMAT_UNKNOWN;
912 VideoColorSpace AVColorSpaceToColorSpace(AVColorSpace color_space,
913 AVColorRange color_range) {
914 // TODO(hubbe): make this better
915 if (color_range == AVCOL_RANGE_JPEG)
916 return VideoColorSpace::JPEG();
918 switch (color_space) {
919 case AVCOL_SPC_UNSPECIFIED:
921 case AVCOL_SPC_BT709:
922 return VideoColorSpace::REC709();
923 case AVCOL_SPC_SMPTE170M:
924 case AVCOL_SPC_BT470BG:
925 return VideoColorSpace::REC601();
927 DVLOG(1) << "Unknown AVColorSpace: " << color_space;
929 return VideoColorSpace();
932 std::string AVErrorToString(int errnum) {
933 char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
934 av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
935 return std::string(errbuf);
938 int32_t HashCodecName(const char* codec_name) {
939 // Use the first 32-bits from the SHA1 hash as the identifier.
941 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4);