• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
238   // libgav1 should have released all the reference frames now.
239   ASSERT_EQ(test.frames_in_use, 0);
240 
241   // Now, the decoder is ready to accept a new coded video sequence.
242 
243   // Enqueue frame1 for decoding.
244   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
245                                       (uint8_t*)&kFrame1);
246   ASSERT_EQ(status, kLibgav1StatusOk);
247 
248   ASSERT_EQ(test.frames_in_use, 0);
249 
250   // Dequeue the output of frame1.
251   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
252   ASSERT_EQ(status, kLibgav1StatusOk);
253   ASSERT_NE(buffer, NULL);
254   ASSERT_EQ(test.released_input_buffer, &kFrame1);
255 
256   ASSERT_EQ(test.frames_in_use, 1);
257   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
258 
259   // Enqueue frame2 for decoding.
260   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
261                                       (uint8_t*)&kFrame2);
262   ASSERT_EQ(status, kLibgav1StatusOk);
263 
264   ASSERT_EQ(test.frames_in_use, 1);
265 
266   // Dequeue the output of frame2.
267   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
268   ASSERT_EQ(status, kLibgav1StatusOk);
269   ASSERT_NE(buffer, NULL);
270   ASSERT_EQ(test.released_input_buffer, &kFrame2);
271 
272   ASSERT_EQ(test.frames_in_use, 2);
273   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
274 
275   // Signal end of stream (method 2). This should ensure that all the references
276   // are released.
277   Libgav1DecoderDestroy(test.decoder);
278   test.decoder = NULL;
279 
280   // libgav1 should have released all the frames now.
281   ASSERT_EQ(test.frames_in_use, 0);
282 }
283 
284 static void
DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing(void)285 DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing(void) {
286   DecoderTest test;
287   DecoderTestInit(&test);
288   DecoderTestSetUp(&test);
289 
290   Libgav1StatusCode status;
291   const Libgav1DecoderBuffer* buffer;
292 
293   // Enqueue frame1 for decoding.
294   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
295                                       (uint8_t*)&kFrame1);
296   ASSERT_EQ(status, kLibgav1StatusOk);
297 
298   // Until the output of frame1 is dequeued, no other frames can be enqueued.
299   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
300                                       (uint8_t*)&kFrame2);
301   ASSERT_EQ(status, kLibgav1StatusTryAgain);
302 
303   ASSERT_EQ(test.frames_in_use, 0);
304 
305   // Dequeue the output of frame1.
306   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
307   ASSERT_EQ(status, kLibgav1StatusOk);
308   ASSERT_NE(buffer, NULL);
309   ASSERT_EQ(test.released_input_buffer, &kFrame1);
310 
311   ASSERT_EQ(test.frames_in_use, 1);
312 
313   // Delete the decoder instance.
314   Libgav1DecoderDestroy(test.decoder);
315   test.decoder = NULL;
316 
317   ASSERT_EQ(test.frames_in_use, 0);
318 }
319 
DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame(void)320 static void DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame(void) {
321   DecoderTest test;
322   DecoderTestInit(&test);
323   DecoderTestSetUp(&test);
324 
325   Libgav1StatusCode status;
326   const Libgav1DecoderBuffer* buffer;
327 
328   // Enqueue frame1 for decoding.
329   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
330                                       (uint8_t*)&kFrame1);
331   ASSERT_EQ(status, kLibgav1StatusOk);
332 
333   ASSERT_EQ(test.frames_in_use, 0);
334 
335   // Dequeue the output of frame1.
336   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
337   ASSERT_EQ(status, kLibgav1StatusOk);
338   ASSERT_NE(buffer, NULL);
339   ASSERT_EQ(test.released_input_buffer, &kFrame1);
340 
341   // Enqueue frame2 for decoding.
342   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
343                                       (uint8_t*)&kFrame2);
344   ASSERT_EQ(status, kLibgav1StatusOk);
345 
346   ASSERT_EQ(test.frames_in_use, 1);
347 
348   // Signal end of stream before dequeuing the output of frame2.
349   status = Libgav1DecoderSignalEOS(test.decoder);
350   ASSERT_EQ(status, kLibgav1StatusOk);
351 
352   // In this case, the output of the last frame that was enqueued is lost (which
353   // is intentional since end of stream was signaled without dequeueing it).
354   ASSERT_EQ(test.frames_in_use, 0);
355 
356   Libgav1DecoderDestroy(test.decoder);
357   test.decoder = NULL;
358 }
359 
DecoderTestNonFrameParallelModeInvalidFrameAfterEOS(void)360 static void DecoderTestNonFrameParallelModeInvalidFrameAfterEOS(void) {
361   DecoderTest test;
362   DecoderTestInit(&test);
363   DecoderTestSetUp(&test);
364 
365   Libgav1StatusCode status;
366   const Libgav1DecoderBuffer* buffer = NULL;
367 
368   // Enqueue frame1 for decoding.
369   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1, sizeof(kFrame1), 0,
370                                       (uint8_t*)&kFrame1);
371   ASSERT_EQ(status, kLibgav1StatusOk);
372 
373   ASSERT_EQ(test.frames_in_use, 0);
374 
375   // Dequeue the output of frame1.
376   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
377   ASSERT_EQ(status, kLibgav1StatusOk);
378   ASSERT_NE(buffer, NULL);
379   ASSERT_EQ(test.released_input_buffer, &kFrame1);
380 
381   ASSERT_EQ(test.frames_in_use, 1);
382 
383   // Signal end of stream.
384   status = Libgav1DecoderSignalEOS(test.decoder);
385 
386   // libgav1 should have released all the reference frames now.
387   ASSERT_EQ(test.frames_in_use, 0);
388 
389   // Now, the decoder is ready to accept a new coded video sequence. But, we
390   // try to enqueue a frame that does not have a sequence header (which is not
391   // allowed).
392 
393   // Enqueue frame2 for decoding.
394   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2, sizeof(kFrame2), 0,
395                                       (uint8_t*)&kFrame2);
396   ASSERT_EQ(status, kLibgav1StatusOk);
397 
398   ASSERT_EQ(test.frames_in_use, 0);
399 
400   // Dequeue the output of frame2 (this will fail since no sequence header has
401   // been seen since the last EOS signal).
402   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
403   ASSERT_EQ(status, kLibgav1StatusBitstreamError);
404   ASSERT_EQ(test.released_input_buffer, &kFrame2);
405 
406   ASSERT_EQ(test.frames_in_use, 0);
407 
408   Libgav1DecoderDestroy(test.decoder);
409   test.decoder = NULL;
410 }
411 
DecoderTestMetadataObu(void)412 static void DecoderTestMetadataObu(void) {
413   DecoderTest test;
414   DecoderTestInit(&test);
415   DecoderTestSetUp(&test);
416 
417   Libgav1StatusCode status;
418   const Libgav1DecoderBuffer* buffer;
419 
420   // Enqueue frame1 for decoding.
421   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame1WithHdrCllAndHdrMdcv,
422                                       sizeof(kFrame1WithHdrCllAndHdrMdcv), 0,
423                                       (uint8_t*)&kFrame1WithHdrCllAndHdrMdcv);
424   ASSERT_EQ(status, kLibgav1StatusOk);
425   ASSERT_EQ(test.frames_in_use, 0);
426 
427   // Dequeue the output of frame1.
428   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
429   ASSERT_EQ(status, kLibgav1StatusOk);
430   ASSERT_NE(buffer, NULL);
431   ASSERT_EQ(buffer->has_hdr_cll, 1);
432   ASSERT_EQ(buffer->has_hdr_mdcv, 1);
433   ASSERT_EQ(buffer->has_itut_t35, 0);
434   ASSERT_EQ(test.released_input_buffer, &kFrame1WithHdrCllAndHdrMdcv);
435 
436   ASSERT_EQ(test.frames_in_use, 1);
437   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
438 
439   // Enqueue frame2 for decoding.
440   status = Libgav1DecoderEnqueueFrame(test.decoder, kFrame2WithItutT35,
441                                       sizeof(kFrame2WithItutT35), 0,
442                                       (uint8_t*)&kFrame2WithItutT35);
443   ASSERT_EQ(status, kLibgav1StatusOk);
444 
445   ASSERT_EQ(test.frames_in_use, 1);
446 
447   // Dequeue the output of frame2.
448   status = Libgav1DecoderDequeueFrame(test.decoder, &buffer);
449   ASSERT_EQ(status, kLibgav1StatusOk);
450   ASSERT_NE(buffer, NULL);
451   ASSERT_EQ(buffer->has_hdr_cll, 0);
452   ASSERT_EQ(buffer->has_hdr_mdcv, 0);
453   ASSERT_EQ(buffer->has_itut_t35, 1);
454   ASSERT_NE(buffer->itut_t35.payload_bytes, NULL);
455   ASSERT_NE(buffer->itut_t35.payload_size, 0);
456   ASSERT_EQ(test.released_input_buffer, &kFrame2WithItutT35);
457 
458   ASSERT_EQ(test.frames_in_use, 2);
459   ASSERT_EQ(test.buffer_private_data, buffer->buffer_private_data);
460 
461   status = Libgav1DecoderSignalEOS(test.decoder);
462   ASSERT_EQ(test.frames_in_use, 0);
463 
464   Libgav1DecoderDestroy(test.decoder);
465 }
466 
main(void)467 int main(void) {
468   fprintf(stderr, "C DecoderTest started\n");
469   DecoderTestAPIFlowForNonFrameParallelMode();
470   DecoderTestNonFrameParallelModeEnqueueMultipleFramesWithoutDequeuing();
471   DecoderTestNonFrameParallelModeEOSBeforeDequeuingLastFrame();
472   DecoderTestNonFrameParallelModeInvalidFrameAfterEOS();
473   DecoderTestMetadataObu();
474   fprintf(stderr, "C DecoderTest passed\n");
475   return 0;
476 }
477