OLD | NEW |
---|---|
(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 | |
OLD | NEW |