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 config->Initialize(codec, sample_format, channel_layout, codec_context->sample_rate,
409 extra_data, encryption_scheme, seek_preroll,
410 codec_context->delay);
411 if (channel_layout == CHANNEL_LAYOUT_DISCRETE)
412 config->SetChannelsForDiscrete(codec_context->ch_layout.nb_channels);
414 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
415 // These are bitstream formats unknown to ffmpeg, so they don't have
416 // a known sample format size.
417 if (codec == AudioCodec::kAC3 || codec == AudioCodec::kEAC3)
420 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
421 if (codec == AudioCodec::kMpegHAudio)
425 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
426 if (codec == AudioCodec::kAAC) {
427 config->set_aac_extra_data(extra_data);
429 // TODO(dalecurtis): Just use the profile from the codec context if ffmpeg
430 // ever starts supporting xHE-AAC.
431 if (codec_context->profile == FF_PROFILE_UNKNOWN) {
432 // Errors aren't fatal here, so just drop any MediaLog messages.
433 NullMediaLog media_log;
435 if (aac_parser.Parse(extra_data, &media_log))
436 config->set_profile(aac_parser.GetProfile());
441 // Verify that AudioConfig.bits_per_channel was calculated correctly for
442 // codecs that have |sample_fmt| set by FFmpeg.
443 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
444 config->bits_per_channel());
448 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext>
449 AVStreamToAVCodecContext(const AVStream* stream) {
450 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
451 avcodec_alloc_context3(nullptr));
452 if (avcodec_parameters_to_context(codec_context.get(), stream->codecpar) <
457 return codec_context;
460 bool AVStreamToAudioDecoderConfig(const AVStream* stream,
461 AudioDecoderConfig* config) {
462 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
463 AVStreamToAVCodecContext(stream));
467 return AVCodecContextToAudioDecoderConfig(
468 codec_context.get(), GetEncryptionScheme(stream), config);
471 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
472 AVCodecContext* codec_context) {
473 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
474 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
475 config.sample_format());
476 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
477 config.sample_format());
479 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
480 // said information to decode.
481 codec_context->ch_layout.nb_channels = config.channels();
482 codec_context->sample_rate = config.samples_per_second();
484 if (config.extra_data().empty()) {
485 codec_context->extradata = nullptr;
486 codec_context->extradata_size = 0;
488 codec_context->extradata_size = config.extra_data().size();
489 codec_context->extradata = reinterpret_cast<uint8_t*>(
490 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
491 memcpy(codec_context->extradata, &config.extra_data()[0],
492 config.extra_data().size());
493 memset(codec_context->extradata + config.extra_data().size(), '\0',
494 AV_INPUT_BUFFER_PADDING_SIZE);
498 bool AVStreamToVideoDecoderConfig(const AVStream* stream,
499 VideoDecoderConfig* config) {
500 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
501 AVStreamToAVCodecContext(stream));
505 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
506 // for now, but may not always be true forever. Fix this in the future.
507 gfx::Rect visible_rect(codec_context->width, codec_context->height);
508 gfx::Size coded_size = visible_rect.size();
509 gfx::HDRMetadata hdr_metadata;
511 // In some cases a container may have a DAR but no PAR, but FFmpeg translates
512 // everything to PAR. It is possible to get the render width and height, but I
513 // didn't find a way to determine whether that should be preferred to the PAR.
514 VideoAspectRatio aspect_ratio;
515 if (stream->sample_aspect_ratio.num) {
516 aspect_ratio = VideoAspectRatio::PAR(stream->sample_aspect_ratio.num,
517 stream->sample_aspect_ratio.den);
518 } else if (codec_context->sample_aspect_ratio.num) {
520 VideoAspectRatio::PAR(codec_context->sample_aspect_ratio.num,
521 codec_context->sample_aspect_ratio.den);
524 // Used to guess color space and to create the config. The first use should
525 // probably change to coded size, and the second should be removed as part of
526 // crbug.com/1214061.
527 gfx::Size natural_size = aspect_ratio.GetNaturalSize(visible_rect);
529 VideoCodec codec = CodecIDToVideoCodec(codec_context->codec_id);
531 // Without the ffmpeg decoder configured, libavformat is unable to get the
532 // profile, format, or coded size. So choose sensible defaults and let
533 // decoders fail later if the configuration is actually unsupported.
535 // TODO(chcunningham): We need real profiles for all of the codecs below to
536 // actually handle capabilities requests correctly. http://crbug.com/784610
537 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
539 // Prefer the color space found by libavcodec if available
540 VideoColorSpace color_space =
541 VideoColorSpace(codec_context->color_primaries, codec_context->color_trc,
542 codec_context->colorspace,
543 codec_context->color_range == AVCOL_RANGE_JPEG
544 ? gfx::ColorSpace::RangeID::FULL
545 : gfx::ColorSpace::RangeID::LIMITED);
547 VideoDecoderConfig::AlphaMode alpha_mode = GetAlphaMode(stream);
550 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
551 case VideoCodec::kH264: {
552 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
553 // if the profile is still unknown, try to extract it from
554 // the extradata using the internal parser
555 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN && codec_context->extradata &&
556 codec_context->extradata_size) {
557 mp4::AVCDecoderConfigurationRecord avc_config;
558 if (avc_config.Parse(codec_context->extradata,
559 codec_context->extradata_size)) {
560 profile = ProfileIDToVideoCodecProfile(avc_config.profile_indication);
563 // All the heuristics failed, let's assign a default profile
564 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN)
565 profile = H264PROFILE_BASELINE;
568 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
569 case VideoCodec::kHEVC: {
570 int hevc_profile = -1;
571 // We need to parse extradata each time, because we wont add ffmpeg
572 // hevc decoder & parser to chromium and codec_context->profile
573 // should always be FF_PROFILE_UNKNOWN (-99) here
574 if (codec_context->extradata && codec_context->extradata_size) {
575 mp4::HEVCDecoderConfigurationRecord hevc_config;
576 if (hevc_config.Parse(codec_context->extradata,
577 codec_context->extradata_size)) {
578 hevc_profile = hevc_config.general_profile_idc;
579 #if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
580 if (!color_space.IsSpecified()) {
581 // We should try to parsed color space from SPS if the
582 // result from libavcodec is not specified in case
583 // that some encoder not write extra colorspace info to
585 color_space = hevc_config.GetColorSpace();
587 hdr_metadata = hevc_config.GetHDRMetadata();
588 alpha_mode = hevc_config.GetAlphaMode();
589 #endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
592 // The values of general_profile_idc are taken from the HEVC standard, see
593 // the latest https://www.itu.int/rec/T-REC-H.265/en
594 switch (hevc_profile) {
596 profile = HEVCPROFILE_MAIN;
599 profile = HEVCPROFILE_MAIN10;
602 profile = HEVCPROFILE_MAIN_STILL_PICTURE;
605 profile = HEVCPROFILE_REXT;
608 profile = HEVCPROFILE_HIGH_THROUGHPUT;
611 profile = HEVCPROFILE_MULTIVIEW_MAIN;
614 profile = HEVCPROFILE_SCALABLE_MAIN;
617 profile = HEVCPROFILE_3D_MAIN;
620 profile = HEVCPROFILE_SCREEN_EXTENDED;
623 profile = HEVCPROFILE_SCALABLE_REXT;
626 profile = HEVCPROFILE_HIGH_THROUGHPUT_SCREEN_EXTENDED;
629 // Always assign a default if all heuristics fail.
630 profile = HEVCPROFILE_MAIN;
635 #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
636 #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
637 case VideoCodec::kVP8:
638 profile = VP8PROFILE_ANY;
640 case VideoCodec::kVP9:
641 switch (codec_context->profile) {
642 case FF_PROFILE_VP9_0:
643 profile = VP9PROFILE_PROFILE0;
645 case FF_PROFILE_VP9_1:
646 profile = VP9PROFILE_PROFILE1;
648 case FF_PROFILE_VP9_2:
649 profile = VP9PROFILE_PROFILE2;
651 case FF_PROFILE_VP9_3:
652 profile = VP9PROFILE_PROFILE3;
655 profile = VP9PROFILE_MIN;
659 case VideoCodec::kAV1:
660 profile = AV1PROFILE_PROFILE_MAIN;
662 case VideoCodec::kTheora:
663 profile = THEORAPROFILE_ANY;
666 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
669 void* display_matrix =
670 av_stream_get_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, nullptr);
672 VideoTransformation video_transformation = VideoTransformation();
673 if (display_matrix) {
674 video_transformation = VideoTransformation::FromFFmpegDisplayMatrix(
675 static_cast<int32_t*>(display_matrix));
678 if (!color_space.IsSpecified()) {
679 // VP9 frames may have color information, but that information cannot
680 // express new color spaces, like HDR. For that reason, color space
681 // information from the container should take precedence over color space
682 // information from the VP9 stream. However, if we infer the color space
683 // based on resolution here, it looks as if it came from the container.
684 // Since this inference causes color shifts and is slated to go away
685 // we just skip it for VP9 and leave the color space undefined, which
686 // will make the VP9 decoder behave correctly..
687 // We also ignore the resolution for AV1, since it's new and it's easy
688 // to make it behave correctly from the get-go.
689 // TODO(hubbe): Skip this inference for all codecs.
690 if (codec_context->codec_id != AV_CODEC_ID_VP9 &&
691 codec_context->codec_id != AV_CODEC_ID_AV1) {
692 // Otherwise, assume that SD video is usually Rec.601, and HD is usually
694 color_space = (natural_size.height() < 720) ? VideoColorSpace::REC601()
695 : VideoColorSpace::REC709();
697 } else if (codec_context->codec_id == AV_CODEC_ID_H264 &&
698 codec_context->colorspace == AVCOL_SPC_RGB &&
699 AVPixelFormatToVideoPixelFormat(codec_context->pix_fmt) ==
701 // Some H.264 videos contain a VUI that specifies a color matrix of GBR,
702 // when they are actually ordinary YUV. Only 4:2:0 formats are checked,
703 // because GBR is reasonable for 4:4:4 content. See crbug.com/1067377.
704 color_space = VideoColorSpace::REC709();
707 // AVCodecContext occasionally has invalid extra data. See
708 // http://crbug.com/517163
709 if (codec_context->extradata != nullptr &&
710 codec_context->extradata_size == 0) {
711 DLOG(ERROR) << __func__ << " Non-Null extra data cannot have size of 0.";
715 std::vector<uint8_t> extra_data;
716 if (codec_context->extradata_size > 0) {
717 extra_data.assign(codec_context->extradata,
718 codec_context->extradata + codec_context->extradata_size);
720 // TODO(tmathmeyer) ffmpeg can't provide us with an actual video rotation yet.
721 config->Initialize(codec, profile, alpha_mode, color_space,
722 video_transformation, coded_size, visible_rect,
723 natural_size, extra_data, GetEncryptionScheme(stream));
724 // Set the aspect ratio explicitly since our version hasn't been rounded.
725 config->set_aspect_ratio(aspect_ratio);
727 if (stream->nb_side_data) {
728 for (int i = 0; i < stream->nb_side_data; ++i) {
729 AVPacketSideData side_data = stream->side_data[i];
730 if (side_data.type != AV_PKT_DATA_MASTERING_DISPLAY_METADATA)
733 AVMasteringDisplayMetadata* metadata =
734 reinterpret_cast<AVMasteringDisplayMetadata*>(side_data.data);
735 if (metadata->has_primaries) {
736 hdr_metadata.color_volume_metadata.primary_r =
737 gfx::PointF(av_q2d(metadata->display_primaries[0][0]),
738 av_q2d(metadata->display_primaries[0][1]));
739 hdr_metadata.color_volume_metadata.primary_g =
740 gfx::PointF(av_q2d(metadata->display_primaries[1][0]),
741 av_q2d(metadata->display_primaries[1][1]));
742 hdr_metadata.color_volume_metadata.primary_b =
743 gfx::PointF(av_q2d(metadata->display_primaries[2][0]),
744 av_q2d(metadata->display_primaries[2][1]));
745 hdr_metadata.color_volume_metadata.white_point = gfx::PointF(
746 av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
748 if (metadata->has_luminance) {
749 hdr_metadata.color_volume_metadata.luminance_max =
750 av_q2d(metadata->max_luminance);
751 hdr_metadata.color_volume_metadata.luminance_min =
752 av_q2d(metadata->min_luminance);
757 if (hdr_metadata.IsValid()) {
758 config->set_hdr_metadata(hdr_metadata);
764 void VideoDecoderConfigToAVCodecContext(
765 const VideoDecoderConfig& config,
766 AVCodecContext* codec_context) {
767 codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
768 codec_context->codec_id = VideoCodecToCodecID(config.codec());
769 codec_context->profile = VideoCodecProfileToProfileID(config.profile());
770 codec_context->coded_width = config.coded_size().width();
771 codec_context->coded_height = config.coded_size().height();
772 if (config.color_space_info().range == gfx::ColorSpace::RangeID::FULL)
773 codec_context->color_range = AVCOL_RANGE_JPEG;
775 if (config.extra_data().empty()) {
776 codec_context->extradata = nullptr;
777 codec_context->extradata_size = 0;
779 codec_context->extradata_size = config.extra_data().size();
780 codec_context->extradata = reinterpret_cast<uint8_t*>(
781 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
782 memcpy(codec_context->extradata, &config.extra_data()[0],
783 config.extra_data().size());
784 memset(codec_context->extradata + config.extra_data().size(), '\0',
785 AV_INPUT_BUFFER_PADDING_SIZE);
789 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
791 case AV_CH_LAYOUT_MONO:
792 return CHANNEL_LAYOUT_MONO;
793 case AV_CH_LAYOUT_STEREO:
794 return CHANNEL_LAYOUT_STEREO;
795 case AV_CH_LAYOUT_2_1:
796 return CHANNEL_LAYOUT_2_1;
797 case AV_CH_LAYOUT_SURROUND:
798 return CHANNEL_LAYOUT_SURROUND;
799 case AV_CH_LAYOUT_4POINT0:
800 return CHANNEL_LAYOUT_4_0;
801 case AV_CH_LAYOUT_2_2:
802 return CHANNEL_LAYOUT_2_2;
803 case AV_CH_LAYOUT_QUAD:
804 return CHANNEL_LAYOUT_QUAD;
805 case AV_CH_LAYOUT_5POINT0:
806 return CHANNEL_LAYOUT_5_0;
807 case AV_CH_LAYOUT_5POINT1:
808 return CHANNEL_LAYOUT_5_1;
809 case AV_CH_LAYOUT_5POINT0_BACK:
810 return CHANNEL_LAYOUT_5_0_BACK;
811 case AV_CH_LAYOUT_5POINT1_BACK:
812 return CHANNEL_LAYOUT_5_1_BACK;
813 case AV_CH_LAYOUT_7POINT0:
814 return CHANNEL_LAYOUT_7_0;
815 case AV_CH_LAYOUT_7POINT1:
816 return CHANNEL_LAYOUT_7_1;
817 case AV_CH_LAYOUT_7POINT1_WIDE:
818 return CHANNEL_LAYOUT_7_1_WIDE;
819 case AV_CH_LAYOUT_STEREO_DOWNMIX:
820 return CHANNEL_LAYOUT_STEREO_DOWNMIX;
821 case AV_CH_LAYOUT_2POINT1:
822 return CHANNEL_LAYOUT_2POINT1;
823 case AV_CH_LAYOUT_3POINT1:
824 return CHANNEL_LAYOUT_3_1;
825 case AV_CH_LAYOUT_4POINT1:
826 return CHANNEL_LAYOUT_4_1;
827 case AV_CH_LAYOUT_6POINT0:
828 return CHANNEL_LAYOUT_6_0;
829 case AV_CH_LAYOUT_6POINT0_FRONT:
830 return CHANNEL_LAYOUT_6_0_FRONT;
831 case AV_CH_LAYOUT_HEXAGONAL:
832 return CHANNEL_LAYOUT_HEXAGONAL;
833 case AV_CH_LAYOUT_6POINT1:
834 return CHANNEL_LAYOUT_6_1;
835 case AV_CH_LAYOUT_6POINT1_BACK:
836 return CHANNEL_LAYOUT_6_1_BACK;
837 case AV_CH_LAYOUT_6POINT1_FRONT:
838 return CHANNEL_LAYOUT_6_1_FRONT;
839 case AV_CH_LAYOUT_7POINT0_FRONT:
840 return CHANNEL_LAYOUT_7_0_FRONT;
841 #ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
842 case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
843 return CHANNEL_LAYOUT_7_1_WIDE_BACK;
845 case AV_CH_LAYOUT_OCTAGONAL:
846 return CHANNEL_LAYOUT_OCTAGONAL;
848 // FFmpeg channel_layout is 0 for .wav and .mp3. Attempt to guess layout
849 // based on the channel count.
850 return GuessChannelLayout(channels);
854 #if !defined(ARCH_CPU_LITTLE_ENDIAN)
855 #error The code below assumes little-endianness.
858 VideoPixelFormat AVPixelFormatToVideoPixelFormat(AVPixelFormat pixel_format) {
859 // The YUVJ alternatives are FFmpeg's (deprecated, but still in use) way to
860 // specify a pixel format and full range color combination.
861 switch (pixel_format) {
862 case AV_PIX_FMT_YUV444P:
863 case AV_PIX_FMT_YUVJ444P:
864 return PIXEL_FORMAT_I444;
866 case AV_PIX_FMT_YUV420P:
867 case AV_PIX_FMT_YUVJ420P:
868 return PIXEL_FORMAT_I420;
870 case AV_PIX_FMT_YUV422P:
871 case AV_PIX_FMT_YUVJ422P:
872 return PIXEL_FORMAT_I422;
874 case AV_PIX_FMT_YUVA420P:
875 return PIXEL_FORMAT_I420A;
877 case AV_PIX_FMT_YUV420P9LE:
878 return PIXEL_FORMAT_YUV420P9;
879 case AV_PIX_FMT_YUV420P10LE:
880 return PIXEL_FORMAT_YUV420P10;
881 case AV_PIX_FMT_YUV420P12LE:
882 return PIXEL_FORMAT_YUV420P12;
884 case AV_PIX_FMT_YUV422P9LE:
885 return PIXEL_FORMAT_YUV422P9;
886 case AV_PIX_FMT_YUV422P10LE:
887 return PIXEL_FORMAT_YUV422P10;
888 case AV_PIX_FMT_YUV422P12LE:
889 return PIXEL_FORMAT_YUV422P12;
891 case AV_PIX_FMT_YUV444P9LE:
892 return PIXEL_FORMAT_YUV444P9;
893 case AV_PIX_FMT_YUV444P10LE:
894 return PIXEL_FORMAT_YUV444P10;
895 case AV_PIX_FMT_YUV444P12LE:
896 return PIXEL_FORMAT_YUV444P12;
898 case AV_PIX_FMT_P016LE:
899 return PIXEL_FORMAT_P016LE;
902 DVLOG(1) << "Unsupported AVPixelFormat: " << pixel_format;
904 return PIXEL_FORMAT_UNKNOWN;
907 VideoColorSpace AVColorSpaceToColorSpace(AVColorSpace color_space,
908 AVColorRange color_range) {
909 // TODO(hubbe): make this better
910 if (color_range == AVCOL_RANGE_JPEG)
911 return VideoColorSpace::JPEG();
913 switch (color_space) {
914 case AVCOL_SPC_UNSPECIFIED:
916 case AVCOL_SPC_BT709:
917 return VideoColorSpace::REC709();
918 case AVCOL_SPC_SMPTE170M:
919 case AVCOL_SPC_BT470BG:
920 return VideoColorSpace::REC601();
922 DVLOG(1) << "Unknown AVColorSpace: " << color_space;
924 return VideoColorSpace();
927 std::string AVErrorToString(int errnum) {
928 char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
929 av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
930 return std::string(errbuf);
933 int32_t HashCodecName(const char* codec_name) {
934 // Use the first 32-bits from the SHA1 hash as the identifier.
936 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4);