1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/ffmpeg/ffmpeg_common.h"
6
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_decoder_config.h"
18 #include "media/base/video_util.h"
19 #include "media/formats/mp4/box_definitions.h"
20 #include "media/media_buildflags.h"
21
22 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
23 #include "media/formats/mp4/aac.h"
24 #endif
25
26 namespace media {
27
28 namespace {
29
GetEncryptionScheme(const AVStream * stream)30 EncryptionScheme GetEncryptionScheme(const AVStream* stream) {
31 AVDictionaryEntry* key =
32 av_dict_get(stream->metadata, "enc_key_id", nullptr, 0);
33 return key ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted;
34 }
35
36 } // namespace
37
38 // Why AV_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
39 // padded. Check here to ensure FFmpeg only receives data padded to its
40 // specifications.
41 static_assert(DecoderBuffer::kPaddingSize >= AV_INPUT_BUFFER_PADDING_SIZE,
42 "DecoderBuffer padding size does not fit ffmpeg requirement");
43
44 // Alignment requirement by FFmpeg for input and output buffers. This need to
45 // be updated to match FFmpeg when it changes.
46 #if defined(ARCH_CPU_ARM_FAMILY)
47 static const int kFFmpegBufferAddressAlignment = 16;
48 #else
49 static const int kFFmpegBufferAddressAlignment = 32;
50 #endif
51
52 // Check here to ensure FFmpeg only receives data aligned to its specifications.
53 static_assert(
54 DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
55 DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
56 "DecoderBuffer alignment size does not fit ffmpeg requirement");
57
58 // Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
59 // See video_get_buffer() in libavcodec/utils.c.
60 static const int kFFmpegOutputBufferPaddingSize = 16;
61
62 static_assert(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
63 "VideoFrame padding size does not fit ffmpeg requirement");
64
65 static_assert(
66 VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
67 VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
68 "VideoFrame frame address alignment does not fit ffmpeg requirement");
69
70 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
71
ConvertFromTimeBase(const AVRational & time_base,int64_t timestamp)72 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base,
73 int64_t timestamp) {
74 int64_t microseconds = av_rescale_q(timestamp, time_base, kMicrosBase);
75 return base::TimeDelta::FromMicroseconds(microseconds);
76 }
77
ConvertToTimeBase(const AVRational & time_base,const base::TimeDelta & timestamp)78 int64_t ConvertToTimeBase(const AVRational& time_base,
79 const base::TimeDelta& timestamp) {
80 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base);
81 }
82
CodecIDToAudioCodec(AVCodecID codec_id)83 AudioCodec CodecIDToAudioCodec(AVCodecID codec_id) {
84 switch (codec_id) {
85 case AV_CODEC_ID_AAC:
86 return kCodecAAC;
87 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
88 case AV_CODEC_ID_AC3:
89 return kCodecAC3;
90 case AV_CODEC_ID_EAC3:
91 return kCodecEAC3;
92 #endif
93 case AV_CODEC_ID_MP3:
94 return kCodecMP3;
95 case AV_CODEC_ID_VORBIS:
96 return kCodecVorbis;
97 case AV_CODEC_ID_PCM_U8:
98 case AV_CODEC_ID_PCM_S16LE:
99 case AV_CODEC_ID_PCM_S24LE:
100 case AV_CODEC_ID_PCM_S32LE:
101 case AV_CODEC_ID_PCM_F32LE:
102 return kCodecPCM;
103 case AV_CODEC_ID_PCM_S16BE:
104 return kCodecPCM_S16BE;
105 case AV_CODEC_ID_PCM_S24BE:
106 return kCodecPCM_S24BE;
107 case AV_CODEC_ID_FLAC:
108 return kCodecFLAC;
109 case AV_CODEC_ID_AMR_NB:
110 return kCodecAMR_NB;
111 case AV_CODEC_ID_AMR_WB:
112 return kCodecAMR_WB;
113 case AV_CODEC_ID_GSM_MS:
114 return kCodecGSM_MS;
115 case AV_CODEC_ID_PCM_ALAW:
116 return kCodecPCM_ALAW;
117 case AV_CODEC_ID_PCM_MULAW:
118 return kCodecPCM_MULAW;
119 case AV_CODEC_ID_OPUS:
120 return kCodecOpus;
121 case AV_CODEC_ID_ALAC:
122 return kCodecALAC;
123 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
124 case AV_CODEC_ID_MPEGH_3D_AUDIO:
125 return kCodecMpegHAudio;
126 #endif
127 default:
128 DVLOG(1) << "Unknown audio CodecID: " << codec_id;
129 }
130 return kUnknownAudioCodec;
131 }
132
AudioCodecToCodecID(AudioCodec audio_codec,SampleFormat sample_format)133 AVCodecID AudioCodecToCodecID(AudioCodec audio_codec,
134 SampleFormat sample_format) {
135 switch (audio_codec) {
136 case kCodecAAC:
137 return AV_CODEC_ID_AAC;
138 case kCodecALAC:
139 return AV_CODEC_ID_ALAC;
140 case kCodecMP3:
141 return AV_CODEC_ID_MP3;
142 case kCodecPCM:
143 switch (sample_format) {
144 case kSampleFormatU8:
145 return AV_CODEC_ID_PCM_U8;
146 case kSampleFormatS16:
147 return AV_CODEC_ID_PCM_S16LE;
148 case kSampleFormatS24:
149 return AV_CODEC_ID_PCM_S24LE;
150 case kSampleFormatS32:
151 return AV_CODEC_ID_PCM_S32LE;
152 case kSampleFormatF32:
153 return AV_CODEC_ID_PCM_F32LE;
154 default:
155 DVLOG(1) << "Unsupported sample format: " << sample_format;
156 }
157 break;
158 case kCodecPCM_S16BE:
159 return AV_CODEC_ID_PCM_S16BE;
160 case kCodecPCM_S24BE:
161 return AV_CODEC_ID_PCM_S24BE;
162 case kCodecVorbis:
163 return AV_CODEC_ID_VORBIS;
164 case kCodecFLAC:
165 return AV_CODEC_ID_FLAC;
166 case kCodecAMR_NB:
167 return AV_CODEC_ID_AMR_NB;
168 case kCodecAMR_WB:
169 return AV_CODEC_ID_AMR_WB;
170 case kCodecGSM_MS:
171 return AV_CODEC_ID_GSM_MS;
172 case kCodecPCM_ALAW:
173 return AV_CODEC_ID_PCM_ALAW;
174 case kCodecPCM_MULAW:
175 return AV_CODEC_ID_PCM_MULAW;
176 case kCodecOpus:
177 return AV_CODEC_ID_OPUS;
178 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
179 case kCodecMpegHAudio:
180 return AV_CODEC_ID_MPEGH_3D_AUDIO;
181 #endif
182 default:
183 DVLOG(1) << "Unknown AudioCodec: " << audio_codec;
184 }
185 return AV_CODEC_ID_NONE;
186 }
187
188 // Converts an FFmpeg video codec ID into its corresponding supported codec id.
CodecIDToVideoCodec(AVCodecID codec_id)189 static VideoCodec CodecIDToVideoCodec(AVCodecID codec_id) {
190 switch (codec_id) {
191 case AV_CODEC_ID_H264:
192 return kCodecH264;
193 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
194 case AV_CODEC_ID_HEVC:
195 return kCodecHEVC;
196 #endif
197 case AV_CODEC_ID_THEORA:
198 return kCodecTheora;
199 case AV_CODEC_ID_MPEG4:
200 return kCodecMPEG4;
201 case AV_CODEC_ID_VP8:
202 return kCodecVP8;
203 case AV_CODEC_ID_VP9:
204 return kCodecVP9;
205 case AV_CODEC_ID_AV1:
206 return kCodecAV1;
207 default:
208 DVLOG(1) << "Unknown video CodecID: " << codec_id;
209 }
210 return kUnknownVideoCodec;
211 }
212
VideoCodecToCodecID(VideoCodec video_codec)213 AVCodecID VideoCodecToCodecID(VideoCodec video_codec) {
214 switch (video_codec) {
215 case kCodecH264:
216 return AV_CODEC_ID_H264;
217 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
218 case kCodecHEVC:
219 return AV_CODEC_ID_HEVC;
220 #endif
221 case kCodecTheora:
222 return AV_CODEC_ID_THEORA;
223 case kCodecMPEG4:
224 return AV_CODEC_ID_MPEG4;
225 case kCodecVP8:
226 return AV_CODEC_ID_VP8;
227 case kCodecVP9:
228 return AV_CODEC_ID_VP9;
229 case kCodecAV1:
230 return AV_CODEC_ID_AV1;
231 default:
232 DVLOG(1) << "Unknown VideoCodec: " << video_codec;
233 }
234 return AV_CODEC_ID_NONE;
235 }
236
ProfileIDToVideoCodecProfile(int profile)237 static VideoCodecProfile ProfileIDToVideoCodecProfile(int profile) {
238 // Clear out the CONSTRAINED & INTRA flags which are strict subsets of the
239 // corresponding profiles with which they're used.
240 profile &= ~FF_PROFILE_H264_CONSTRAINED;
241 profile &= ~FF_PROFILE_H264_INTRA;
242 switch (profile) {
243 case FF_PROFILE_H264_BASELINE:
244 return H264PROFILE_BASELINE;
245 case FF_PROFILE_H264_MAIN:
246 return H264PROFILE_MAIN;
247 case FF_PROFILE_H264_EXTENDED:
248 return H264PROFILE_EXTENDED;
249 case FF_PROFILE_H264_HIGH:
250 return H264PROFILE_HIGH;
251 case FF_PROFILE_H264_HIGH_10:
252 return H264PROFILE_HIGH10PROFILE;
253 case FF_PROFILE_H264_HIGH_422:
254 return H264PROFILE_HIGH422PROFILE;
255 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
256 return H264PROFILE_HIGH444PREDICTIVEPROFILE;
257 default:
258 DVLOG(1) << "Unknown profile id: " << profile;
259 }
260 return VIDEO_CODEC_PROFILE_UNKNOWN;
261 }
262
VideoCodecProfileToProfileID(VideoCodecProfile profile)263 static int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
264 switch (profile) {
265 case H264PROFILE_BASELINE:
266 return FF_PROFILE_H264_BASELINE;
267 case H264PROFILE_MAIN:
268 return FF_PROFILE_H264_MAIN;
269 case H264PROFILE_EXTENDED:
270 return FF_PROFILE_H264_EXTENDED;
271 case H264PROFILE_HIGH:
272 return FF_PROFILE_H264_HIGH;
273 case H264PROFILE_HIGH10PROFILE:
274 return FF_PROFILE_H264_HIGH_10;
275 case H264PROFILE_HIGH422PROFILE:
276 return FF_PROFILE_H264_HIGH_422;
277 case H264PROFILE_HIGH444PREDICTIVEPROFILE:
278 return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
279 default:
280 DVLOG(1) << "Unknown VideoCodecProfile: " << profile;
281 }
282 return FF_PROFILE_UNKNOWN;
283 }
284
AVSampleFormatToSampleFormat(AVSampleFormat sample_format,AVCodecID codec_id)285 SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format,
286 AVCodecID codec_id) {
287 switch (sample_format) {
288 case AV_SAMPLE_FMT_U8:
289 return kSampleFormatU8;
290 case AV_SAMPLE_FMT_S16:
291 return kSampleFormatS16;
292 case AV_SAMPLE_FMT_S32:
293 if (codec_id == AV_CODEC_ID_PCM_S24LE)
294 return kSampleFormatS24;
295 else
296 return kSampleFormatS32;
297 case AV_SAMPLE_FMT_FLT:
298 return kSampleFormatF32;
299 case AV_SAMPLE_FMT_S16P:
300 return kSampleFormatPlanarS16;
301 case AV_SAMPLE_FMT_S32P:
302 return kSampleFormatPlanarS32;
303 case AV_SAMPLE_FMT_FLTP:
304 return kSampleFormatPlanarF32;
305 default:
306 DVLOG(1) << "Unknown AVSampleFormat: " << sample_format;
307 }
308 return kUnknownSampleFormat;
309 }
310
SampleFormatToAVSampleFormat(SampleFormat sample_format)311 static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) {
312 switch (sample_format) {
313 case kSampleFormatU8:
314 return AV_SAMPLE_FMT_U8;
315 case kSampleFormatS16:
316 return AV_SAMPLE_FMT_S16;
317 // pcm_s24le is treated as a codec with sample format s32 in ffmpeg
318 case kSampleFormatS24:
319 case kSampleFormatS32:
320 return AV_SAMPLE_FMT_S32;
321 case kSampleFormatF32:
322 return AV_SAMPLE_FMT_FLT;
323 case kSampleFormatPlanarS16:
324 return AV_SAMPLE_FMT_S16P;
325 case kSampleFormatPlanarF32:
326 return AV_SAMPLE_FMT_FLTP;
327 default:
328 DVLOG(1) << "Unknown SampleFormat: " << sample_format;
329 }
330 return AV_SAMPLE_FMT_NONE;
331 }
332
AVCodecContextToAudioDecoderConfig(const AVCodecContext * codec_context,EncryptionScheme encryption_scheme,AudioDecoderConfig * config)333 bool AVCodecContextToAudioDecoderConfig(const AVCodecContext* codec_context,
334 EncryptionScheme encryption_scheme,
335 AudioDecoderConfig* config) {
336 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO);
337
338 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
339
340 SampleFormat sample_format = AVSampleFormatToSampleFormat(
341 codec_context->sample_fmt, codec_context->codec_id);
342
343 ChannelLayout channel_layout =
344 codec_context->channels > 8
345 ? CHANNEL_LAYOUT_DISCRETE
346 : ChannelLayoutToChromeChannelLayout(codec_context->channel_layout,
347 codec_context->channels);
348
349 int sample_rate = codec_context->sample_rate;
350 switch (codec) {
351 // For AC3/EAC3 we enable only demuxing, but not decoding, so FFmpeg does
352 // not fill |sample_fmt|.
353 case kCodecAC3:
354 case kCodecEAC3:
355 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
356 // The spec for AC3/EAC3 audio is ETSI TS 102 366. According to sections
357 // F.3.1 and F.5.1 in that spec the sample_format for AC3/EAC3 must be 16.
358 sample_format = kSampleFormatS16;
359 #else
360 NOTREACHED();
361 #endif
362 break;
363 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
364 case kCodecMpegHAudio:
365 channel_layout = CHANNEL_LAYOUT_BITSTREAM;
366 sample_format = kSampleFormatMpegHAudio;
367 break;
368 #endif
369
370 default:
371 break;
372 }
373
374 base::TimeDelta seek_preroll;
375 if (codec_context->seek_preroll > 0) {
376 seek_preroll = base::TimeDelta::FromMicroseconds(
377 codec_context->seek_preroll * 1000000.0 / codec_context->sample_rate);
378 }
379
380 // AVStream occasionally has invalid extra data. See http://crbug.com/517163
381 if ((codec_context->extradata_size == 0) !=
382 (codec_context->extradata == nullptr)) {
383 LOG(ERROR) << __func__
384 << (codec_context->extradata == nullptr ? " NULL" : " Non-NULL")
385 << " extra data cannot have size of "
386 << codec_context->extradata_size << ".";
387 return false;
388 }
389
390 std::vector<uint8_t> extra_data;
391 if (codec_context->extradata_size > 0) {
392 extra_data.assign(codec_context->extradata,
393 codec_context->extradata + codec_context->extradata_size);
394 }
395
396 config->Initialize(codec, sample_format, channel_layout, sample_rate,
397 extra_data, encryption_scheme, seek_preroll,
398 codec_context->delay);
399 if (channel_layout == CHANNEL_LAYOUT_DISCRETE)
400 config->SetChannelsForDiscrete(codec_context->channels);
401
402 #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
403 // These are bitstream formats unknown to ffmpeg, so they don't have
404 // a known sample format size.
405 if (codec == kCodecAC3 || codec == kCodecEAC3)
406 return true;
407 #endif
408 #if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
409 if (codec == kCodecMpegHAudio)
410 return true;
411 #endif
412
413 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
414 // TODO(dalecurtis): Just use the profile from the codec context if ffmpeg
415 // ever starts supporting xHE-AAC.
416 if (codec == kCodecAAC && codec_context->profile == FF_PROFILE_UNKNOWN) {
417 // Errors aren't fatal here, so just drop any MediaLog messages.
418 NullMediaLog media_log;
419 mp4::AAC aac_parser;
420 if (aac_parser.Parse(extra_data, &media_log))
421 config->set_profile(aac_parser.GetProfile());
422 }
423 #endif
424
425 // Verify that AudioConfig.bits_per_channel was calculated correctly for
426 // codecs that have |sample_fmt| set by FFmpeg.
427 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
428 config->bits_per_channel());
429 return true;
430 }
431
432 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext>
AVStreamToAVCodecContext(const AVStream * stream)433 AVStreamToAVCodecContext(const AVStream* stream) {
434 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
435 avcodec_alloc_context3(nullptr));
436 if (avcodec_parameters_to_context(codec_context.get(), stream->codecpar) <
437 0) {
438 return nullptr;
439 }
440
441 return codec_context;
442 }
443
AVStreamToAudioDecoderConfig(const AVStream * stream,AudioDecoderConfig * config)444 bool AVStreamToAudioDecoderConfig(const AVStream* stream,
445 AudioDecoderConfig* config) {
446 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
447 AVStreamToAVCodecContext(stream));
448 if (!codec_context)
449 return false;
450
451 return AVCodecContextToAudioDecoderConfig(
452 codec_context.get(), GetEncryptionScheme(stream), config);
453 }
454
AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig & config,AVCodecContext * codec_context)455 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
456 AVCodecContext* codec_context) {
457 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
458 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
459 config.sample_format());
460 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
461 config.sample_format());
462
463 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
464 // said information to decode.
465 codec_context->channels = config.channels();
466 codec_context->sample_rate = config.samples_per_second();
467
468 if (config.extra_data().empty()) {
469 codec_context->extradata = nullptr;
470 codec_context->extradata_size = 0;
471 } else {
472 codec_context->extradata_size = config.extra_data().size();
473 codec_context->extradata = reinterpret_cast<uint8_t*>(
474 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
475 memcpy(codec_context->extradata, &config.extra_data()[0],
476 config.extra_data().size());
477 memset(codec_context->extradata + config.extra_data().size(), '\0',
478 AV_INPUT_BUFFER_PADDING_SIZE);
479 }
480 }
481
AVStreamToVideoDecoderConfig(const AVStream * stream,VideoDecoderConfig * config)482 bool AVStreamToVideoDecoderConfig(const AVStream* stream,
483 VideoDecoderConfig* config) {
484 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
485 AVStreamToAVCodecContext(stream));
486 if (!codec_context)
487 return false;
488
489 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
490 // for now, but may not always be true forever. Fix this in the future.
491 gfx::Rect visible_rect(codec_context->width, codec_context->height);
492 gfx::Size coded_size = visible_rect.size();
493
494 AVRational aspect_ratio = {1, 1};
495 if (stream->sample_aspect_ratio.num)
496 aspect_ratio = stream->sample_aspect_ratio;
497 else if (codec_context->sample_aspect_ratio.num)
498 aspect_ratio = codec_context->sample_aspect_ratio;
499
500 VideoCodec codec = CodecIDToVideoCodec(codec_context->codec_id);
501
502 gfx::Size natural_size =
503 GetNaturalSize(visible_rect.size(), aspect_ratio.num, aspect_ratio.den);
504
505 // Without the ffmpeg decoder configured, libavformat is unable to get the
506 // profile, format, or coded size. So choose sensible defaults and let
507 // decoders fail later if the configuration is actually unsupported.
508 //
509 // TODO(chcunningham): We need real profiles for all of the codecs below to
510 // actually handle capabilities requests correctly. http://crbug.com/784610
511 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
512 switch (codec) {
513 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
514 case kCodecH264: {
515 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
516 // if the profile is still unknown, try to extract it from
517 // the extradata using the internal parser
518 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN && codec_context->extradata &&
519 codec_context->extradata_size) {
520 mp4::AVCDecoderConfigurationRecord avc_config;
521 if (avc_config.Parse(codec_context->extradata,
522 codec_context->extradata_size)) {
523 profile = ProfileIDToVideoCodecProfile(avc_config.profile_indication);
524 }
525 }
526 // All the heuristics failed, let's assign a default profile
527 if (profile == VIDEO_CODEC_PROFILE_UNKNOWN)
528 profile = H264PROFILE_BASELINE;
529 break;
530 }
531 #endif
532 case kCodecVP8:
533 profile = VP8PROFILE_ANY;
534 break;
535 case kCodecVP9:
536 switch (codec_context->profile) {
537 case FF_PROFILE_VP9_0:
538 profile = VP9PROFILE_PROFILE0;
539 break;
540 case FF_PROFILE_VP9_1:
541 profile = VP9PROFILE_PROFILE1;
542 break;
543 case FF_PROFILE_VP9_2:
544 profile = VP9PROFILE_PROFILE2;
545 break;
546 case FF_PROFILE_VP9_3:
547 profile = VP9PROFILE_PROFILE3;
548 break;
549 default:
550 profile = VP9PROFILE_MIN;
551 break;
552 }
553 break;
554 case kCodecAV1:
555 profile = AV1PROFILE_PROFILE_MAIN;
556 break;
557 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
558 case kCodecHEVC:
559 profile = HEVCPROFILE_MAIN;
560 break;
561 #endif
562 case kCodecTheora:
563 profile = THEORAPROFILE_ANY;
564 break;
565 default:
566 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
567 }
568
569 auto* alpha_mode = av_dict_get(stream->metadata, "alpha_mode", nullptr, 0);
570 const bool has_alpha = alpha_mode && !strcmp(alpha_mode->value, "1");
571
572 VideoRotation video_rotation = VIDEO_ROTATION_0;
573 int rotation = 0;
574 AVDictionaryEntry* rotation_entry = NULL;
575 rotation_entry = av_dict_get(stream->metadata, "rotate", nullptr, 0);
576 if (rotation_entry && rotation_entry->value && rotation_entry->value[0])
577 base::StringToInt(rotation_entry->value, &rotation);
578
579 switch (rotation) {
580 case 0:
581 break;
582 case 90:
583 video_rotation = VIDEO_ROTATION_90;
584 break;
585 case 180:
586 video_rotation = VIDEO_ROTATION_180;
587 break;
588 case 270:
589 video_rotation = VIDEO_ROTATION_270;
590 break;
591 default:
592 DLOG(ERROR) << "Unsupported video rotation metadata: " << rotation;
593 break;
594 }
595
596 // Prefer the color space found by libavcodec if available.
597 VideoColorSpace color_space =
598 VideoColorSpace(codec_context->color_primaries, codec_context->color_trc,
599 codec_context->colorspace,
600 codec_context->color_range == AVCOL_RANGE_JPEG
601 ? gfx::ColorSpace::RangeID::FULL
602 : gfx::ColorSpace::RangeID::LIMITED);
603 if (!color_space.IsSpecified()) {
604 // VP9 frames may have color information, but that information cannot
605 // express new color spaces, like HDR. For that reason, color space
606 // information from the container should take precedence over color space
607 // information from the VP9 stream. However, if we infer the color space
608 // based on resolution here, it looks as if it came from the container.
609 // Since this inference causes color shifts and is slated to go away
610 // we just skip it for VP9 and leave the color space undefined, which
611 // will make the VP9 decoder behave correctly..
612 // We also ignore the resolution for AV1, since it's new and it's easy
613 // to make it behave correctly from the get-go.
614 // TODO(hubbe): Skip this inference for all codecs.
615 if (codec_context->codec_id != AV_CODEC_ID_VP9 &&
616 codec_context->codec_id != AV_CODEC_ID_AV1) {
617 // Otherwise, assume that SD video is usually Rec.601, and HD is usually
618 // Rec.709.
619 color_space = (natural_size.height() < 720) ? VideoColorSpace::REC601()
620 : VideoColorSpace::REC709();
621 }
622 }
623
624 // AVCodecContext occasionally has invalid extra data. See
625 // http://crbug.com/517163
626 if (codec_context->extradata != nullptr &&
627 codec_context->extradata_size == 0) {
628 DLOG(ERROR) << __func__ << " Non-Null extra data cannot have size of 0.";
629 return false;
630 }
631
632 std::vector<uint8_t> extra_data;
633 if (codec_context->extradata_size > 0) {
634 extra_data.assign(codec_context->extradata,
635 codec_context->extradata + codec_context->extradata_size);
636 }
637 // TODO(tmathmeyer) ffmpeg can't provide us with an actual video rotation yet.
638 config->Initialize(codec, profile,
639 has_alpha ? VideoDecoderConfig::AlphaMode::kHasAlpha
640 : VideoDecoderConfig::AlphaMode::kIsOpaque,
641 color_space, VideoTransformation(video_rotation),
642 coded_size, visible_rect, natural_size, extra_data,
643 GetEncryptionScheme(stream));
644
645 if (stream->nb_side_data) {
646 for (int i = 0; i < stream->nb_side_data; ++i) {
647 AVPacketSideData side_data = stream->side_data[i];
648 if (side_data.type != AV_PKT_DATA_MASTERING_DISPLAY_METADATA)
649 continue;
650
651 HDRMetadata hdr_metadata{};
652 AVMasteringDisplayMetadata* metadata =
653 reinterpret_cast<AVMasteringDisplayMetadata*>(side_data.data);
654 if (metadata->has_primaries) {
655 hdr_metadata.mastering_metadata.primary_r =
656 gfx::PointF(av_q2d(metadata->display_primaries[0][0]),
657 av_q2d(metadata->display_primaries[0][1]));
658 hdr_metadata.mastering_metadata.primary_g =
659 gfx::PointF(av_q2d(metadata->display_primaries[1][0]),
660 av_q2d(metadata->display_primaries[1][1]));
661 hdr_metadata.mastering_metadata.primary_b =
662 gfx::PointF(av_q2d(metadata->display_primaries[2][0]),
663 av_q2d(metadata->display_primaries[2][1]));
664 hdr_metadata.mastering_metadata.white_point = gfx::PointF(
665 av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
666 }
667 if (metadata->has_luminance) {
668 hdr_metadata.mastering_metadata.luminance_max =
669 av_q2d(metadata->max_luminance);
670 hdr_metadata.mastering_metadata.luminance_min =
671 av_q2d(metadata->min_luminance);
672 }
673 config->set_hdr_metadata(hdr_metadata);
674 }
675 }
676
677 return true;
678 }
679
VideoDecoderConfigToAVCodecContext(const VideoDecoderConfig & config,AVCodecContext * codec_context)680 void VideoDecoderConfigToAVCodecContext(
681 const VideoDecoderConfig& config,
682 AVCodecContext* codec_context) {
683 codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
684 codec_context->codec_id = VideoCodecToCodecID(config.codec());
685 codec_context->profile = VideoCodecProfileToProfileID(config.profile());
686 codec_context->coded_width = config.coded_size().width();
687 codec_context->coded_height = config.coded_size().height();
688 if (config.color_space_info().range == gfx::ColorSpace::RangeID::FULL)
689 codec_context->color_range = AVCOL_RANGE_JPEG;
690
691 if (config.extra_data().empty()) {
692 codec_context->extradata = nullptr;
693 codec_context->extradata_size = 0;
694 } else {
695 codec_context->extradata_size = config.extra_data().size();
696 codec_context->extradata = reinterpret_cast<uint8_t*>(
697 av_malloc(config.extra_data().size() + AV_INPUT_BUFFER_PADDING_SIZE));
698 memcpy(codec_context->extradata, &config.extra_data()[0],
699 config.extra_data().size());
700 memset(codec_context->extradata + config.extra_data().size(), '\0',
701 AV_INPUT_BUFFER_PADDING_SIZE);
702 }
703 }
704
ChannelLayoutToChromeChannelLayout(int64_t layout,int channels)705 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
706 switch (layout) {
707 case AV_CH_LAYOUT_MONO:
708 return CHANNEL_LAYOUT_MONO;
709 case AV_CH_LAYOUT_STEREO:
710 return CHANNEL_LAYOUT_STEREO;
711 case AV_CH_LAYOUT_2_1:
712 return CHANNEL_LAYOUT_2_1;
713 case AV_CH_LAYOUT_SURROUND:
714 return CHANNEL_LAYOUT_SURROUND;
715 case AV_CH_LAYOUT_4POINT0:
716 return CHANNEL_LAYOUT_4_0;
717 case AV_CH_LAYOUT_2_2:
718 return CHANNEL_LAYOUT_2_2;
719 case AV_CH_LAYOUT_QUAD:
720 return CHANNEL_LAYOUT_QUAD;
721 case AV_CH_LAYOUT_5POINT0:
722 return CHANNEL_LAYOUT_5_0;
723 case AV_CH_LAYOUT_5POINT1:
724 return CHANNEL_LAYOUT_5_1;
725 case AV_CH_LAYOUT_5POINT0_BACK:
726 return CHANNEL_LAYOUT_5_0_BACK;
727 case AV_CH_LAYOUT_5POINT1_BACK:
728 return CHANNEL_LAYOUT_5_1_BACK;
729 case AV_CH_LAYOUT_7POINT0:
730 return CHANNEL_LAYOUT_7_0;
731 case AV_CH_LAYOUT_7POINT1:
732 return CHANNEL_LAYOUT_7_1;
733 case AV_CH_LAYOUT_7POINT1_WIDE:
734 return CHANNEL_LAYOUT_7_1_WIDE;
735 case AV_CH_LAYOUT_STEREO_DOWNMIX:
736 return CHANNEL_LAYOUT_STEREO_DOWNMIX;
737 case AV_CH_LAYOUT_2POINT1:
738 return CHANNEL_LAYOUT_2POINT1;
739 case AV_CH_LAYOUT_3POINT1:
740 return CHANNEL_LAYOUT_3_1;
741 case AV_CH_LAYOUT_4POINT1:
742 return CHANNEL_LAYOUT_4_1;
743 case AV_CH_LAYOUT_6POINT0:
744 return CHANNEL_LAYOUT_6_0;
745 case AV_CH_LAYOUT_6POINT0_FRONT:
746 return CHANNEL_LAYOUT_6_0_FRONT;
747 case AV_CH_LAYOUT_HEXAGONAL:
748 return CHANNEL_LAYOUT_HEXAGONAL;
749 case AV_CH_LAYOUT_6POINT1:
750 return CHANNEL_LAYOUT_6_1;
751 case AV_CH_LAYOUT_6POINT1_BACK:
752 return CHANNEL_LAYOUT_6_1_BACK;
753 case AV_CH_LAYOUT_6POINT1_FRONT:
754 return CHANNEL_LAYOUT_6_1_FRONT;
755 case AV_CH_LAYOUT_7POINT0_FRONT:
756 return CHANNEL_LAYOUT_7_0_FRONT;
757 #ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
758 case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
759 return CHANNEL_LAYOUT_7_1_WIDE_BACK;
760 #endif
761 case AV_CH_LAYOUT_OCTAGONAL:
762 return CHANNEL_LAYOUT_OCTAGONAL;
763 default:
764 // FFmpeg channel_layout is 0 for .wav and .mp3. Attempt to guess layout
765 // based on the channel count.
766 return GuessChannelLayout(channels);
767 }
768 }
769
AVPixelFormatToVideoPixelFormat(AVPixelFormat pixel_format)770 VideoPixelFormat AVPixelFormatToVideoPixelFormat(AVPixelFormat pixel_format) {
771 // The YUVJ alternatives are FFmpeg's (deprecated, but still in use) way to
772 // specify a pixel format and full range color combination.
773 switch (pixel_format) {
774 case AV_PIX_FMT_YUV444P:
775 case AV_PIX_FMT_YUVJ444P:
776 return PIXEL_FORMAT_I444;
777
778 case AV_PIX_FMT_YUV420P:
779 case AV_PIX_FMT_YUVJ420P:
780 return PIXEL_FORMAT_I420;
781
782 case AV_PIX_FMT_YUV422P:
783 case AV_PIX_FMT_YUVJ422P:
784 return PIXEL_FORMAT_I422;
785
786 case AV_PIX_FMT_YUVA420P:
787 return PIXEL_FORMAT_I420A;
788
789 case AV_PIX_FMT_YUV420P9LE:
790 return PIXEL_FORMAT_YUV420P9;
791 case AV_PIX_FMT_YUV420P10LE:
792 return PIXEL_FORMAT_YUV420P10;
793 case AV_PIX_FMT_YUV420P12LE:
794 return PIXEL_FORMAT_YUV420P12;
795
796 case AV_PIX_FMT_YUV422P9LE:
797 return PIXEL_FORMAT_YUV422P9;
798 case AV_PIX_FMT_YUV422P10LE:
799 return PIXEL_FORMAT_YUV422P10;
800 case AV_PIX_FMT_YUV422P12LE:
801 return PIXEL_FORMAT_YUV422P12;
802
803 case AV_PIX_FMT_YUV444P9LE:
804 return PIXEL_FORMAT_YUV444P9;
805 case AV_PIX_FMT_YUV444P10LE:
806 return PIXEL_FORMAT_YUV444P10;
807 case AV_PIX_FMT_YUV444P12LE:
808 return PIXEL_FORMAT_YUV444P12;
809
810 case AV_PIX_FMT_P016LE:
811 return PIXEL_FORMAT_P016LE;
812
813 default:
814 DVLOG(1) << "Unsupported AVPixelFormat: " << pixel_format;
815 }
816 return PIXEL_FORMAT_UNKNOWN;
817 }
818
AVColorSpaceToColorSpace(AVColorSpace color_space,AVColorRange color_range)819 VideoColorSpace AVColorSpaceToColorSpace(AVColorSpace color_space,
820 AVColorRange color_range) {
821 // TODO(hubbe): make this better
822 if (color_range == AVCOL_RANGE_JPEG)
823 return VideoColorSpace::JPEG();
824
825 switch (color_space) {
826 case AVCOL_SPC_UNSPECIFIED:
827 break;
828 case AVCOL_SPC_BT709:
829 return VideoColorSpace::REC709();
830 case AVCOL_SPC_SMPTE170M:
831 case AVCOL_SPC_BT470BG:
832 return VideoColorSpace::REC601();
833 default:
834 DVLOG(1) << "Unknown AVColorSpace: " << color_space;
835 }
836 return VideoColorSpace();
837 }
838
AVErrorToString(int errnum)839 std::string AVErrorToString(int errnum) {
840 char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
841 av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
842 return std::string(errbuf);
843 }
844
HashCodecName(const char * codec_name)845 int32_t HashCodecName(const char* codec_name) {
846 // Use the first 32-bits from the SHA1 hash as the identifier.
847 int32_t hash;
848 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4);
849 return hash;
850 }
851
852 } // namespace media
853