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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/webm/webm_parser.cc ('k') | media/webm/webm_tracks_parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/webm/cluster_builder.h"
6 #include "media/webm/webm_constants.h"
7 #include "media/webm/webm_parser.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 using ::testing::InSequence;
12 using ::testing::Return;
13 using ::testing::StrictMock;
14 using ::testing::_;
15
16 namespace media {
17
18 class MockWebMParserClient : public WebMParserClient {
19 public:
20 virtual ~MockWebMParserClient() {}
21
22 // WebMParserClient methods.
23 MOCK_METHOD1(OnListStart, bool(int));
24 MOCK_METHOD1(OnListEnd, bool(int));
25 MOCK_METHOD2(OnUInt, bool(int, int64));
26 MOCK_METHOD2(OnFloat, bool(int, double));
27 MOCK_METHOD3(OnBinary, bool(int, const uint8*, int));
28 MOCK_METHOD2(OnString, bool(int, const std::string&));
29 MOCK_METHOD5(OnSimpleBlock, bool(int, int, int, const uint8*, int));
30 };
31
32 class WebMParserTest : public testing::Test {
33 protected:
34 struct SimpleBlockInfo {
35 int track_num;
36 int timestamp;
37 };
38
39 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.
40 int64 timecode) {
41 uint8 data[] = { 0x00 };
42 cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
43 }
44
45 static Cluster* CreateCluster(int timecode,
46 const SimpleBlockInfo* block_info,
47 int block_count) {
48 ClusterBuilder cb;
49 cb.SetClusterTimecode(0);
50
51 for (int i = 0; i < block_count; i++)
52 AddSimpleBlock(&cb, block_info[i].track_num, block_info[i].timestamp);
53
54 return cb.Finish();
55 }
56
57 static void CreateClusterExpectations(int timecode,
58 const SimpleBlockInfo* block_info,
59 int block_count,
60 MockWebMParserClient* client) {
61
62 InSequence s;
63 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
64 EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0)).WillOnce(Return(true));
65
66 for (int i = 0; i < block_count; i++) {
67 EXPECT_CALL(*client, OnSimpleBlock(block_info[i].track_num,
68 block_info[i].timestamp,
69 _, _, _)
70 ).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.
71 }
72
73 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
74 }
75 };
76
77 TEST_F(WebMParserTest, EmptyCluster) {
78 const uint8 kEmptyCluster[] = {
79 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0)
80 };
81 int size = sizeof(kEmptyCluster);
82
83 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
84 new StrictMock<MockWebMParserClient>());
85
86 InSequence s;
87 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
88 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
89
90 WebMListParser parser(kWebMIdCluster);
91 int result = parser.Parse(kEmptyCluster, size, client.get());
92 EXPECT_EQ(size, result);
93 EXPECT_TRUE(parser.IsParsingComplete());
94 }
95
96 TEST_F(WebMParserTest, EmptyClusterInSegment) {
97 const uint8 kBuffer[] = {
98 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
99 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0)
100 };
101 int size = sizeof(kBuffer);
102
103 scoped_ptr<StrictMock<MockWebMParserClient> > client(
104 new StrictMock<MockWebMParserClient>());
105
106 InSequence s;
107 EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
108 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
109 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
110 EXPECT_CALL(*client, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
111
112 WebMListParser parser(kWebMIdSegment);
113 int result = parser.Parse(kBuffer, size, client.get());
114 EXPECT_EQ(size, result);
115 EXPECT_TRUE(parser.IsParsingComplete());
116 }
117
118 // Test the case where a non-list child element has a size
119 // that is beyond the end of the parent.
120 TEST_F(WebMParserTest, ChildNonListLargerThanParent) {
121 const uint8 kBuffer[] = {
122 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1)
123 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.
124 };
125 int size = sizeof(kBuffer);
126
127 scoped_ptr<StrictMock<MockWebMParserClient> > client(
128 new StrictMock<MockWebMParserClient>());
129
130 InSequence s;
131 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
132
133 WebMListParser parser(kWebMIdCluster);
134 int result = parser.Parse(kBuffer, size, client.get());
135 EXPECT_EQ(-1, result);
136 EXPECT_FALSE(parser.IsParsingComplete());
137 }
138
139 // Test the case where a list child element has a size
140 // that is beyond the end of the parent.
141 TEST_F(WebMParserTest, ChildListLargerThanParent) {
142 const uint8 kBuffer[] = {
143 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
144 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1)
145 };
146 int size = sizeof(kBuffer);
147
148 scoped_ptr<StrictMock<MockWebMParserClient> > client(
149 new StrictMock<MockWebMParserClient>());
150
151 InSequence s;
152 EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
153
154 WebMListParser parser(kWebMIdSegment);
155 int result = parser.Parse(kBuffer, size, client.get());
156 EXPECT_EQ(-1, result);
157 EXPECT_FALSE(parser.IsParsingComplete());
158 }
159
160 // Expecting to parse a Cluster, but get a Segment.
161 TEST_F(WebMParserTest, ListIdDoesNotMatch) {
162 const uint8 kBuffer[] = {
163 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0)
164 };
165 int size = sizeof(kBuffer);
166
167 scoped_ptr<StrictMock<MockWebMParserClient> > client(
168 new StrictMock<MockWebMParserClient>());
169
170 WebMListParser parser(kWebMIdCluster);
171 int result = parser.Parse(kBuffer, size, client.get());
172 EXPECT_EQ(-1, result);
173 EXPECT_FALSE(parser.IsParsingComplete());
174 }
175
176 TEST_F(WebMParserTest, InvalidElementInList) {
177 const uint8 kBuffer[] = {
178 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2)
179 0xAE, 0x80, // TrackEntry (size = 0)
180 };
181 int size = sizeof(kBuffer);
182
183 scoped_ptr<StrictMock<MockWebMParserClient> > client(
184 new StrictMock<MockWebMParserClient>());
185
186 InSequence s;
187 EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
188
189 WebMListParser parser(kWebMIdSegment);
190 int result = parser.Parse(kBuffer, size, client.get());
191 EXPECT_EQ(-1, result);
192 EXPECT_FALSE(parser.IsParsingComplete());
193 }
194
195 TEST_F(WebMParserTest, VoidAndCRC32InList) {
196 const uint8 kBuffer[] = {
197 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25)
198 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
199 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
200 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10)
201 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
202 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
203 };
204 int size = sizeof(kBuffer);
205
206 scoped_ptr<StrictMock<MockWebMParserClient> > client(
207 new StrictMock<MockWebMParserClient>());
208
209 InSequence s;
210 EXPECT_CALL(*client, OnListStart(kWebMIdSegment)).WillOnce(Return(true));
211 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(true));
212 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
213 EXPECT_CALL(*client, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
214
215 WebMListParser parser(kWebMIdSegment);
216 int result = parser.Parse(kBuffer, size, client.get());
217 EXPECT_EQ(size, result);
218 EXPECT_TRUE(parser.IsParsingComplete());
219 }
220
221
222 TEST_F(WebMParserTest, ParseListElementWithSingleCall) {
223 scoped_ptr<StrictMock<MockWebMParserClient> > client(
224 new StrictMock<MockWebMParserClient>());
225
226 const SimpleBlockInfo kBlockInfo[] = {
227 { 0, 1 },
228 { 1, 2 },
229 { 0, 3 },
230 { 0, 4 },
231 { 1, 4 },
232 };
233 int block_count = arraysize(kBlockInfo);
234
235 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
236 CreateClusterExpectations(0, kBlockInfo, block_count, client.get());
237
238 WebMListParser parser(kWebMIdCluster);
239 int result = parser.Parse(cluster->data(), cluster->size(), client.get());
240 EXPECT_EQ(cluster->size(), result);
241 EXPECT_TRUE(parser.IsParsingComplete());
242 }
243
244 TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) {
245 scoped_ptr<StrictMock<MockWebMParserClient> > client(
246 new StrictMock<MockWebMParserClient>());
247
248 const SimpleBlockInfo kBlockInfo[] = {
249 { 0, 1 },
250 { 1, 2 },
251 { 0, 3 },
252 { 0, 4 },
253 { 1, 4 },
254 };
255 int block_count = arraysize(kBlockInfo);
256
257 scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
258 CreateClusterExpectations(0, kBlockInfo, block_count, client.get());
259
260 const uint8* data = cluster->data();
261 int size = cluster->size();
262 int default_parse_size = 3;
263 WebMListParser parser(kWebMIdCluster);
264 int parse_size = std::min(default_parse_size, size);
265
266 while (size > 0) {
267 int result = parser.Parse(data, parse_size, client.get());
268 EXPECT_GE(result, 0);
269 EXPECT_LE(result, parse_size);
270
271 if (result == 0) {
272 // The parser needs more data so increase the parse_size a little.
273 EXPECT_FALSE(parser.IsParsingComplete());
274 parse_size += default_parse_size;
275 parse_size = std::min(parse_size, size);
276 continue;
277 }
278
279 parse_size = default_parse_size;
280
281 data += result;
282 size -= result;
283
284 EXPECT_EQ((size == 0), parser.IsParsingComplete());
285 }
286 EXPECT_TRUE(parser.IsParsingComplete());
287 }
288
289 } // namespace media
OLDNEW
« 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