1 /*
2 * Copyright(c) 2019 Netflix, Inc.
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 https://www.aomedia.org/license/software-license. 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 https://www.aomedia.org/license/patent-license.
10 */
11 
12 #include <stdlib.h>
13 #include <stddef.h>
14 #include <string.h>
15 #include <assert.h>
16 
17 #include "EbFileUtils.h"
18 
19 const char *ivf_signature = "DKIF";
20 
21 static const size_t  k_maximum_leb_128_size = 8;
22 static const uint8_t k_leb_128byte_mask     = 0x7f; // Binary: 01111111
23 
mem_get_le16(const void * vmem)24 static unsigned int mem_get_le16(const void *vmem) {
25     unsigned int   val;
26     const uint8_t *mem = (const uint8_t *)vmem;
27 
28     val = mem[1] << 8;
29     val |= mem[0];
30     return val;
31 }
32 
mem_get_le32(const void * vmem)33 static unsigned int mem_get_le32(const void *vmem) {
34     unsigned int   val;
35     const uint8_t *mem = (const uint8_t *)vmem;
36 
37     val = ((unsigned int)mem[3]) << 24;
38     val |= mem[2] << 16;
39     val |= mem[1] << 8;
40     val |= mem[0];
41     return val;
42 }
43 
fix_framerate(int * num,int * den)44 static void fix_framerate(int *num, int *den) {
45     if (*den <= 0 || *den >= 1000000000 || *num <= 0 || *num >= 1000) {
46         // framerate seems to be invalid, just default to 30fps.
47         *num = 30;
48         *den = 1;
49     }
50 }
51 
52 typedef struct ReadBitBuffer {
53     const uint8_t *bit_buffer;
54     const uint8_t *bit_buffer_end;
55     uint32_t       bit_offset;
56 } ReadBitBuffer;
57 
uleb_decode(const uint8_t * buffer,size_t available,uint64_t * value,size_t * length)58 int uleb_decode(const uint8_t *buffer, size_t available, uint64_t *value, size_t *length) {
59     if (buffer && value) {
60         *value = 0;
61         for (size_t i = 0; i < k_maximum_leb_128_size && i < available; ++i) {
62             const uint8_t decoded_byte = *(buffer + i) & k_leb_128byte_mask;
63             *value |= ((uint64_t)decoded_byte) << (i * 7);
64             if ((*(buffer + i) >> 7) == 0) {
65                 if (length) {
66                     *length = i + 1;
67                 }
68 
69                 // Fail on values larger than 32-bits to ensure consistent
70                 // behavior on 32 and 64 bit targets: value is typically
71                 // used to determine buffer allocation size.
72                 if (*value > UINT32_MAX)
73                     return -1;
74 
75                 return 0;
76             }
77         }
78     }
79 
80     // If we get here, either the buffer/value pointers were invalid,
81     // or we ran over the available space
82     return -1;
83 }
84 
85 // Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
86 // Stores raw bytes in 'value_buffer', length of the number in 'value_length',
87 // and decoded value in 'value'.
obudec_read_leb128(FILE * f,uint8_t * value_buffer,size_t * value_length,uint64_t * value)88 static int obudec_read_leb128(FILE *f, uint8_t *value_buffer, size_t *value_length,
89                               uint64_t *value) {
90     if (!f || !value_buffer || !value_length || !value)
91         return -1;
92     size_t len;
93     for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
94         const size_t num_read = fread(&value_buffer[len], 1, 1, f);
95         if (num_read == 0) {
96             if (len == 0 && feof(f)) {
97                 *value_length = 0;
98                 return 0;
99             }
100             // Ran out of data before completing read of value.
101             return -1;
102         }
103         if ((value_buffer[len] >> 7) == 0) {
104             ++len;
105             *value_length = len;
106             break;
107         }
108     }
109 
110     return uleb_decode(value_buffer, len, value, NULL);
111 }
112 
rb_read_bit(ReadBitBuffer * rb)113 int rb_read_bit(ReadBitBuffer *rb) {
114     const uint32_t off = rb->bit_offset;
115     const uint32_t p   = off >> 3;
116     const int      q   = 7 - (int)(off & 0x7);
117     if (rb->bit_buffer + p < rb->bit_buffer_end) {
118         const int bit  = (rb->bit_buffer[p] >> q) & 1;
119         rb->bit_offset = off + 1;
120         return bit;
121     } else
122         return 0;
123 }
124 
rb_read_literal(ReadBitBuffer * rb,int bits)125 int rb_read_literal(ReadBitBuffer *rb, int bits) {
126     assert(bits <= 31);
127     int value = 0, bit;
128     for (bit = bits - 1; bit >= 0; bit--) value |= rb_read_bit(rb) << bit;
129     return value;
130 }
131 
132 // Returns 1 when OBU type is valid, and 0 otherwise.
valid_obu_type(int obu_type)133 static int valid_obu_type(int obu_type) {
134     int valid_type = 0;
135     switch (obu_type) {
136     case OBU_SEQUENCE_HEADER:
137     case OBU_TEMPORAL_DELIMITER:
138     case OBU_FRAME_HEADER:
139     case OBU_TILE_GROUP:
140     case OBU_METADATA:
141     case OBU_FRAME:
142     case OBU_REDUNDANT_FRAME_HEADER:
143     case OBU_TILE_LIST:
144     case OBU_PADDING: valid_type = 1; break;
145     default: break;
146     }
147     return valid_type;
148 }
149 
150 // Parses OBU header and stores values in 'header'.
read_obu_header(ReadBitBuffer * rb,uint32_t is_annexb,ObuHeader * header)151 static int read_obu_header(ReadBitBuffer *rb, uint32_t is_annexb, ObuHeader *header) {
152     if (!rb || !header)
153         return -1;
154 
155     const ptrdiff_t bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer;
156     if (bit_buffer_byte_length < 1)
157         return -1;
158 
159     header->size = 1;
160 
161     if (rb_read_bit(rb) != 0) {
162         // Forbidden bit. Must not be set.
163         return -1;
164     }
165 
166     header->type = (OBU_TYPE)rb_read_literal(rb, 4);
167 
168     if (!valid_obu_type(header->type))
169         return -1;
170 
171     header->has_extension  = rb_read_bit(rb);
172     header->has_size_field = rb_read_bit(rb);
173 
174     if (!header->has_size_field && !is_annexb) {
175         // section 5 obu streams must have obu_size field set.
176         return -1;
177     }
178 
179     if (rb_read_bit(rb) != 0) {
180         // obu_reserved_1bit must be set to 0.
181         return -1;
182     }
183 
184     if (header->has_extension) {
185         if (bit_buffer_byte_length == 1)
186             return -1;
187 
188         header->size += 1;
189         header->temporal_layer_id = rb_read_literal(rb, 3);
190         header->spatial_layer_id  = rb_read_literal(rb, 2);
191         if (rb_read_literal(rb, 3) != 0) {
192             // extension_header_reserved_3bits must be set to 0.
193             return -1;
194         }
195     }
196 
197     return 0;
198 }
199 
svt_read_obu_header(uint8_t * buffer,size_t buffer_length,size_t * consumed,ObuHeader * header,uint32_t is_annexb)200 int svt_read_obu_header(uint8_t *buffer, size_t buffer_length, size_t *consumed, ObuHeader *header,
201                         uint32_t is_annexb) {
202     if (buffer_length < 1 || !consumed || !header)
203         return -1;
204 
205     ReadBitBuffer rb           = {buffer, buffer + buffer_length, 0};
206     int           parse_result = read_obu_header(&rb, is_annexb, header);
207     if (parse_result == 0)
208         *consumed = header->size;
209     return parse_result;
210 }
211 
212 // Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
213 // enough to store an OBU header with extension (2 bytes). Raw OBU data is
214 // written to 'obu_data', parsed OBU header values are written to 'obu_header',
215 // and total bytes read from file are written to 'bytes_read'. Returns 0 for
216 // success, and non-zero on failure. When end of file is reached, the return
217 // value is 0 and the 'bytes_read' value is set to 0.
obudec_read_obu_header(FILE * f,size_t buffer_capacity,uint32_t is_annexb,uint8_t * obu_data,ObuHeader * obu_header,size_t * bytes_read)218 static int obudec_read_obu_header(FILE *f, size_t buffer_capacity, uint32_t is_annexb,
219                                   uint8_t *obu_data, ObuHeader *obu_header, size_t *bytes_read) {
220     if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) || !obu_data ||
221         !obu_header || !bytes_read) {
222         return -1;
223     }
224     *bytes_read = fread(obu_data, 1, 1, f);
225 
226     if (feof(f) && *bytes_read == 0) {
227         return 0;
228     } else if (*bytes_read != 1) {
229         fprintf(stderr, "obudec: Failure reading OBU header.\n");
230         return -1;
231     }
232 
233     const int has_extension = (obu_data[0] >> 2) & 0x1;
234     if (has_extension) {
235         if (fread(&obu_data[1], 1, 1, f) != 1) {
236             fprintf(stderr, "obudec: Failure reading OBU extension.");
237             return -1;
238         }
239         ++*bytes_read;
240     }
241 
242     size_t obu_bytes_parsed = 0;
243     svt_read_obu_header(obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
244 
245     return 0;
246 }
247 
obudec_read_obu_header_and_size(FILE * f,size_t buffer_capacity,uint32_t is_annexb,uint8_t * buffer,size_t * bytes_read,size_t * payload_length,ObuHeader * obu_header)248 static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity, uint32_t is_annexb,
249                                            uint8_t *buffer, size_t *bytes_read,
250                                            size_t *payload_length, ObuHeader *obu_header) {
251     const size_t k_minimum_buffer_size = OBU_MAX_HEADER_SIZE;
252     if (!f || !buffer || !bytes_read || !payload_length || !obu_header ||
253         buffer_capacity < k_minimum_buffer_size) {
254         return -1;
255     }
256 
257     size_t   leb128_length_obu     = 0;
258     size_t   leb128_length_payload = 0;
259     uint64_t obu_size              = 0;
260     if (is_annexb) {
261         if (obudec_read_leb128(f, &buffer[0], &leb128_length_obu, &obu_size) != 0) {
262             fprintf(stderr, "obudec: Failure reading OBU size length.\n");
263             return -1;
264         } else if (leb128_length_obu == 0) {
265             *payload_length = 0;
266             return 0;
267         }
268         if (obu_size > UINT32_MAX) {
269             fprintf(stderr, "obudec: OBU payload length too large.\n");
270             return -1;
271         }
272     }
273 
274     size_t header_size = 0;
275     if (obudec_read_obu_header(f,
276                                buffer_capacity - leb128_length_obu,
277                                is_annexb,
278                                buffer + leb128_length_obu,
279                                obu_header,
280                                &header_size) != 0) {
281         return -1;
282     } else if (header_size == 0) {
283         *payload_length = 0;
284         return 0;
285     }
286 
287     if (!obu_header->has_size_field) {
288         assert(is_annexb);
289         if (obu_size < header_size) {
290             fprintf(stderr, "obudec: OBU size is too small.\n");
291             return -1;
292         }
293         *payload_length = (size_t)obu_size - header_size;
294     } else {
295         uint64_t u64_payload_length = 0;
296         if (obudec_read_leb128(f,
297                                &buffer[leb128_length_obu + header_size],
298                                &leb128_length_payload,
299                                &u64_payload_length) != 0) {
300             fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
301             return -1;
302         }
303         if (u64_payload_length > UINT32_MAX) {
304             fprintf(stderr, "obudec: OBU payload length too large.\n");
305             return -1;
306         }
307 
308         *payload_length = (size_t)u64_payload_length;
309     }
310 
311     *bytes_read = leb128_length_obu + header_size + leb128_length_payload;
312     return 0;
313 }
314 
315 // Reads OBU payload from 'f' and returns 0 for success when all payload bytes
316 // are read from the file. Payload data is written to 'obu_data', and actual
317 // bytes read added to 'bytes_read'.
obudec_read_obu_payload(FILE * f,size_t payload_length,uint8_t * obu_data,size_t * bytes_read)318 static int obudec_read_obu_payload(FILE *f, size_t payload_length, uint8_t *obu_data,
319                                    size_t *bytes_read) {
320     if (!f || payload_length == 0 || !obu_data || !bytes_read)
321         return -1;
322 
323     if (fread(obu_data, 1, payload_length, f) != payload_length) {
324         fprintf(stderr, "obudec: Failure reading OBU payload.\n");
325         return -1;
326     }
327 
328     *bytes_read += payload_length;
329     return 0;
330 }
331 
file_is_obu(CliInput * cli,ObuDecInputContext * obu_ctx)332 int file_is_obu(CliInput *cli, ObuDecInputContext *obu_ctx) {
333     if (!obu_ctx || !cli)
334         return 0;
335 
336     uint8_t        detect_buf[OBU_DETECTION_SIZE] = {0};
337     const uint32_t is_annexb                      = obu_ctx->is_annexb;
338     FILE *         f                              = cli->in_file;
339     size_t         payload_length                 = 0;
340     ObuHeader      obu_header;
341     memset(&obu_header, 0, sizeof(obu_header));
342     size_t   length_of_unit_size  = 0;
343     size_t   annexb_header_length = 0;
344     uint64_t unit_size            = 0;
345 
346     if (is_annexb) {
347         // read the size of first temporal unit
348         if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size, &unit_size) != 0) {
349             fprintf(stderr, "obudec: Failure reading temporal unit header\n");
350             return 0;
351         }
352 
353         // read the size of first frame unit
354         if (obudec_read_leb128(
355                 f, &detect_buf[length_of_unit_size], &annexb_header_length, &unit_size) != 0) {
356             fprintf(stderr, "obudec: Failure reading frame unit header\n");
357             return 0;
358         }
359         annexb_header_length += length_of_unit_size;
360     }
361 
362     size_t bytes_read = 0;
363     if (obudec_read_obu_header_and_size(f,
364                                         OBU_DETECTION_SIZE - annexb_header_length,
365                                         is_annexb,
366                                         &detect_buf[annexb_header_length],
367                                         &bytes_read,
368                                         &payload_length,
369                                         &obu_header) != 0) {
370         fprintf(stderr, "obudec: Failure reading first OBU.\n");
371         rewind(f);
372         return 0;
373     }
374 
375     if (is_annexb) {
376         bytes_read += annexb_header_length;
377     }
378 
379     if (obu_header.type != OBU_TEMPORAL_DELIMITER && obu_header.type != OBU_SEQUENCE_HEADER) {
380         return 0;
381     }
382 
383     if (obu_header.has_size_field) {
384         if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
385             fprintf(stderr, "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
386             rewind(f);
387             return 0;
388         }
389     } else if (!is_annexb) {
390         fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
391         rewind(f);
392         return 0;
393     }
394 
395     // Appears that input is valid Section 5 AV1 stream.
396     obu_ctx->buffer = (uint8_t *)malloc(OBU_BUFFER_SIZE);
397     if (!obu_ctx->buffer) {
398         fprintf(stderr, "Out of memory.\n");
399         rewind(f);
400         return 0;
401     }
402     obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
403 
404     memcpy(obu_ctx->buffer, &detect_buf[0], bytes_read);
405     obu_ctx->bytes_buffered = bytes_read;
406     // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
407     // We need to read this in so that our buffer only contains complete OBUs.
408     if (payload_length > 0) {
409         if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
410             fprintf(stderr, "obudec: First OBU's payload is too large\n");
411             rewind(f);
412             return 0;
413         }
414 
415         size_t    payload_bytes = 0;
416         const int status        = obudec_read_obu_payload(
417             f, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes);
418         if (status < 0) {
419             rewind(f);
420             return 0;
421         }
422         obu_ctx->bytes_buffered += payload_bytes;
423     }
424 
425     /* This is because to avoid to many conditions while reading
426     frame by frame information in TU's */
427     if (is_annexb) {
428         rewind(f);
429         obu_ctx->bytes_buffered = 0;
430     }
431     return 1;
432 }
433 
obudec_grow_buffer(size_t growth_amount,uint8_t ** obu_buffer,size_t * obu_buffer_capacity)434 static int obudec_grow_buffer(size_t growth_amount, uint8_t **obu_buffer,
435                               size_t *obu_buffer_capacity) {
436     if (!*obu_buffer || !obu_buffer_capacity || growth_amount == 0) {
437         return -1;
438     }
439 
440     const size_t capacity = *obu_buffer_capacity;
441     if (SIZE_MAX - growth_amount < capacity) {
442         fprintf(stderr, "obudec: cannot grow buffer, capacity will roll over.\n");
443         return -1;
444     }
445 
446     const size_t new_capacity = capacity + growth_amount;
447 
448     uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);
449     if (!new_buffer) {
450         fprintf(stderr, "obudec: Failed to allocate compressed data buffer.\n");
451         return -1;
452     }
453 
454     *obu_buffer          = new_buffer;
455     *obu_buffer_capacity = new_capacity;
456     return 0;
457 }
458 
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,uint32_t is_annexb)459 static int obudec_read_one_obu(FILE *f, uint8_t **obu_buffer, size_t obu_bytes_buffered,
460                                size_t *obu_buffer_capacity, size_t *obu_length,
461                                ObuHeader *obu_header, uint32_t is_annexb) {
462     if (!f || !(*obu_buffer) || !obu_buffer_capacity || !obu_length || !obu_header) {
463         return -1;
464     }
465 
466     size_t bytes_read                = 0;
467     size_t obu_payload_length        = 0;
468     size_t available_buffer_capacity = *obu_buffer_capacity - obu_bytes_buffered;
469 
470     if (available_buffer_capacity < OBU_MAX_HEADER_SIZE) {
471         if (obudec_grow_buffer(DECAPP_MAX(*obu_buffer_capacity, OBU_MAX_HEADER_SIZE),
472                                obu_buffer,
473                                obu_buffer_capacity) != 0) {
474             *obu_length = bytes_read;
475             return -1;
476         }
477         available_buffer_capacity += DECAPP_MAX(*obu_buffer_capacity, OBU_MAX_HEADER_SIZE);
478     }
479 
480     const int status = obudec_read_obu_header_and_size(f,
481                                                        available_buffer_capacity,
482                                                        is_annexb,
483                                                        *obu_buffer + obu_bytes_buffered,
484                                                        &bytes_read,
485                                                        &obu_payload_length,
486                                                        obu_header);
487     if (status < 0)
488         return status;
489 
490     if (obu_payload_length > SIZE_MAX - bytes_read)
491         return -1;
492 
493     if (obu_payload_length > 256 * 1024 * 1024) {
494         fprintf(stderr, "obudec: Read invalid OBU size (%u)\n", (unsigned int)obu_payload_length);
495         *obu_length = bytes_read + obu_payload_length;
496         return -1;
497     }
498 
499     if (bytes_read + obu_payload_length > available_buffer_capacity &&
500         obudec_grow_buffer(DECAPP_MAX(*obu_buffer_capacity, obu_payload_length),
501                            obu_buffer,
502                            obu_buffer_capacity) != 0) {
503         *obu_length = bytes_read + obu_payload_length;
504         return -1;
505     }
506 
507     if (obu_payload_length > 0 &&
508         obudec_read_obu_payload(
509             f, obu_payload_length, *obu_buffer + obu_bytes_buffered + bytes_read, &bytes_read) !=
510             0) {
511         return -1;
512     }
513 
514     *obu_length = bytes_read;
515     return 0;
516 }
517 
obudec_read_temporal_unit(DecInputContext * input,uint8_t ** buffer,size_t * bytes_read,size_t * buffer_size)518 int obudec_read_temporal_unit(DecInputContext *input, uint8_t **buffer, size_t *bytes_read,
519                               size_t *buffer_size) {
520     CliInput *          cli     = input->cli_ctx;
521     FILE *              f       = cli->in_file;
522     ObuDecInputContext *obu_ctx = input->obu_ctx;
523     if (!f)
524         return 0;
525 
526     *buffer_size = 0;
527     *bytes_read  = 0;
528 
529     if (feof(f)) {
530         return 0;
531     }
532 
533     size_t txb_size = 0, fr_size = 0;
534     size_t obu_size                     = 0;
535     size_t length_of_temporal_unit_size = 0;
536     size_t length_of_frame_unit_size    = 0;
537 
538     if (obu_ctx->is_annexb) {
539         uint64_t size                                = 0;
540         uint8_t  frheader[OBU_MAX_LENGTH_FIELD_SIZE] = {0};
541 
542         assert(obu_ctx->bytes_buffered == 0);
543 
544         if (!obu_ctx->rem_txb_size) {
545             if (obudec_read_leb128(f, &frheader[0], &length_of_temporal_unit_size, &size) != 0) {
546                 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
547                 return 0;
548             }
549             if (size == 0 && feof(f)) {
550                 return 0;
551             }
552             /*Stores only tu size ie excluding tu header*/
553             obu_ctx->rem_txb_size = size;
554         }
555 
556         if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
557             fprintf(stderr, "obudec: TU too large.\n");
558             return 0;
559         }
560 
561         if (obudec_read_leb128(f, &frheader[0], &length_of_frame_unit_size, &size) != 0) {
562             fprintf(stderr, "obudec: Failure reading frame header\n");
563             return 0;
564         }
565         if (size == 0 || feof(f)) {
566             return 0;
567         }
568 
569         fr_size  = (size_t)size;
570         txb_size = fr_size;
571     } else {
572         while (1) {
573             ObuHeader obu_header;
574             memset(&obu_header, 0, sizeof(obu_header));
575 
576             if (obudec_read_one_obu(f,
577                                     &obu_ctx->buffer,
578                                     obu_ctx->bytes_buffered,
579                                     &obu_ctx->buffer_capacity,
580                                     &obu_size,
581                                     &obu_header,
582                                     0) != 0) {
583                 fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
584                 return 0;
585             }
586 
587             if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0) {
588                 txb_size = obu_ctx->bytes_buffered;
589                 break;
590             } else {
591                 obu_ctx->bytes_buffered += obu_size;
592             }
593         }
594     }
595 
596     uint8_t *new_buffer = (uint8_t *)realloc(*buffer, txb_size);
597     if (!new_buffer) {
598         free(*buffer);
599         fprintf(stderr, "obudec: Out of memory.\n");
600         return 0;
601     }
602     *buffer      = new_buffer;
603     *bytes_read  = txb_size;
604     *buffer_size = txb_size;
605 
606     if (!obu_ctx->is_annexb) {
607         memcpy(*buffer, obu_ctx->buffer, txb_size);
608 
609         // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
610         // points to the end of the buffer.
611         memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered, obu_size);
612         obu_ctx->bytes_buffered = obu_size;
613     } else {
614         if (!feof(f)) {
615             if (fread(*buffer, 1, fr_size, f) != fr_size) {
616                 fprintf(stderr, "obudec: Failed to read full temporal unit\n");
617                 return 0;
618             }
619             obu_ctx->rem_txb_size -= (fr_size + length_of_frame_unit_size);
620         }
621     }
622     return 1;
623 }
624 
file_is_ivf(CliInput * cli)625 int file_is_ivf(CliInput *cli) {
626     char raw_hdr[32];
627     int  is_ivf = 0;
628 
629     if (fread(raw_hdr, 1, 32, cli->in_file) == 32) {
630         if (memcmp(ivf_signature, raw_hdr, 4) == 0) {
631             is_ivf = 1;
632 
633             if (mem_get_le16(raw_hdr + 4) != 0) {
634                 fprintf(stderr,
635                         "Error: Unrecognized IVF version! This file may not"
636                         " decode properly.");
637             }
638 
639             cli->fourcc                = mem_get_le32(raw_hdr + 8);
640             cli->width                 = mem_get_le16(raw_hdr + 12);
641             cli->height                = mem_get_le16(raw_hdr + 14);
642             cli->framerate.numerator   = mem_get_le32(raw_hdr + 16);
643             cli->framerate.denominator = mem_get_le32(raw_hdr + 20);
644             fix_framerate(&cli->framerate.numerator, &cli->framerate.denominator);
645         }
646     }
647 
648     if (!is_ivf) {
649         rewind(cli->in_file);
650         cli->detect.buf_read = 0;
651     } else
652         cli->detect.position = 4;
653     return is_ivf;
654 }
655 
read_ivf_frame(FILE * infile,uint8_t ** buffer,size_t * bytes_read,size_t * buffer_size,int64_t * pts)656 int read_ivf_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read, size_t *buffer_size,
657                    int64_t *pts) {
658     char   raw_header[IVF_FRAME_HDR_SZ] = {0};
659     size_t frame_size                   = 0;
660 
661     if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
662         if (!feof(infile))
663             fprintf(stderr, "Failed to read frame size. \n");
664     } else {
665         frame_size = mem_get_le32(raw_header);
666 
667         if (frame_size > 256 * 1024 * 1024) {
668             fprintf(stderr, "Read invalid frame size (%u) \n", (unsigned int)frame_size);
669             frame_size = 0;
670         }
671 
672         if (frame_size > *buffer_size) {
673             uint8_t *new_buffer = (uint8_t *)realloc(*buffer, 2 * frame_size);
674 
675             if (new_buffer) {
676                 *buffer      = new_buffer;
677                 *buffer_size = 2 * frame_size;
678             } else {
679                 fprintf(stderr, "Failed to allocate compressed data buffer. \n");
680                 frame_size = 0;
681             }
682         }
683 
684         if (pts) {
685             *pts = mem_get_le32(&raw_header[4]);
686             *pts += ((int64_t)mem_get_le32(&raw_header[8]) << 32);
687         }
688     }
689 
690     if (!feof(infile)) {
691         if (fread(*buffer, 1, frame_size, infile) != frame_size) {
692             fprintf(stderr, "Failed to read full frame. \n");
693             return 0;
694         }
695         *bytes_read = frame_size;
696         return 1;
697     }
698     return 0;
699 }
700