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
22 #include "gtest/gtest.h"
23 #include "src/decoder_test_data.h"
24
25 namespace libgav1 {
26 namespace {
27
28 constexpr uint8_t kFrame1[] = {OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER,
29 OBU_FRAME_1};
30
31 constexpr uint8_t kFrame2[] = {OBU_TEMPORAL_DELIMITER, OBU_FRAME_2};
32
33 constexpr uint8_t kFrame1WithHdrCllAndHdrMdcv[] = {
34 OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER, OBU_METADATA_HDR_CLL,
35 OBU_METADATA_HDR_MDCV, OBU_FRAME_1};
36
37 constexpr uint8_t kFrame2WithItutT35[] = {OBU_TEMPORAL_DELIMITER,
38 OBU_METADATA_ITUT_T35, OBU_FRAME_2};
39
40 class DecoderTest : public testing::Test {
41 public:
42 void SetUp() override;
IncrementFramesInUse()43 void IncrementFramesInUse() { ++frames_in_use_; }
DecrementFramesInUse()44 void DecrementFramesInUse() { --frames_in_use_; }
SetBufferPrivateData(void * buffer_private_data)45 void SetBufferPrivateData(void* buffer_private_data) {
46 buffer_private_data_ = buffer_private_data;
47 }
SetReleasedInputBuffer(void * released_input_buffer)48 void SetReleasedInputBuffer(void* released_input_buffer) {
49 released_input_buffer_ = released_input_buffer;
50 }
51
52 protected:
53 std::unique_ptr<Decoder> decoder_;
54 int frames_in_use_ = 0;
55 void* buffer_private_data_ = nullptr;
56 void* released_input_buffer_ = nullptr;
57 };
58
59 struct FrameBufferPrivate {
60 uint8_t* data[3];
61 };
62
63 extern "C" {
64
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)65 static Libgav1StatusCode GetFrameBuffer(
66 void* callback_private_data, int bitdepth, Libgav1ImageFormat image_format,
67 int width, int height, int left_border, int right_border, int top_border,
68 int bottom_border, int stride_alignment, Libgav1FrameBuffer* frame_buffer) {
69 Libgav1FrameBufferInfo info;
70 Libgav1StatusCode status = Libgav1ComputeFrameBufferInfo(
71 bitdepth, image_format, width, height, left_border, right_border,
72 top_border, bottom_border, stride_alignment, &info);
73 if (status != kLibgav1StatusOk) return status;
74
75 std::unique_ptr<FrameBufferPrivate> buffer_private(new (std::nothrow)
76 FrameBufferPrivate);
77 if (buffer_private == nullptr) return kLibgav1StatusOutOfMemory;
78
79 for (int i = 0; i < 3; ++i) {
80 const size_t size = (i == 0) ? info.y_buffer_size : info.uv_buffer_size;
81 buffer_private->data[i] = new (std::nothrow) uint8_t[size];
82 if (buffer_private->data[i] == nullptr) {
83 return kLibgav1StatusOutOfMemory;
84 }
85 }
86
87 uint8_t* const y_buffer = buffer_private->data[0];
88 uint8_t* const u_buffer =
89 (info.uv_buffer_size != 0) ? buffer_private->data[1] : nullptr;
90 uint8_t* const v_buffer =
91 (info.uv_buffer_size != 0) ? buffer_private->data[2] : nullptr;
92
93 status = Libgav1SetFrameBuffer(&info, y_buffer, u_buffer, v_buffer,
94 buffer_private.release(), frame_buffer);
95 if (status != kLibgav1StatusOk) return status;
96
97 auto* const decoder_test = static_cast<DecoderTest*>(callback_private_data);
98 decoder_test->IncrementFramesInUse();
99 decoder_test->SetBufferPrivateData(frame_buffer->private_data);
100 return kLibgav1StatusOk;
101 }
102
ReleaseFrameBuffer(void * callback_private_data,void * buffer_private_data)103 static void ReleaseFrameBuffer(void* callback_private_data,
104 void* buffer_private_data) {
105 auto* buffer_private = static_cast<FrameBufferPrivate*>(buffer_private_data);
106 for (auto& data : buffer_private->data) {
107 delete[] data;
108 }
109 delete buffer_private;
110 auto* const decoder_test = static_cast<DecoderTest*>(callback_private_data);
111 decoder_test->DecrementFramesInUse();
112 }
113
ReleaseInputBuffer(void * private_data,void * input_buffer)114 static void ReleaseInputBuffer(void* private_data, void* input_buffer) {
115 auto* const decoder_test = static_cast<DecoderTest*>(private_data);
116 decoder_test->SetReleasedInputBuffer(input_buffer);
117 }
118
119 } // extern "C"
120
SetUp()121 void DecoderTest::SetUp() {
122 decoder_.reset(new (std::nothrow) Decoder());
123 ASSERT_NE(decoder_, nullptr);
124 DecoderSettings settings = {};
125 settings.frame_parallel = false;
126 settings.get_frame_buffer = GetFrameBuffer;
127 settings.release_frame_buffer = ReleaseFrameBuffer;
128 settings.callback_private_data = this;
129 settings.release_input_buffer = ReleaseInputBuffer;
130 ASSERT_EQ(decoder_->Init(&settings), kStatusOk);
131 }
132
TEST_F(DecoderTest,APIFlowForNonFrameParallelMode)133 TEST_F(DecoderTest, APIFlowForNonFrameParallelMode) {
134 StatusCode status;
135 const DecoderBuffer* buffer;
136
137 // Enqueue frame1 for decoding.
138 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
139 const_cast<uint8_t*>(kFrame1));
140 ASSERT_EQ(status, kStatusOk);
141
142 // In non-frame-parallel mode, decoding happens only in the DequeueFrame call.
143 // So there should be no frames in use yet.
144 EXPECT_EQ(frames_in_use_, 0);
145
146 // Dequeue the output of frame1.
147 status = decoder_->DequeueFrame(&buffer);
148 ASSERT_EQ(status, kStatusOk);
149 ASSERT_NE(buffer, nullptr);
150 EXPECT_EQ(released_input_buffer_, &kFrame1);
151
152 // libgav1 has decoded frame1 and is holding a reference to it.
153 EXPECT_EQ(frames_in_use_, 1);
154 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
155
156 // Enqueue frame2 for decoding.
157 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
158 const_cast<uint8_t*>(kFrame2));
159 ASSERT_EQ(status, kStatusOk);
160
161 EXPECT_EQ(frames_in_use_, 1);
162
163 // Dequeue the output of frame2.
164 status = decoder_->DequeueFrame(&buffer);
165 ASSERT_EQ(status, kStatusOk);
166 ASSERT_NE(buffer, nullptr);
167 EXPECT_EQ(released_input_buffer_, &kFrame2);
168
169 EXPECT_EQ(frames_in_use_, 2);
170 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
171
172 // Signal end of stream (method 1). This should ensure that all the references
173 // are released.
174 status = decoder_->SignalEOS();
175 EXPECT_EQ(status, kStatusOk);
176
177 // libgav1 should have released all the reference frames now.
178 EXPECT_EQ(frames_in_use_, 0);
179
180 // Now, the decoder is ready to accept a new coded video sequence.
181
182 // Enqueue frame1 for decoding.
183 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
184 const_cast<uint8_t*>(kFrame1));
185 ASSERT_EQ(status, kStatusOk);
186
187 EXPECT_EQ(frames_in_use_, 0);
188
189 // Dequeue the output of frame1.
190 status = decoder_->DequeueFrame(&buffer);
191 ASSERT_EQ(status, kStatusOk);
192 ASSERT_NE(buffer, nullptr);
193 EXPECT_EQ(released_input_buffer_, &kFrame1);
194
195 EXPECT_EQ(frames_in_use_, 1);
196 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
197
198 // Enqueue frame2 for decoding.
199 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
200 const_cast<uint8_t*>(kFrame2));
201 ASSERT_EQ(status, kStatusOk);
202
203 EXPECT_EQ(frames_in_use_, 1);
204
205 // Dequeue the output of frame2.
206 status = decoder_->DequeueFrame(&buffer);
207 ASSERT_EQ(status, kStatusOk);
208 ASSERT_NE(buffer, nullptr);
209 EXPECT_EQ(released_input_buffer_, &kFrame2);
210
211 EXPECT_EQ(frames_in_use_, 2);
212 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
213
214 // Signal end of stream (method 2). This should ensure that all the references
215 // are released.
216 decoder_ = nullptr;
217
218 // libgav1 should have released all the frames now.
219 EXPECT_EQ(frames_in_use_, 0);
220 }
221
TEST_F(DecoderTest,NonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing)222 TEST_F(DecoderTest, NonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing) {
223 StatusCode status;
224 const DecoderBuffer* buffer;
225
226 // Enqueue frame1 for decoding.
227 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
228 const_cast<uint8_t*>(kFrame1));
229 ASSERT_EQ(status, kStatusOk);
230
231 // Until the output of frame1 is dequeued, no other frames can be enqueued.
232 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
233 const_cast<uint8_t*>(kFrame2));
234 ASSERT_EQ(status, kStatusTryAgain);
235
236 EXPECT_EQ(frames_in_use_, 0);
237
238 // Dequeue the output of frame1.
239 status = decoder_->DequeueFrame(&buffer);
240 ASSERT_EQ(status, kStatusOk);
241 ASSERT_NE(buffer, nullptr);
242 EXPECT_EQ(released_input_buffer_, &kFrame1);
243
244 EXPECT_EQ(frames_in_use_, 1);
245
246 // Delete the decoder instance.
247 decoder_ = nullptr;
248
249 EXPECT_EQ(frames_in_use_, 0);
250 }
251
TEST_F(DecoderTest,NonFrameParallelModeEOSBeforeDequeuingLastFrame)252 TEST_F(DecoderTest, NonFrameParallelModeEOSBeforeDequeuingLastFrame) {
253 StatusCode status;
254 const DecoderBuffer* buffer;
255
256 // Enqueue frame1 for decoding.
257 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
258 const_cast<uint8_t*>(kFrame1));
259 ASSERT_EQ(status, kStatusOk);
260
261 EXPECT_EQ(frames_in_use_, 0);
262
263 // Dequeue the output of frame1.
264 status = decoder_->DequeueFrame(&buffer);
265 ASSERT_EQ(status, kStatusOk);
266 ASSERT_NE(buffer, nullptr);
267 EXPECT_EQ(released_input_buffer_, &kFrame1);
268
269 // Enqueue frame2 for decoding.
270 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
271 const_cast<uint8_t*>(kFrame2));
272 ASSERT_EQ(status, kStatusOk);
273
274 EXPECT_EQ(frames_in_use_, 1);
275
276 // Signal end of stream before dequeuing the output of frame2.
277 status = decoder_->SignalEOS();
278 ASSERT_EQ(status, kStatusOk);
279
280 // In this case, the output of the last frame that was enqueued is lost (which
281 // is intentional since end of stream was signaled without dequeueing it).
282 EXPECT_EQ(frames_in_use_, 0);
283 }
284
TEST_F(DecoderTest,NonFrameParallelModeInvalidFrameAfterEOS)285 TEST_F(DecoderTest, NonFrameParallelModeInvalidFrameAfterEOS) {
286 StatusCode status;
287 const DecoderBuffer* buffer = nullptr;
288
289 // Enqueue frame1 for decoding.
290 status = decoder_->EnqueueFrame(kFrame1, sizeof(kFrame1), 0,
291 const_cast<uint8_t*>(kFrame1));
292 ASSERT_EQ(status, kStatusOk);
293
294 EXPECT_EQ(frames_in_use_, 0);
295
296 // Dequeue the output of frame1.
297 status = decoder_->DequeueFrame(&buffer);
298 ASSERT_EQ(status, kStatusOk);
299 ASSERT_NE(buffer, nullptr);
300 EXPECT_EQ(released_input_buffer_, &kFrame1);
301
302 EXPECT_EQ(frames_in_use_, 1);
303
304 // Signal end of stream.
305 status = decoder_->SignalEOS();
306 EXPECT_EQ(status, kStatusOk);
307
308 // libgav1 should have released all the reference frames now.
309 EXPECT_EQ(frames_in_use_, 0);
310
311 // Now, the decoder is ready to accept a new coded video sequence. But, we
312 // try to enqueue a frame that does not have a sequence header (which is not
313 // allowed).
314
315 // Enqueue frame2 for decoding.
316 status = decoder_->EnqueueFrame(kFrame2, sizeof(kFrame2), 0,
317 const_cast<uint8_t*>(kFrame2));
318 ASSERT_EQ(status, kStatusOk);
319
320 EXPECT_EQ(frames_in_use_, 0);
321
322 // Dequeue the output of frame2 (this will fail since no sequence header has
323 // been seen since the last EOS signal).
324 status = decoder_->DequeueFrame(&buffer);
325 ASSERT_EQ(status, kStatusBitstreamError);
326 EXPECT_EQ(released_input_buffer_, &kFrame2);
327
328 EXPECT_EQ(frames_in_use_, 0);
329 }
330
TEST_F(DecoderTest,MetadataObu)331 TEST_F(DecoderTest, MetadataObu) {
332 StatusCode status;
333 const DecoderBuffer* buffer;
334
335 // Enqueue frame1 for decoding.
336 status = decoder_->EnqueueFrame(
337 kFrame1WithHdrCllAndHdrMdcv, sizeof(kFrame1WithHdrCllAndHdrMdcv), 0,
338 const_cast<uint8_t*>(kFrame1WithHdrCllAndHdrMdcv));
339 ASSERT_EQ(status, kStatusOk);
340
341 // Dequeue the output of frame1.
342 status = decoder_->DequeueFrame(&buffer);
343 ASSERT_EQ(status, kStatusOk);
344 ASSERT_NE(buffer, nullptr);
345 EXPECT_EQ(buffer->has_hdr_cll, 1);
346 EXPECT_EQ(buffer->has_hdr_mdcv, 1);
347 EXPECT_EQ(buffer->has_itut_t35, 0);
348 EXPECT_EQ(released_input_buffer_, &kFrame1WithHdrCllAndHdrMdcv);
349
350 // libgav1 has decoded frame1 and is holding a reference to it.
351 EXPECT_EQ(frames_in_use_, 1);
352 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
353
354 // Enqueue frame2 for decoding.
355 status =
356 decoder_->EnqueueFrame(kFrame2WithItutT35, sizeof(kFrame2WithItutT35), 0,
357 const_cast<uint8_t*>(kFrame2WithItutT35));
358 ASSERT_EQ(status, kStatusOk);
359
360 EXPECT_EQ(frames_in_use_, 1);
361
362 // Dequeue the output of frame2.
363 status = decoder_->DequeueFrame(&buffer);
364 ASSERT_EQ(status, kStatusOk);
365 ASSERT_NE(buffer, nullptr);
366 EXPECT_EQ(buffer->has_hdr_cll, 0);
367 EXPECT_EQ(buffer->has_hdr_mdcv, 0);
368 EXPECT_EQ(buffer->has_itut_t35, 1);
369 EXPECT_NE(buffer->itut_t35.payload_bytes, nullptr);
370 EXPECT_GT(buffer->itut_t35.payload_size, 0);
371 EXPECT_EQ(released_input_buffer_, &kFrame2WithItutT35);
372
373 EXPECT_EQ(frames_in_use_, 2);
374 EXPECT_EQ(buffer_private_data_, buffer->buffer_private_data);
375
376 status = decoder_->SignalEOS();
377 EXPECT_EQ(status, kStatusOk);
378 EXPECT_EQ(frames_in_use_, 0);
379 }
380
381 } // namespace
382 } // namespace libgav1
383