| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/ffmpeg/ffmpeg_common.h" | 5 #include "media/ffmpeg/ffmpeg_common.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_split.h" | 11 #include "base/strings/string_split.h" |
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "media/base/audio_decoder_config.h" | 14 #include "media/base/audio_decoder_config.h" |
| 15 #include "media/base/decoder_buffer.h" | 15 #include "media/base/decoder_buffer.h" |
| 16 #include "media/base/encryption_scheme.h" |
| 16 #include "media/base/video_decoder_config.h" | 17 #include "media/base/video_decoder_config.h" |
| 17 #include "media/base/video_util.h" | 18 #include "media/base/video_util.h" |
| 18 #include "media/media_features.h" | 19 #include "media/media_features.h" |
| 19 | 20 |
| 20 namespace media { | 21 namespace media { |
| 21 | 22 |
| 23 namespace { |
| 24 |
| 25 EncryptionScheme GetEncryptionScheme(const AVStream* stream) { |
| 26 AVDictionaryEntry* key = |
| 27 av_dict_get(stream->metadata, "enc_key_id", nullptr, 0); |
| 28 return EncryptionScheme(key ? EncryptionScheme::kCipherModeAesCtr |
| 29 : EncryptionScheme::kCipherModeUnencrypted); |
| 30 } |
| 31 |
| 32 } // namespace |
| 33 |
| 22 // Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are | 34 // Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are |
| 23 // padded. Check here to ensure FFmpeg only receives data padded to its | 35 // padded. Check here to ensure FFmpeg only receives data padded to its |
| 24 // specifications. | 36 // specifications. |
| 25 static_assert(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE, | 37 static_assert(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE, |
| 26 "DecoderBuffer padding size does not fit ffmpeg requirement"); | 38 "DecoderBuffer padding size does not fit ffmpeg requirement"); |
| 27 | 39 |
| 28 // Alignment requirement by FFmpeg for input and output buffers. This need to | 40 // Alignment requirement by FFmpeg for input and output buffers. This need to |
| 29 // be updated to match FFmpeg when it changes. | 41 // be updated to match FFmpeg when it changes. |
| 30 #if defined(ARCH_CPU_ARM_FAMILY) | 42 #if defined(ARCH_CPU_ARM_FAMILY) |
| 31 static const int kFFmpegBufferAddressAlignment = 16; | 43 static const int kFFmpegBufferAddressAlignment = 16; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 case kSampleFormatPlanarS16: | 308 case kSampleFormatPlanarS16: |
| 297 return AV_SAMPLE_FMT_S16P; | 309 return AV_SAMPLE_FMT_S16P; |
| 298 case kSampleFormatPlanarF32: | 310 case kSampleFormatPlanarF32: |
| 299 return AV_SAMPLE_FMT_FLTP; | 311 return AV_SAMPLE_FMT_FLTP; |
| 300 default: | 312 default: |
| 301 DVLOG(1) << "Unknown SampleFormat: " << sample_format; | 313 DVLOG(1) << "Unknown SampleFormat: " << sample_format; |
| 302 } | 314 } |
| 303 return AV_SAMPLE_FMT_NONE; | 315 return AV_SAMPLE_FMT_NONE; |
| 304 } | 316 } |
| 305 | 317 |
| 306 bool AVCodecContextToAudioDecoderConfig(const AVCodecContext* codec_context, | 318 bool AVCodecContextToAudioDecoderConfig( |
| 307 bool is_encrypted, | 319 const AVCodecContext* codec_context, |
| 308 AudioDecoderConfig* config) { | 320 const EncryptionScheme& encryption_scheme, |
| 321 AudioDecoderConfig* config) { |
| 309 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); | 322 DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); |
| 310 | 323 |
| 311 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); | 324 AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); |
| 312 | 325 |
| 313 SampleFormat sample_format = AVSampleFormatToSampleFormat( | 326 SampleFormat sample_format = AVSampleFormatToSampleFormat( |
| 314 codec_context->sample_fmt, codec_context->codec_id); | 327 codec_context->sample_fmt, codec_context->codec_id); |
| 315 | 328 |
| 316 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout( | 329 ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout( |
| 317 codec_context->channel_layout, codec_context->channels); | 330 codec_context->channel_layout, codec_context->channels); |
| 318 | 331 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 << " extra data cannot have size of " | 377 << " extra data cannot have size of " |
| 365 << codec_context->extradata_size << "."; | 378 << codec_context->extradata_size << "."; |
| 366 return false; | 379 return false; |
| 367 } | 380 } |
| 368 | 381 |
| 369 std::vector<uint8_t> extra_data; | 382 std::vector<uint8_t> extra_data; |
| 370 if (codec_context->extradata_size > 0) { | 383 if (codec_context->extradata_size > 0) { |
| 371 extra_data.assign(codec_context->extradata, | 384 extra_data.assign(codec_context->extradata, |
| 372 codec_context->extradata + codec_context->extradata_size); | 385 codec_context->extradata + codec_context->extradata_size); |
| 373 } | 386 } |
| 374 config->Initialize(codec, | 387 |
| 375 sample_format, | 388 config->Initialize(codec, sample_format, channel_layout, sample_rate, |
| 376 channel_layout, | 389 extra_data, encryption_scheme, seek_preroll, |
| 377 sample_rate, | |
| 378 extra_data, | |
| 379 is_encrypted, | |
| 380 seek_preroll, | |
| 381 codec_context->delay); | 390 codec_context->delay); |
| 382 | 391 |
| 383 // Verify that AudioConfig.bits_per_channel was calculated correctly for | 392 // Verify that AudioConfig.bits_per_channel was calculated correctly for |
| 384 // codecs that have |sample_fmt| set by FFmpeg. | 393 // codecs that have |sample_fmt| set by FFmpeg. |
| 385 switch (codec) { | 394 switch (codec) { |
| 386 case kCodecOpus: | 395 case kCodecOpus: |
| 387 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | 396 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) |
| 388 case kCodecAC3: | 397 case kCodecAC3: |
| 389 case kCodecEAC3: | 398 case kCodecEAC3: |
| 390 #endif | 399 #endif |
| 391 break; | 400 break; |
| 392 default: | 401 default: |
| 393 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8, | 402 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8, |
| 394 config->bits_per_channel()); | 403 config->bits_per_channel()); |
| 395 break; | 404 break; |
| 396 } | 405 } |
| 397 | 406 |
| 398 return true; | 407 return true; |
| 399 } | 408 } |
| 400 | 409 |
| 401 bool AVStreamToAudioDecoderConfig(const AVStream* stream, | 410 bool AVStreamToAudioDecoderConfig(const AVStream* stream, |
| 402 AudioDecoderConfig* config) { | 411 AudioDecoderConfig* config) { |
| 403 bool is_encrypted = false; | 412 return AVCodecContextToAudioDecoderConfig( |
| 404 AVDictionaryEntry* key = | 413 stream->codec, GetEncryptionScheme(stream), config); |
| 405 av_dict_get(stream->metadata, "enc_key_id", nullptr, 0); | |
| 406 if (key) | |
| 407 is_encrypted = true; | |
| 408 return AVCodecContextToAudioDecoderConfig(stream->codec, is_encrypted, | |
| 409 config); | |
| 410 } | 414 } |
| 411 | 415 |
| 412 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config, | 416 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config, |
| 413 AVCodecContext* codec_context) { | 417 AVCodecContext* codec_context) { |
| 414 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; | 418 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; |
| 415 codec_context->codec_id = AudioCodecToCodecID(config.codec(), | 419 codec_context->codec_id = AudioCodecToCodecID(config.codec(), |
| 416 config.sample_format()); | 420 config.sample_format()); |
| 417 codec_context->sample_fmt = SampleFormatToAVSampleFormat( | 421 codec_context->sample_fmt = SampleFormatToAVSampleFormat( |
| 418 config.sample_format()); | 422 config.sample_format()); |
| 419 | 423 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 coded_size = visible_rect.size(); | 494 coded_size = visible_rect.size(); |
| 491 } | 495 } |
| 492 | 496 |
| 493 // Pad out |coded_size| for subsampled YUV formats. | 497 // Pad out |coded_size| for subsampled YUV formats. |
| 494 if (format != PIXEL_FORMAT_YV24) { | 498 if (format != PIXEL_FORMAT_YV24) { |
| 495 coded_size.set_width((coded_size.width() + 1) / 2 * 2); | 499 coded_size.set_width((coded_size.width() + 1) / 2 * 2); |
| 496 if (format != PIXEL_FORMAT_YV16) | 500 if (format != PIXEL_FORMAT_YV16) |
| 497 coded_size.set_height((coded_size.height() + 1) / 2 * 2); | 501 coded_size.set_height((coded_size.height() + 1) / 2 * 2); |
| 498 } | 502 } |
| 499 | 503 |
| 500 bool is_encrypted = false; | |
| 501 AVDictionaryEntry* key = | |
| 502 av_dict_get(stream->metadata, "enc_key_id", nullptr, 0); | |
| 503 if (key) | |
| 504 is_encrypted = true; | |
| 505 | |
| 506 AVDictionaryEntry* webm_alpha = | 504 AVDictionaryEntry* webm_alpha = |
| 507 av_dict_get(stream->metadata, "alpha_mode", nullptr, 0); | 505 av_dict_get(stream->metadata, "alpha_mode", nullptr, 0); |
| 508 if (webm_alpha && !strcmp(webm_alpha->value, "1")) { | 506 if (webm_alpha && !strcmp(webm_alpha->value, "1")) { |
| 509 format = PIXEL_FORMAT_YV12A; | 507 format = PIXEL_FORMAT_YV12A; |
| 510 } | 508 } |
| 511 | 509 |
| 512 // Prefer the color space found by libavcodec if available. | 510 // Prefer the color space found by libavcodec if available. |
| 513 ColorSpace color_space = AVColorSpaceToColorSpace(stream->codec->colorspace, | 511 ColorSpace color_space = AVColorSpaceToColorSpace(stream->codec->colorspace, |
| 514 stream->codec->color_range); | 512 stream->codec->color_range); |
| 515 if (color_space == COLOR_SPACE_UNSPECIFIED) { | 513 if (color_space == COLOR_SPACE_UNSPECIFIED) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 528 << stream->codec->extradata_size << "."; | 526 << stream->codec->extradata_size << "."; |
| 529 return false; | 527 return false; |
| 530 } | 528 } |
| 531 | 529 |
| 532 std::vector<uint8_t> extra_data; | 530 std::vector<uint8_t> extra_data; |
| 533 if (stream->codec->extradata_size > 0) { | 531 if (stream->codec->extradata_size > 0) { |
| 534 extra_data.assign(stream->codec->extradata, | 532 extra_data.assign(stream->codec->extradata, |
| 535 stream->codec->extradata + stream->codec->extradata_size); | 533 stream->codec->extradata + stream->codec->extradata_size); |
| 536 } | 534 } |
| 537 config->Initialize(codec, profile, format, color_space, coded_size, | 535 config->Initialize(codec, profile, format, color_space, coded_size, |
| 538 visible_rect, natural_size, extra_data, is_encrypted); | 536 visible_rect, natural_size, extra_data, |
| 537 GetEncryptionScheme(stream)); |
| 539 return true; | 538 return true; |
| 540 } | 539 } |
| 541 | 540 |
| 542 void VideoDecoderConfigToAVCodecContext( | 541 void VideoDecoderConfigToAVCodecContext( |
| 543 const VideoDecoderConfig& config, | 542 const VideoDecoderConfig& config, |
| 544 AVCodecContext* codec_context) { | 543 AVCodecContext* codec_context) { |
| 545 codec_context->codec_type = AVMEDIA_TYPE_VIDEO; | 544 codec_context->codec_type = AVMEDIA_TYPE_VIDEO; |
| 546 codec_context->codec_id = VideoCodecToCodecID(config.codec()); | 545 codec_context->codec_id = VideoCodecToCodecID(config.codec()); |
| 547 codec_context->profile = VideoCodecProfileToProfileID(config.profile()); | 546 codec_context->profile = VideoCodecProfileToProfileID(config.profile()); |
| 548 codec_context->coded_width = config.coded_size().width(); | 547 codec_context->coded_width = config.coded_size().width(); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 } | 759 } |
| 761 | 760 |
| 762 int32_t HashCodecName(const char* codec_name) { | 761 int32_t HashCodecName(const char* codec_name) { |
| 763 // Use the first 32-bits from the SHA1 hash as the identifier. | 762 // Use the first 32-bits from the SHA1 hash as the identifier. |
| 764 int32_t hash; | 763 int32_t hash; |
| 765 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4); | 764 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4); |
| 766 return hash; | 765 return hash; |
| 767 } | 766 } |
| 768 | 767 |
| 769 } // namespace media | 768 } // namespace media |
| OLD | NEW |