xref: /aosp_15_r20/external/libwebm/webm_parser/tests/master_value_parser_test.cc (revision 103e46e4cd4b6efcf6001f23fa8665fb110abf8d)
1 // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS.  All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "src/master_value_parser.h"
9 
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 
13 #include "src/int_parser.h"
14 #include "test_utils/element_parser_test.h"
15 #include "webm/element.h"
16 #include "webm/id.h"
17 #include "webm/status.h"
18 
19 using testing::_;
20 using testing::DoAll;
21 using testing::InSequence;
22 using testing::NotNull;
23 using testing::Return;
24 using testing::SetArgPointee;
25 
26 using webm::Action;
27 using webm::Callback;
28 using webm::Cluster;
29 using webm::ElementMetadata;
30 using webm::ElementParserTest;
31 using webm::Id;
32 using webm::MasterValueParser;
33 using webm::Status;
34 using webm::UnsignedIntParser;
35 
36 namespace {
37 
38 // An instance of MasterValueParser that can actually be used in the tests to
39 // parse Cluster structures.
40 class FakeClusterParser : public MasterValueParser<Cluster> {
41  public:
FakeClusterParser()42   FakeClusterParser()
43       : MasterValueParser(
44             MakeChild<UnsignedIntParser>(Id::kTimecode, &Cluster::timecode),
45             MakeChild<UnsignedIntParser>(Id::kPrevSize, &Cluster::previous_size)
46                 .UseAsStartEvent()) {}
47 
48  protected:
OnParseStarted(Callback * callback,Action * action)49   Status OnParseStarted(Callback* callback, Action* action) override {
50     return callback->OnClusterBegin(metadata(Id::kCluster), value(), action);
51   }
52 
OnParseCompleted(Callback * callback)53   Status OnParseCompleted(Callback* callback) override {
54     return callback->OnClusterEnd(metadata(Id::kCluster), value());
55   }
56 };
57 
58 class MasterValueParserTest
59     : public ElementParserTest<FakeClusterParser, Id::kCluster> {};
60 
TEST_F(MasterValueParserTest,InvalidId)61 TEST_F(MasterValueParserTest, InvalidId) {
62   SetReaderData({
63       0x00,  // Invalid ID.
64   });
65 
66   ParseAndExpectResult(Status::kInvalidElementId);
67 }
68 
TEST_F(MasterValueParserTest,InvalidSize)69 TEST_F(MasterValueParserTest, InvalidSize) {
70   SetReaderData({
71       0xE7,  // ID = 0xE7 (Timecode).
72       0xFF,  // Size = unknown.
73   });
74 
75   ParseAndExpectResult(Status::kInvalidElementSize);
76 }
77 
TEST_F(MasterValueParserTest,DefaultParse)78 TEST_F(MasterValueParserTest, DefaultParse) {
79   {
80     InSequence dummy;
81 
82     EXPECT_CALL(callback_, OnClusterBegin(metadata_, Cluster{}, NotNull()))
83         .Times(1);
84 
85     EXPECT_CALL(callback_, OnClusterEnd(metadata_, Cluster{})).Times(1);
86   }
87 
88   ParseAndVerify();
89 }
90 
TEST_F(MasterValueParserTest,DefaultValues)91 TEST_F(MasterValueParserTest, DefaultValues) {
92   SetReaderData({
93       0xE7,  // ID = 0xE7 (Timecode).
94       0x80,  // Size = 0.
95 
96       0xAB,  // ID = 0xAB (PrevSize).
97       0x80,  // Size = 0.
98   });
99 
100   {
101     InSequence dummy;
102 
103     Cluster cluster{};
104     cluster.timecode.Set(0, true);
105 
106     ElementMetadata child_metadata = {Id::kTimecode, 2, 0, 0};
107     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
108 
109     child_metadata = {Id::kPrevSize, 2, 0, 2};
110     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
111 
112     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
113         .Times(1);
114 
115     cluster.previous_size.Set(0, true);
116     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
117   }
118 
119   ParseAndVerify();
120 }
121 
TEST_F(MasterValueParserTest,CustomValues)122 TEST_F(MasterValueParserTest, CustomValues) {
123   SetReaderData({
124       0xE7,  // ID = 0xE7 (Timecode).
125       0x82,  // Size = 2.
126       0x04, 0x00,  // Body (value = 1024).
127 
128       0xAB,  // ID = 0xAB (PrevSize).
129       0x40, 0x01,  // Size = 1.
130       0x01,  // Body (value = 1).
131   });
132 
133   {
134     InSequence dummy;
135 
136     Cluster cluster{};
137     cluster.timecode.Set(1024, true);
138 
139     ElementMetadata child_metadata = {Id::kTimecode, 2, 2, 0};
140     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
141 
142     child_metadata = {Id::kPrevSize, 3, 1, 4};
143     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
144 
145     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
146         .Times(1);
147 
148     cluster.previous_size.Set(1, true);
149     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
150   }
151 
152   ParseAndVerify();
153 }
154 
TEST_F(MasterValueParserTest,IncrementalParse)155 TEST_F(MasterValueParserTest, IncrementalParse) {
156   SetReaderData({
157       0xE7,  // ID = 0xE7 (Timecode).
158       0x40, 0x02,  // Size = 2.
159       0x04, 0x00,  // Body (value = 1024).
160 
161       0x40, 0x00,  // ID = 0x4000 (Unknown).
162       0x40, 0x02,  // Size = 2.
163       0x00, 0x00,  // Body.
164 
165       0xAB,  // ID = 0xAB (PrevSize).
166       0x40, 0x02,  // Size = 2.
167       0x00, 0x01,  // Body (value = 1).
168   });
169 
170   {
171     InSequence dummy;
172 
173     Cluster cluster{};
174     cluster.timecode.Set(1024, true);
175 
176     ElementMetadata child_metadata = {Id::kTimecode, 3, 2, 0};
177     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
178 
179     child_metadata = {static_cast<Id>(0x4000), 4, 2, 5};
180     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
181     EXPECT_CALL(callback_,
182                 OnUnknownElement(child_metadata, NotNull(), NotNull()))
183         .Times(3);
184 
185     child_metadata = {Id::kPrevSize, 3, 2, 11};
186     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
187 
188     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
189         .Times(1);
190 
191     cluster.previous_size.Set(1, true);
192     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
193   }
194 
195   IncrementalParseAndVerify();
196 }
197 
TEST_F(MasterValueParserTest,StartEventWithoutPreviousSize)198 TEST_F(MasterValueParserTest, StartEventWithoutPreviousSize) {
199   SetReaderData({
200       0xE7,  // ID = 0xE7 (Timecode).
201       0x80,  // Size = 0.
202   });
203 
204   {
205     InSequence dummy;
206 
207     Cluster cluster{};
208 
209     const ElementMetadata child_metadata = {Id::kTimecode, 2, 0, 0};
210     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
211 
212     cluster.timecode.Set(0, true);
213     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
214         .Times(1);
215 
216     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
217   }
218 
219   ParseAndVerify();
220 }
221 
TEST_F(MasterValueParserTest,StartEventWithPreviousSize)222 TEST_F(MasterValueParserTest, StartEventWithPreviousSize) {
223   SetReaderData({
224       0xAB,  // ID = 0xAB (PrevSize).
225       0x80,  // Size = 0.
226 
227       0xE7,  // ID = 0xE7 (Timecode).
228       0x80,  // Size = 0.
229   });
230 
231   {
232     InSequence dummy;
233 
234     Cluster cluster{};
235 
236     ElementMetadata child_metadata = {Id::kPrevSize, 2, 0, 0};
237     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
238 
239     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
240         .Times(1);
241 
242     child_metadata = {Id::kTimecode, 2, 0, 2};
243     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
244 
245     cluster.previous_size.Set(0, true);
246     cluster.timecode.Set(0, true);
247     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
248   }
249 
250   ParseAndVerify();
251 }
252 
TEST_F(MasterValueParserTest,PartialStartThenRead)253 TEST_F(MasterValueParserTest, PartialStartThenRead) {
254   SetReaderData({
255       0xAB,  // ID = 0xAB (PrevSize).
256       0x81,  // Size = 1.
257       0x01,  // Body (value = 1).
258 
259       0xE7,  // ID = 0xE7 (Timecode).
260       0x81,  // Size = 1.
261       0x01,  // Body (value = 1).
262   });
263 
264   {
265     InSequence dummy;
266 
267     Cluster cluster{};
268 
269     ElementMetadata child_metadata = {Id::kPrevSize, 2, 1, 0};
270     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
271 
272     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
273         .WillOnce(Return(Status(Status::kOkPartial)))
274         .WillOnce(DoAll(SetArgPointee<2>(Action::kRead),
275                         Return(Status(Status::kOkCompleted))));
276 
277     child_metadata = {Id::kTimecode, 2, 1, 3};
278     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
279 
280     cluster.previous_size.Set(1, true);
281     cluster.timecode.Set(1, true);
282     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
283   }
284 
285   IncrementalParseAndVerify();
286 }
287 
TEST_F(MasterValueParserTest,EmptySkip)288 TEST_F(MasterValueParserTest, EmptySkip) {
289   const Cluster cluster{};
290 
291   EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
292       .WillOnce(DoAll(SetArgPointee<2>(Action::kSkip),
293                       Return(Status(Status::kOkCompleted))));
294 
295   EXPECT_CALL(callback_, OnElementBegin(_, _)).Times(0);
296   EXPECT_CALL(callback_, OnClusterEnd(_, _)).Times(0);
297 
298   ParseAndVerify();
299 
300   EXPECT_EQ(cluster, parser_.value());
301 }
302 
TEST_F(MasterValueParserTest,Skip)303 TEST_F(MasterValueParserTest, Skip) {
304   SetReaderData({
305       0xAB,  // ID = 0xAB (PrevSize).
306       0x81,  // Size = 1.
307       0x01,  // Body (value = 1).
308 
309       0xE7,  // ID = 0xE7 (Timecode).
310       0x81,  // Size = 1.
311       0x01,  // Body (value = 1).
312   });
313 
314   const Cluster cluster{};
315 
316   {
317     InSequence dummy;
318 
319     const ElementMetadata child_metadata = {Id::kPrevSize, 2, 1, 0};
320     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
321 
322     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
323         .WillOnce(DoAll(SetArgPointee<2>(Action::kSkip),
324                         Return(Status(Status::kOkCompleted))));
325 
326     EXPECT_CALL(callback_, OnClusterEnd(_, _)).Times(0);
327   }
328 
329   ParseAndVerify();
330 
331   EXPECT_EQ(cluster, parser_.value());
332 }
333 
TEST_F(MasterValueParserTest,PartialStartThenSkip)334 TEST_F(MasterValueParserTest, PartialStartThenSkip) {
335   SetReaderData({
336       0xAB,  // ID = 0xAB (PrevSize).
337       0x81,  // Size = 1.
338       0x01,  // Body (value = 1).
339 
340       0xE7,  // ID = 0xE7 (Timecode).
341       0x81,  // Size = 1.
342       0x01,  // Body (value = 1).
343   });
344 
345   const Cluster cluster{};
346 
347   {
348     InSequence dummy;
349 
350     const ElementMetadata child_metadata = {Id::kPrevSize, 2, 1, 0};
351     EXPECT_CALL(callback_, OnElementBegin(child_metadata, NotNull())).Times(1);
352 
353     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
354         .WillOnce(Return(Status(Status::kOkPartial)))
355         .WillOnce(DoAll(SetArgPointee<2>(Action::kSkip),
356                         Return(Status(Status::kOkCompleted))));
357 
358     EXPECT_CALL(callback_, OnClusterEnd(_, _)).Times(0);
359   }
360 
361   IncrementalParseAndVerify();
362 
363   EXPECT_EQ(cluster, parser_.value());
364 }
365 
366 }  // namespace
367