All instances of addresses as void* are changed to uintptr_t in
[chromium-blink-merge.git] / media / ffmpeg / ffmpeg_common.cc
blobf4f9e31935ac91c3679d88628cf94220bbfc14f4
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.
5 #include "media/ffmpeg/ffmpeg_common.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h"
13 #include "media/base/decoder_buffer.h"
14 #include "media/base/video_decoder_config.h"
15 #include "media/base/video_util.h"
17 namespace media {
19 // Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
20 // padded. Check here to ensure FFmpeg only receives data padded to its
21 // specifications.
22 static_assert(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE,
23 "DecoderBuffer padding size does not fit ffmpeg requirement");
25 // Alignment requirement by FFmpeg for input and output buffers. This need to
26 // be updated to match FFmpeg when it changes.
27 #if defined(ARCH_CPU_ARM_FAMILY)
28 static const int kFFmpegBufferAddressAlignment = 16;
29 #else
30 static const int kFFmpegBufferAddressAlignment = 32;
31 #endif
33 // Check here to ensure FFmpeg only receives data aligned to its specifications.
34 static_assert(
35 DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
36 DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
37 "DecoderBuffer alignment size does not fit ffmpeg requirement");
39 // Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
40 // See video_get_buffer() in libavcodec/utils.c.
41 static const int kFFmpegOutputBufferPaddingSize = 16;
43 static_assert(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
44 "VideoFrame padding size does not fit ffmpeg requirement");
46 static_assert(
47 VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
48 VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
49 "VideoFrame frame address alignment does not fit ffmpeg requirement");
51 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
53 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base,
54 int64 timestamp) {
55 int64 microseconds = av_rescale_q(timestamp, time_base, kMicrosBase);
56 return base::TimeDelta::FromMicroseconds(microseconds);
59 int64 ConvertToTimeBase(const AVRational& time_base,
60 const base::TimeDelta& timestamp) {
61 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base);
64 // Converts an FFmpeg audio codec ID into its corresponding supported codec id.
65 static AudioCodec CodecIDToAudioCodec(AVCodecID codec_id) {
66 switch (codec_id) {
67 case AV_CODEC_ID_AAC:
68 return kCodecAAC;
69 case AV_CODEC_ID_MP3:
70 return kCodecMP3;
71 case AV_CODEC_ID_VORBIS:
72 return kCodecVorbis;
73 case AV_CODEC_ID_PCM_U8:
74 case AV_CODEC_ID_PCM_S16LE:
75 case AV_CODEC_ID_PCM_S24LE:
76 case AV_CODEC_ID_PCM_F32LE:
77 return kCodecPCM;
78 case AV_CODEC_ID_PCM_S16BE:
79 return kCodecPCM_S16BE;
80 case AV_CODEC_ID_PCM_S24BE:
81 return kCodecPCM_S24BE;
82 case AV_CODEC_ID_FLAC:
83 return kCodecFLAC;
84 case AV_CODEC_ID_AMR_NB:
85 return kCodecAMR_NB;
86 case AV_CODEC_ID_AMR_WB:
87 return kCodecAMR_WB;
88 case AV_CODEC_ID_GSM_MS:
89 return kCodecGSM_MS;
90 case AV_CODEC_ID_PCM_ALAW:
91 return kCodecPCM_ALAW;
92 case AV_CODEC_ID_PCM_MULAW:
93 return kCodecPCM_MULAW;
94 case AV_CODEC_ID_OPUS:
95 return kCodecOpus;
96 case AV_CODEC_ID_ALAC:
97 return kCodecALAC;
98 default:
99 DVLOG(1) << "Unknown audio CodecID: " << codec_id;
101 return kUnknownAudioCodec;
104 static AVCodecID AudioCodecToCodecID(AudioCodec audio_codec,
105 SampleFormat sample_format) {
106 switch (audio_codec) {
107 case kCodecAAC:
108 return AV_CODEC_ID_AAC;
109 case kCodecALAC:
110 return AV_CODEC_ID_ALAC;
111 case kCodecMP3:
112 return AV_CODEC_ID_MP3;
113 case kCodecPCM:
114 switch (sample_format) {
115 case kSampleFormatU8:
116 return AV_CODEC_ID_PCM_U8;
117 case kSampleFormatS16:
118 return AV_CODEC_ID_PCM_S16LE;
119 case kSampleFormatS32:
120 return AV_CODEC_ID_PCM_S24LE;
121 case kSampleFormatF32:
122 return AV_CODEC_ID_PCM_F32LE;
123 default:
124 DVLOG(1) << "Unsupported sample format: " << sample_format;
126 break;
127 case kCodecPCM_S16BE:
128 return AV_CODEC_ID_PCM_S16BE;
129 case kCodecPCM_S24BE:
130 return AV_CODEC_ID_PCM_S24BE;
131 case kCodecVorbis:
132 return AV_CODEC_ID_VORBIS;
133 case kCodecFLAC:
134 return AV_CODEC_ID_FLAC;
135 case kCodecAMR_NB:
136 return AV_CODEC_ID_AMR_NB;
137 case kCodecAMR_WB:
138 return AV_CODEC_ID_AMR_WB;
139 case kCodecGSM_MS:
140 return AV_CODEC_ID_GSM_MS;
141 case kCodecPCM_ALAW:
142 return AV_CODEC_ID_PCM_ALAW;
143 case kCodecPCM_MULAW:
144 return AV_CODEC_ID_PCM_MULAW;
145 case kCodecOpus:
146 return AV_CODEC_ID_OPUS;
147 default:
148 DVLOG(1) << "Unknown AudioCodec: " << audio_codec;
150 return AV_CODEC_ID_NONE;
153 // Converts an FFmpeg video codec ID into its corresponding supported codec id.
154 static VideoCodec CodecIDToVideoCodec(AVCodecID codec_id) {
155 switch (codec_id) {
156 case AV_CODEC_ID_H264:
157 return kCodecH264;
158 #if defined(ENABLE_HEVC_DEMUXING)
159 case AV_CODEC_ID_HEVC:
160 return kCodecHEVC;
161 #endif
162 case AV_CODEC_ID_THEORA:
163 return kCodecTheora;
164 case AV_CODEC_ID_MPEG4:
165 return kCodecMPEG4;
166 case AV_CODEC_ID_VP8:
167 return kCodecVP8;
168 case AV_CODEC_ID_VP9:
169 return kCodecVP9;
170 default:
171 DVLOG(1) << "Unknown video CodecID: " << codec_id;
173 return kUnknownVideoCodec;
176 AVCodecID VideoCodecToCodecID(VideoCodec video_codec) {
177 switch (video_codec) {
178 case kCodecH264:
179 return AV_CODEC_ID_H264;
180 #if defined(ENABLE_HEVC_DEMUXING)
181 case kCodecHEVC:
182 return AV_CODEC_ID_HEVC;
183 #endif
184 case kCodecTheora:
185 return AV_CODEC_ID_THEORA;
186 case kCodecMPEG4:
187 return AV_CODEC_ID_MPEG4;
188 case kCodecVP8:
189 return AV_CODEC_ID_VP8;
190 case kCodecVP9:
191 return AV_CODEC_ID_VP9;
192 default:
193 DVLOG(1) << "Unknown VideoCodec: " << video_codec;
195 return AV_CODEC_ID_NONE;
198 static VideoCodecProfile ProfileIDToVideoCodecProfile(int profile) {
199 // Clear out the CONSTRAINED & INTRA flags which are strict subsets of the
200 // corresponding profiles with which they're used.
201 profile &= ~FF_PROFILE_H264_CONSTRAINED;
202 profile &= ~FF_PROFILE_H264_INTRA;
203 switch (profile) {
204 case FF_PROFILE_H264_BASELINE:
205 return H264PROFILE_BASELINE;
206 case FF_PROFILE_H264_MAIN:
207 return H264PROFILE_MAIN;
208 case FF_PROFILE_H264_EXTENDED:
209 return H264PROFILE_EXTENDED;
210 case FF_PROFILE_H264_HIGH:
211 return H264PROFILE_HIGH;
212 case FF_PROFILE_H264_HIGH_10:
213 return H264PROFILE_HIGH10PROFILE;
214 case FF_PROFILE_H264_HIGH_422:
215 return H264PROFILE_HIGH422PROFILE;
216 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
217 return H264PROFILE_HIGH444PREDICTIVEPROFILE;
218 default:
219 DVLOG(1) << "Unknown profile id: " << profile;
221 return VIDEO_CODEC_PROFILE_UNKNOWN;
224 static int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
225 switch (profile) {
226 case H264PROFILE_BASELINE:
227 return FF_PROFILE_H264_BASELINE;
228 case H264PROFILE_MAIN:
229 return FF_PROFILE_H264_MAIN;
230 case H264PROFILE_EXTENDED:
231 return FF_PROFILE_H264_EXTENDED;
232 case H264PROFILE_HIGH:
233 return FF_PROFILE_H264_HIGH;
234 case H264PROFILE_HIGH10PROFILE:
235 return FF_PROFILE_H264_HIGH_10;
236 case H264PROFILE_HIGH422PROFILE:
237 return FF_PROFILE_H264_HIGH_422;
238 case H264PROFILE_HIGH444PREDICTIVEPROFILE:
239 return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
240 default:
241 DVLOG(1) << "Unknown VideoCodecProfile: " << profile;
243 return FF_PROFILE_UNKNOWN;
246 SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format) {
247 switch (sample_format) {
248 case AV_SAMPLE_FMT_U8:
249 return kSampleFormatU8;
250 case AV_SAMPLE_FMT_S16:
251 return kSampleFormatS16;
252 case AV_SAMPLE_FMT_S32:
253 return kSampleFormatS32;
254 case AV_SAMPLE_FMT_FLT:
255 return kSampleFormatF32;
256 case AV_SAMPLE_FMT_S16P:
257 return kSampleFormatPlanarS16;
258 case AV_SAMPLE_FMT_S32P:
259 return kSampleFormatPlanarS32;
260 case AV_SAMPLE_FMT_FLTP:
261 return kSampleFormatPlanarF32;
262 default:
263 DVLOG(1) << "Unknown AVSampleFormat: " << sample_format;
265 return kUnknownSampleFormat;
268 static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) {
269 switch (sample_format) {
270 case kSampleFormatU8:
271 return AV_SAMPLE_FMT_U8;
272 case kSampleFormatS16:
273 return AV_SAMPLE_FMT_S16;
274 case kSampleFormatS32:
275 return AV_SAMPLE_FMT_S32;
276 case kSampleFormatF32:
277 return AV_SAMPLE_FMT_FLT;
278 case kSampleFormatPlanarS16:
279 return AV_SAMPLE_FMT_S16P;
280 case kSampleFormatPlanarF32:
281 return AV_SAMPLE_FMT_FLTP;
282 default:
283 DVLOG(1) << "Unknown SampleFormat: " << sample_format;
285 return AV_SAMPLE_FMT_NONE;
288 void AVCodecContextToAudioDecoderConfig(const AVCodecContext* codec_context,
289 bool is_encrypted,
290 AudioDecoderConfig* config) {
291 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO);
293 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
295 SampleFormat sample_format =
296 AVSampleFormatToSampleFormat(codec_context->sample_fmt);
298 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout(
299 codec_context->channel_layout, codec_context->channels);
301 int sample_rate = codec_context->sample_rate;
302 if (codec == kCodecOpus) {
303 // |codec_context->sample_fmt| is not set by FFmpeg because Opus decoding is
304 // not enabled in FFmpeg. It doesn't matter what value is set here, so long
305 // as it's valid, the true sample format is selected inside the decoder.
306 sample_format = kSampleFormatF32;
308 // Always use 48kHz for OPUS. Technically we should match to the highest
309 // supported hardware sample rate among [8, 12, 16, 24, 48] kHz, but we
310 // don't know the hardware sample rate at this point and those rates are
311 // rarely used for output. See the "Input Sample Rate" section of the spec:
312 // http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
313 sample_rate = 48000;
316 base::TimeDelta seek_preroll;
317 if (codec_context->seek_preroll > 0) {
318 seek_preroll = base::TimeDelta::FromMicroseconds(
319 codec_context->seek_preroll * 1000000.0 / codec_context->sample_rate);
322 config->Initialize(codec,
323 sample_format,
324 channel_layout,
325 sample_rate,
326 codec_context->extradata,
327 codec_context->extradata_size,
328 is_encrypted,
329 seek_preroll,
330 codec_context->delay);
332 if (codec != kCodecOpus) {
333 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
334 config->bits_per_channel());
338 void AVStreamToAudioDecoderConfig(const AVStream* stream,
339 AudioDecoderConfig* config) {
340 bool is_encrypted = false;
341 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
342 if (key)
343 is_encrypted = true;
344 AVCodecContextToAudioDecoderConfig(stream->codec, is_encrypted, config);
347 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
348 AVCodecContext* codec_context) {
349 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
350 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
351 config.sample_format());
352 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
353 config.sample_format());
355 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
356 // said information to decode.
357 codec_context->channels =
358 ChannelLayoutToChannelCount(config.channel_layout());
359 codec_context->sample_rate = config.samples_per_second();
361 if (config.extra_data()) {
362 codec_context->extradata_size = config.extra_data_size();
363 codec_context->extradata = reinterpret_cast<uint8_t*>(
364 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
365 memcpy(codec_context->extradata, config.extra_data(),
366 config.extra_data_size());
367 memset(codec_context->extradata + config.extra_data_size(), '\0',
368 FF_INPUT_BUFFER_PADDING_SIZE);
369 } else {
370 codec_context->extradata = NULL;
371 codec_context->extradata_size = 0;
375 void AVStreamToVideoDecoderConfig(const AVStream* stream,
376 VideoDecoderConfig* config) {
377 gfx::Size coded_size(stream->codec->coded_width, stream->codec->coded_height);
379 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
380 // for now, but may not always be true forever. Fix this in the future.
381 gfx::Rect visible_rect(stream->codec->width, stream->codec->height);
383 AVRational aspect_ratio = { 1, 1 };
384 if (stream->sample_aspect_ratio.num)
385 aspect_ratio = stream->sample_aspect_ratio;
386 else if (stream->codec->sample_aspect_ratio.num)
387 aspect_ratio = stream->codec->sample_aspect_ratio;
389 VideoCodec codec = CodecIDToVideoCodec(stream->codec->codec_id);
391 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
392 if (codec == kCodecVP8)
393 profile = VP8PROFILE_ANY;
394 else if (codec == kCodecVP9)
395 profile = VP9PROFILE_ANY;
396 else
397 profile = ProfileIDToVideoCodecProfile(stream->codec->profile);
399 // Without the FFmpeg h264 decoder, AVFormat is unable to get the profile, so
400 // default to baseline and let the VDA fail later if it doesn't support the
401 // real profile. This is alright because if the FFmpeg h264 decoder isn't
402 // enabled, there is no fallback if the VDA fails.
403 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS)
404 if (codec == kCodecH264)
405 profile = H264PROFILE_BASELINE;
406 #endif
408 gfx::Size natural_size = GetNaturalSize(
409 visible_rect.size(), aspect_ratio.num, aspect_ratio.den);
411 VideoPixelFormat format =
412 AVPixelFormatToVideoPixelFormat(stream->codec->pix_fmt);
413 // The format and coded size may be unknown if FFmpeg is compiled without
414 // video decoders.
415 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS)
416 if (format == PIXEL_FORMAT_UNKNOWN)
417 format = PIXEL_FORMAT_YV12;
418 if (coded_size == gfx::Size(0, 0))
419 coded_size = visible_rect.size();
420 #endif
422 if (codec == kCodecVP9) {
423 // TODO(tomfinegan): libavcodec doesn't know about VP9.
424 format = PIXEL_FORMAT_YV12;
425 coded_size = visible_rect.size();
428 // Pad out |coded_size| for subsampled YUV formats.
429 if (format != PIXEL_FORMAT_YV24) {
430 coded_size.set_width((coded_size.width() + 1) / 2 * 2);
431 if (format != PIXEL_FORMAT_YV16)
432 coded_size.set_height((coded_size.height() + 1) / 2 * 2);
435 bool is_encrypted = false;
436 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
437 if (key)
438 is_encrypted = true;
440 AVDictionaryEntry* webm_alpha =
441 av_dict_get(stream->metadata, "alpha_mode", NULL, 0);
442 if (webm_alpha && !strcmp(webm_alpha->value, "1")) {
443 format = PIXEL_FORMAT_YV12A;
446 // Prefer the color space found by libavcodec if available.
447 ColorSpace color_space = AVColorSpaceToColorSpace(stream->codec->colorspace,
448 stream->codec->color_range);
449 if (color_space == COLOR_SPACE_UNSPECIFIED) {
450 // Otherwise, assume that SD video is usually Rec.601, and HD is usually
451 // Rec.709.
452 color_space = (natural_size.height() < 720) ? COLOR_SPACE_SD_REC601
453 : COLOR_SPACE_HD_REC709;
456 config->Initialize(codec, profile, format, color_space, coded_size,
457 visible_rect, natural_size, stream->codec->extradata,
458 stream->codec->extradata_size, is_encrypted);
461 void VideoDecoderConfigToAVCodecContext(
462 const VideoDecoderConfig& config,
463 AVCodecContext* codec_context) {
464 codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
465 codec_context->codec_id = VideoCodecToCodecID(config.codec());
466 codec_context->profile = VideoCodecProfileToProfileID(config.profile());
467 codec_context->coded_width = config.coded_size().width();
468 codec_context->coded_height = config.coded_size().height();
469 codec_context->pix_fmt = VideoPixelFormatToAVPixelFormat(config.format());
470 if (config.color_space() == COLOR_SPACE_JPEG)
471 codec_context->color_range = AVCOL_RANGE_JPEG;
473 if (config.extra_data()) {
474 codec_context->extradata_size = config.extra_data_size();
475 codec_context->extradata = reinterpret_cast<uint8_t*>(
476 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
477 memcpy(codec_context->extradata, config.extra_data(),
478 config.extra_data_size());
479 memset(codec_context->extradata + config.extra_data_size(), '\0',
480 FF_INPUT_BUFFER_PADDING_SIZE);
481 } else {
482 codec_context->extradata = NULL;
483 codec_context->extradata_size = 0;
487 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
488 switch (layout) {
489 case AV_CH_LAYOUT_MONO:
490 return CHANNEL_LAYOUT_MONO;
491 case AV_CH_LAYOUT_STEREO:
492 return CHANNEL_LAYOUT_STEREO;
493 case AV_CH_LAYOUT_2_1:
494 return CHANNEL_LAYOUT_2_1;
495 case AV_CH_LAYOUT_SURROUND:
496 return CHANNEL_LAYOUT_SURROUND;
497 case AV_CH_LAYOUT_4POINT0:
498 return CHANNEL_LAYOUT_4_0;
499 case AV_CH_LAYOUT_2_2:
500 return CHANNEL_LAYOUT_2_2;
501 case AV_CH_LAYOUT_QUAD:
502 return CHANNEL_LAYOUT_QUAD;
503 case AV_CH_LAYOUT_5POINT0:
504 return CHANNEL_LAYOUT_5_0;
505 case AV_CH_LAYOUT_5POINT1:
506 return CHANNEL_LAYOUT_5_1;
507 case AV_CH_LAYOUT_5POINT0_BACK:
508 return CHANNEL_LAYOUT_5_0_BACK;
509 case AV_CH_LAYOUT_5POINT1_BACK:
510 return CHANNEL_LAYOUT_5_1_BACK;
511 case AV_CH_LAYOUT_7POINT0:
512 return CHANNEL_LAYOUT_7_0;
513 case AV_CH_LAYOUT_7POINT1:
514 return CHANNEL_LAYOUT_7_1;
515 case AV_CH_LAYOUT_7POINT1_WIDE:
516 return CHANNEL_LAYOUT_7_1_WIDE;
517 case AV_CH_LAYOUT_STEREO_DOWNMIX:
518 return CHANNEL_LAYOUT_STEREO_DOWNMIX;
519 case AV_CH_LAYOUT_2POINT1:
520 return CHANNEL_LAYOUT_2POINT1;
521 case AV_CH_LAYOUT_3POINT1:
522 return CHANNEL_LAYOUT_3_1;
523 case AV_CH_LAYOUT_4POINT1:
524 return CHANNEL_LAYOUT_4_1;
525 case AV_CH_LAYOUT_6POINT0:
526 return CHANNEL_LAYOUT_6_0;
527 case AV_CH_LAYOUT_6POINT0_FRONT:
528 return CHANNEL_LAYOUT_6_0_FRONT;
529 case AV_CH_LAYOUT_HEXAGONAL:
530 return CHANNEL_LAYOUT_HEXAGONAL;
531 case AV_CH_LAYOUT_6POINT1:
532 return CHANNEL_LAYOUT_6_1;
533 case AV_CH_LAYOUT_6POINT1_BACK:
534 return CHANNEL_LAYOUT_6_1_BACK;
535 case AV_CH_LAYOUT_6POINT1_FRONT:
536 return CHANNEL_LAYOUT_6_1_FRONT;
537 case AV_CH_LAYOUT_7POINT0_FRONT:
538 return CHANNEL_LAYOUT_7_0_FRONT;
539 #ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
540 case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
541 return CHANNEL_LAYOUT_7_1_WIDE_BACK;
542 #endif
543 case AV_CH_LAYOUT_OCTAGONAL:
544 return CHANNEL_LAYOUT_OCTAGONAL;
545 default:
546 // FFmpeg channel_layout is 0 for .wav and .mp3. Attempt to guess layout
547 // based on the channel count.
548 return GuessChannelLayout(channels);
552 VideoPixelFormat AVPixelFormatToVideoPixelFormat(AVPixelFormat pixel_format) {
553 // The YUVJ alternatives are FFmpeg's (deprecated, but still in use) way to
554 // specify a pixel format and full range color combination.
555 switch (pixel_format) {
556 case AV_PIX_FMT_YUV422P:
557 case AV_PIX_FMT_YUVJ422P:
558 return PIXEL_FORMAT_YV16;
559 case AV_PIX_FMT_YUV444P:
560 case AV_PIX_FMT_YUVJ444P:
561 return PIXEL_FORMAT_YV24;
562 case AV_PIX_FMT_YUV420P:
563 case AV_PIX_FMT_YUVJ420P:
564 return PIXEL_FORMAT_YV12;
565 case AV_PIX_FMT_YUVA420P:
566 return PIXEL_FORMAT_YV12A;
567 default:
568 DVLOG(1) << "Unsupported AVPixelFormat: " << pixel_format;
570 return PIXEL_FORMAT_UNKNOWN;
573 AVPixelFormat VideoPixelFormatToAVPixelFormat(VideoPixelFormat video_format) {
574 switch (video_format) {
575 case PIXEL_FORMAT_YV16:
576 return AV_PIX_FMT_YUV422P;
577 case PIXEL_FORMAT_YV12:
578 return AV_PIX_FMT_YUV420P;
579 case PIXEL_FORMAT_YV12A:
580 return AV_PIX_FMT_YUVA420P;
581 case PIXEL_FORMAT_YV24:
582 return AV_PIX_FMT_YUV444P;
583 default:
584 DVLOG(1) << "Unsupported Format: " << video_format;
586 return AV_PIX_FMT_NONE;
589 ColorSpace AVColorSpaceToColorSpace(AVColorSpace color_space,
590 AVColorRange color_range) {
591 if (color_range == AVCOL_RANGE_JPEG)
592 return COLOR_SPACE_JPEG;
594 switch (color_space) {
595 case AVCOL_SPC_UNSPECIFIED:
596 break;
597 case AVCOL_SPC_BT709:
598 return COLOR_SPACE_HD_REC709;
599 case AVCOL_SPC_SMPTE170M:
600 case AVCOL_SPC_BT470BG:
601 return COLOR_SPACE_SD_REC601;
602 default:
603 DVLOG(1) << "Unknown AVColorSpace: " << color_space;
605 return COLOR_SPACE_UNSPECIFIED;
608 bool FFmpegUTCDateToTime(const char* date_utc, base::Time* out) {
609 DCHECK(date_utc);
610 DCHECK(out);
612 std::vector<base::StringPiece> fields = base::SplitStringPiece(
613 date_utc, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
614 if (fields.size() != 2)
615 return false;
617 std::vector<base::StringPiece> date_fields = base::SplitStringPiece(
618 fields[0], "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
619 if (date_fields.size() != 3)
620 return false;
622 // TODO(acolwell): Update this parsing code when FFmpeg returns sub-second
623 // information.
624 std::vector<base::StringPiece> time_fields = base::SplitStringPiece(
625 fields[1], ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
626 if (time_fields.size() != 3)
627 return false;
629 base::Time::Exploded exploded;
630 exploded.millisecond = 0;
631 if (base::StringToInt(date_fields[0], &exploded.year) &&
632 base::StringToInt(date_fields[1], &exploded.month) &&
633 base::StringToInt(date_fields[2], &exploded.day_of_month) &&
634 base::StringToInt(time_fields[0], &exploded.hour) &&
635 base::StringToInt(time_fields[1], &exploded.minute) &&
636 base::StringToInt(time_fields[2], &exploded.second)) {
637 base::Time parsed_time = base::Time::FromUTCExploded(exploded);
638 if (parsed_time.is_null())
639 return false;
641 *out = parsed_time;
642 return true;
645 return false;
648 } // namespace media