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/block_group_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/id.h"
15 #include "webm/status.h"
16
17 using testing::_;
18 using testing::InSequence;
19 using testing::NotNull;
20 using testing::Return;
21
22 using webm::Block;
23 using webm::BlockAdditions;
24 using webm::BlockGroup;
25 using webm::BlockGroupParser;
26 using webm::BlockMore;
27 using webm::ElementParserTest;
28 using webm::Id;
29 using webm::Slices;
30 using webm::Status;
31 using webm::TimeSlice;
32 using webm::VirtualBlock;
33
34 namespace {
35
36 class BlockGroupParserTest
37 : public ElementParserTest<BlockGroupParser, Id::kBlockGroup> {};
38
TEST_F(BlockGroupParserTest,InvalidBlock)39 TEST_F(BlockGroupParserTest, InvalidBlock) {
40 SetReaderData({
41 0xA1, // ID = 0xA1 (Block).
42 0x80, // Size = 0.
43 });
44
45 EXPECT_CALL(callback_, OnBlockGroupBegin(_, _)).Times(1);
46 EXPECT_CALL(callback_, OnBlockGroupEnd(_, _)).Times(0);
47
48 ParseAndExpectResult(Status::kInvalidElementSize);
49 }
50
TEST_F(BlockGroupParserTest,InvalidVirtualBlock)51 TEST_F(BlockGroupParserTest, InvalidVirtualBlock) {
52 SetReaderData({
53 0xA2, // ID = 0xA2 (BlockVirtual).
54 0x80, // Size = 0.
55 });
56
57 EXPECT_CALL(callback_, OnBlockGroupBegin(_, _)).Times(1);
58 EXPECT_CALL(callback_, OnBlockGroupEnd(_, _)).Times(0);
59
60 ParseAndExpectResult(Status::kInvalidElementSize);
61 }
62
TEST_F(BlockGroupParserTest,DefaultParse)63 TEST_F(BlockGroupParserTest, DefaultParse) {
64 {
65 InSequence dummy;
66
67 EXPECT_CALL(callback_, OnBlockGroupBegin(metadata_, NotNull())).Times(1);
68 EXPECT_CALL(callback_, OnBlockGroupEnd(metadata_, BlockGroup{})).Times(1);
69 }
70
71 ParseAndVerify();
72 }
73
TEST_F(BlockGroupParserTest,DefaultActionIsRead)74 TEST_F(BlockGroupParserTest, DefaultActionIsRead) {
75 {
76 InSequence dummy;
77
78 // This intentionally does not set the action and relies on the parser using
79 // a default action value of kRead.
80 EXPECT_CALL(callback_, OnBlockGroupBegin(metadata_, NotNull()))
81 .WillOnce(Return(Status(Status::kOkCompleted)));
82 EXPECT_CALL(callback_, OnBlockGroupEnd(metadata_, BlockGroup{})).Times(1);
83 }
84
85 ParseAndVerify();
86 }
87
TEST_F(BlockGroupParserTest,DefaultValues)88 TEST_F(BlockGroupParserTest, DefaultValues) {
89 SetReaderData({
90 0xA1, // ID = 0xA1 (Block).
91 0x85, // Size = 5.
92 0x81, // Track number = 1.
93 0x00, 0x00, // Timecode = 0.
94 0x00, // Flags = 0.
95 0x00, // Frame 0.
96
97 0xA2, // ID = 0xA2 (BlockVirtual).
98 0x84, // Size = 4.
99 0x81, // Track number = 1.
100 0x00, 0x00, // Timecode = 0.
101 0x00, // Flags = 0.
102
103 0x75, 0xA1, // ID = 0x75A1 (BlockAdditions).
104 0x80, // Size = 0.
105
106 0x9B, // ID = 0x9B (BlockDuration).
107 0x40, 0x00, // Size = 0.
108
109 0xFB, // ID = 0xFB (ReferenceBlock).
110 0x40, 0x00, // Size = 0.
111
112 0x75, 0xA2, // ID = 0x75A2 (DiscardPadding).
113 0x80, // Size = 0.
114
115 0x8E, // ID = 0x8E (Slices).
116 0x40, 0x00, // Size = 0.
117 });
118
119 {
120 InSequence dummy;
121
122 EXPECT_CALL(callback_, OnBlockGroupBegin(metadata_, NotNull())).Times(1);
123
124 BlockGroup block_group;
125 // Blocks and VirtualBlocks don't have any kind of default defined, so they
126 // can't have an element state of kPresentAsDefault.
127 Block block{};
128 block.track_number = 1;
129 block.num_frames = 1;
130 block.is_visible = true;
131 block_group.block.Set(block, true);
132
133 EXPECT_CALL(callback_, OnBlockBegin(_, block, NotNull())).Times(1);
134 EXPECT_CALL(callback_, OnFrame(_, NotNull(), NotNull())).Times(1);
135 EXPECT_CALL(callback_, OnBlockEnd(_, block_group.block.value())).Times(1);
136
137 VirtualBlock virtual_block{};
138 virtual_block.track_number = 1;
139 block_group.virtual_block.Set(virtual_block, true);
140
141 block_group.additions.Set({}, true);
142 block_group.duration.Set(0, true);
143 block_group.references.emplace_back(0, true);
144 block_group.discard_padding.Set(0, true);
145 block_group.slices.Set({}, true);
146
147 EXPECT_CALL(callback_, OnBlockGroupEnd(metadata_, block_group)).Times(1);
148 }
149
150 ParseAndVerify();
151 }
152
TEST_F(BlockGroupParserTest,CustomValues)153 TEST_F(BlockGroupParserTest, CustomValues) {
154 SetReaderData({
155 0xA1, // ID = 0xA1 (Block).
156 0x85, // Size = 5.
157 0x82, // Track number = 2.
158 0x00, 0x00, // Timecode = 0.
159 0x00, // Flags = 0.
160 0x00, // Frame 0.
161
162 0xA2, // ID = 0xA2 (BlockVirtual).
163 0x84, // Size = 4.
164 0x83, // Track number = 3.
165 0x00, 0x00, // Timecode = 0.
166 0x00, // Flags = 0.
167
168 0x75, 0xA1, // ID = 0x75A1 (BlockAdditions).
169 0x83, // Size = 3.
170
171 0xA6, // ID = 0xA6 (BlockMore).
172 0x40, 0x00, // Size = 0.
173
174 0x9B, // ID = 0x9B (BlockDuration).
175 0x40, 0x01, // Size = 1.
176 0x01, // Body (value = 1).
177
178 0xFB, // ID = 0xFB (ReferenceBlock).
179 0x40, 0x01, // Size = 1.
180 0x01, // Body (value = 1).
181
182 0xFB, // ID = 0xFB (ReferenceBlock).
183 0x40, 0x01, // Size = 1.
184 0x02, // Body (value = 2).
185
186 0x75, 0xA2, // ID = 0x75A2 (DiscardPadding).
187 0x81, // Size = 1.
188 0xFF, // Body (value = -1).
189
190 0x8E, // ID = 0x8E (Slices).
191 0x40, 0x03, // Size = 3.
192
193 0xE8, // ID = 0xE8 (TimeSlice).
194 0x40, 0x00, // Size = 0.
195 });
196
197 {
198 InSequence dummy;
199
200 EXPECT_CALL(callback_, OnBlockGroupBegin(metadata_, NotNull())).Times(1);
201
202 BlockGroup block_group;
203 // Blocks and VirtualBlocks don't have any kind of default defined, so they
204 // can't have an element state of kPresentAsDefault.
205 Block block{};
206 block.track_number = 2;
207 block.num_frames = 1;
208 block.is_visible = true;
209 block_group.block.Set(block, true);
210
211 VirtualBlock virtual_block{};
212 virtual_block.track_number = 3;
213 block_group.virtual_block.Set(virtual_block, true);
214
215 BlockAdditions block_additions;
216 block_additions.block_mores.emplace_back(BlockMore{}, true);
217 block_group.additions.Set(block_additions, true);
218
219 block_group.duration.Set(1, true);
220 block_group.references.emplace_back(1, true);
221 block_group.references.emplace_back(2, true);
222 block_group.discard_padding.Set(-1, true);
223
224 Slices slices;
225 slices.slices.emplace_back(TimeSlice{}, true);
226 block_group.slices.Set(slices, true);
227
228 EXPECT_CALL(callback_, OnBlockGroupEnd(metadata_, block_group)).Times(1);
229 }
230
231 ParseAndVerify();
232 }
233
234 } // namespace
235