diff options
Diffstat (limited to 'media/formats')
-rw-r--r-- | media/formats/webm/webm_cluster_parser.cc | 21 | ||||
-rw-r--r-- | media/formats/webm/webm_cluster_parser_unittest.cc | 253 | ||||
-rw-r--r-- | media/formats/webm/webm_content_encodings_client_unittest.cc | 49 | ||||
-rw-r--r-- | media/formats/webm/webm_tracks_parser_unittest.cc | 80 |
4 files changed, 275 insertions, 128 deletions
diff --git a/media/formats/webm/webm_cluster_parser.cc b/media/formats/webm/webm_cluster_parser.cc index 92b508b..38a9f42 100644 --- a/media/formats/webm/webm_cluster_parser.cc +++ b/media/formats/webm/webm_cluster_parser.cc @@ -241,8 +241,9 @@ base::TimeDelta WebMClusterParser::ReadOpusDuration(const uint8_t* data, // things go sideways. LIMITED_MEDIA_LOG(DEBUG, media_log_, num_duration_errors_, kMaxDurationErrorLogs) - << "Warning, demuxed Opus packet with encoded duration: " << duration - << ". Should be no greater than " << kPacketDurationMax; + << "Warning, demuxed Opus packet with encoded duration: " + << duration.InMilliseconds() << "ms. Should be no greater than " + << kPacketDurationMax.InMilliseconds() << "ms."; } return duration; @@ -561,10 +562,9 @@ bool WebMClusterParser::OnBlock(bool is_simple_block, if (duration_difference.magnitude() > kWarnDurationDiff) { LIMITED_MEDIA_LOG(DEBUG, media_log_, num_duration_errors_, kMaxDurationErrorLogs) - << "BlockDuration " - << "(" << block_duration_time_delta << ") " - << "differs significantly from encoded duration " - << "(" << encoded_duration << ")."; + << "BlockDuration (" << block_duration_time_delta.InMilliseconds() + << "ms) differs significantly from encoded duration (" + << encoded_duration.InMilliseconds() << "ms)."; } } } else if (block_duration_time_delta != kNoTimestamp()) { @@ -693,10 +693,11 @@ void WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() { LIMITED_MEDIA_LOG(INFO, media_log_, num_duration_estimates_, kMaxDurationEstimateLogs) - << "Estimating WebM block duration to be " << estimated_duration << " " - << "for the last (Simple)Block in the Cluster for this Track. Use " - << "BlockGroups with BlockDurations at the end of each Track in a " - << "Cluster to avoid estimation."; + << "Estimating WebM block duration to be " + << estimated_duration.InMilliseconds() + << "ms for the last (Simple)Block in the Cluster for this Track. Use " + "BlockGroups with BlockDurations at the end of each Track in a " + "Cluster to avoid estimation."; DVLOG(2) << __FUNCTION__ << " new dur : ts " << last_added_buffer_missing_duration_->timestamp().InSecondsF() diff --git a/media/formats/webm/webm_cluster_parser_unittest.cc b/media/formats/webm/webm_cluster_parser_unittest.cc index eaeb318..db3321a 100644 --- a/media/formats/webm/webm_cluster_parser_unittest.cc +++ b/media/formats/webm/webm_cluster_parser_unittest.cc @@ -4,12 +4,15 @@ #include <algorithm> #include <cstdlib> +#include <string> #include <vector> #include "base/bind.h" #include "base/logging.h" +#include "base/strings/string_number_conversions.h" #include "media/base/audio_decoder_config.h" #include "media/base/decrypt_config.h" +#include "media/base/mock_media_log.h" #include "media/formats/webm/cluster_builder.h" #include "media/formats/webm/opus_packet_builder.h" #include "media/formats/webm/webm_cluster_parser.h" @@ -17,24 +20,53 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::HasSubstr; using ::testing::InSequence; using ::testing::Return; +using ::testing::StrictMock; using ::testing::_; namespace media { typedef WebMTracksParser::TextTracks TextTracks; +// Matchers for verifying common media log entry strings. +MATCHER_P(OpusPacketDurationTooHigh, actual_duration_ms, "") { + return CONTAINS_STRING( + arg, "Warning, demuxed Opus packet with encoded duration: " + + base::IntToString(actual_duration_ms) + + "ms. Should be no greater than 120ms."); +} + +MATCHER_P(WebMSimpleBlockDurationEstimated, estimated_duration_ms, "") { + return CONTAINS_STRING(arg, "Estimating WebM block duration to be " + + base::IntToString(estimated_duration_ms) + + "ms for the last (Simple)Block in the " + "Cluster for this Track. Use BlockGroups " + "with BlockDurations at the end of each " + "Track in a Cluster to avoid estimation."); +} + +MATCHER_P2(WebMBlockDurationMismatchesOpusDuration, + block_duration_ms, + opus_duration_ms, + "") { + return CONTAINS_STRING( + arg, "BlockDuration (" + base::IntToString(block_duration_ms) + + "ms) differs significantly from encoded duration (" + + base::IntToString(opus_duration_ms) + "ms)."); +} + namespace { -enum { - kTimecodeScale = 1000000, // Timecode scale for millisecond timestamps. - kAudioTrackNum = 1, - kVideoTrackNum = 2, - kTextTrackNum = 3, - kTestAudioFrameDefaultDurationInMs = 13, - kTestVideoFrameDefaultDurationInMs = 17 -}; +// Timecode scale for millisecond timestamps. +const int kTimecodeScale = 1000000; + +const int kAudioTrackNum = 1; +const int kVideoTrackNum = 2; +const int kTextTrackNum = 3; +const int kTestAudioFrameDefaultDurationInMs = 13; +const int kTestVideoFrameDefaultDurationInMs = 17; // Test duration defaults must differ from parser estimation defaults to know // which durations parser used when emitting buffers. @@ -83,58 +115,6 @@ const uint8_t kEncryptedFrame[] = { // IV 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; -// Helper that hard-codes some non-varying constructor parameters. -WebMClusterParser* CreateParserHelper( - base::TimeDelta audio_default_duration, - base::TimeDelta video_default_duration, - const WebMTracksParser::TextTracks& text_tracks, - const std::set<int64>& ignored_tracks, - const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id, - const AudioCodec audio_codec) { - return new WebMClusterParser( - kTimecodeScale, kAudioTrackNum, audio_default_duration, kVideoTrackNum, - video_default_duration, text_tracks, ignored_tracks, - audio_encryption_key_id, video_encryption_key_id, audio_codec, - new MediaLog()); -} - -// Create a default version of the parser for test. -WebMClusterParser* CreateDefaultParser() { - return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), - std::set<int64>(), std::string(), std::string(), - kUnknownAudioCodec); -} - -// Create a parser for test with custom audio and video default durations, and -// optionally custom text tracks. -WebMClusterParser* CreateParserWithDefaultDurationsAndOptionalTextTracks( - base::TimeDelta audio_default_duration, - base::TimeDelta video_default_duration, - const WebMTracksParser::TextTracks& text_tracks = TextTracks()) { - return CreateParserHelper(audio_default_duration, video_default_duration, - text_tracks, std::set<int64>(), std::string(), - std::string(), kUnknownAudioCodec); -} - -// Create a parser for test with custom ignored tracks. -WebMClusterParser* CreateParserWithIgnoredTracks( - std::set<int64>& ignored_tracks) { - return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), - ignored_tracks, std::string(), std::string(), - kUnknownAudioCodec); -} - -// Create a parser for test with custom encryption key ids and audio codec. -WebMClusterParser* CreateParserWithKeyIdsAndAudioCodec( - const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id, - const AudioCodec audio_codec) { - return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), - std::set<int64>(), audio_encryption_key_id, - video_encryption_key_id, audio_codec); -} - scoped_ptr<Cluster> CreateCluster(int timecode, const BlockInfo* block_info, int block_count) { @@ -313,7 +293,9 @@ void AppendToEnd(const WebMClusterParser::BufferQueue& src, class WebMClusterParserTest : public testing::Test { public: - WebMClusterParserTest() : parser_(CreateDefaultParser()) {} + WebMClusterParserTest() + : media_log_(new StrictMock<MockMediaLog>()), + parser_(CreateDefaultParser()) {} protected: void ResetParserToHaveDefaultDurations() { @@ -330,6 +312,59 @@ class WebMClusterParserTest : public testing::Test { default_audio_duration, default_video_duration)); } + // Helper that hard-codes some non-varying constructor parameters. + WebMClusterParser* CreateParserHelper( + base::TimeDelta audio_default_duration, + base::TimeDelta video_default_duration, + const WebMTracksParser::TextTracks& text_tracks, + const std::set<int64>& ignored_tracks, + const std::string& audio_encryption_key_id, + const std::string& video_encryption_key_id, + const AudioCodec audio_codec) { + return new WebMClusterParser( + kTimecodeScale, kAudioTrackNum, audio_default_duration, kVideoTrackNum, + video_default_duration, text_tracks, ignored_tracks, + audio_encryption_key_id, video_encryption_key_id, audio_codec, + media_log_); + } + + // Create a default version of the parser for test. + WebMClusterParser* CreateDefaultParser() { + return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), + std::set<int64>(), std::string(), std::string(), + kUnknownAudioCodec); + } + + // Create a parser for test with custom audio and video default durations, and + // optionally custom text tracks. + WebMClusterParser* CreateParserWithDefaultDurationsAndOptionalTextTracks( + base::TimeDelta audio_default_duration, + base::TimeDelta video_default_duration, + const WebMTracksParser::TextTracks& text_tracks = TextTracks()) { + return CreateParserHelper(audio_default_duration, video_default_duration, + text_tracks, std::set<int64>(), std::string(), + std::string(), kUnknownAudioCodec); + } + + // Create a parser for test with custom ignored tracks. + WebMClusterParser* CreateParserWithIgnoredTracks( + std::set<int64>& ignored_tracks) { + return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), + ignored_tracks, std::string(), std::string(), + kUnknownAudioCodec); + } + + // Create a parser for test with custom encryption key ids and audio codec. + WebMClusterParser* CreateParserWithKeyIdsAndAudioCodec( + const std::string& audio_encryption_key_id, + const std::string& video_encryption_key_id, + const AudioCodec audio_codec) { + return CreateParserHelper(kNoTimestamp(), kNoTimestamp(), TextTracks(), + std::set<int64>(), audio_encryption_key_id, + video_encryption_key_id, audio_codec); + } + + scoped_refptr<StrictMock<MockMediaLog>> media_log_; scoped_ptr<WebMClusterParser> parser_; private: @@ -356,6 +391,8 @@ TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) { parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks( default_audio_duration, kNoTimestamp(), text_tracks)); + const int kExpectedVideoEstimationInMs = 33; + const BlockInfo kBlockInfo[] = { {kVideoTrackNum, 0, 33, true, NULL, 0}, {kAudioTrackNum, 0, 23, false, NULL, 0}, @@ -363,7 +400,7 @@ TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) { {kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true, NULL, 0}, {kVideoTrackNum, 33, 33, true, NULL, 0}, {kAudioTrackNum, 36, kTestAudioFrameDefaultDurationInMs, true, NULL, 0}, - {kVideoTrackNum, 66, 33, true, NULL, 0}, + {kVideoTrackNum, 66, kExpectedVideoEstimationInMs, true, NULL, 0}, {kAudioTrackNum, 70, kTestAudioFrameDefaultDurationInMs, true, NULL, 0}, {kAudioTrackNum, 83, kTestAudioFrameDefaultDurationInMs, true, NULL, 0}, }; @@ -400,6 +437,12 @@ TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) { blocks_in_cluster)); // Parse all but the last byte unless we need to parse the full cluster. bool parse_full_cluster = i == (block_count - 1); + + if (parse_full_cluster) { + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); + } + int result = parser_->Parse(cluster->data(), parse_full_cluster ? cluster->size() : cluster->size() - 1); if (parse_full_cluster) { @@ -561,6 +604,8 @@ TEST_F(WebMClusterParserTest, IgnoredTracks) { scoped_ptr<Cluster> cluster( CreateCluster(0, kInputBlockInfo, input_block_count)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34)); int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kOutputBlockInfo, output_block_count)); @@ -590,6 +635,8 @@ TEST_F(WebMClusterParserTest, ParseTextTracks) { scoped_ptr<Cluster> cluster( CreateCluster(0, kInputBlockInfo, input_block_count)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34)); int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kInputBlockInfo, input_block_count)); @@ -649,6 +696,8 @@ TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) { scoped_ptr<Cluster> cluster( CreateCluster(0, kInputBlockInfo, input_block_count)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34)); int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); @@ -671,6 +720,11 @@ TEST_F(WebMClusterParserTest, ParseEncryptedBlock) { parser_.reset(CreateParserWithKeyIdsAndAudioCodec( std::string(), "video_key_id", kUnknownAudioCodec)); + + // The encrypted cluster contains just one block, video. + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated( + WebMClusterParser::kDefaultVideoBufferDurationInMs)); + int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); ASSERT_EQ(1UL, parser_->GetVideoBuffers().size()); @@ -771,16 +825,17 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsSimpleBlocks) { // cluster. For video tracks we use the maximum seen so far. For audio we use // the the minimum. // TODO(chcunningham): Move audio over to use the maximum. + + const int kExpectedAudioEstimationInMs = 22; + const int kExpectedVideoEstimationInMs = 34; const BlockInfo kBlockInfo1[] = { {kAudioTrackNum, 0, 23, true, NULL, 0}, {kAudioTrackNum, 23, 22, true, NULL, 0}, {kVideoTrackNum, 33, 33, true, NULL, 0}, {kAudioTrackNum, 45, 23, true, NULL, 0}, {kVideoTrackNum, 66, 34, true, NULL, 0}, - // Estimated from minimum audio dur - {kAudioTrackNum, 68, 22, true, NULL, 0}, - // Estimated from maximum video dur - {kVideoTrackNum, 100, 34, true, NULL, 0}, + {kAudioTrackNum, 68, kExpectedAudioEstimationInMs, true, NULL, 0}, + {kVideoTrackNum, 100, kExpectedVideoEstimationInMs, true, NULL, 0}, }; int block_count1 = arraysize(kBlockInfo1); @@ -801,6 +856,10 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsSimpleBlocks) { parser_->Reset(); // Now parse the full first cluster and verify all the blocks are parsed. + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); result = parser_->Parse(cluster1->data(), cluster1->size()); EXPECT_EQ(cluster1->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1)); @@ -809,13 +868,17 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsSimpleBlocks) { // each track. const BlockInfo kBlockInfo2[] = { // Estimate carries over across clusters - {kAudioTrackNum, 200, 22, true, NULL, 0}, + {kAudioTrackNum, 200, kExpectedAudioEstimationInMs, true, NULL, 0}, // Estimate carries over across clusters - {kVideoTrackNum, 201, 34, true, NULL, 0}, + {kVideoTrackNum, 201, kExpectedVideoEstimationInMs, true, NULL, 0}, }; int block_count2 = arraysize(kBlockInfo2); scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); result = parser_->Parse(cluster2->data(), cluster2->size()); EXPECT_EQ(cluster2->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2)); @@ -830,16 +893,17 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) { // independently for each track in the cluster. For video tracks we use the // maximum seen so far. For audio we use the the minimum. // TODO(chcunningham): Move audio over to use the maximum. + + const int kExpectedAudioEstimationInMs = 22; + const int kExpectedVideoEstimationInMs = 34; const BlockInfo kBlockInfo1[] = { {kAudioTrackNum, 0, -23, false, NULL, 0}, {kAudioTrackNum, 23, -22, false, NULL, 0}, {kVideoTrackNum, 33, -33, false, NULL, 0}, {kAudioTrackNum, 45, -23, false, NULL, 0}, {kVideoTrackNum, 66, -34, false, NULL, 0}, - // Estimated from minimum audio dur - {kAudioTrackNum, 68, -22, false, NULL, 0}, - // Estimated from maximum video dur - {kVideoTrackNum, 100, -34, false, NULL, 0}, + {kAudioTrackNum, 68, -kExpectedAudioEstimationInMs, false, NULL, 0}, + {kVideoTrackNum, 100, -kExpectedVideoEstimationInMs, false, NULL, 0}, }; int block_count1 = arraysize(kBlockInfo1); @@ -860,6 +924,10 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) { parser_->Reset(); // Now parse the full first cluster and verify all the blocks are parsed. + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); result = parser_->Parse(cluster1->data(), cluster1->size()); EXPECT_EQ(cluster1->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1)); @@ -867,12 +935,16 @@ TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) { // Verify that the estimated frame duration is tracked across clusters for // each track. const BlockInfo kBlockInfo2[] = { - {kAudioTrackNum, 200, -22, false, NULL, 0}, - {kVideoTrackNum, 201, -34, false, NULL, 0}, + {kAudioTrackNum, 200, -kExpectedAudioEstimationInMs, false, NULL, 0}, + {kVideoTrackNum, 201, -kExpectedVideoEstimationInMs, false, NULL, 0}, }; int block_count2 = arraysize(kBlockInfo2); scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs)); + EXPECT_MEDIA_LOG( + WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs)); result = parser_->Parse(cluster2->data(), cluster2->size()); EXPECT_EQ(cluster2->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2)); @@ -939,6 +1011,10 @@ TEST_F(WebMClusterParserTest, int block_count = arraysize(kBlockInfo); scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated( + WebMClusterParser::kDefaultAudioBufferDurationInMs)); + EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated( + WebMClusterParser::kDefaultVideoBufferDurationInMs)); int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); @@ -961,12 +1037,14 @@ TEST_F(WebMClusterParserTest, } TEST_F(WebMClusterParserTest, ReadOpusDurationsSimpleBlockAtEndOfCluster) { - // Reset parser to expect Opus codec audio. - parser_.reset(CreateParserWithKeyIdsAndAudioCodec(std::string(), - std::string(), kCodecOpus)); + InSequence s; int loop_count = 0; for (const auto* packet_ptr : BuildAllOpusPackets()) { + // Get a new parser each iteration to prevent exceeding the media log cap. + parser_.reset(CreateParserWithKeyIdsAndAudioCodec( + std::string(), std::string(), kCodecOpus)); + const BlockInfo kBlockInfo[] = {{kAudioTrackNum, 0, packet_ptr->duration_ms(), @@ -976,6 +1054,11 @@ TEST_F(WebMClusterParserTest, ReadOpusDurationsSimpleBlockAtEndOfCluster) { int block_count = arraysize(kBlockInfo); scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count)); + int duration_ms = packet_ptr->duration_ms(); // Casts from double. + if (duration_ms > 120) { + EXPECT_MEDIA_LOG(OpusPacketDurationTooHigh(duration_ms)); + } + int result = parser_->Parse(cluster->data(), cluster->size()); EXPECT_EQ(cluster->size(), result); ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); @@ -987,14 +1070,24 @@ TEST_F(WebMClusterParserTest, ReadOpusDurationsSimpleBlockAtEndOfCluster) { } TEST_F(WebMClusterParserTest, PreferOpusDurationsOverBlockDurations) { - // Reset parser to expect Opus codec audio. - parser_.reset(CreateParserWithKeyIdsAndAudioCodec(std::string(), - std::string(), kCodecOpus)); + // Exhaustively testing expected media logs' emission sequence in this test at + // least causes 10x execution time. Therefore, no InSequence is used here, but + // the set of expected messages is verified. int loop_count = 0; for (const auto* packet_ptr : BuildAllOpusPackets()) { + // Get a new parser each iteration to prevent exceeding the media log cap. + parser_.reset(CreateParserWithKeyIdsAndAudioCodec( + std::string(), std::string(), kCodecOpus)); + // Setting BlockDuration != Opus duration to see which one the parser uses. int block_duration_ms = packet_ptr->duration_ms() + 10; + if (packet_ptr->duration_ms() > 120) { + EXPECT_MEDIA_LOG(OpusPacketDurationTooHigh(packet_ptr->duration_ms())); + } + + EXPECT_MEDIA_LOG(WebMBlockDurationMismatchesOpusDuration( + block_duration_ms, packet_ptr->duration_ms())); BlockInfo block_infos[] = {{kAudioTrackNum, 0, diff --git a/media/formats/webm/webm_content_encodings_client_unittest.cc b/media/formats/webm/webm_content_encodings_client_unittest.cc index 22049eb..d31ad27 100644 --- a/media/formats/webm/webm_content_encodings_client_unittest.cc +++ b/media/formats/webm/webm_content_encodings_client_unittest.cc @@ -2,18 +2,56 @@ // 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_content_encodings_client.h" + +#include <string> + #include "base/bind.h" +#include "base/strings/string_number_conversions.h" +#include "media/base/mock_media_log.h" #include "media/formats/webm/webm_constants.h" -#include "media/formats/webm/webm_content_encodings_client.h" #include "media/formats/webm/webm_parser.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::StrictMock; + namespace media { +// Matchers for verifying common media log entry strings. +MATCHER(MissingContentEncoding, "") { + return CONTAINS_STRING(arg, "Missing ContentEncoding."); +} + +MATCHER(UnexpectedContentEncodingOrder, "") { + return CONTAINS_STRING(arg, "Unexpected ContentEncodingOrder."); +} + +MATCHER(UnexpectedContentEncodingScope, "") { + return CONTAINS_STRING(arg, "Unexpected ContentEncodingScope."); +} + +MATCHER(ContentCompressionNotSupported, "") { + return CONTAINS_STRING(arg, "ContentCompression not supported."); +} + +MATCHER(MissingContentEncryption, "") { + return CONTAINS_STRING( + arg, + "ContentEncodingType is encryption but ContentEncryption is missing."); +} + +MATCHER_P(UnexpectedContentEncAlgo, algo, "") { + return CONTAINS_STRING( + arg, "Unexpected ContentEncAlgo " + base::IntToString(algo) + "."); +} + class WebMContentEncodingsClientTest : public testing::Test { public: WebMContentEncodingsClientTest() - : client_(new MediaLog()), parser_(kWebMIdContentEncodings, &client_) {} + : media_log_(new StrictMock<MockMediaLog>()), + client_(media_log_), + parser_(kWebMIdContentEncodings, &client_) {} void ParseAndExpectToFail(const uint8* buf, int size) { int result = parser_.Parse(buf, size); @@ -21,6 +59,7 @@ class WebMContentEncodingsClientTest : public testing::Test { } protected: + scoped_refptr<StrictMock<MockMediaLog>> media_log_; WebMContentEncodingsClient client_; WebMListParser parser_; }; @@ -30,6 +69,7 @@ TEST_F(WebMContentEncodingsClientTest, EmptyContentEncodings) { 0x6D, 0x80, 0x80, // ContentEncodings (size = 0) }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(MissingContentEncoding()); ParseAndExpectToFail(kContentEncodings, size); } @@ -182,6 +222,7 @@ TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingOrder) { 0x50, 0x35, 0x80, // ContentEncryption (size = 0) }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(UnexpectedContentEncodingOrder()); ParseAndExpectToFail(kContentEncodings, size); } @@ -194,6 +235,7 @@ TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingScope) { 0x50, 0x35, 0x80, // ContentEncryption (size = 0) }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(UnexpectedContentEncodingScope()); ParseAndExpectToFail(kContentEncodings, size); } @@ -205,6 +247,7 @@ TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingType) { 0x50, 0x35, 0x80, // ContentEncryption (size = 0) }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(ContentCompressionNotSupported()); ParseAndExpectToFail(kContentEncodings, size); } @@ -217,6 +260,7 @@ TEST_F(WebMContentEncodingsClientTest, MissingContentEncryption) { // ContentEncryption missing }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(MissingContentEncryption()); ParseAndExpectToFail(kContentEncodings, size); } @@ -231,6 +275,7 @@ TEST_F(WebMContentEncodingsClientTest, InvalidContentEncAlgo) { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, }; int size = sizeof(kContentEncodings); + EXPECT_MEDIA_LOG(UnexpectedContentEncAlgo(0xEE)); ParseAndExpectToFail(kContentEncodings, size); } diff --git a/media/formats/webm/webm_tracks_parser_unittest.cc b/media/formats/webm/webm_tracks_parser_unittest.cc index 39854ef..4fc6cee 100644 --- a/media/formats/webm/webm_tracks_parser_unittest.cc +++ b/media/formats/webm/webm_tracks_parser_unittest.cc @@ -5,14 +5,17 @@ #include "base/logging.h" #include "media/base/buffers.h" #include "media/base/channel_layout.h" +#include "media/base/mock_media_log.h" #include "media/formats/webm/tracks_builder.h" #include "media/formats/webm/webm_constants.h" #include "media/formats/webm/webm_tracks_parser.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::HasSubstr; using ::testing::InSequence; using ::testing::Return; +using ::testing::StrictMock; using ::testing::_; namespace media { @@ -21,33 +24,37 @@ static const double kDefaultTimecodeScaleInUs = 1000.0; // 1 ms resolution class WebMTracksParserTest : public testing::Test { public: - WebMTracksParserTest() {} + WebMTracksParserTest() : media_log_(new StrictMock<MockMediaLog>()) {} + + protected: + void VerifyTextTrackInfo(const uint8* buffer, + int buffer_size, + TextKind text_kind, + const std::string& name, + const std::string& language) { + scoped_ptr<WebMTracksParser> parser( + new WebMTracksParser(media_log_, false)); + + int result = parser->Parse(buffer, buffer_size); + EXPECT_GT(result, 0); + EXPECT_EQ(result, buffer_size); + + const WebMTracksParser::TextTracks& text_tracks = parser->text_tracks(); + EXPECT_EQ(text_tracks.size(), WebMTracksParser::TextTracks::size_type(1)); + + const WebMTracksParser::TextTracks::const_iterator itr = + text_tracks.begin(); + EXPECT_EQ(itr->first, 1); // track num + + const TextTrackConfig& config = itr->second; + EXPECT_EQ(config.kind(), text_kind); + EXPECT_TRUE(config.label() == name); + EXPECT_TRUE(config.language() == language); + } + + scoped_refptr<StrictMock<MockMediaLog>> media_log_; }; -static void VerifyTextTrackInfo(const uint8* buffer, - int buffer_size, - TextKind text_kind, - const std::string& name, - const std::string& language) { - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), false)); - - int result = parser->Parse(buffer, buffer_size); - EXPECT_GT(result, 0); - EXPECT_EQ(result, buffer_size); - - const WebMTracksParser::TextTracks& text_tracks = parser->text_tracks(); - EXPECT_EQ(text_tracks.size(), WebMTracksParser::TextTracks::size_type(1)); - - const WebMTracksParser::TextTracks::const_iterator itr = text_tracks.begin(); - EXPECT_EQ(itr->first, 1); // track num - - const TextTrackConfig& config = itr->second; - EXPECT_EQ(config.kind(), text_kind); - EXPECT_TRUE(config.label() == name); - EXPECT_TRUE(config.language() == language); -} - TEST_F(WebMTracksParserTest, SubtitleNoNameNoLang) { InSequence s; @@ -96,8 +103,10 @@ TEST_F(WebMTracksParserTest, IgnoringTextTracks) { tb.AddTextTrack(2, 2, kWebMCodecSubtitles, "Commentary", "fre"); const std::vector<uint8> buf = tb.Finish(); - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), true)); + scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(media_log_, true)); + + EXPECT_MEDIA_LOG(HasSubstr("Ignoring text track 1")); + EXPECT_MEDIA_LOG(HasSubstr("Ignoring text track 2")); int result = parser->Parse(&buf[0], buf.size()); EXPECT_GT(result, 0); @@ -110,7 +119,7 @@ TEST_F(WebMTracksParserTest, IgnoringTextTracks) { EXPECT_TRUE(ignored_tracks.find(2) != ignored_tracks.end()); // Test again w/o ignoring the test tracks. - parser.reset(new WebMTracksParser(new MediaLog(), false)); + parser.reset(new WebMTracksParser(media_log_, false)); result = parser->Parse(&buf[0], buf.size()); EXPECT_GT(result, 0); @@ -130,8 +139,7 @@ TEST_F(WebMTracksParserTest, AudioVideoDefaultDurationUnset) { tb.AddVideoTrack(2, 2, "V_VP8", "video", "", -1, 320, 240); const std::vector<uint8> buf = tb.Finish(); - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), true)); + scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(media_log_, true)); int result = parser->Parse(&buf[0], buf.size()); EXPECT_LE(0, result); EXPECT_EQ(static_cast<int>(buf.size()), result); @@ -160,8 +168,7 @@ TEST_F(WebMTracksParserTest, AudioVideoDefaultDurationSet) { tb.AddVideoTrack(2, 2, "V_VP8", "video", "", 987654321, 320, 240); const std::vector<uint8> buf = tb.Finish(); - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), true)); + scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(media_log_, true)); int result = parser->Parse(&buf[0], buf.size()); EXPECT_LE(0, result); EXPECT_EQ(static_cast<int>(buf.size()), result); @@ -183,8 +190,10 @@ TEST_F(WebMTracksParserTest, InvalidZeroDefaultDurationSet) { tb.AddAudioTrack(1, 1, "A_VORBIS", "audio", "", 0, 2, 8000); const std::vector<uint8> buf = tb.Finish(); - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), true)); + scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(media_log_, true)); + + EXPECT_MEDIA_LOG(HasSubstr("Illegal 0ns audio TrackEntry DefaultDuration")); + EXPECT_EQ(-1, parser->Parse(&buf[0], buf.size())); } @@ -195,8 +204,7 @@ TEST_F(WebMTracksParserTest, HighTrackUID) { tb.AddAudioTrack(1, 1ULL << 31, "A_VORBIS", "audio", "", 40, 2, 8000); const std::vector<uint8> buf = tb.Finish(); - scoped_ptr<WebMTracksParser> parser( - new WebMTracksParser(new MediaLog(), true)); + scoped_ptr<WebMTracksParser> parser(new WebMTracksParser(media_log_, true)); EXPECT_GT(parser->Parse(&buf[0], buf.size()),0); } |