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