Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: media/ffmpeg/ffmpeg_common.cc

Issue 2534193003: To M56: Roll src/third_party/ffmpeg/ 3c7a09882..cdf4accee (3188 commits). (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/ffmpeg/ffmpeg_common.h ('k') | media/ffmpeg/ffmpeg_common_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/sha1.h" 8 #include "base/sha1.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 break; 398 break;
399 default: 399 default:
400 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8, 400 DCHECK_EQ(av_get_bytes_per_sample(codec_context->sample_fmt) * 8,
401 config->bits_per_channel()); 401 config->bits_per_channel());
402 break; 402 break;
403 } 403 }
404 404
405 return true; 405 return true;
406 } 406 }
407 407
408 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext>
409 AVStreamToAVCodecContext(const AVStream* stream) {
410 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
411 avcodec_alloc_context3(nullptr));
412 if (avcodec_parameters_to_context(codec_context.get(), stream->codecpar) <
413 0) {
414 return nullptr;
415 }
416
417 return codec_context;
418 }
419
408 bool AVStreamToAudioDecoderConfig(const AVStream* stream, 420 bool AVStreamToAudioDecoderConfig(const AVStream* stream,
409 AudioDecoderConfig* config) { 421 AudioDecoderConfig* config) {
422 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
423 AVStreamToAVCodecContext(stream));
424 if (!codec_context)
425 return false;
426
410 return AVCodecContextToAudioDecoderConfig( 427 return AVCodecContextToAudioDecoderConfig(
411 stream->codec, GetEncryptionScheme(stream), config); 428 codec_context.get(), GetEncryptionScheme(stream), config);
412 } 429 }
413 430
414 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config, 431 void AudioDecoderConfigToAVCodecContext(const AudioDecoderConfig& config,
415 AVCodecContext* codec_context) { 432 AVCodecContext* codec_context) {
416 codec_context->codec_type = AVMEDIA_TYPE_AUDIO; 433 codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
417 codec_context->codec_id = AudioCodecToCodecID(config.codec(), 434 codec_context->codec_id = AudioCodecToCodecID(config.codec(),
418 config.sample_format()); 435 config.sample_format());
419 codec_context->sample_fmt = SampleFormatToAVSampleFormat( 436 codec_context->sample_fmt = SampleFormatToAVSampleFormat(
420 config.sample_format()); 437 config.sample_format());
421 438
(...skipping 12 matching lines...) Expand all
434 av_malloc(config.extra_data().size() + FF_INPUT_BUFFER_PADDING_SIZE)); 451 av_malloc(config.extra_data().size() + FF_INPUT_BUFFER_PADDING_SIZE));
435 memcpy(codec_context->extradata, &config.extra_data()[0], 452 memcpy(codec_context->extradata, &config.extra_data()[0],
436 config.extra_data().size()); 453 config.extra_data().size());
437 memset(codec_context->extradata + config.extra_data().size(), '\0', 454 memset(codec_context->extradata + config.extra_data().size(), '\0',
438 FF_INPUT_BUFFER_PADDING_SIZE); 455 FF_INPUT_BUFFER_PADDING_SIZE);
439 } 456 }
440 } 457 }
441 458
442 bool AVStreamToVideoDecoderConfig(const AVStream* stream, 459 bool AVStreamToVideoDecoderConfig(const AVStream* stream,
443 VideoDecoderConfig* config) { 460 VideoDecoderConfig* config) {
444 // Anticipating AVStream.codec.coded_{width,height} will be inaccessible in 461 std::unique_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context(
445 // ffmpeg soon, just use the width and height, padded below, as hints of the 462 AVStreamToAVCodecContext(stream));
446 // coded size. 463 if (!codec_context)
447 gfx::Size coded_size(stream->codec->width, stream->codec->height); 464 return false;
465
466 // AVStream.codec->coded_{width,height} access is deprecated in ffmpeg.
467 // Use just the width and height as hints of coded size.
468 gfx::Size coded_size(codec_context->width, codec_context->height);
448 469
449 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true 470 // TODO(vrk): This assumes decoded frame data starts at (0, 0), which is true
450 // for now, but may not always be true forever. Fix this in the future. 471 // for now, but may not always be true forever. Fix this in the future.
451 gfx::Rect visible_rect(stream->codec->width, stream->codec->height); 472 gfx::Rect visible_rect(codec_context->width, codec_context->height);
452 473
453 AVRational aspect_ratio = { 1, 1 }; 474 AVRational aspect_ratio = { 1, 1 };
454 if (stream->sample_aspect_ratio.num) 475 if (stream->sample_aspect_ratio.num)
455 aspect_ratio = stream->sample_aspect_ratio; 476 aspect_ratio = stream->sample_aspect_ratio;
456 else if (stream->codec->sample_aspect_ratio.num) 477 else if (codec_context->sample_aspect_ratio.num)
457 aspect_ratio = stream->codec->sample_aspect_ratio; 478 aspect_ratio = codec_context->sample_aspect_ratio;
458 479
459 VideoCodec codec = CodecIDToVideoCodec(stream->codec->codec_id); 480 VideoCodec codec = CodecIDToVideoCodec(codec_context->codec_id);
460 481
461 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; 482 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
462 if (codec == kCodecVP8) 483 if (codec == kCodecVP8)
463 profile = VP8PROFILE_ANY; 484 profile = VP8PROFILE_ANY;
464 else if (codec == kCodecVP9) 485 else if (codec == kCodecVP9)
465 // TODO(servolk): Find a way to obtain actual VP9 profile from FFmpeg. 486 // TODO(servolk): Find a way to obtain actual VP9 profile from FFmpeg.
466 // crbug.com/592074 487 // crbug.com/592074
467 profile = VP9PROFILE_PROFILE0; 488 profile = VP9PROFILE_PROFILE0;
468 else 489 else
469 profile = ProfileIDToVideoCodecProfile(stream->codec->profile); 490 profile = ProfileIDToVideoCodecProfile(codec_context->profile);
470 491
471 // Without the FFmpeg h264 decoder, AVFormat is unable to get the profile, so 492 // Without the FFmpeg h264 decoder, AVFormat is unable to get the profile, so
472 // default to baseline and let the VDA fail later if it doesn't support the 493 // default to baseline and let the VDA fail later if it doesn't support the
473 // real profile. This is alright because if the FFmpeg h264 decoder isn't 494 // real profile. This is alright because if the FFmpeg h264 decoder isn't
474 // enabled, there is no fallback if the VDA fails. 495 // enabled, there is no fallback if the VDA fails.
475 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS) 496 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS)
476 if (codec == kCodecH264) 497 if (codec == kCodecH264)
477 profile = H264PROFILE_BASELINE; 498 profile = H264PROFILE_BASELINE;
478 #endif 499 #endif
479 500
480 gfx::Size natural_size = GetNaturalSize( 501 gfx::Size natural_size = GetNaturalSize(
481 visible_rect.size(), aspect_ratio.num, aspect_ratio.den); 502 visible_rect.size(), aspect_ratio.num, aspect_ratio.den);
482 503
483 VideoPixelFormat format = 504 VideoPixelFormat format =
484 AVPixelFormatToVideoPixelFormat(stream->codec->pix_fmt); 505 AVPixelFormatToVideoPixelFormat(codec_context->pix_fmt);
485 // The format and coded size may be unknown if FFmpeg is compiled without 506 // The format and coded size may be unknown if FFmpeg is compiled without
486 // video decoders. 507 // video decoders.
487 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS) 508 #if defined(DISABLE_FFMPEG_VIDEO_DECODERS)
488 if (format == PIXEL_FORMAT_UNKNOWN) 509 if (format == PIXEL_FORMAT_UNKNOWN)
489 format = PIXEL_FORMAT_YV12; 510 format = PIXEL_FORMAT_YV12;
490 if (coded_size == gfx::Size(0, 0)) 511 if (coded_size == gfx::Size(0, 0))
491 coded_size = visible_rect.size(); 512 coded_size = visible_rect.size();
492 #endif 513 #endif
493 514
494 if (codec == kCodecVP9) { 515 if (codec == kCodecVP9) {
495 // TODO(tomfinegan): libavcodec doesn't know about VP9. 516 // TODO(tomfinegan): libavcodec doesn't know about VP9.
496 format = PIXEL_FORMAT_YV12; 517 format = PIXEL_FORMAT_YV12;
497 coded_size = visible_rect.size(); 518 coded_size = visible_rect.size();
498 } 519 }
499 520
500 // Pad out |coded_size| for subsampled YUV formats. 521 // Pad out |coded_size| for subsampled YUV formats.
501 if (format != PIXEL_FORMAT_YV24) { 522 if (format != PIXEL_FORMAT_YV24) {
502 coded_size.set_width((coded_size.width() + 1) / 2 * 2); 523 coded_size.set_width((coded_size.width() + 1) / 2 * 2);
503 if (format != PIXEL_FORMAT_YV16) 524 if (format != PIXEL_FORMAT_YV16)
504 coded_size.set_height((coded_size.height() + 1) / 2 * 2); 525 coded_size.set_height((coded_size.height() + 1) / 2 * 2);
505 } 526 }
506 527
507 AVDictionaryEntry* webm_alpha = 528 AVDictionaryEntry* webm_alpha =
508 av_dict_get(stream->metadata, "alpha_mode", nullptr, 0); 529 av_dict_get(stream->metadata, "alpha_mode", nullptr, 0);
509 if (webm_alpha && !strcmp(webm_alpha->value, "1")) { 530 if (webm_alpha && !strcmp(webm_alpha->value, "1")) {
510 format = PIXEL_FORMAT_YV12A; 531 format = PIXEL_FORMAT_YV12A;
511 } 532 }
512 533
513 // Prefer the color space found by libavcodec if available. 534 // Prefer the color space found by libavcodec if available.
514 ColorSpace color_space = AVColorSpaceToColorSpace(stream->codec->colorspace, 535 ColorSpace color_space = AVColorSpaceToColorSpace(codec_context->colorspace,
515 stream->codec->color_range); 536 codec_context->color_range);
516 if (color_space == COLOR_SPACE_UNSPECIFIED) { 537 if (color_space == COLOR_SPACE_UNSPECIFIED) {
517 // Otherwise, assume that SD video is usually Rec.601, and HD is usually 538 // Otherwise, assume that SD video is usually Rec.601, and HD is usually
518 // Rec.709. 539 // Rec.709.
519 color_space = (natural_size.height() < 720) ? COLOR_SPACE_SD_REC601 540 color_space = (natural_size.height() < 720) ? COLOR_SPACE_SD_REC601
520 : COLOR_SPACE_HD_REC709; 541 : COLOR_SPACE_HD_REC709;
521 } 542 }
522 543
523 // AVStream occasionally has invalid extra data. See http://crbug.com/517163 544 // AVCodecContext occasionally has invalid extra data. See
524 if ((stream->codec->extradata_size == 0) != 545 // http://crbug.com/517163
525 (stream->codec->extradata == nullptr)) { 546 if (codec_context->extradata != nullptr &&
526 LOG(ERROR) << __func__ 547 codec_context->extradata_size == 0) {
527 << (stream->codec->extradata == nullptr ? " NULL" : " Non-Null") 548 LOG(ERROR) << __func__ << " Non-Null extra data cannot have size of 0.";
528 << " extra data cannot have size of "
529 << stream->codec->extradata_size << ".";
530 return false; 549 return false;
531 } 550 }
551 CHECK_EQ(codec_context->extradata == nullptr,
552 codec_context->extradata_size == 0);
532 553
533 std::vector<uint8_t> extra_data; 554 std::vector<uint8_t> extra_data;
534 if (stream->codec->extradata_size > 0) { 555 if (codec_context->extradata_size > 0) {
535 extra_data.assign(stream->codec->extradata, 556 extra_data.assign(codec_context->extradata,
536 stream->codec->extradata + stream->codec->extradata_size); 557 codec_context->extradata + codec_context->extradata_size);
537 } 558 }
538 config->Initialize(codec, profile, format, color_space, coded_size, 559 config->Initialize(codec, profile, format, color_space, coded_size,
539 visible_rect, natural_size, extra_data, 560 visible_rect, natural_size, extra_data,
540 GetEncryptionScheme(stream)); 561 GetEncryptionScheme(stream));
541 return true; 562 return true;
542 } 563 }
543 564
544 void VideoDecoderConfigToAVCodecContext( 565 void VideoDecoderConfigToAVCodecContext(
545 const VideoDecoderConfig& config, 566 const VideoDecoderConfig& config,
546 AVCodecContext* codec_context) { 567 AVCodecContext* codec_context) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 return COLOR_SPACE_HD_REC709; 747 return COLOR_SPACE_HD_REC709;
727 case AVCOL_SPC_SMPTE170M: 748 case AVCOL_SPC_SMPTE170M:
728 case AVCOL_SPC_BT470BG: 749 case AVCOL_SPC_BT470BG:
729 return COLOR_SPACE_SD_REC601; 750 return COLOR_SPACE_SD_REC601;
730 default: 751 default:
731 DVLOG(1) << "Unknown AVColorSpace: " << color_space; 752 DVLOG(1) << "Unknown AVColorSpace: " << color_space;
732 } 753 }
733 return COLOR_SPACE_UNSPECIFIED; 754 return COLOR_SPACE_UNSPECIFIED;
734 } 755 }
735 756
736 bool FFmpegUTCDateToTime(const char* date_utc, base::Time* out) {
737 DCHECK(date_utc);
738 DCHECK(out);
739
740 std::vector<base::StringPiece> fields = base::SplitStringPiece(
741 date_utc, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
742 if (fields.size() != 2)
743 return false;
744
745 std::vector<base::StringPiece> date_fields = base::SplitStringPiece(
746 fields[0], "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
747 if (date_fields.size() != 3)
748 return false;
749
750 // TODO(acolwell): Update this parsing code when FFmpeg returns sub-second
751 // information.
752 std::vector<base::StringPiece> time_fields = base::SplitStringPiece(
753 fields[1], ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
754 if (time_fields.size() != 3)
755 return false;
756
757 base::Time::Exploded exploded;
758 exploded.millisecond = 0;
759 // This field cannot be uninitialized. Unless not modified, make it 0 here
760 // then.
761 exploded.day_of_week = 0;
762 if (base::StringToInt(date_fields[0], &exploded.year) &&
763 base::StringToInt(date_fields[1], &exploded.month) &&
764 base::StringToInt(date_fields[2], &exploded.day_of_month) &&
765 base::StringToInt(time_fields[0], &exploded.hour) &&
766 base::StringToInt(time_fields[1], &exploded.minute) &&
767 base::StringToInt(time_fields[2], &exploded.second)) {
768 if (base::Time::FromUTCExploded(exploded, out))
769 return true;
770 }
771
772 return false;
773 }
774
775 int32_t HashCodecName(const char* codec_name) { 757 int32_t HashCodecName(const char* codec_name) {
776 // Use the first 32-bits from the SHA1 hash as the identifier. 758 // Use the first 32-bits from the SHA1 hash as the identifier.
777 int32_t hash; 759 int32_t hash;
778 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4); 760 memcpy(&hash, base::SHA1HashString(codec_name).substr(0, 4).c_str(), 4);
779 return hash; 761 return hash;
780 } 762 }
781 763
782 #define TEST_PRIMARY(P) \ 764 #define TEST_PRIMARY(P) \
783 static_assert( \ 765 static_assert( \
784 static_cast<int>(gfx::ColorSpace::PrimaryID::P) == AVCOL_PRI_##P, \ 766 static_cast<int>(gfx::ColorSpace::PrimaryID::P) == AVCOL_PRI_##P, \
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 TEST_COLORSPACE(RESERVED); 813 TEST_COLORSPACE(RESERVED);
832 TEST_COLORSPACE(FCC); 814 TEST_COLORSPACE(FCC);
833 TEST_COLORSPACE(BT470BG); 815 TEST_COLORSPACE(BT470BG);
834 TEST_COLORSPACE(SMPTE170M); 816 TEST_COLORSPACE(SMPTE170M);
835 TEST_COLORSPACE(SMPTE240M); 817 TEST_COLORSPACE(SMPTE240M);
836 TEST_COLORSPACE(YCOCG); 818 TEST_COLORSPACE(YCOCG);
837 TEST_COLORSPACE(BT2020_NCL); 819 TEST_COLORSPACE(BT2020_NCL);
838 TEST_COLORSPACE(BT2020_CL); 820 TEST_COLORSPACE(BT2020_CL);
839 821
840 } // namespace media 822 } // namespace media
OLDNEW
« no previous file with comments | « media/ffmpeg/ffmpeg_common.h ('k') | media/ffmpeg/ffmpeg_common_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698