• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/cluster_parser.h"
9 
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 
13 #include "test_utils/element_parser_test.h"
14 #include "webm/element.h"
15 #include "webm/id.h"
16 
17 using testing::_;
18 using testing::DoAll;
19 using testing::InSequence;
20 using testing::NotNull;
21 using testing::Return;
22 using testing::SetArgPointee;
23 
24 using webm::Action;
25 using webm::Ancestory;
26 using webm::BlockGroup;
27 using webm::Cluster;
28 using webm::ClusterParser;
29 using webm::ElementMetadata;
30 using webm::ElementParserTest;
31 using webm::Id;
32 using webm::SimpleBlock;
33 using webm::Status;
34 
35 namespace {
36 
37 class ClusterParserTest
38     : public ElementParserTest<ClusterParser, Id::kCluster> {};
39 
TEST_F(ClusterParserTest,DefaultParse)40 TEST_F(ClusterParserTest, DefaultParse) {
41   {
42     InSequence dummy;
43 
44     EXPECT_CALL(callback_, OnClusterBegin(metadata_, Cluster{}, NotNull()))
45         .Times(1);
46 
47     EXPECT_CALL(callback_, OnClusterEnd(metadata_, Cluster{})).Times(1);
48   }
49 
50   ParseAndVerify();
51 }
52 
TEST_F(ClusterParserTest,DefaultActionIsRead)53 TEST_F(ClusterParserTest, DefaultActionIsRead) {
54   {
55     InSequence dummy;
56 
57     // This intentionally does not set the action and relies on the parser using
58     // a default action value of kRead.
59     EXPECT_CALL(callback_, OnClusterBegin(metadata_, Cluster{}, NotNull()))
60         .WillOnce(Return(Status(Status::kOkCompleted)));
61     EXPECT_CALL(callback_, OnClusterEnd(metadata_, Cluster{})).Times(1);
62   }
63 
64   ParseAndVerify();
65 }
66 
TEST_F(ClusterParserTest,DefaultValues)67 TEST_F(ClusterParserTest, DefaultValues) {
68   SetReaderData({
69       0xE7,  // ID = 0xE7 (Timecode).
70       0x40, 0x00,  // Size = 0.
71 
72       0xAB,  // ID = 0xAB (PrevSize).
73       0x40, 0x00,  // Size = 0.
74 
75       0xA3,  // ID = 0xA3 (SimpleBlock).
76       0x85,  // Size = 5.
77       0x81,  // Track number = 1.
78       0x00, 0x00,  // Timecode = 0.
79       0x00,  // Flags = 0.
80       0x00,  // Frame 0.
81 
82       0xA0,  // ID = 0xA0 (BlockGroup).
83       0x40, 0x00,  // Size = 0.
84   });
85 
86   {
87     InSequence dummy;
88 
89     Cluster cluster{};
90     cluster.timecode.Set(0, true);
91     cluster.previous_size.Set(0, true);
92 
93     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
94         .Times(1);
95 
96     SimpleBlock simple_block{};
97     simple_block.track_number = 1;
98     simple_block.num_frames = 1;
99     simple_block.is_visible = true;
100     cluster.simple_blocks.emplace_back(simple_block, true);
101 
102     BlockGroup block_group{};
103     cluster.block_groups.emplace_back(block_group, true);
104 
105     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
106   }
107 
108   ParseAndVerify();
109 }
110 
TEST_F(ClusterParserTest,CustomValues)111 TEST_F(ClusterParserTest, CustomValues) {
112   SetReaderData({
113       0xE7,  // ID = 0xE7 (Timecode).
114       0x40, 0x01,  // Size = 1.
115       0x01,  // Body (value = 1).
116 
117       0xAB,  // ID = 0xAB (PrevSize).
118       0x40, 0x01,  // Size = 1.
119       0x02,  // Body (value = 2).
120 
121       0xA3,  // ID = 0xA3 (SimpleBlock).
122       0x85,  // Size = 5.
123       0x81,  // Track number = 1.
124       0x00, 0x00,  // Timecode = 0.
125       0x00,  // Flags = 0.
126       0x00,  // Frame 0.
127 
128       0xA3,  // ID = 0xA3 (SimpleBlock).
129       0x85,  // Size = 5.
130       0x82,  // Track number = 2.
131       0x00, 0x00,  // Timecode = 0.
132       0x00,  // Flags = 0.
133       0x00,  // Frame 0.
134 
135       0xA0,  // ID = 0xA0 (BlockGroup).
136       0x40, 0x04,  // Size = 4.
137 
138       0x9B,  //   ID = 0x9B (BlockDuration).
139       0x40, 0x01,  //   Size = 1.
140       0x01,  //   Body (value = 1).
141 
142       0xA0,  // ID = 0xA0 (BlockGroup).
143       0x40, 0x04,  // Size = 4.
144 
145       0x9B,  //   ID = 0x9B (BlockDuration).
146       0x40, 0x01,  //   Size = 1.
147       0x02,  //   Body (value = 2).
148   });
149 
150   {
151     InSequence dummy;
152 
153     Cluster cluster{};
154     cluster.timecode.Set(1, true);
155     cluster.previous_size.Set(2, true);
156 
157     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
158         .Times(1);
159 
160     SimpleBlock simple_block{};
161     simple_block.num_frames = 1;
162     simple_block.is_visible = true;
163 
164     simple_block.track_number = 1;
165     cluster.simple_blocks.emplace_back(simple_block, true);
166     simple_block.track_number = 2;
167     cluster.simple_blocks.emplace_back(simple_block, true);
168 
169     BlockGroup block_group{};
170     block_group.duration.Set(1, true);
171     cluster.block_groups.emplace_back(block_group, true);
172     block_group.duration.Set(2, true);
173     cluster.block_groups.emplace_back(block_group, true);
174 
175     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
176   }
177 
178   ParseAndVerify();
179 }
180 
TEST_F(ClusterParserTest,SkipOnClusterBegin)181 TEST_F(ClusterParserTest, SkipOnClusterBegin) {
182   {
183     InSequence dummy;
184 
185     EXPECT_CALL(callback_, OnClusterBegin(_, _, _)).Times(0);
186 
187     EXPECT_CALL(callback_, OnBlockGroupBegin(_, NotNull())).Times(1);
188 
189     EXPECT_CALL(callback_, OnClusterEnd(_, _)).Times(1);
190   }
191 
192   ElementMetadata child_metadata = {Id::kBlockGroup, 0, 0, 0};
193 
194   Ancestory ancestory;
195   ASSERT_TRUE(Ancestory::ById(child_metadata.id, &ancestory));
196   // Skip the Segment and Cluster ancestors.
197   ancestory = ancestory.next().next();
198 
199   parser_.InitAfterSeek(ancestory, child_metadata);
200 
201   std::uint64_t num_bytes_read = 0;
202   const Status status = parser_.Feed(&callback_, &reader_, &num_bytes_read);
203   EXPECT_EQ(Status::kOkCompleted, status.code);
204   EXPECT_EQ(reader_.size(), num_bytes_read);
205 }
206 
TEST_F(ClusterParserTest,SkipSimpleBlock)207 TEST_F(ClusterParserTest, SkipSimpleBlock) {
208   SetReaderData({
209       0xA3,  // ID = 0xA3 (SimpleBlock).
210       0x85,  // Size = 5.
211       0x81,  // Track number = 1.
212       0x00, 0x00,  // Timecode = 0.
213       0x00,  // Flags = 0.
214       0x00,  // Frame 0.
215   });
216 
217   {
218     InSequence dummy;
219 
220     Cluster cluster{};
221     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
222         .Times(1);
223 
224     SimpleBlock simple_block{};
225     simple_block.num_frames = 1;
226     simple_block.is_visible = true;
227     simple_block.track_number = 1;
228 
229     EXPECT_CALL(callback_, OnSimpleBlockBegin(_, simple_block, NotNull()))
230         .WillOnce(DoAll(SetArgPointee<2>(Action::kSkip),
231                         Return(Status(Status::kOkCompleted))));
232 
233     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
234   }
235 
236   ParseAndVerify();
237 }
238 
TEST_F(ClusterParserTest,SkipBlockGroup)239 TEST_F(ClusterParserTest, SkipBlockGroup) {
240   SetReaderData({
241       0xA0,  // ID = 0xA0 (BlockGroup).
242       0x40, 0x04,  // Size = 4.
243 
244       0x9B,  //   ID = 0x9B (BlockDuration).
245       0x40, 0x01,  //   Size = 1.
246       0x01,  //   Body (value = 1).
247   });
248 
249   {
250     InSequence dummy;
251 
252     Cluster cluster{};
253     EXPECT_CALL(callback_, OnClusterBegin(metadata_, cluster, NotNull()))
254         .Times(1);
255 
256     EXPECT_CALL(callback_, OnBlockGroupBegin(_, NotNull()))
257         .WillOnce(DoAll(SetArgPointee<1>(Action::kSkip),
258                         Return(Status(Status::kOkCompleted))));
259 
260     EXPECT_CALL(callback_, OnClusterEnd(metadata_, cluster)).Times(1);
261   }
262 
263   ParseAndVerify();
264 }
265 
266 }  // namespace
267