xref: /aosp_15_r20/external/libaom/common/obudec.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <assert.h>
16 
17 #include "common/obudec.h"
18 
19 #include "aom_dsp/aom_dsp_common.h"
20 #include "aom_ports/mem_ops.h"
21 #include "av1/common/common.h"
22 #include "av1/common/obu_util.h"
23 #include "tools_common.h"
24 
25 #define OBU_BUFFER_SIZE (500 * 1024)
26 
27 #define OBU_HEADER_SIZE 1
28 #define OBU_EXTENSION_SIZE 1
29 #define OBU_MAX_LENGTH_FIELD_SIZE 8
30 
31 #define OBU_MAX_HEADER_SIZE \
32   (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 2 * OBU_MAX_LENGTH_FIELD_SIZE)
33 
34 #define OBU_DETECTION_SIZE \
35   (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 4 * OBU_MAX_LENGTH_FIELD_SIZE)
36 
37 // Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
38 // Stores raw bytes in 'value_buffer', length of the number in 'value_length',
39 // and decoded value in 'value'. If 'buffered' is true, it is buffered in the
40 // detect buffer first.
obudec_read_leb128(struct AvxInputContext * input_ctx,uint8_t * value_buffer,size_t * value_length,uint64_t * value,bool buffered)41 static int obudec_read_leb128(struct AvxInputContext *input_ctx,
42                               uint8_t *value_buffer, size_t *value_length,
43                               uint64_t *value, bool buffered) {
44   if (!input_ctx || !value_buffer || !value_length || !value) return -1;
45   size_t len;
46   for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
47     const size_t num_read =
48         buffer_input(input_ctx, 1, &value_buffer[len], buffered);
49     if (num_read == 0) {
50       if (len == 0 && input_eof(input_ctx)) {
51         *value_length = 0;
52         return 0;
53       }
54       // Ran out of data before completing read of value.
55       return -1;
56     }
57     if ((value_buffer[len] >> 7) == 0) {
58       ++len;
59       *value_length = len;
60       break;
61     }
62   }
63 
64   return aom_uleb_decode(value_buffer, len, value, NULL);
65 }
66 
67 // Reads OBU header from 'input_ctx'. The 'buffer_capacity' passed in must be
68 // large enough to store an OBU header with extension (2 bytes). Raw OBU data is
69 // written to 'obu_data', parsed OBU header values are written to 'obu_header',
70 // and total bytes read from file are written to 'bytes_read'. Returns 0 for
71 // success, and non-zero on failure. When end of file is reached, the return
72 // value is 0 and the 'bytes_read' value is set to 0. If 'buffered' is true, it
73 // is buffered in the detect buffer first.
obudec_read_obu_header(struct AvxInputContext * input_ctx,size_t buffer_capacity,int is_annexb,uint8_t * obu_data,ObuHeader * obu_header,size_t * bytes_read,bool buffered)74 static int obudec_read_obu_header(struct AvxInputContext *input_ctx,
75                                   size_t buffer_capacity, int is_annexb,
76                                   uint8_t *obu_data, ObuHeader *obu_header,
77                                   size_t *bytes_read, bool buffered) {
78   if (!input_ctx || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
79       !obu_data || !obu_header || !bytes_read) {
80     return -1;
81   }
82   *bytes_read = buffer_input(input_ctx, 1, obu_data, buffered);
83 
84   if (input_eof(input_ctx) && *bytes_read == 0) {
85     return 0;
86   } else if (*bytes_read != 1) {
87     fprintf(stderr, "obudec: Failure reading OBU header.\n");
88     return -1;
89   }
90 
91   const int has_extension = (obu_data[0] >> 2) & 0x1;
92   if (has_extension) {
93     if (buffer_input(input_ctx, 1, &obu_data[1], buffered) != 1) {
94       fprintf(stderr, "obudec: Failure reading OBU extension.");
95       return -1;
96     }
97     ++*bytes_read;
98   }
99 
100   size_t obu_bytes_parsed = 0;
101   const aom_codec_err_t parse_result = aom_read_obu_header(
102       obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
103   if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
104     fprintf(stderr, "obudec: Error parsing OBU header.\n");
105     return -1;
106   }
107 
108   return 0;
109 }
110 
111 // Reads OBU payload from 'input_ctx' and returns 0 for success when all payload
112 // bytes are read from the file. Payload data is written to 'obu_data', and
113 // actual bytes read added to 'bytes_read'. If 'buffered' is true, it is
114 // buffered in the detect buffer first.
obudec_read_obu_payload(struct AvxInputContext * input_ctx,size_t payload_length,uint8_t * obu_data,size_t * bytes_read,bool buffered)115 static int obudec_read_obu_payload(struct AvxInputContext *input_ctx,
116                                    size_t payload_length, uint8_t *obu_data,
117                                    size_t *bytes_read, bool buffered) {
118   if (!input_ctx || payload_length == 0 || !obu_data || !bytes_read) return -1;
119 
120   if (buffer_input(input_ctx, payload_length, obu_data, buffered) !=
121       payload_length) {
122     fprintf(stderr, "obudec: Failure reading OBU payload.\n");
123     return -1;
124   }
125 
126   *bytes_read += payload_length;
127   return 0;
128 }
129 
obudec_read_obu_header_and_size(struct AvxInputContext * input_ctx,size_t buffer_capacity,int is_annexb,uint8_t * buffer,size_t * bytes_read,size_t * payload_length,ObuHeader * obu_header,bool buffered)130 static int obudec_read_obu_header_and_size(
131     struct AvxInputContext *input_ctx, size_t buffer_capacity, int is_annexb,
132     uint8_t *buffer, size_t *bytes_read, size_t *payload_length,
133     ObuHeader *obu_header, bool buffered) {
134   const size_t kMinimumBufferSize = OBU_MAX_HEADER_SIZE;
135   if (!input_ctx || !buffer || !bytes_read || !payload_length || !obu_header ||
136       buffer_capacity < kMinimumBufferSize) {
137     return -1;
138   }
139 
140   size_t leb128_length_obu = 0;
141   size_t leb128_length_payload = 0;
142   uint64_t obu_size = 0;
143   if (is_annexb) {
144     if (obudec_read_leb128(input_ctx, &buffer[0], &leb128_length_obu, &obu_size,
145                            buffered) != 0) {
146       fprintf(stderr, "obudec: Failure reading OBU size length.\n");
147       return -1;
148     } else if (leb128_length_obu == 0) {
149       *payload_length = 0;
150       return 0;
151     }
152     if (obu_size > UINT32_MAX) {
153       fprintf(stderr, "obudec: OBU payload length too large.\n");
154       return -1;
155     }
156   }
157 
158   size_t header_size = 0;
159   if (obudec_read_obu_header(input_ctx, buffer_capacity - leb128_length_obu,
160                              is_annexb, buffer + leb128_length_obu, obu_header,
161                              &header_size, buffered) != 0) {
162     return -1;
163   } else if (header_size == 0) {
164     *payload_length = 0;
165     return 0;
166   }
167 
168   if (!obu_header->has_size_field) {
169     assert(is_annexb);
170     if (obu_size < header_size) {
171       fprintf(stderr, "obudec: OBU size is too small.\n");
172       return -1;
173     }
174     *payload_length = (size_t)obu_size - header_size;
175   } else {
176     uint64_t u64_payload_length = 0;
177     if (obudec_read_leb128(input_ctx, &buffer[leb128_length_obu + header_size],
178                            &leb128_length_payload, &u64_payload_length,
179                            buffered) != 0) {
180       fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
181       return -1;
182     }
183     if (u64_payload_length > UINT32_MAX) {
184       fprintf(stderr, "obudec: OBU payload length too large.\n");
185       return -1;
186     }
187 
188     *payload_length = (size_t)u64_payload_length;
189   }
190 
191   *bytes_read = leb128_length_obu + header_size + leb128_length_payload;
192   return 0;
193 }
194 
obudec_grow_buffer(size_t growth_amount,uint8_t ** obu_buffer,size_t * obu_buffer_capacity)195 static int obudec_grow_buffer(size_t growth_amount, uint8_t **obu_buffer,
196                               size_t *obu_buffer_capacity) {
197   if (!*obu_buffer || !obu_buffer_capacity || growth_amount == 0) {
198     return -1;
199   }
200 
201   const size_t capacity = *obu_buffer_capacity;
202   if (SIZE_MAX - growth_amount < capacity) {
203     fprintf(stderr, "obudec: cannot grow buffer, capacity will roll over.\n");
204     return -1;
205   }
206 
207   const size_t new_capacity = capacity + growth_amount;
208 
209 #if defined AOM_MAX_ALLOCABLE_MEMORY
210   if (new_capacity > AOM_MAX_ALLOCABLE_MEMORY) {
211     fprintf(stderr, "obudec: OBU size exceeds max alloc size.\n");
212     return -1;
213   }
214 #endif
215 
216   uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);
217   if (!new_buffer) {
218     fprintf(stderr, "obudec: Failed to allocate compressed data buffer.\n");
219     return -1;
220   }
221 
222   *obu_buffer = new_buffer;
223   *obu_buffer_capacity = new_capacity;
224   return 0;
225 }
226 
obudec_read_one_obu(struct AvxInputContext * input_ctx,uint8_t ** obu_buffer,size_t obu_bytes_buffered,size_t * obu_buffer_capacity,size_t * obu_length,ObuHeader * obu_header,int is_annexb,bool buffered)227 static int obudec_read_one_obu(struct AvxInputContext *input_ctx,
228                                uint8_t **obu_buffer, size_t obu_bytes_buffered,
229                                size_t *obu_buffer_capacity, size_t *obu_length,
230                                ObuHeader *obu_header, int is_annexb,
231                                bool buffered) {
232   if (!input_ctx || !(*obu_buffer) || !obu_buffer_capacity || !obu_length ||
233       !obu_header) {
234     return -1;
235   }
236 
237   size_t bytes_read = 0;
238   size_t obu_payload_length = 0;
239   size_t available_buffer_capacity = *obu_buffer_capacity - obu_bytes_buffered;
240 
241   if (available_buffer_capacity < OBU_MAX_HEADER_SIZE) {
242     if (obudec_grow_buffer(AOMMAX(*obu_buffer_capacity, OBU_MAX_HEADER_SIZE),
243                            obu_buffer, obu_buffer_capacity) != 0) {
244       *obu_length = bytes_read;
245       return -1;
246     }
247     available_buffer_capacity +=
248         AOMMAX(*obu_buffer_capacity, OBU_MAX_HEADER_SIZE);
249   }
250 
251   const int status = obudec_read_obu_header_and_size(
252       input_ctx, available_buffer_capacity, is_annexb,
253       *obu_buffer + obu_bytes_buffered, &bytes_read, &obu_payload_length,
254       obu_header, buffered);
255   if (status < 0) return status;
256 
257   if (obu_payload_length > SIZE_MAX - bytes_read) return -1;
258 
259   if (obu_payload_length > 256 * 1024 * 1024) {
260     fprintf(stderr, "obudec: Read invalid OBU size (%u)\n",
261             (unsigned int)obu_payload_length);
262     *obu_length = bytes_read + obu_payload_length;
263     return -1;
264   }
265 
266   if (bytes_read + obu_payload_length > available_buffer_capacity &&
267       obudec_grow_buffer(AOMMAX(*obu_buffer_capacity, obu_payload_length),
268                          obu_buffer, obu_buffer_capacity) != 0) {
269     *obu_length = bytes_read + obu_payload_length;
270     return -1;
271   }
272 
273   if (obu_payload_length > 0 &&
274       obudec_read_obu_payload(input_ctx, obu_payload_length,
275                               *obu_buffer + obu_bytes_buffered + bytes_read,
276                               &bytes_read, buffered) != 0) {
277     return -1;
278   }
279 
280   *obu_length = bytes_read;
281   return 0;
282 }
283 
file_is_obu(struct ObuDecInputContext * obu_ctx)284 int file_is_obu(struct ObuDecInputContext *obu_ctx) {
285   if (!obu_ctx || !obu_ctx->avx_ctx) return 0;
286 
287   struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
288   uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
289   const int is_annexb = obu_ctx->is_annexb;
290   size_t payload_length = 0;
291   ObuHeader obu_header;
292   memset(&obu_header, 0, sizeof(obu_header));
293   size_t length_of_unit_size = 0;
294   size_t annexb_header_length = 0;
295   uint64_t unit_size = 0;
296 
297   if (is_annexb) {
298     // read the size of first temporal unit
299     if (obudec_read_leb128(avx_ctx, &detect_buf[0], &length_of_unit_size,
300                            &unit_size, /*buffered=*/true) != 0) {
301       fprintf(stderr, "obudec: Failure reading temporal unit header\n");
302       rewind_detect(avx_ctx);
303       return 0;
304     }
305 
306     // read the size of first frame unit
307     if (obudec_read_leb128(avx_ctx, &detect_buf[length_of_unit_size],
308                            &annexb_header_length, &unit_size,
309                            /*buffered=*/true) != 0) {
310       fprintf(stderr, "obudec: Failure reading frame unit header\n");
311       rewind_detect(avx_ctx);
312       return 0;
313     }
314     annexb_header_length += length_of_unit_size;
315   }
316 
317   size_t bytes_read = 0;
318   if (obudec_read_obu_header_and_size(
319           avx_ctx, OBU_DETECTION_SIZE - annexb_header_length, is_annexb,
320           &detect_buf[annexb_header_length], &bytes_read, &payload_length,
321           &obu_header, /*buffered=*/true) != 0) {
322     fprintf(stderr, "obudec: Failure reading first OBU.\n");
323     rewind_detect(avx_ctx);
324     return 0;
325   }
326 
327   if (is_annexb) {
328     bytes_read += annexb_header_length;
329   }
330 
331   if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
332       obu_header.type != OBU_SEQUENCE_HEADER) {
333     rewind_detect(avx_ctx);
334     return 0;
335   }
336 
337   if (obu_header.has_size_field) {
338     if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
339       fprintf(
340           stderr,
341           "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
342       rewind_detect(avx_ctx);
343       return 0;
344     }
345   } else if (!is_annexb) {
346     fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
347     rewind_detect(avx_ctx);
348     return 0;
349   }
350 
351   // Appears that input is valid Section 5 AV1 stream.
352   obu_ctx->buffer = (uint8_t *)malloc(OBU_BUFFER_SIZE);
353   if (!obu_ctx->buffer) {
354     fprintf(stderr, "Out of memory.\n");
355     rewind_detect(avx_ctx);
356     return 0;
357   }
358   obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
359 
360   memcpy(obu_ctx->buffer, &detect_buf[0], bytes_read);
361   obu_ctx->bytes_buffered = bytes_read;
362   // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
363   // We need to read this in so that our buffer only contains complete OBUs.
364   if (payload_length > 0) {
365     if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
366       fprintf(stderr, "obudec: First OBU's payload is too large\n");
367       rewind_detect(avx_ctx);
368       obudec_free(obu_ctx);
369       return 0;
370     }
371 
372     size_t payload_bytes = 0;
373     const int status = obudec_read_obu_payload(
374         avx_ctx, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes,
375         /*buffered=*/false);
376     if (status < 0) {
377       rewind_detect(avx_ctx);
378       obudec_free(obu_ctx);
379       return 0;
380     }
381     obu_ctx->bytes_buffered += payload_bytes;
382   }
383   return 1;
384 }
385 
obudec_read_temporal_unit(struct ObuDecInputContext * obu_ctx,uint8_t ** buffer,size_t * bytes_read,size_t * buffer_size)386 int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
387                               uint8_t **buffer, size_t *bytes_read,
388                               size_t *buffer_size) {
389   FILE *f = obu_ctx->avx_ctx->file;
390   if (!f) return -1;
391 
392   *buffer_size = 0;
393   *bytes_read = 0;
394 
395   if (input_eof(obu_ctx->avx_ctx)) {
396     return 1;
397   }
398 
399   size_t tu_size;
400   size_t obu_size = 0;
401   size_t length_of_temporal_unit_size = 0;
402   uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
403 
404   if (obu_ctx->is_annexb) {
405     uint64_t size = 0;
406 
407     if (obu_ctx->bytes_buffered == 0) {
408       if (obudec_read_leb128(obu_ctx->avx_ctx, &tuheader[0],
409                              &length_of_temporal_unit_size, &size,
410                              /*buffered=*/false) != 0) {
411         fprintf(stderr, "obudec: Failure reading temporal unit header\n");
412         return -1;
413       }
414       if (size == 0 && input_eof(obu_ctx->avx_ctx)) {
415         return 1;
416       }
417     } else {
418       // temporal unit size was already stored in buffer
419       if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
420                           &length_of_temporal_unit_size) != 0) {
421         fprintf(stderr, "obudec: Failure reading temporal unit header\n");
422         return -1;
423       }
424     }
425 
426     if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
427       fprintf(stderr, "obudec: TU too large.\n");
428       return -1;
429     }
430 
431     size += length_of_temporal_unit_size;
432     tu_size = (size_t)size;
433   } else {
434     while (1) {
435       ObuHeader obu_header;
436       memset(&obu_header, 0, sizeof(obu_header));
437 
438       if (obudec_read_one_obu(obu_ctx->avx_ctx, &obu_ctx->buffer,
439                               obu_ctx->bytes_buffered,
440                               &obu_ctx->buffer_capacity, &obu_size, &obu_header,
441                               0, /*buffered=*/false) != 0) {
442         fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
443         return -1;
444       }
445 
446       if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0) {
447         tu_size = obu_ctx->bytes_buffered;
448         break;
449       } else {
450         obu_ctx->bytes_buffered += obu_size;
451       }
452     }
453   }
454 
455 #if defined AOM_MAX_ALLOCABLE_MEMORY
456   if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
457     fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
458     return -1;
459   }
460 #endif
461   if (tu_size > 0) {
462     uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
463     if (!new_buffer) {
464       free(*buffer);
465       fprintf(stderr, "obudec: Out of memory.\n");
466       return -1;
467     }
468     *buffer = new_buffer;
469   }
470   *bytes_read = tu_size;
471   *buffer_size = tu_size;
472 
473   if (!obu_ctx->is_annexb) {
474     memcpy(*buffer, obu_ctx->buffer, tu_size);
475 
476     // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
477     // points to the end of the buffer.
478     memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered,
479             obu_size);
480     obu_ctx->bytes_buffered = obu_size;
481   } else {
482     if (!input_eof(obu_ctx->avx_ctx)) {
483       size_t data_size;
484       size_t offset;
485       if (!obu_ctx->bytes_buffered) {
486         data_size = tu_size - length_of_temporal_unit_size;
487         memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
488         offset = length_of_temporal_unit_size;
489       } else {
490         const size_t copy_size = AOMMIN(obu_ctx->bytes_buffered, tu_size);
491         memcpy(*buffer, obu_ctx->buffer, copy_size);
492         offset = copy_size;
493         data_size = tu_size - copy_size;
494         obu_ctx->bytes_buffered -= copy_size;
495       }
496 
497       if (read_from_input(obu_ctx->avx_ctx, data_size, *buffer + offset) !=
498           data_size) {
499         fprintf(stderr, "obudec: Failed to read full temporal unit\n");
500         return -1;
501       }
502     }
503   }
504   return 0;
505 }
506 
obudec_free(struct ObuDecInputContext * obu_ctx)507 void obudec_free(struct ObuDecInputContext *obu_ctx) {
508   free(obu_ctx->buffer);
509   obu_ctx->buffer = NULL;
510   obu_ctx->buffer_capacity = 0;
511   obu_ctx->bytes_buffered = 0;
512 }
513