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"
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
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;
26 static const int kFFmpegBufferAddressAlignment
= 32;
29 // Check here to ensure FFmpeg only receives data aligned to its specifications.
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
);
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
,
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
) {
69 case CODEC_ID_PCM_S16LE
:
70 case CODEC_ID_PCM_S24LE
:
71 case CODEC_ID_PCM_F32LE
:
73 case CODEC_ID_PCM_S16BE
:
74 return kCodecPCM_S16BE
;
75 case CODEC_ID_PCM_S24BE
:
76 return kCodecPCM_S24BE
;
85 case CODEC_ID_PCM_MULAW
:
86 return kCodecPCM_MULAW
;
87 #ifndef CHROMIUM_OMIT_CODEC_ID_OPUS
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
) {
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
;
115 DVLOG(1) << "Unsupported sample format: " << sample_format
;
118 case kCodecPCM_S16BE
:
119 return CODEC_ID_PCM_S16BE
;
120 case kCodecPCM_S24BE
:
121 return CODEC_ID_PCM_S24BE
;
123 return CODEC_ID_VORBIS
;
125 return CODEC_ID_FLAC
;
127 return CODEC_ID_AMR_NB
;
129 return CODEC_ID_AMR_WB
;
131 return CODEC_ID_GSM_MS
;
132 case kCodecPCM_MULAW
:
133 return CODEC_ID_PCM_MULAW
;
134 #ifndef CHROMIUM_OMIT_CODEC_ID_OPUS
136 return CODEC_ID_OPUS
;
139 DVLOG(1) << "Unknown AudioCodec: " << audio_codec
;
141 return CODEC_ID_NONE
;
144 VideoCodec
CodecIDToVideoCodec(CodecID codec_id
) {
148 case CODEC_ID_THEORA
:
154 #ifndef CHROMIUM_OMIT_AV_CODEC_ID_VP9
155 case AV_CODEC_ID_VP9
:
159 DVLOG(1) << "Unknown video CodecID: " << codec_id
;
161 return kUnknownVideoCodec
;
164 static CodecID
VideoCodecToCodecID(VideoCodec video_codec
) {
165 switch (video_codec
) {
167 return CODEC_ID_H264
;
169 return CODEC_ID_THEORA
;
171 return CODEC_ID_MPEG4
;
174 #ifndef CHROMIUM_OMIT_AV_CODEC_ID_VP9
176 return AV_CODEC_ID_VP9
;
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
;
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
;
205 DVLOG(1) << "Unknown profile id: " << profile
;
207 return VIDEO_CODEC_PROFILE_UNKNOWN
;
210 static int VideoCodecProfileToProfileID(VideoCodecProfile 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
;
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
;
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
;
267 DVLOG(1) << "Unknown SampleFormat: " << sample_format
;
269 return AV_SAMPLE_FMT_NONE
;
272 static void AVCodecContextToAudioDecoderConfig(
273 const AVCodecContext
* codec_context
,
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
,
295 codec_context
->sample_rate
,
296 codec_context
->extradata
,
297 codec_context
->extradata_size
,
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);
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
);
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
;
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);
385 config
->Initialize(codec
,
388 coded_size
, visible_rect
, natural_size
,
389 stream
->codec
->extradata
, stream
->codec
->extradata_size
,
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
);
413 codec_context
->extradata
= NULL
;
414 codec_context
->extradata_size
= 0;
418 ChannelLayout
ChannelLayoutToChromeChannelLayout(int64_t layout
, int channels
) {
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
;
474 case AV_CH_LAYOUT_OCTAGONAL
:
475 return CHANNEL_LAYOUT_OCTAGONAL
;
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
;
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
;
506 DVLOG(1) << "Unsupported VideoFrame::Format: " << video_format
;