• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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