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

Unified Diff: media/webm/webm_parser_unittest.cc

Issue 8775035: Add support for incremental cluster parsing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments & include new unit tests this time" Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/webm/webm_parser.cc ('k') | media/webm/webm_tracks_parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/webm/webm_parser_unittest.cc
diff --git a/media/webm/webm_parser_unittest.cc b/media/webm/webm_parser_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5e74a94ebaf79f3157f939b9774732bea8cd9527
--- /dev/null
+++ b/media/webm/webm_parser_unittest.cc
@@ -0,0 +1,289 @@
+// Copyright (c) 2011 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/webm/cluster_builder.h"
+#include "media/webm/webm_constants.h"
+#include "media/webm/webm_parser.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::InSequence;
+using ::testing::Return;
+using ::testing::StrictMock;
+using ::testing::_;
+
+namespace media {
+
+class MockWebMParserClient : public WebMParserClient {
+ public:
+ virtual ~MockWebMParserClient() {}
+
+ // WebMParserClient methods.
+ MOCK_METHOD1(OnListStart, bool(int));
+ MOCK_METHOD1(OnListEnd, bool(int));
+ MOCK_METHOD2(OnUInt, bool(int, int64));
+ MOCK_METHOD2(OnFloat, bool(int, double));
+ MOCK_METHOD3(OnBinary, bool(int, const uint8*, int));
+ MOCK_METHOD2(OnString, bool(int, const std::string&));
+ MOCK_METHOD5(OnSimpleBlock, bool(int, int, int, const uint8*, int));
+};
+
+class WebMParserTest : public testing::Test {
+ protected:
+ struct SimpleBlockInfo {
+ int track_num;
+ int timestamp;
+ };
+
+ static void AddSimpleBlock(ClusterBuilder* cb, int track_num,
scherkus (not reviewing) 2011/12/09 21:36:03 nit: move all these static methods to outside the
acolwell GONE FROM CHROMIUM 2011/12/09 22:53:53 Done.
+ int64 timecode) {
+ uint8 data[] = { 0x00 };
+ cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
+ }
+
+ static Cluster* CreateCluster(int timecode,
+ const SimpleBlockInfo* block_info,
+ int block_count) {
+ ClusterBuilder cb;
+ cb.SetClusterTimecode(0);
+
+ for (int i = 0; i < block_count; i++)
+ AddSimpleBlock(&cb, block_info[i].track_num, block_info[i].timestamp);
+
+ return cb.Finish();
+ }
+
+ static void CreateClusterExpectations(int timecode,
+ const SimpleBlockInfo* block_info,
+ int block_count,
+ MockWebMParserClient* client) {
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0)).WillOnce(Return(true));
+
+ for (int i = 0; i < block_count; i++) {
+ EXPECT_CALL(*client, OnSimpleBlock(block_info[i].track_num,
+ block_info[i].timestamp,
+ _, _, _)
+ ).WillOnce(Return(true));
scherkus (not reviewing) 2011/12/09 21:36:03 nit: move ) to previous line and have this .WillOn
acolwell GONE FROM CHROMIUM 2011/12/09 22:53:53 Done. Not sure why I did that in the first place.
+ }
+
+ EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
+ }
+};
+
+TEST_F(WebMParserTest, EmptyCluster) {
+ const uint8 kEmptyCluster[] = {
+ 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0)
+ };
+ int size = sizeof(kEmptyCluster);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
scherkus (not reviewing) 2011/12/09 21:36:03 nit: does this need to be a pointer? Looks like st
acolwell GONE FROM CHROMIUM 2011/12/09 22:53:53 Done. Removed pointer and placed it in WebMParserT
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdCluster);
+ int result = parser.Parse(kEmptyCluster, size, client.get());
+ EXPECT_EQ(size, result);
+ EXPECT_TRUE(parser.IsParsingComplete());
+}
+
+TEST_F(WebMParserTest, EmptyClusterInSegment) {
+ const uint8 kBuffer[] = {
+ 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
+ 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0)
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdSegment);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(size, result);
+ EXPECT_TRUE(parser.IsParsingComplete());
+}
+
+// Test the case where a non-list child element has a size
+// that is beyond the end of the parent.
+TEST_F(WebMParserTest, ChildNonListLargerThanParent) {
+ const uint8 kBuffer[] = {
+ 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1)
+ 0xE7, 0x81, 0x01, // Timecode (size=1, value=1)
scherkus (not reviewing) 2011/12/09 21:36:03 two space
acolwell GONE FROM CHROMIUM 2011/12/09 22:53:53 Done.
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdCluster);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(-1, result);
+ EXPECT_FALSE(parser.IsParsingComplete());
+}
+
+// Test the case where a list child element has a size
+// that is beyond the end of the parent.
+TEST_F(WebMParserTest, ChildListLargerThanParent) {
+ const uint8 kBuffer[] = {
+ 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
+ 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1)
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdSegment);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(-1, result);
+ EXPECT_FALSE(parser.IsParsingComplete());
+}
+
+// Expecting to parse a Cluster, but get a Segment.
+TEST_F(WebMParserTest, ListIdDoesNotMatch) {
+ const uint8 kBuffer[] = {
+ 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0)
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ WebMListParser parser(kWebMIdCluster);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(-1, result);
+ EXPECT_FALSE(parser.IsParsingComplete());
+}
+
+TEST_F(WebMParserTest, InvalidElementInList) {
+ const uint8 kBuffer[] = {
+ 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2)
+ 0xAE, 0x80, // TrackEntry (size = 0)
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdSegment);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(-1, result);
+ EXPECT_FALSE(parser.IsParsingComplete());
+}
+
+TEST_F(WebMParserTest, VoidAndCRC32InList) {
+ const uint8 kBuffer[] = {
+ 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25)
+ 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
+ 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
+ 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10)
+ 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
+ 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
+ };
+ int size = sizeof(kBuffer);
+
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ InSequence s;
+ EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
+ EXPECT_CALL(*client, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
+
+ WebMListParser parser(kWebMIdSegment);
+ int result = parser.Parse(kBuffer, size, client.get());
+ EXPECT_EQ(size, result);
+ EXPECT_TRUE(parser.IsParsingComplete());
+}
+
+
+TEST_F(WebMParserTest, ParseListElementWithSingleCall) {
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ const SimpleBlockInfo kBlockInfo[] = {
+ { 0, 1 },
+ { 1, 2 },
+ { 0, 3 },
+ { 0, 4 },
+ { 1, 4 },
+ };
+ int block_count = arraysize(kBlockInfo);
+
+ scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
+ CreateClusterExpectations(0, kBlockInfo, block_count, client.get());
+
+ WebMListParser parser(kWebMIdCluster);
+ int result = parser.Parse(cluster->data(), cluster->size(), client.get());
+ EXPECT_EQ(cluster->size(), result);
+ EXPECT_TRUE(parser.IsParsingComplete());
+}
+
+TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) {
+ scoped_ptr<StrictMock<MockWebMParserClient> > client(
+ new StrictMock<MockWebMParserClient>());
+
+ const SimpleBlockInfo kBlockInfo[] = {
+ { 0, 1 },
+ { 1, 2 },
+ { 0, 3 },
+ { 0, 4 },
+ { 1, 4 },
+ };
+ int block_count = arraysize(kBlockInfo);
+
+ scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
+ CreateClusterExpectations(0, kBlockInfo, block_count, client.get());
+
+ const uint8* data = cluster->data();
+ int size = cluster->size();
+ int default_parse_size = 3;
+ WebMListParser parser(kWebMIdCluster);
+ int parse_size = std::min(default_parse_size, size);
+
+ while (size > 0) {
+ int result = parser.Parse(data, parse_size, client.get());
+ EXPECT_GE(result, 0);
+ EXPECT_LE(result, parse_size);
+
+ if (result == 0) {
+ // The parser needs more data so increase the parse_size a little.
+ EXPECT_FALSE(parser.IsParsingComplete());
+ parse_size += default_parse_size;
+ parse_size = std::min(parse_size, size);
+ continue;
+ }
+
+ parse_size = default_parse_size;
+
+ data += result;
+ size -= result;
+
+ EXPECT_EQ((size == 0), parser.IsParsingComplete());
+ }
+ EXPECT_TRUE(parser.IsParsingComplete());
+}
+
+} // namespace media
« no previous file with comments | « media/webm/webm_parser.cc ('k') | media/webm/webm_tracks_parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698