xref: /aosp_15_r20/external/libgav1/src/decoder_test.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
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