1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/gav1/decoder.h"
16
17 #include <cstddef>
18 #include <cstdint>
19 #include <memory>
20 #include <new>
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "src/decoder_test_data.h"
25
26 namespace libgav1 {
27 namespace {
28
29 constexpr uint8_t kFrame1[] = {OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER,
30 OBU_FRAME_1};
31 constexpr uint8_t kFrame1MeanQp = 81;
32
33 constexpr uint8_t kFrame2[] = {OBU_TEMPORAL_DELIMITER, OBU_FRAME_2};
34 constexpr uint8_t kFrame2MeanQp = 81;
35
36 constexpr uint8_t kFrame1WithHdrCllAndHdrMdcv[] = {
37 OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER, OBU_METADATA_HDR_CLL,
38 OBU_METADATA_HDR_MDCV, OBU_FRAME_1};
39
40 constexpr uint8_t kFrame2WithItutT35[] = {OBU_TEMPORAL_DELIMITER,
41 OBU_METADATA_ITUT_T35, OBU_FRAME_2};
42
43 class DecoderTest : public testing::Test {
44 public:
45 void SetUp() override;
IncrementFramesInUse()46 void IncrementFramesInUse() { ++frames_in_use_; }
DecrementFramesInUse()47 void DecrementFramesInUse() { --frames_in_use_; }
SetBufferPrivateData(void * buffer_private_data)48 void SetBufferPrivateData(void* buffer_private_data) {
49 buffer_private_data_ = buffer_private_data;
50 }
SetReleasedInputBuffer(void * released_input_buffer)51 void SetReleasedInputBuffer(void* released_input_buffer) {
52 released_input_buffer_ = released_input_buffer;
53 }
54
55 protected:
56 std::unique_ptr<Decoder> decoder_;
57 int frames_in_use_ = 0;
58 void* buffer_private_data_ = nullptr;
59 void* released_input_buffer_ = nullptr;
60 };
61
62 struct FrameBufferPrivate {
63 uint8_t* data[3];
64 };
65
66 extern "C" {
67
GetFrameBuffer(void * callback_private_data,int bitdepth,Libgav1ImageFormat image_format,int width,int height,int left_border,int right_border,int top_border,int bottom_border,int stride_alignment,Libgav1FrameBuffer * frame_buffer)68 static Libgav1StatusCode GetFrameBuffer(
69 void* callback_private_data, int bitdepth, Libgav1ImageFormat image_format,
70 int width, int height, int left_border, int right_border, int top_border,
71 int bottom_border, int stride_alignment, Libgav1FrameBuffer* frame_buffer) {
72 Libgav1FrameBufferInfo info;
73 Libgav1StatusCode status = Libgav1ComputeFrameBufferInfo(
74 bitdepth, image_format, width, height, left_border, right_border,
75 top_border, bottom_border, stride_alignment, &info);
76 if (status != kLibgav1StatusOk) return status;
77
78 std::unique_ptr<FrameBufferPrivate> buffer_private(new (std::nothrow)
79 FrameBufferPrivate);
80 if (buffer_private == nullptr) return kLibgav1StatusOutOfMemory;
81
82 for (int i = 0; i < 3; ++i) {
83 const size_t size = (i == 0) ? info.y_buffer_size : info.uv_buffer_size;
84 buffer_private->data[i] = new (std::nothrow) uint8_t[size];
85 if (buffer_private->data[i] == nullptr) {
86 return kLibgav1StatusOutOfMemory;
87 }
88 }
89
90 uint8_t* const y_buffer = buffer_private->data[0];
91 uint8_t* const u_buffer =
92 (info.uv_buffer_size != 0) ? buffer_private->data[1] : nullptr;
93 uint8_t* const v_buffer =
94 (info.uv_buffer_size != 0) ? buffer_private->data[2] : nullptr;
95
96 status = Libgav1SetFrameBuffer(&info, y_buffer, u_buffer, v_buffer,
97 buffer_private.release(), frame_buffer);
98 if (status != kLibgav1StatusOk) return status;
99
100 auto* const decoder_test = static_cast<DecoderTest*>(callback_private_data);
101 decoder_test->IncrementFramesInUse();
102 decoder_test->SetBufferPrivateData(frame_buffer->private_data);
103 return kLibgav1StatusOk;
104 }
105
ReleaseFrameBuffer(void * callback_private_data,void * buffer_private_data)106 static void ReleaseFrameBuffer(void* callback_private_data,
107 void* buffer_private_data) {
108 auto* buffer_private = static_cast<FrameBufferPrivate*>(buffer_private_data);
109 for (auto& data : buffer_private->data) {
110 delete[] data;
111 }
112 delete buffer_private;
113 auto* const decoder_test = static_cast<DecoderTest*>(callback_private_data);
114 decoder_test->DecrementFramesInUse();
115 }
116
ReleaseInputBuffer(void * private_data,void * input_buffer)117 static void ReleaseInputBuffer(void* private_data, void* input_buffer) {
118 auto* const decoder_test = static_cast<DecoderTest*>(private_data);
119 decoder_test->SetReleasedInputBuffer(input_buffer);
120 }
121
122 } // extern "C"
123
SetUp()124 void DecoderTest::SetUp() {
125 decoder_.reset(new (std::nothrow) Decoder());
126 ASSERT_NE(decoder_, nullptr);
127 DecoderSettings settings = {};
128 settings.frame_parallel = false;
129 settings.get_frame_buffer = GetFrameBuffer;
130 settings.release_frame_buffer = ReleaseFrameBuffer;
131 settings.callback_private_data = this;
132 settings.release_input_buffer = ReleaseInputBuffer;
133 ASSERT_EQ(decoder_->Init(&settings), kStatusOk);
134 }
135
TEST_F(DecoderTest,APIFlowForNonFrameParallelMode)136 TEST_F(DecoderTest, APIFlowForNonFrameParallelMode) {
137 StatusCode status;
138 const DecoderBuffer* buffer;
139
140 // Enqueue frame1 for decoding.
141 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
142 const_cast<uint8_t*>(kFrame1));
143 ASSERT_EQ(status, kStatusOk);
144
145 // In non-frame-parallel mode, decoding happens only in the DequeueFrame call.
146 // So there should be no frames in use yet.
147 EXPECT_EQ(frames_in_use_, 0);
148
149 // Dequeue the output of frame1.
150 status = decoder_->DequeueFrame(&buffer);
151 ASSERT_EQ(status, kStatusOk);
152 ASSERT_NE(buffer, nullptr);
153 EXPECT_EQ(released_input_buffer_, &kFrame1);
154
155 // libgav1 has decoded frame1 and is holding a reference to it.
156 EXPECT_EQ(frames_in_use_, 1);
157 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
158
159 // Enqueue frame2 for decoding.
160 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
161 const_cast<uint8_t*>(kFrame2));
162 ASSERT_EQ(status, kStatusOk);
163
164 EXPECT_EQ(frames_in_use_, 1);
165
166 // Dequeue the output of frame2.
167 status = decoder_->DequeueFrame(&buffer);
168 ASSERT_EQ(status, kStatusOk);
169 ASSERT_NE(buffer, nullptr);
170 EXPECT_EQ(released_input_buffer_, &kFrame2);
171
172 EXPECT_EQ(frames_in_use_, 2);
173 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
174
175 // Signal end of stream (method 1). This should ensure that all the references
176 // are released.
177 status = decoder_->SignalEOS();
178 EXPECT_EQ(status, kStatusOk);
179
180 // libgav1 should have released all the reference frames now.
181 EXPECT_EQ(frames_in_use_, 0);
182
183 // Now, the decoder is ready to accept a new coded video sequence.
184
185 // Enqueue frame1 for decoding.
186 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
187 const_cast<uint8_t*>(kFrame1));
188 ASSERT_EQ(status, kStatusOk);
189
190 EXPECT_EQ(frames_in_use_, 0);
191
192 // Dequeue the output of frame1.
193 status = decoder_->DequeueFrame(&buffer);
194 ASSERT_EQ(status, kStatusOk);
195 ASSERT_NE(buffer, nullptr);
196 EXPECT_EQ(released_input_buffer_, &kFrame1);
197
198 EXPECT_EQ(frames_in_use_, 1);
199 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
200
201 // Enqueue frame2 for decoding.
202 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
203 const_cast<uint8_t*>(kFrame2));
204 ASSERT_EQ(status, kStatusOk);
205
206 EXPECT_EQ(frames_in_use_, 1);
207
208 // Dequeue the output of frame2.
209 status = decoder_->DequeueFrame(&buffer);
210 ASSERT_EQ(status, kStatusOk);
211 ASSERT_NE(buffer, nullptr);
212 EXPECT_EQ(released_input_buffer_, &kFrame2);
213
214 EXPECT_EQ(frames_in_use_, 2);
215 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
216
217 // Signal end of stream (method 2). This should ensure that all the references
218 // are released.
219 decoder_ = nullptr;
220
221 // libgav1 should have released all the frames now.
222 EXPECT_EQ(frames_in_use_, 0);
223 }
224
TEST_F(DecoderTest,NonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing)225 TEST_F(DecoderTest, NonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing) {
226 StatusCode status;
227 const DecoderBuffer* buffer;
228
229 // Enqueue frame1 for decoding.
230 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
231 const_cast<uint8_t*>(kFrame1));
232 ASSERT_EQ(status, kStatusOk);
233
234 // Until the output of frame1 is dequeued, no other frames can be enqueued.
235 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
236 const_cast<uint8_t*>(kFrame2));
237 ASSERT_EQ(status, kStatusTryAgain);
238
239 EXPECT_EQ(frames_in_use_, 0);
240
241 // Dequeue the output of frame1.
242 status = decoder_->DequeueFrame(&buffer);
243 ASSERT_EQ(status, kStatusOk);
244 ASSERT_NE(buffer, nullptr);
245 EXPECT_EQ(released_input_buffer_, &kFrame1);
246
247 EXPECT_EQ(frames_in_use_, 1);
248
249 // Delete the decoder instance.
250 decoder_ = nullptr;
251
252 EXPECT_EQ(frames_in_use_, 0);
253 }
254
TEST_F(DecoderTest,NonFrameParallelModeEOSBeforeDequeuingLastFrame)255 TEST_F(DecoderTest, NonFrameParallelModeEOSBeforeDequeuingLastFrame) {
256 StatusCode status;
257 const DecoderBuffer* buffer;
258
259 // Enqueue frame1 for decoding.
260 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
261 const_cast<uint8_t*>(kFrame1));
262 ASSERT_EQ(status, kStatusOk);
263
264 EXPECT_EQ(frames_in_use_, 0);
265
266 // Dequeue the output of frame1.
267 status = decoder_->DequeueFrame(&buffer);
268 ASSERT_EQ(status, kStatusOk);
269 ASSERT_NE(buffer, nullptr);
270 EXPECT_EQ(released_input_buffer_, &kFrame1);
271
272 // Enqueue frame2 for decoding.
273 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
274 const_cast<uint8_t*>(kFrame2));
275 ASSERT_EQ(status, kStatusOk);
276
277 EXPECT_EQ(frames_in_use_, 1);
278
279 // Signal end of stream before dequeuing the output of frame2.
280 status = decoder_->SignalEOS();
281 ASSERT_EQ(status, kStatusOk);
282
283 // In this case, the output of the last frame that was enqueued is lost (which
284 // is intentional since end of stream was signaled without dequeueing it).
285 EXPECT_EQ(frames_in_use_, 0);
286 }
287
TEST_F(DecoderTest,NonFrameParallelModeInvalidFrameAfterEOS)288 TEST_F(DecoderTest, NonFrameParallelModeInvalidFrameAfterEOS) {
289 StatusCode status;
290 const DecoderBuffer* buffer = nullptr;
291
292 // Enqueue frame1 for decoding.
293 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
294 const_cast<uint8_t*>(kFrame1));
295 ASSERT_EQ(status, kStatusOk);
296
297 EXPECT_EQ(frames_in_use_, 0);
298
299 // Dequeue the output of frame1.
300 status = decoder_->DequeueFrame(&buffer);
301 ASSERT_EQ(status, kStatusOk);
302 ASSERT_NE(buffer, nullptr);
303 EXPECT_EQ(released_input_buffer_, &kFrame1);
304
305 EXPECT_EQ(frames_in_use_, 1);
306
307 // Signal end of stream.
308 status = decoder_->SignalEOS();
309 EXPECT_EQ(status, kStatusOk);
310
311 // libgav1 should have released all the reference frames now.
312 EXPECT_EQ(frames_in_use_, 0);
313
314 // Now, the decoder is ready to accept a new coded video sequence. But, we
315 // try to enqueue a frame that does not have a sequence header (which is not
316 // allowed).
317
318 // Enqueue frame2 for decoding.
319 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
320 const_cast<uint8_t*>(kFrame2));
321 ASSERT_EQ(status, kStatusOk);
322
323 EXPECT_EQ(frames_in_use_, 0);
324
325 // Dequeue the output of frame2 (this will fail since no sequence header has
326 // been seen since the last EOS signal).
327 status = decoder_->DequeueFrame(&buffer);
328 ASSERT_EQ(status, kStatusBitstreamError);
329 EXPECT_EQ(released_input_buffer_, &kFrame2);
330
331 EXPECT_EQ(frames_in_use_, 0);
332 }
333
TEST_F(DecoderTest,MetadataObu)334 TEST_F(DecoderTest, MetadataObu) {
335 StatusCode status;
336 const DecoderBuffer* buffer;
337
338 // Enqueue frame1 for decoding.
339 status = decoder_->EnqueueFrame(
340 kFrame1WithHdrCllAndHdrMdcv, sizeof(kFrame1WithHdrCllAndHdrMdcv), 0,
341 const_cast<uint8_t*>(kFrame1WithHdrCllAndHdrMdcv));
342 ASSERT_EQ(status, kStatusOk);
343
344 // Dequeue the output of frame1.
345 status = decoder_->DequeueFrame(&buffer);
346 ASSERT_EQ(status, kStatusOk);
347 ASSERT_NE(buffer, nullptr);
348 EXPECT_EQ(buffer->has_hdr_cll, 1);
349 EXPECT_EQ(buffer->has_hdr_mdcv, 1);
350 EXPECT_EQ(buffer->has_itut_t35, 0);
351 EXPECT_EQ(released_input_buffer_, &kFrame1WithHdrCllAndHdrMdcv);
352
353 // libgav1 has decoded frame1 and is holding a reference to it.
354 EXPECT_EQ(frames_in_use_, 1);
355 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
356
357 // Enqueue frame2 for decoding.
358 status =
359 decoder_->EnqueueFrame(kFrame2WithItutT35, sizeof(kFrame2WithItutT35), 0,
360 const_cast<uint8_t*>(kFrame2WithItutT35));
361 ASSERT_EQ(status, kStatusOk);
362
363 EXPECT_EQ(frames_in_use_, 1);
364
365 // Dequeue the output of frame2.
366 status = decoder_->DequeueFrame(&buffer);
367 ASSERT_EQ(status, kStatusOk);
368 ASSERT_NE(buffer, nullptr);
369 EXPECT_EQ(buffer->has_hdr_cll, 0);
370 EXPECT_EQ(buffer->has_hdr_mdcv, 0);
371 EXPECT_EQ(buffer->has_itut_t35, 1);
372 EXPECT_NE(buffer->itut_t35.payload_bytes, nullptr);
373 EXPECT_GT(buffer->itut_t35.payload_size, 0);
374 EXPECT_EQ(released_input_buffer_, &kFrame2WithItutT35);
375
376 EXPECT_EQ(frames_in_use_, 2);
377 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
378
379 status = decoder_->SignalEOS();
380 EXPECT_EQ(status, kStatusOk);
381 EXPECT_EQ(frames_in_use_, 0);
382 }
383
384 class ParseOnlyTest : public testing::Test {
385 public:
386 void SetUp() override;
387
388 protected:
389 std::unique_ptr<Decoder> decoder_;
390 };
391
SetUp()392 void ParseOnlyTest::SetUp() {
393 decoder_.reset(new (std::nothrow) Decoder());
394 ASSERT_NE(decoder_, nullptr);
395 DecoderSettings settings = {};
396 settings.parse_only = true; // parse_only mode activated
397 ASSERT_EQ(decoder_->Init(&settings), kStatusOk);
398 }
399
TEST_F(ParseOnlyTest,NonFrameParallelModeParseOnly)400 TEST_F(ParseOnlyTest, NonFrameParallelModeParseOnly) {
401 StatusCode status;
402 const DecoderBuffer* buffer;
403
404 // Enqueue frame1 for decoding.
405 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
406 const_cast<uint8_t*>(kFrame1));
407 ASSERT_EQ(status, kStatusOk);
408
409 // Dequeue the output of frame1.
410 status = decoder_->DequeueFrame(&buffer);
411 ASSERT_EQ(status, kStatusOk);
412 ASSERT_EQ(buffer,
413 nullptr); // in the parse only case the buffer should be nullptr
414
415 // Frame 1 has 1 coding block and the value of it is kFrame1MeanQp.
416 std::vector<int> frame1_qp = decoder_->GetFramesMeanQpInTemporalUnit();
417 EXPECT_EQ(frame1_qp[0], kFrame1MeanQp);
418
419 // Enqueue frame2 for decoding.
420 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
421 const_cast<uint8_t*>(kFrame2));
422 ASSERT_EQ(status, kStatusOk);
423
424 // Dequeue the output of frame2.
425 status = decoder_->DequeueFrame(&buffer);
426 ASSERT_EQ(status, kStatusOk);
427 ASSERT_EQ(buffer,
428 nullptr); // in the parse only case the buffer should be nullptr
429
430 // Frame 2 has 4 coding blocks and the mean value of them is kFrame2MeanQp.
431 std::vector<int> frame2_qp = decoder_->GetFramesMeanQpInTemporalUnit();
432 EXPECT_EQ(frame2_qp[0], kFrame2MeanQp);
433 }
434
435 } // namespace
436 } // namespace libgav1
437