| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "media/formats/webm/webm_video_client.h" |
| |
| #include "media/base/media_util.h" |
| #include "media/base/mock_media_log.h" |
| #include "media/base/video_decoder_config.h" |
| #include "media/formats/webm/webm_constants.h" |
| |
| namespace media { |
| |
| namespace { |
| const gfx::Size kCodedSize(321, 243); |
| |
| MATCHER(UnexpectedStereoMode, "") { |
| return CONTAINS_STRING(arg, "Unexpected value for StereoMode: 0x"); |
| } |
| |
| MATCHER(UnexpectedMultipleValues, "") { |
| return CONTAINS_STRING(arg, "Multiple values for id"); |
| } |
| } |
| |
| static const struct CodecTestParams { |
| VideoCodecProfile profile; |
| const std::vector<uint8_t> codec_private; |
| } kCodecTestParams[] = { |
| {VP9PROFILE_PROFILE0, {}}, |
| {VP9PROFILE_PROFILE2, |
| // Valid VP9 Profile 2 example, extracted out of a sample file at |
| // https://www.webmproject.org/vp9/levels/#test-bitstreams |
| {0x01, 0x01, 0x02, 0x02, 0x01, 0x0a, 0x3, 0x1, 0xa, 0x4, 0x1, 0x1}}, |
| // Invalid VP9 CodecPrivate: too short. |
| {VP9PROFILE_PROFILE0, {0x01, 0x01}}, |
| // Invalid VP9 CodecPrivate: wrong field id. |
| {VP9PROFILE_PROFILE0, {0x77, 0x01, 0x02}}, |
| // Invalid VP9 CodecPrivate: wrong field length. |
| {VP9PROFILE_PROFILE0, {0x01, 0x75, 0x02}}, |
| // Invalid VP9 CodecPrivate: wrong Profile (can't be > 3). |
| {VP9PROFILE_PROFILE0, {0x01, 0x01, 0x34}}}; |
| |
| class WebMVideoClientTest : public testing::TestWithParam<CodecTestParams> { |
| public: |
| WebMVideoClientTest() : webm_video_client_(&media_log_) { |
| // Simulate configuring width and height in the |webm_video_client_|. |
| webm_video_client_.OnUInt(kWebMIdPixelWidth, kCodedSize.width()); |
| webm_video_client_.OnUInt(kWebMIdPixelHeight, kCodedSize.height()); |
| } |
| |
| WebMParserClient* OnListStart(int id) { |
| return webm_video_client_.OnListStart(id); |
| } |
| |
| void OnListEnd(int id) { webm_video_client_.OnListEnd(id); } |
| |
| bool OnUInt(int id, int64_t val) { |
| return webm_video_client_.OnUInt(id, val); |
| } |
| |
| testing::StrictMock<MockMediaLog> media_log_; |
| WebMVideoClient webm_video_client_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WebMVideoClientTest); |
| }; |
| |
| TEST_P(WebMVideoClientTest, AutodetectVp9Profile2NoDetection) { |
| const bool has_valid_codec_private = GetParam().codec_private.size() > 3; |
| |
| auto* parser = OnListStart(kWebMIdColour); |
| // Set 8bit and SDR fields. |
| parser->OnUInt(kWebMIdBitsPerChannel, 8); |
| parser->OnUInt(kWebMIdTransferCharacteristics, |
| static_cast<int64_t>(VideoColorSpace::TransferID::BT709)); |
| OnListEnd(kWebMIdColour); |
| |
| VideoDecoderConfig config; |
| EXPECT_TRUE(webm_video_client_.InitializeConfig( |
| "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); |
| |
| if (!has_valid_codec_private) |
| EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE0); |
| else |
| EXPECT_EQ(config.profile(), GetParam().profile); |
| } |
| |
| TEST_P(WebMVideoClientTest, AutodetectVp9Profile2BitsPerChannel) { |
| const bool has_valid_codec_private = GetParam().codec_private.size() > 3; |
| |
| auto* parser = OnListStart(kWebMIdColour); |
| parser->OnUInt(kWebMIdBitsPerChannel, 10); |
| OnListEnd(kWebMIdColour); |
| |
| VideoDecoderConfig config; |
| EXPECT_TRUE(webm_video_client_.InitializeConfig( |
| "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); |
| |
| if (!has_valid_codec_private) |
| EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); |
| else |
| EXPECT_EQ(config.profile(), GetParam().profile); |
| } |
| |
| TEST_P(WebMVideoClientTest, AutodetectVp9Profile2HDRMetaData) { |
| const bool has_valid_codec_private = GetParam().codec_private.size() > 3; |
| |
| auto* color_parser = OnListStart(kWebMIdColour); |
| auto* metadata_parser = color_parser->OnListStart(kWebMIdColorVolumeMetadata); |
| metadata_parser->OnFloat(kWebMIdPrimaryRChromaticityX, 1.0); |
| color_parser->OnListEnd(kWebMIdColorVolumeMetadata); |
| OnListEnd(kWebMIdColour); |
| |
| VideoDecoderConfig config; |
| EXPECT_TRUE(webm_video_client_.InitializeConfig( |
| "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); |
| |
| if (!has_valid_codec_private) |
| EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); |
| else |
| EXPECT_EQ(config.profile(), GetParam().profile); |
| } |
| |
| TEST_P(WebMVideoClientTest, AutodetectVp9Profile2HDRColorSpace) { |
| const bool has_valid_codec_private = GetParam().codec_private.size() > 3; |
| |
| auto* parser = OnListStart(kWebMIdColour); |
| parser->OnUInt( |
| kWebMIdTransferCharacteristics, |
| static_cast<int64_t>(VideoColorSpace::TransferID::SMPTEST2084)); |
| OnListEnd(kWebMIdColour); |
| |
| VideoDecoderConfig config; |
| EXPECT_TRUE(webm_video_client_.InitializeConfig( |
| "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); |
| |
| if (!has_valid_codec_private) |
| EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); |
| else |
| EXPECT_EQ(config.profile(), GetParam().profile); |
| } |
| |
| TEST_P(WebMVideoClientTest, InitializeConfigVP9Profiles) { |
| const std::string kCodecId = "V_VP9"; |
| const VideoCodecProfile profile = GetParam().profile; |
| const std::vector<uint8_t> codec_private = GetParam().codec_private; |
| |
| VideoDecoderConfig config; |
| EXPECT_TRUE(webm_video_client_.InitializeConfig(kCodecId, codec_private, |
| EncryptionScheme(), &config)); |
| |
| VideoDecoderConfig expected_config( |
| VideoCodec::kVP9, profile, VideoDecoderConfig::AlphaMode::kIsOpaque, |
| VideoColorSpace::REC709(), kNoTransformation, kCodedSize, |
| gfx::Rect(kCodedSize), kCodedSize, codec_private, |
| EncryptionScheme::kUnencrypted); |
| |
| EXPECT_TRUE(config.Matches(expected_config)) |
| << "Config (" << config.AsHumanReadableString() |
| << ") does not match expected (" |
| << expected_config.AsHumanReadableString() << ")"; |
| } |
| |
| TEST_F(WebMVideoClientTest, InvalidStereoMode) { |
| EXPECT_MEDIA_LOG(UnexpectedStereoMode()); |
| OnUInt(kWebMIdStereoMode, 15); |
| } |
| |
| TEST_F(WebMVideoClientTest, MultipleStereoMode) { |
| OnUInt(kWebMIdStereoMode, 1); |
| EXPECT_MEDIA_LOG(UnexpectedMultipleValues()); |
| OnUInt(kWebMIdStereoMode, 1); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(All, |
| WebMVideoClientTest, |
| ::testing::ValuesIn(kCodecTestParams)); |
| |
| } // namespace media |