xref: /aosp_15_r20/external/libgav1/src/c_decoder_test.c (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1 /*
2  * Copyright 2021 The libgav1 Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifdef __cplusplus
18 #error Do not compile this file with a C++ compiler
19 #endif
20 
21 // clang-format off
22 #include "src/gav1/decoder.h"
23 
24 // Import the test frame #defines.
25 #include "src/decoder_test_data.h"
26 // clang-format on
27 
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 
33 #define ASSERT_EQ(a, b)                                                      \
34   do {                                                                       \
35     if ((a) != (b)) {                                                        \
36       fprintf(stderr, "Assertion failure: (%s) == (%s), at %s:%d\n", #a, #b, \
37               __FILE__, __LINE__);                                           \
38       fprintf(stderr, "C DecoderTest failed\n");                             \
39       exit(1);                                                               \
40     }                                                                        \
41   } while (0)
42 
43 #define ASSERT_NE(a, b)                                                      \
44   do {                                                                       \
45     if ((a) == (b)) {                                                        \
46       fprintf(stderr, "Assertion failure: (%s) != (%s), at %s:%d\n", #a, #b, \
47               __FILE__, __LINE__);                                           \
48       fprintf(stderr, "C DecoderTest failed\n");                             \
49       exit(1);                                                               \
50     }                                                                        \
51   } while (0)
52 
53 #define ASSERT_TRUE(a)                                                   \
54   do {                                                                   \
55     if (!(a)) {                                                          \
56       fprintf(stderr, "Assertion failure: %s, at %s:%d\n", #a, __FILE__, \
57               __LINE__);                                                 \
58       fprintf(stderr, "C DecoderTest failed\n");                         \
59       exit(1);                                                           \
60     }                                                                    \
61   } while (0)
62 
63 #define ASSERT_FALSE(a)                                                     \
64   do {                                                                      \
65     if (a) {                                                                \
66       fprintf(stderr, "Assertion failure: !(%s), at %s:%d\n", #a, __FILE__, \
67               __LINE__);                                                    \
68       fprintf(stderr, "C DecoderTest failed\n");                            \
69       exit(1);                                                              \
70     }                                                                       \
71   } while (0)
72 
73 static const uint8_t kFrame1[] = {OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER,
74                                   OBU_FRAME_1};
75 
76 static const uint8_t kFrame2[] = {OBU_TEMPORAL_DELIMITER, OBU_FRAME_2};
77 
78 static const uint8_t kFrame1WithHdrCllAndHdrMdcv[] = {
79     OBU_TEMPORAL_DELIMITER, OBU_SEQUENCE_HEADER, OBU_METADATA_HDR_CLL,
80     OBU_METADATA_HDR_MDCV, OBU_FRAME_1};
81 
82 static const uint8_t kFrame2WithItutT35[] = {
83     OBU_TEMPORAL_DELIMITER, OBU_METADATA_ITUT_T35, OBU_FRAME_2};
84 
85 typedef struct DecoderTest {
86   Libgav1Decoder* decoder;
87   int frames_in_use;
88   void* buffer_private_data;
89   void* released_input_buffer;
90 } DecoderTest;
91 
DecoderTestInit(DecoderTest * test)92 static void DecoderTestInit(DecoderTest* test) {
93   test->decoder = NULL;
94   test->frames_in_use = 0;
95   test->buffer_private_data = NULL;
96   test->released_input_buffer = NULL;
97 }
98 
DecoderTestIncrementFramesInUse(DecoderTest * test)99 static void DecoderTestIncrementFramesInUse(DecoderTest* test) {
100   ++test->frames_in_use;
101 }
102 
DecoderTestDecrementFramesInUse(DecoderTest * test)103 static void DecoderTestDecrementFramesInUse(DecoderTest* test) {
104   --test->frames_in_use;
105 }
106 
DecoderTestSetReleasedInputBuffer(DecoderTest * test,void * released_input_buffer)107 static void DecoderTestSetReleasedInputBuffer(DecoderTest* test,
108                                               void* released_input_buffer) {
109   test->released_input_buffer = released_input_buffer;
110 }
111 
DecoderTestSetBufferPrivateData(DecoderTest * test,void * buffer_private_data)112 static void DecoderTestSetBufferPrivateData(DecoderTest* test,
113                                             void* buffer_private_data) {
114   test->buffer_private_data = buffer_private_data;
115 }
116 
117 typedef struct FrameBufferPrivate {
118   uint8_t* data[3];
119 } FrameBufferPrivate;
120 
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)121 static Libgav1StatusCode GetFrameBuffer(
122     void* callback_private_data, int bitdepth, Libgav1ImageFormat image_format,
123     int width, int height, int left_border, int right_border, int top_border,
124     int bottom_border, int stride_alignment, Libgav1FrameBuffer* frame_buffer) {
125   Libgav1FrameBufferInfo info;
126   Libgav1StatusCode status = Libgav1ComputeFrameBufferInfo(
127       bitdepth, image_format, width, height, left_border, right_border,
128       top_border, bottom_border, stride_alignment, &info);
129   if (status != kLibgav1StatusOk) return status;
130 
131   FrameBufferPrivate* buffer_private =
132       (FrameBufferPrivate*)malloc(sizeof(FrameBufferPrivate));
133   if (buffer_private == NULL) return kLibgav1StatusOutOfMemory;
134 
135   for (int i = 0; i < 3; ++i) {
136     const size_t size = (i == 0) ? info.y_buffer_size : info.uv_buffer_size;
137     buffer_private->data[i] = (uint8_t*)malloc(sizeof(uint8_t) * size);
138     if (buffer_private->data[i] == NULL) {
139       for (int j = 0; j < i; j++) {
140         free(buffer_private->data[j]);
141       }
142       free(buffer_private);
143       return kLibgav1StatusOutOfMemory;
144     }
145   }
146 
147   uint8_t* const y_buffer = buffer_private->data[0];
148   uint8_t* const u_buffer =
149       (info.uv_buffer_size != 0) ? buffer_private->data[1] : NULL;
150   uint8_t* const v_buffer =
151       (info.uv_buffer_size != 0) ? buffer_private->data[2] : NULL;
152 
153   status = Libgav1SetFrameBuffer(&info, y_buffer, u_buffer, v_buffer,
154                                  buffer_private, frame_buffer);
155   if (status != kLibgav1StatusOk) return status;
156 
157   DecoderTest* const decoder_test = (DecoderTest*)callback_private_data;
158   DecoderTestIncrementFramesInUse(decoder_test);
159   DecoderTestSetBufferPrivateData(decoder_test, frame_buffer->private_data);
160   return kLibgav1StatusOk;
161 }
162 
ReleaseFrameBuffer(void * callback_private_data,void * buffer_private_data)163 static void ReleaseFrameBuffer(void* callback_private_data,
164                                void* buffer_private_data) {
165   FrameBufferPrivate* buffer_private = (FrameBufferPrivate*)buffer_private_data;
166   for (int i = 0; i < 3; ++i) {
167     free(buffer_private->data[i]);
168   }
169   free(buffer_private);
170   DecoderTest* const decoder_test = (DecoderTest*)callback_private_data;
171   DecoderTestDecrementFramesInUse(decoder_test);
172 }
173 
ReleaseInputBuffer(void * private_data,void * input_buffer)174 static void ReleaseInputBuffer(void* private_data, void* input_buffer) {
175   DecoderTestSetReleasedInputBuffer((DecoderTest*)private_data, input_buffer);
176 }
177 
DecoderTestSetUp(DecoderTest * test)178 static void DecoderTestSetUp(DecoderTest* test) {
179   Libgav1DecoderSettings settings;
180   Libgav1DecoderSettingsInitDefault(&settings);
181   settings.frame_parallel = 0;  // false
182   settings.get_frame_buffer = GetFrameBuffer;
183   settings.release_frame_buffer = ReleaseFrameBuffer;
184   settings.callback_private_data = test;
185   settings.release_input_buffer = ReleaseInputBuffer;
186   ASSERT_EQ(test->decoder, NULL);
187   ASSERT_EQ(Libgav1DecoderCreate(&settings, &test->decoder), kLibgav1StatusOk);
188   ASSERT_NE(test->decoder, NULL);
189 }
190 
DecoderTestAPIFlowForNonFrameParallelMode(void)191 static void DecoderTestAPIFlowForNonFrameParallelMode(void) {
192   DecoderTest test;
193   DecoderTestInit(&test);
194   DecoderTestSetUp(&test);
195 
196   Libgav1StatusCode status;
197   const Libgav1DecoderBuffer* buffer;
198 
199   // Enqueue frame1 for decoding.
200   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
201                                       (uint8_t*)&kFrame1);
202   ASSERT_EQ(status, kLibgav1StatusOk);
203 
204   // In non-frame-parallel mode, decoding happens only in the DequeueFrame call.
205   // So there should be no frames in use yet.
206   ASSERT_EQ(test.frames_in_use, 0);
207 
208   // Dequeue the output of frame1.
209   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
210   ASSERT_EQ(status, kLibgav1StatusOk);
211   ASSERT_NE(buffer, NULL);
212   ASSERT_EQ(test.released_input_buffer, &kFrame1);
213 
214   // libgav1 has decoded frame1 and is holding a reference to it.
215   ASSERT_EQ(test.frames_in_use, 1);
216   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
217 
218   // Enqueue frame2 for decoding.
219   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
220                                       (uint8_t*)&kFrame2);
221   ASSERT_EQ(status, kLibgav1StatusOk);
222 
223   ASSERT_EQ(test.frames_in_use, 1);
224 
225   // Dequeue the output of frame2.
226   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
227   ASSERT_EQ(status, kLibgav1StatusOk);
228   ASSERT_NE(buffer, NULL);
229   ASSERT_EQ(test.released_input_buffer, &kFrame2);
230 
231   ASSERT_EQ(test.frames_in_use, 2);
232   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
233 
234   // Signal end of stream (method 1). This should ensure that all the references
235   // are released.
236   status = Libgav1DecoderSignalEOS(test.decoder);
237   ASSERT_EQ(status, kLibgav1StatusOk);
238 
239   // libgav1 should have released all the reference frames now.
240   ASSERT_EQ(test.frames_in_use, 0);
241 
242   // Now, the decoder is ready to accept a new coded video sequence.
243 
244   // Enqueue frame1 for decoding.
245   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
246                                       (uint8_t*)&kFrame1);
247   ASSERT_EQ(status, kLibgav1StatusOk);
248 
249   ASSERT_EQ(test.frames_in_use, 0);
250 
251   // Dequeue the output of frame1.
252   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
253   ASSERT_EQ(status, kLibgav1StatusOk);
254   ASSERT_NE(buffer, NULL);
255   ASSERT_EQ(test.released_input_buffer, &kFrame1);
256 
257   ASSERT_EQ(test.frames_in_use, 1);
258   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
259 
260   // Enqueue frame2 for decoding.
261   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
262                                       (uint8_t*)&kFrame2);
263   ASSERT_EQ(status, kLibgav1StatusOk);
264 
265   ASSERT_EQ(test.frames_in_use, 1);
266 
267   // Dequeue the output of frame2.
268   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
269   ASSERT_EQ(status, kLibgav1StatusOk);
270   ASSERT_NE(buffer, NULL);
271   ASSERT_EQ(test.released_input_buffer, &kFrame2);
272 
273   ASSERT_EQ(test.frames_in_use, 2);
274   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
275 
276   // Signal end of stream (method 2). This should ensure that all the references
277   // are released.
278   Libgav1DecoderDestroy(test.decoder);
279   test.decoder = NULL;
280 
281   // libgav1 should have released all the frames now.
282   ASSERT_EQ(test.frames_in_use, 0);
283 }
284 
285 static void
DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing(void)286 DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing(void) {
287   DecoderTest test;
288   DecoderTestInit(&test);
289   DecoderTestSetUp(&test);
290 
291   Libgav1StatusCode status;
292   const Libgav1DecoderBuffer* buffer;
293 
294   // Enqueue frame1 for decoding.
295   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
296                                       (uint8_t*)&kFrame1);
297   ASSERT_EQ(status, kLibgav1StatusOk);
298 
299   // Until the output of frame1 is dequeued, no other frames can be enqueued.
300   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
301                                       (uint8_t*)&kFrame2);
302   ASSERT_EQ(status, kLibgav1StatusTryAgain);
303 
304   ASSERT_EQ(test.frames_in_use, 0);
305 
306   // Dequeue the output of frame1.
307   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
308   ASSERT_EQ(status, kLibgav1StatusOk);
309   ASSERT_NE(buffer, NULL);
310   ASSERT_EQ(test.released_input_buffer, &kFrame1);
311 
312   ASSERT_EQ(test.frames_in_use, 1);
313 
314   // Delete the decoder instance.
315   Libgav1DecoderDestroy(test.decoder);
316   test.decoder = NULL;
317 
318   ASSERT_EQ(test.frames_in_use, 0);
319 }
320 
DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame(void)321 static void DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame(void) {
322   DecoderTest test;
323   DecoderTestInit(&test);
324   DecoderTestSetUp(&test);
325 
326   Libgav1StatusCode status;
327   const Libgav1DecoderBuffer* buffer;
328 
329   // Enqueue frame1 for decoding.
330   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
331                                       (uint8_t*)&kFrame1);
332   ASSERT_EQ(status, kLibgav1StatusOk);
333 
334   ASSERT_EQ(test.frames_in_use, 0);
335 
336   // Dequeue the output of frame1.
337   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
338   ASSERT_EQ(status, kLibgav1StatusOk);
339   ASSERT_NE(buffer, NULL);
340   ASSERT_EQ(test.released_input_buffer, &kFrame1);
341 
342   // Enqueue frame2 for decoding.
343   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
344                                       (uint8_t*)&kFrame2);
345   ASSERT_EQ(status, kLibgav1StatusOk);
346 
347   ASSERT_EQ(test.frames_in_use, 1);
348 
349   // Signal end of stream before dequeuing the output of frame2.
350   status = Libgav1DecoderSignalEOS(test.decoder);
351   ASSERT_EQ(status, kLibgav1StatusOk);
352 
353   // In this case, the output of the last frame that was enqueued is lost (which
354   // is intentional since end of stream was signaled without dequeueing it).
355   ASSERT_EQ(test.frames_in_use, 0);
356 
357   Libgav1DecoderDestroy(test.decoder);
358   test.decoder = NULL;
359 }
360 
DecoderTestNonFrameParallelModeInvalidFrameAfterEOS(void)361 static void DecoderTestNonFrameParallelModeInvalidFrameAfterEOS(void) {
362   DecoderTest test;
363   DecoderTestInit(&test);
364   DecoderTestSetUp(&test);
365 
366   Libgav1StatusCode status;
367   const Libgav1DecoderBuffer* buffer = NULL;
368 
369   // Enqueue frame1 for decoding.
370   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
371                                       (uint8_t*)&kFrame1);
372   ASSERT_EQ(status, kLibgav1StatusOk);
373 
374   ASSERT_EQ(test.frames_in_use, 0);
375 
376   // Dequeue the output of frame1.
377   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
378   ASSERT_EQ(status, kLibgav1StatusOk);
379   ASSERT_NE(buffer, NULL);
380   ASSERT_EQ(test.released_input_buffer, &kFrame1);
381 
382   ASSERT_EQ(test.frames_in_use, 1);
383 
384   // Signal end of stream.
385   status = Libgav1DecoderSignalEOS(test.decoder);
386   ASSERT_EQ(status, kLibgav1StatusOk);
387 
388   // libgav1 should have released all the reference frames now.
389   ASSERT_EQ(test.frames_in_use, 0);
390 
391   // Now, the decoder is ready to accept a new coded video sequence. But, we
392   // try to enqueue a frame that does not have a sequence header (which is not
393   // allowed).
394 
395   // Enqueue frame2 for decoding.
396   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
397                                       (uint8_t*)&kFrame2);
398   ASSERT_EQ(status, kLibgav1StatusOk);
399 
400   ASSERT_EQ(test.frames_in_use, 0);
401 
402   // Dequeue the output of frame2 (this will fail since no sequence header has
403   // been seen since the last EOS signal).
404   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
405   ASSERT_EQ(status, kLibgav1StatusBitstreamError);
406   ASSERT_EQ(test.released_input_buffer, &kFrame2);
407 
408   ASSERT_EQ(test.frames_in_use, 0);
409 
410   Libgav1DecoderDestroy(test.decoder);
411   test.decoder = NULL;
412 }
413 
DecoderTestMetadataObu(void)414 static void DecoderTestMetadataObu(void) {
415   DecoderTest test;
416   DecoderTestInit(&test);
417   DecoderTestSetUp(&test);
418 
419   Libgav1StatusCode status;
420   const Libgav1DecoderBuffer* buffer;
421 
422   // Enqueue frame1 for decoding.
423   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1WithHdrCllAndHdrMdcv,
424                                       sizeof(kFrame1WithHdrCllAndHdrMdcv), 0,
425                                       (uint8_t*)&kFrame1WithHdrCllAndHdrMdcv);
426   ASSERT_EQ(status, kLibgav1StatusOk);
427   ASSERT_EQ(test.frames_in_use, 0);
428 
429   // Dequeue the output of frame1.
430   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
431   ASSERT_EQ(status, kLibgav1StatusOk);
432   ASSERT_NE(buffer, NULL);
433   ASSERT_EQ(buffer->has_hdr_cll, 1);
434   ASSERT_EQ(buffer->has_hdr_mdcv, 1);
435   ASSERT_EQ(buffer->has_itut_t35, 0);
436   ASSERT_EQ(test.released_input_buffer, &kFrame1WithHdrCllAndHdrMdcv);
437 
438   ASSERT_EQ(test.frames_in_use, 1);
439   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
440 
441   // Enqueue frame2 for decoding.
442   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2WithItutT35,
443                                       sizeof(kFrame2WithItutT35), 0,
444                                       (uint8_t*)&kFrame2WithItutT35);
445   ASSERT_EQ(status, kLibgav1StatusOk);
446 
447   ASSERT_EQ(test.frames_in_use, 1);
448 
449   // Dequeue the output of frame2.
450   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
451   ASSERT_EQ(status, kLibgav1StatusOk);
452   ASSERT_NE(buffer, NULL);
453   ASSERT_EQ(buffer->has_hdr_cll, 0);
454   ASSERT_EQ(buffer->has_hdr_mdcv, 0);
455   ASSERT_EQ(buffer->has_itut_t35, 1);
456   ASSERT_NE(buffer->itut_t35.payload_bytes, NULL);
457   ASSERT_NE(buffer->itut_t35.payload_size, 0);
458   ASSERT_EQ(test.released_input_buffer, &kFrame2WithItutT35);
459 
460   ASSERT_EQ(test.frames_in_use, 2);
461   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
462 
463   status = Libgav1DecoderSignalEOS(test.decoder);
464   ASSERT_EQ(status, kLibgav1StatusOk);
465   ASSERT_EQ(test.frames_in_use, 0);
466 
467   Libgav1DecoderDestroy(test.decoder);
468 }
469 
main(void)470 int main(void) {
471   fprintf(stderr, "C DecoderTest started\n");
472   DecoderTestAPIFlowForNonFrameParallelMode();
473   DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing();
474   DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame();
475   DecoderTestNonFrameParallelModeInvalidFrameAfterEOS();
476   DecoderTestMetadataObu();
477   fprintf(stderr, "C DecoderTest passed\n");
478   return 0;
479 }
480