Added histogram for v2 app launch source
[chromium-blink-merge.git] / media / ffmpeg / ffmpeg_common.cc
blob8a69a86ad66989dc501075ecd036e25027a36d0b
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 "media/base/decoder_buffer.h"
10 #include "media/base/video_frame.h"
11 #include "media/base/video_util.h"
13 namespace media {
15 // Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
16 // padded. Check here to ensure FFmpeg only receives data padded to its
17 // specifications.
18 COMPILE_ASSERT(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE,
19 decoder_buffer_padding_size_does_not_fit_ffmpeg_requirement);
21 // Alignment requirement by FFmpeg for input and output buffers. This need to
22 // be updated to match FFmpeg when it changes.
23 #if defined(ARCH_CPU_ARM_FAMILY)
24 static const int kFFmpegBufferAddressAlignment = 16;
25 #else
26 static const int kFFmpegBufferAddressAlignment = 32;
27 #endif
29 // Check here to ensure FFmpeg only receives data aligned to its specifications.
30 COMPILE_ASSERT(
31 DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
32 DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
33 decoder_buffer_alignment_size_does_not_fit_ffmpeg_requirement);
35 // Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
36 // See video_get_buffer() in libavcodec/utils.c.
37 static const int kFFmpegOutputBufferPaddingSize = 16;
39 COMPILE_ASSERT(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
40 video_frame_padding_size_does_not_fit_ffmpeg_requirement);
42 COMPILE_ASSERT(
43 VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
44 VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
45 video_frame_address_alignment_does_not_fit_ffmpeg_requirement);
47 static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
49 base::TimeDelta ConvertFromTimeBase(const AVRational& time_base,
50 int64 timestamp) {
51 int64 microseconds = av_rescale_q(timestamp, time_base, kMicrosBase);
52 return base::TimeDelta::FromMicroseconds(microseconds);
55 int64 ConvertToTimeBase(const AVRational& time_base,
56 const base::TimeDelta& timestamp) {
57 return av_rescale_q(timestamp.InMicroseconds(), kMicrosBase, time_base);
60 AudioCodec CodecIDToAudioCodec(CodecID codec_id) {
61 switch (codec_id) {
62 case CODEC_ID_AAC:
63 return kCodecAAC;
64 case CODEC_ID_MP3:
65 return kCodecMP3;
66 case CODEC_ID_VORBIS:
67 return kCodecVorbis;
68 case CODEC_ID_PCM_U8:
69 case CODEC_ID_PCM_S16LE:
70 case CODEC_ID_PCM_S24LE:
71 case CODEC_ID_PCM_F32LE:
72 return kCodecPCM;
73 case CODEC_ID_PCM_S16BE:
74 return kCodecPCM_S16BE;
75 case CODEC_ID_PCM_S24BE:
76 return kCodecPCM_S24BE;
77 case CODEC_ID_FLAC:
78 return kCodecFLAC;
79 case CODEC_ID_AMR_NB:
80 return kCodecAMR_NB;
81 case CODEC_ID_AMR_WB:
82 return kCodecAMR_WB;
83 case CODEC_ID_GSM_MS:
84 return kCodecGSM_MS;
85 case CODEC_ID_PCM_MULAW:
86 return kCodecPCM_MULAW;
87 #ifndef CHROMIUM_OMIT_CODEC_ID_OPUS
88 case CODEC_ID_OPUS:
89 return kCodecOpus;
90 #endif
91 default:
92 DVLOG(1) << "Unknown audio CodecID: " << codec_id;
94 return kUnknownAudioCodec;
97 static CodecID AudioCodecToCodecID(AudioCodec audio_codec,
98 SampleFormat sample_format) {
99 switch (audio_codec) {
100 case kCodecAAC:
101 return CODEC_ID_AAC;
102 case kCodecMP3:
103 return CODEC_ID_MP3;
104 case kCodecPCM:
105 switch (sample_format) {
106 case kSampleFormatU8:
107 return CODEC_ID_PCM_U8;
108 case kSampleFormatS16:
109 return CODEC_ID_PCM_S16LE;
110 case kSampleFormatS32:
111 return CODEC_ID_PCM_S24LE;
112 case kSampleFormatF32:
113 return CODEC_ID_PCM_F32LE;
114 default:
115 DVLOG(1) << "Unsupported sample format: " << sample_format;
117 break;
118 case kCodecPCM_S16BE:
119 return CODEC_ID_PCM_S16BE;
120 case kCodecPCM_S24BE:
121 return CODEC_ID_PCM_S24BE;
122 case kCodecVorbis:
123 return CODEC_ID_VORBIS;
124 case kCodecFLAC:
125 return CODEC_ID_FLAC;
126 case kCodecAMR_NB:
127 return CODEC_ID_AMR_NB;
128 case kCodecAMR_WB:
129 return CODEC_ID_AMR_WB;
130 case kCodecGSM_MS:
131 return CODEC_ID_GSM_MS;
132 case kCodecPCM_MULAW:
133 return CODEC_ID_PCM_MULAW;
134 #ifndef CHROMIUM_OMIT_CODEC_ID_OPUS
135 case kCodecOpus:
136 return CODEC_ID_OPUS;
137 #endif
138 default:
139 DVLOG(1) << "Unknown AudioCodec: " << audio_codec;
141 return CODEC_ID_NONE;
144 VideoCodec CodecIDToVideoCodec(CodecID codec_id) {
145 switch (codec_id) {
146 case CODEC_ID_H264:
147 return kCodecH264;
148 case CODEC_ID_THEORA:
149 return kCodecTheora;
150 case CODEC_ID_MPEG4:
151 return kCodecMPEG4;
152 case CODEC_ID_VP8:
153 return kCodecVP8;
154 #ifndef CHROMIUM_OMIT_AV_CODEC_ID_VP9
155 case AV_CODEC_ID_VP9:
156 return kCodecVP9;
157 #endif
158 default:
159 DVLOG(1) << "Unknown video CodecID: " << codec_id;
161 return kUnknownVideoCodec;
164 static CodecID VideoCodecToCodecID(VideoCodec video_codec) {
165 switch (video_codec) {
166 case kCodecH264:
167 return CODEC_ID_H264;
168 case kCodecTheora:
169 return CODEC_ID_THEORA;
170 case kCodecMPEG4:
171 return CODEC_ID_MPEG4;
172 case kCodecVP8:
173 return CODEC_ID_VP8;
174 #ifndef CHROMIUM_OMIT_AV_CODEC_ID_VP9
175 case kCodecVP9:
176 return AV_CODEC_ID_VP9;
177 #endif
178 default:
179 DVLOG(1) << "Unknown VideoCodec: " << video_codec;
181 return CODEC_ID_NONE;
184 static VideoCodecProfile ProfileIDToVideoCodecProfile(int profile) {
185 // Clear out the CONSTRAINED & INTRA flags which are strict subsets of the
186 // corresponding profiles with which they're used.
187 profile &= ~FF_PROFILE_H264_CONSTRAINED;
188 profile &= ~FF_PROFILE_H264_INTRA;
189 switch (profile) {
190 case FF_PROFILE_H264_BASELINE:
191 return H264PROFILE_BASELINE;
192 case FF_PROFILE_H264_MAIN:
193 return H264PROFILE_MAIN;
194 case FF_PROFILE_H264_EXTENDED:
195 return H264PROFILE_EXTENDED;
196 case FF_PROFILE_H264_HIGH:
197 return H264PROFILE_HIGH;
198 case FF_PROFILE_H264_HIGH_10:
199 return H264PROFILE_HIGH10PROFILE;
200 case FF_PROFILE_H264_HIGH_422:
201 return H264PROFILE_HIGH422PROFILE;
202 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
203 return H264PROFILE_HIGH444PREDICTIVEPROFILE;
204 default:
205 DVLOG(1) << "Unknown profile id: " << profile;
207 return VIDEO_CODEC_PROFILE_UNKNOWN;
210 static int VideoCodecProfileToProfileID(VideoCodecProfile profile) {
211 switch (profile) {
212 case H264PROFILE_BASELINE:
213 return FF_PROFILE_H264_BASELINE;
214 case H264PROFILE_MAIN:
215 return FF_PROFILE_H264_MAIN;
216 case H264PROFILE_EXTENDED:
217 return FF_PROFILE_H264_EXTENDED;
218 case H264PROFILE_HIGH:
219 return FF_PROFILE_H264_HIGH;
220 case H264PROFILE_HIGH10PROFILE:
221 return FF_PROFILE_H264_HIGH_10;
222 case H264PROFILE_HIGH422PROFILE:
223 return FF_PROFILE_H264_HIGH_422;
224 case H264PROFILE_HIGH444PREDICTIVEPROFILE:
225 return FF_PROFILE_H264_HIGH_444_PREDICTIVE;
226 default:
227 DVLOG(1) << "Unknown VideoCodecProfile: " << profile;
229 return FF_PROFILE_UNKNOWN;
232 static SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format) {
233 switch (sample_format) {
234 case AV_SAMPLE_FMT_U8:
235 return kSampleFormatU8;
236 case AV_SAMPLE_FMT_S16:
237 return kSampleFormatS16;
238 case AV_SAMPLE_FMT_S32:
239 return kSampleFormatS32;
240 case AV_SAMPLE_FMT_FLT:
241 return kSampleFormatF32;
242 case AV_SAMPLE_FMT_S16P:
243 return kSampleFormatPlanarS16;
244 case AV_SAMPLE_FMT_FLTP:
245 return kSampleFormatPlanarF32;
246 default:
247 DVLOG(1) << "Unknown AVSampleFormat: " << sample_format;
249 return kUnknownSampleFormat;
252 static AVSampleFormat SampleFormatToAVSampleFormat(SampleFormat sample_format) {
253 switch (sample_format) {
254 case kSampleFormatU8:
255 return AV_SAMPLE_FMT_U8;
256 case kSampleFormatS16:
257 return AV_SAMPLE_FMT_S16;
258 case kSampleFormatS32:
259 return AV_SAMPLE_FMT_S32;
260 case kSampleFormatF32:
261 return AV_SAMPLE_FMT_FLT;
262 case kSampleFormatPlanarS16:
263 return AV_SAMPLE_FMT_S16P;
264 case kSampleFormatPlanarF32:
265 return AV_SAMPLE_FMT_FLTP;
266 default:
267 DVLOG(1) << "Unknown SampleFormat: " << sample_format;
269 return AV_SAMPLE_FMT_NONE;
272 static void AVCodecContextToAudioDecoderConfig(
273 const AVCodecContext* codec_context,
274 bool is_encrypted,
275 AudioDecoderConfig* config) {
276 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO);
278 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id);
280 SampleFormat sample_format =
281 AVSampleFormatToSampleFormat(codec_context->sample_fmt);
283 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout(
284 codec_context->channel_layout, codec_context->channels);
286 if (codec == kCodecOpus) {
287 // |codec_context->sample_fmt| is not set by FFmpeg because Opus decoding is
288 // not enabled in FFmpeg, so we need to manually set the sample format.
289 sample_format = kSampleFormatS16;
292 config->Initialize(codec,
293 sample_format,
294 channel_layout,
295 codec_context->sample_rate,
296 codec_context->extradata,
297 codec_context->extradata_size,
298 is_encrypted,
299 true);
300 if (codec != kCodecOpus) {
301 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
302 config->bits_per_channel());
306 void AVStreamToAudioDecoderConfig(
307 const AVStream* stream,
308 AudioDecoderConfig* config) {
309 bool is_encrypted = false;
310 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
311 if (key)
312 is_encrypted = true;
313 return AVCodecContextToAudioDecoderConfig(stream->codec,
314 is_encrypted, config);
317 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
318 AVCodecContext* codec_context) {
319 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
320 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
321 config.sample_format());
322 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
323 config.sample_format());
325 // TODO(scherkus): should we set |channel_layout|? I'm not sure if FFmpeg uses
326 // said information to decode.
327 codec_context->channels =
328 ChannelLayoutToChannelCount(config.channel_layout());
329 codec_context->sample_rate = config.samples_per_second();
331 if (config.extra_data()) {
332 codec_context->extradata_size = config.extra_data_size();
333 codec_context->extradata = reinterpret_cast<uint8_t*>(
334 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
335 memcpy(codec_context->extradata, config.extra_data(),
336 config.extra_data_size());
337 memset(codec_context->extradata + config.extra_data_size(), '\0',
338 FF_INPUT_BUFFER_PADDING_SIZE);
339 } else {
340 codec_context->extradata = NULL;
341 codec_context->extradata_size = 0;
345 void AVStreamToVideoDecoderConfig(
346 const AVStream* stream,
347 VideoDecoderConfig* config) {
348 gfx::Size coded_size(stream->codec->coded_width, stream->codec->coded_height);
350 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
351 // for now, but may not always be true forever. Fix this in the future.
352 gfx::Rect visible_rect(stream->codec->width, stream->codec->height);
354 AVRational aspect_ratio = { 1, 1 };
355 if (stream->sample_aspect_ratio.num)
356 aspect_ratio = stream->sample_aspect_ratio;
357 else if (stream->codec->sample_aspect_ratio.num)
358 aspect_ratio = stream->codec->sample_aspect_ratio;
360 VideoCodec codec = CodecIDToVideoCodec(stream->codec->codec_id);
362 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
363 if (codec == kCodecVP8)
364 profile = VP8PROFILE_MAIN;
365 else if (codec == kCodecVP9)
366 profile = VP9PROFILE_MAIN;
367 else
368 profile = ProfileIDToVideoCodecProfile(stream->codec->profile);
370 gfx::Size natural_size = GetNaturalSize(
371 visible_rect.size(), aspect_ratio.num, aspect_ratio.den);
373 VideoFrame::Format format = PixelFormatToVideoFormat(stream->codec->pix_fmt);
374 if (codec == kCodecVP9) {
375 // TODO(tomfinegan): libavcodec doesn't know about VP9.
376 format = VideoFrame::YV12;
377 coded_size = natural_size;
380 bool is_encrypted = false;
381 AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0);
382 if (key)
383 is_encrypted = true;
385 config->Initialize(codec,
386 profile,
387 format,
388 coded_size, visible_rect, natural_size,
389 stream->codec->extradata, stream->codec->extradata_size,
390 is_encrypted,
391 true);
394 void VideoDecoderConfigToAVCodecContext(
395 const VideoDecoderConfig& config,
396 AVCodecContext* codec_context) {
397 codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
398 codec_context->codec_id = VideoCodecToCodecID(config.codec());
399 codec_context->profile = VideoCodecProfileToProfileID(config.profile());
400 codec_context->coded_width = config.coded_size().width();
401 codec_context->coded_height = config.coded_size().height();
402 codec_context->pix_fmt = VideoFormatToPixelFormat(config.format());
404 if (config.extra_data()) {
405 codec_context->extradata_size = config.extra_data_size();
406 codec_context->extradata = reinterpret_cast<uint8_t*>(
407 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE));
408 memcpy(codec_context->extradata, config.extra_data(),
409 config.extra_data_size());
410 memset(codec_context->extradata + config.extra_data_size(), '\0',
411 FF_INPUT_BUFFER_PADDING_SIZE);
412 } else {
413 codec_context->extradata = NULL;
414 codec_context->extradata_size = 0;
418 ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) {
419 switch (layout) {
420 case AV_CH_LAYOUT_MONO:
421 return CHANNEL_LAYOUT_MONO;
422 case AV_CH_LAYOUT_STEREO:
423 return CHANNEL_LAYOUT_STEREO;
424 case AV_CH_LAYOUT_2_1:
425 return CHANNEL_LAYOUT_2_1;
426 case AV_CH_LAYOUT_SURROUND:
427 return CHANNEL_LAYOUT_SURROUND;
428 case AV_CH_LAYOUT_4POINT0:
429 return CHANNEL_LAYOUT_4_0;
430 case AV_CH_LAYOUT_2_2:
431 return CHANNEL_LAYOUT_2_2;
432 case AV_CH_LAYOUT_QUAD:
433 return CHANNEL_LAYOUT_QUAD;
434 case AV_CH_LAYOUT_5POINT0:
435 return CHANNEL_LAYOUT_5_0;
436 case AV_CH_LAYOUT_5POINT1:
437 return CHANNEL_LAYOUT_5_1;
438 case AV_CH_LAYOUT_5POINT0_BACK:
439 return CHANNEL_LAYOUT_5_0_BACK;
440 case AV_CH_LAYOUT_5POINT1_BACK:
441 return CHANNEL_LAYOUT_5_1_BACK;
442 case AV_CH_LAYOUT_7POINT0:
443 return CHANNEL_LAYOUT_7_0;
444 case AV_CH_LAYOUT_7POINT1:
445 return CHANNEL_LAYOUT_7_1;
446 case AV_CH_LAYOUT_7POINT1_WIDE:
447 return CHANNEL_LAYOUT_7_1_WIDE;
448 case AV_CH_LAYOUT_STEREO_DOWNMIX:
449 return CHANNEL_LAYOUT_STEREO_DOWNMIX;
450 case AV_CH_LAYOUT_2POINT1:
451 return CHANNEL_LAYOUT_2POINT1;
452 case AV_CH_LAYOUT_3POINT1:
453 return CHANNEL_LAYOUT_3_1;
454 case AV_CH_LAYOUT_4POINT1:
455 return CHANNEL_LAYOUT_4_1;
456 case AV_CH_LAYOUT_6POINT0:
457 return CHANNEL_LAYOUT_6_0;
458 case AV_CH_LAYOUT_6POINT0_FRONT:
459 return CHANNEL_LAYOUT_6_0_FRONT;
460 case AV_CH_LAYOUT_HEXAGONAL:
461 return CHANNEL_LAYOUT_HEXAGONAL;
462 case AV_CH_LAYOUT_6POINT1:
463 return CHANNEL_LAYOUT_6_1;
464 case AV_CH_LAYOUT_6POINT1_BACK:
465 return CHANNEL_LAYOUT_6_1_BACK;
466 case AV_CH_LAYOUT_6POINT1_FRONT:
467 return CHANNEL_LAYOUT_6_1_FRONT;
468 case AV_CH_LAYOUT_7POINT0_FRONT:
469 return CHANNEL_LAYOUT_7_0_FRONT;
470 #ifdef AV_CH_LAYOUT_7POINT1_WIDE_BACK
471 case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
472 return CHANNEL_LAYOUT_7_1_WIDE_BACK;
473 #endif
474 case AV_CH_LAYOUT_OCTAGONAL:
475 return CHANNEL_LAYOUT_OCTAGONAL;
476 default:
477 // FFmpeg channel_layout is 0 for .wav and .mp3. Attempt to guess layout
478 // based on the channel count.
479 return GuessChannelLayout(channels);
483 VideoFrame::Format PixelFormatToVideoFormat(PixelFormat pixel_format) {
484 switch (pixel_format) {
485 case PIX_FMT_YUV422P:
486 return VideoFrame::YV16;
487 // TODO(scherkus): We should be paying attention to the color range of each
488 // format and scaling as appropriate when rendering. Regular YUV has a range
489 // of 16-239 where as YUVJ has a range of 0-255.
490 case PIX_FMT_YUV420P:
491 case PIX_FMT_YUVJ420P:
492 return VideoFrame::YV12;
493 default:
494 DVLOG(1) << "Unsupported PixelFormat: " << pixel_format;
496 return VideoFrame::INVALID;
499 PixelFormat VideoFormatToPixelFormat(VideoFrame::Format video_format) {
500 switch (video_format) {
501 case VideoFrame::YV16:
502 return PIX_FMT_YUV422P;
503 case VideoFrame::YV12:
504 return PIX_FMT_YUV420P;
505 default:
506 DVLOG(1) << "Unsupported VideoFrame::Format: " << video_format;
508 return PIX_FMT_NONE;
511 } // namespace media