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