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

Unified Diff: media/formats/webm/webm_cluster_parser_unittest.cc

Issue 1306923004: Reland MSE: Verify MediaLog events created by existing WebM unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months 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 side-by-side diff with in-line comments
Download patch
Index: media/formats/webm/webm_cluster_parser_unittest.cc
diff --git a/media/formats/webm/webm_cluster_parser_unittest.cc b/media/formats/webm/webm_cluster_parser_unittest.cc
index eaeb3186da3d37acacbdf6983dd14e2cfe950130..db3321a426f395f48e9927105ba72e7de738b3cd 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
wolenetz 2015/08/25 19:34:48 Compared to previously reverted CL http://crrev.co
+ // 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,
« no previous file with comments | « media/formats/webm/webm_cluster_parser.cc ('k') | media/formats/webm/webm_content_encodings_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698