cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / media / webm / webm_parser_unittest.cc
blobcb71fe98bda13a0ac31e272c35a9f9118d99d9fe
1 // Copyright (c) 2012 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.
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"
11 using ::testing::InSequence;
12 using ::testing::Return;
13 using ::testing::ReturnNull;
14 using ::testing::StrictMock;
15 using ::testing::_;
17 namespace media {
19 enum { kBlockCount = 5 };
21 class MockWebMParserClient : public WebMParserClient {
22 public:
23 virtual ~MockWebMParserClient() {}
25 // WebMParserClient methods.
26 MOCK_METHOD1(OnListStart, WebMParserClient*(int));
27 MOCK_METHOD1(OnListEnd, bool(int));
28 MOCK_METHOD2(OnUInt, bool(int, int64));
29 MOCK_METHOD2(OnFloat, bool(int, double));
30 MOCK_METHOD3(OnBinary, bool(int, const uint8*, int));
31 MOCK_METHOD2(OnString, bool(int, const std::string&));
34 class WebMParserTest : public testing::Test {
35 protected:
36 StrictMock<MockWebMParserClient> client_;
39 static scoped_ptr<Cluster> CreateCluster(int block_count) {
40 ClusterBuilder cb;
41 cb.SetClusterTimecode(0);
43 for (int i = 0; i < block_count; i++) {
44 uint8 data[] = { 0x00 };
45 cb.AddSimpleBlock(0, i, 0, data, sizeof(data));
48 return cb.Finish();
51 static void CreateClusterExpectations(int block_count,
52 bool is_complete_cluster,
53 MockWebMParserClient* client) {
55 InSequence s;
56 EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(client));
57 EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0))
58 .WillOnce(Return(true));
60 for (int i = 0; i < block_count; i++) {
61 EXPECT_CALL(*client, OnBinary(kWebMIdSimpleBlock, _, _))
62 .WillOnce(Return(true));
65 if (is_complete_cluster)
66 EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
69 TEST_F(WebMParserTest, EmptyCluster) {
70 const uint8 kEmptyCluster[] = {
71 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0)
73 int size = sizeof(kEmptyCluster);
75 InSequence s;
76 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
77 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
79 WebMListParser parser(kWebMIdCluster, &client_);
80 int result = parser.Parse(kEmptyCluster, size);
81 EXPECT_EQ(size, result);
82 EXPECT_TRUE(parser.IsParsingComplete());
85 TEST_F(WebMParserTest, EmptyClusterInSegment) {
86 const uint8 kBuffer[] = {
87 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
88 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0)
90 int size = sizeof(kBuffer);
92 InSequence s;
93 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
94 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
95 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
96 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
98 WebMListParser parser(kWebMIdSegment, &client_);
99 int result = parser.Parse(kBuffer, size);
100 EXPECT_EQ(size, result);
101 EXPECT_TRUE(parser.IsParsingComplete());
104 // Test the case where a non-list child element has a size
105 // that is beyond the end of the parent.
106 TEST_F(WebMParserTest, ChildNonListLargerThanParent) {
107 const uint8 kBuffer[] = {
108 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1)
109 0xE7, 0x81, 0x01, // Timecode (size=1, value=1)
111 int size = sizeof(kBuffer);
113 InSequence s;
114 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
116 WebMListParser parser(kWebMIdCluster, &client_);
117 int result = parser.Parse(kBuffer, size);
118 EXPECT_EQ(-1, result);
119 EXPECT_FALSE(parser.IsParsingComplete());
122 // Test the case where a list child element has a size
123 // that is beyond the end of the parent.
124 TEST_F(WebMParserTest, ChildListLargerThanParent) {
125 const uint8 kBuffer[] = {
126 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5)
127 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1)
129 int size = sizeof(kBuffer);
131 InSequence s;
132 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
134 WebMListParser parser(kWebMIdSegment, &client_);
135 int result = parser.Parse(kBuffer, size);
136 EXPECT_EQ(-1, result);
137 EXPECT_FALSE(parser.IsParsingComplete());
140 // Expecting to parse a Cluster, but get a Segment.
141 TEST_F(WebMParserTest, ListIdDoesNotMatch) {
142 const uint8 kBuffer[] = {
143 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0)
145 int size = sizeof(kBuffer);
147 WebMListParser parser(kWebMIdCluster, &client_);
148 int result = parser.Parse(kBuffer, size);
149 EXPECT_EQ(-1, result);
150 EXPECT_FALSE(parser.IsParsingComplete());
153 TEST_F(WebMParserTest, InvalidElementInList) {
154 const uint8 kBuffer[] = {
155 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2)
156 0xAE, 0x80, // TrackEntry (size = 0)
158 int size = sizeof(kBuffer);
160 InSequence s;
161 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
163 WebMListParser parser(kWebMIdSegment, &client_);
164 int result = parser.Parse(kBuffer, size);
165 EXPECT_EQ(-1, result);
166 EXPECT_FALSE(parser.IsParsingComplete());
169 TEST_F(WebMParserTest, VoidAndCRC32InList) {
170 const uint8 kBuffer[] = {
171 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25)
172 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
173 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
174 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10)
175 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
176 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3)
178 int size = sizeof(kBuffer);
180 InSequence s;
181 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_));
182 EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_));
183 EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
184 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
186 WebMListParser parser(kWebMIdSegment, &client_);
187 int result = parser.Parse(kBuffer, size);
188 EXPECT_EQ(size, result);
189 EXPECT_TRUE(parser.IsParsingComplete());
193 TEST_F(WebMParserTest, ParseListElementWithSingleCall) {
194 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
195 CreateClusterExpectations(kBlockCount, true, &client_);
197 WebMListParser parser(kWebMIdCluster, &client_);
198 int result = parser.Parse(cluster->data(), cluster->size());
199 EXPECT_EQ(cluster->size(), result);
200 EXPECT_TRUE(parser.IsParsingComplete());
203 TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) {
204 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
205 CreateClusterExpectations(kBlockCount, true, &client_);
207 const uint8* data = cluster->data();
208 int size = cluster->size();
209 int default_parse_size = 3;
210 WebMListParser parser(kWebMIdCluster, &client_);
211 int parse_size = std::min(default_parse_size, size);
213 while (size > 0) {
214 int result = parser.Parse(data, parse_size);
215 ASSERT_GE(result, 0);
216 ASSERT_LE(result, parse_size);
218 if (result == 0) {
219 // The parser needs more data so increase the parse_size a little.
220 EXPECT_FALSE(parser.IsParsingComplete());
221 parse_size += default_parse_size;
222 parse_size = std::min(parse_size, size);
223 continue;
226 parse_size = default_parse_size;
228 data += result;
229 size -= result;
231 EXPECT_EQ((size == 0), parser.IsParsingComplete());
233 EXPECT_TRUE(parser.IsParsingComplete());
236 TEST_F(WebMParserTest, Reset) {
237 InSequence s;
238 scoped_ptr<Cluster> cluster(CreateCluster(kBlockCount));
240 // First expect all but the last block.
241 CreateClusterExpectations(kBlockCount - 1, false, &client_);
243 // Now expect all blocks.
244 CreateClusterExpectations(kBlockCount, true, &client_);
246 WebMListParser parser(kWebMIdCluster, &client_);
248 // Send slightly less than the full cluster so all but the last block is
249 // parsed.
250 int result = parser.Parse(cluster->data(), cluster->size() - 1);
251 EXPECT_GT(result, 0);
252 EXPECT_LT(result, cluster->size());
253 EXPECT_FALSE(parser.IsParsingComplete());
255 parser.Reset();
257 // Now parse a whole cluster to verify that all the blocks will get parsed.
258 result = parser.Parse(cluster->data(), cluster->size());
259 EXPECT_EQ(result, cluster->size());
260 EXPECT_TRUE(parser.IsParsingComplete());
263 // Test the case where multiple clients are used for different lists.
264 TEST_F(WebMParserTest, MultipleClients) {
265 const uint8 kBuffer[] = {
266 0x18, 0x53, 0x80, 0x67, 0x94, // SEGMENT (size = 20)
267 0x16, 0x54, 0xAE, 0x6B, 0x85, // TRACKS (size = 5)
268 0xAE, 0x83, // TRACKENTRY (size = 3)
269 0xD7, 0x81, 0x01, // TRACKNUMBER (size = 1)
270 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5)
271 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3)
273 int size = sizeof(kBuffer);
275 StrictMock<MockWebMParserClient> c1_;
276 StrictMock<MockWebMParserClient> c2_;
277 StrictMock<MockWebMParserClient> c3_;
279 InSequence s;
280 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&c1_));
281 EXPECT_CALL(c1_, OnListStart(kWebMIdTracks)).WillOnce(Return(&c2_));
282 EXPECT_CALL(c2_, OnListStart(kWebMIdTrackEntry)).WillOnce(Return(&c3_));
283 EXPECT_CALL(c3_, OnUInt(kWebMIdTrackNumber, 1)).WillOnce(Return(true));
284 EXPECT_CALL(c2_, OnListEnd(kWebMIdTrackEntry)).WillOnce(Return(true));
285 EXPECT_CALL(c1_, OnListEnd(kWebMIdTracks)).WillOnce(Return(true));
286 EXPECT_CALL(c1_, OnListStart(kWebMIdCluster)).WillOnce(Return(&c2_));
287 EXPECT_CALL(c1_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true));
288 EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true));
290 WebMListParser parser(kWebMIdSegment, &client_);
291 int result = parser.Parse(kBuffer, size);
292 EXPECT_EQ(size, result);
293 EXPECT_TRUE(parser.IsParsingComplete());
296 // Test the case where multiple clients are used for different lists.
297 TEST_F(WebMParserTest, InvalidClient) {
298 const uint8 kBuffer[] = {
299 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 20)
300 0x16, 0x54, 0xAE, 0x6B, 0x80, // TRACKS (size = 5)
302 int size = sizeof(kBuffer);
304 InSequence s;
305 EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(ReturnNull());
307 WebMListParser parser(kWebMIdSegment, &client_);
308 int result = parser.Parse(kBuffer, size);
309 EXPECT_EQ(-1, result);
310 EXPECT_FALSE(parser.IsParsingComplete());
313 TEST_F(WebMParserTest, ReservedIds) {
314 const uint8 k1ByteReservedId[] = { 0xFF, 0x81 };
315 const uint8 k2ByteReservedId[] = { 0x7F, 0xFF, 0x81 };
316 const uint8 k3ByteReservedId[] = { 0x3F, 0xFF, 0xFF, 0x81 };
317 const uint8 k4ByteReservedId[] = { 0x1F, 0xFF, 0xFF, 0xFF, 0x81 };
318 const uint8* kBuffers[] = {
319 k1ByteReservedId,
320 k2ByteReservedId,
321 k3ByteReservedId,
322 k4ByteReservedId
325 for (size_t i = 0; i < arraysize(kBuffers); i++) {
326 int id;
327 int64 element_size;
328 int buffer_size = 2 + i;
329 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size,
330 &id, &element_size));
331 EXPECT_EQ(id, kWebMReservedId);
332 EXPECT_EQ(element_size, 1);
336 TEST_F(WebMParserTest, ReservedSizes) {
337 const uint8 k1ByteReservedSize[] = { 0xA3, 0xFF };
338 const uint8 k2ByteReservedSize[] = { 0xA3, 0x7F, 0xFF };
339 const uint8 k3ByteReservedSize[] = { 0xA3, 0x3F, 0xFF, 0xFF };
340 const uint8 k4ByteReservedSize[] = { 0xA3, 0x1F, 0xFF, 0xFF, 0xFF };
341 const uint8 k5ByteReservedSize[] = { 0xA3, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF };
342 const uint8 k6ByteReservedSize[] = { 0xA3, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
343 0xFF };
344 const uint8 k7ByteReservedSize[] = { 0xA3, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
345 0xFF };
346 const uint8 k8ByteReservedSize[] = { 0xA3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
347 0xFF, 0xFF };
348 const uint8* kBuffers[] = {
349 k1ByteReservedSize,
350 k2ByteReservedSize,
351 k3ByteReservedSize,
352 k4ByteReservedSize,
353 k5ByteReservedSize,
354 k6ByteReservedSize,
355 k7ByteReservedSize,
356 k8ByteReservedSize
359 for (size_t i = 0; i < arraysize(kBuffers); i++) {
360 int id;
361 int64 element_size;
362 int buffer_size = 2 + i;
363 EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size,
364 &id, &element_size));
365 EXPECT_EQ(id, 0xA3);
366 EXPECT_EQ(element_size, kWebMUnknownSize);
370 TEST_F(WebMParserTest, ZeroPaddedStrings) {
371 const uint8 kBuffer[] = {
372 0x1A, 0x45, 0xDF, 0xA3, 0x91, // EBMLHEADER (size = 17)
373 0x42, 0x82, 0x80, // DocType (size = 0)
374 0x42, 0x82, 0x81, 0x00, // DocType (size = 1) ""
375 0x42, 0x82, 0x81, 'a', // DocType (size = 1) "a"
376 0x42, 0x82, 0x83, 'a', 0x00, 0x00 // DocType (size = 3) "a"
378 int size = sizeof(kBuffer);
380 InSequence s;
381 EXPECT_CALL(client_, OnListStart(kWebMIdEBMLHeader))
382 .WillOnce(Return(&client_));
383 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true));
384 EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true));
385 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true));
386 EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true));
387 EXPECT_CALL(client_, OnListEnd(kWebMIdEBMLHeader)).WillOnce(Return(true));
389 WebMListParser parser(kWebMIdEBMLHeader, &client_);
390 int result = parser.Parse(kBuffer, size);
391 EXPECT_EQ(size, result);
392 EXPECT_TRUE(parser.IsParsingComplete());
395 } // namespace media