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