2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
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.
18 #include "aom_ports/mem_ops.h"
19 #include "av1/common/common.h"
20 #include "av1/decoder/obu.h"
22 #define OBU_BUFFER_SIZE (500 * 1024)
24 #define OBU_HEADER_SIZE 1
25 #define OBU_EXTENSION_SIZE 1
26 #define OBU_MAX_LENGTH_FIELD_SIZE 8
27 #define OBU_DETECTION_SIZE \
28 (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 3 * OBU_MAX_LENGTH_FIELD_SIZE)
30 // Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
31 // Stores raw bytes in 'value_buffer', length of the number in 'value_length',
32 // and decoded value in 'value'.
33 static int obudec_read_leb128(FILE *f
, uint8_t *value_buffer
,
34 size_t *value_length
, uint64_t *value
) {
35 if (!f
|| !value_buffer
|| !value_length
|| !value
) return -1;
37 for (len
= 0; len
< OBU_MAX_LENGTH_FIELD_SIZE
; ++len
) {
38 const size_t num_read
= fread(&value_buffer
[len
], 1, 1, f
);
40 if (len
== 0 && feof(f
)) {
44 // Ran out of data before completing read of value.
47 if ((value_buffer
[len
] >> 7) == 0) {
54 return aom_uleb_decode(value_buffer
, len
, value
, NULL
);
57 // Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
58 // enough to store an OBU header with extension (2 bytes). Raw OBU data is
59 // written to 'obu_data', parsed OBU header values are written to 'obu_header',
60 // and total bytes read from file are written to 'bytes_read'. Returns 0 for
61 // success, and non-zero on failure. When end of file is reached, the return
62 // value is 0 and the 'bytes_read' value is set to 0.
63 static int obudec_read_obu_header(FILE *f
, size_t buffer_capacity
,
64 int is_annexb
, uint8_t *obu_data
,
65 ObuHeader
*obu_header
, size_t *bytes_read
) {
66 if (!f
|| buffer_capacity
< (OBU_HEADER_SIZE
+ OBU_EXTENSION_SIZE
) ||
67 !obu_data
|| !obu_header
|| !bytes_read
) {
70 *bytes_read
= fread(obu_data
, 1, 1, f
);
72 if (feof(f
) && *bytes_read
== 0) {
74 } else if (*bytes_read
!= 1) {
75 fprintf(stderr
, "obudec: Failure reading OBU header.\n");
79 const int has_extension
= (obu_data
[0] >> 2) & 0x1;
81 if (fread(&obu_data
[1], 1, 1, f
) != 1) {
82 fprintf(stderr
, "obudec: Failure reading OBU extension.");
88 size_t obu_bytes_parsed
= 0;
89 const aom_codec_err_t parse_result
= aom_read_obu_header(
90 obu_data
, *bytes_read
, &obu_bytes_parsed
, obu_header
, is_annexb
);
91 if (parse_result
!= AOM_CODEC_OK
|| *bytes_read
!= obu_bytes_parsed
) {
92 fprintf(stderr
, "obudec: Error parsing OBU header.\n");
99 // Reads OBU payload from 'f' and returns 0 for success when all payload bytes
100 // are read from the file. Payload data is written to 'obu_data', and actual
101 // bytes read added to 'bytes_read'.
102 static int obudec_read_obu_payload(FILE *f
, size_t payload_length
,
103 uint8_t *obu_data
, size_t *bytes_read
) {
104 if (!f
|| payload_length
== 0 || !obu_data
|| !bytes_read
) return -1;
106 if (fread(obu_data
, 1, payload_length
, f
) != payload_length
) {
107 fprintf(stderr
, "obudec: Failure reading OBU payload.\n");
111 *bytes_read
+= payload_length
;
115 static int obudec_read_obu_header_and_size(FILE *f
, size_t buffer_capacity
,
116 int is_annexb
, uint8_t *buffer
,
118 size_t *payload_length
,
119 ObuHeader
*obu_header
) {
120 const size_t kMinimumBufferSize
=
121 (OBU_HEADER_SIZE
+ OBU_EXTENSION_SIZE
+ OBU_MAX_LENGTH_FIELD_SIZE
);
122 if (!f
|| !buffer
|| !bytes_read
|| !payload_length
|| !obu_header
||
123 buffer_capacity
< kMinimumBufferSize
) {
127 size_t leb128_length
= 0;
128 uint64_t obu_size
= 0;
130 if (obudec_read_leb128(f
, &buffer
[0], &leb128_length
, &obu_size
) != 0) {
131 fprintf(stderr
, "obudec: Failure reading OBU size length.\n");
133 } else if (leb128_length
== 0) {
137 if (obu_size
> UINT32_MAX
) {
138 fprintf(stderr
, "obudec: OBU payload length too large.\n");
143 size_t header_size
= 0;
144 if (obudec_read_obu_header(f
, buffer_capacity
- leb128_length
, is_annexb
,
145 buffer
+ leb128_length
, obu_header
,
146 &header_size
) != 0) {
148 } else if (header_size
== 0) {
154 if (obu_size
< header_size
) {
155 fprintf(stderr
, "obudec: OBU size is too small.\n");
158 *payload_length
= (size_t)obu_size
- header_size
;
160 uint64_t u64_payload_length
= 0;
161 if (obudec_read_leb128(f
, &buffer
[header_size
], &leb128_length
,
162 &u64_payload_length
) != 0) {
163 fprintf(stderr
, "obudec: Failure reading OBU payload length.\n");
166 if (u64_payload_length
> UINT32_MAX
) {
167 fprintf(stderr
, "obudec: OBU payload length too large.\n");
171 *payload_length
= (size_t)u64_payload_length
;
174 *bytes_read
= leb128_length
+ header_size
;
178 static int obudec_read_one_obu(FILE *f
, uint8_t **obu_buffer
,
179 size_t obu_bytes_buffered
,
180 size_t *obu_buffer_capacity
, size_t *obu_length
,
181 ObuHeader
*obu_header
, int is_annexb
) {
182 size_t available_buffer_capacity
= *obu_buffer_capacity
- obu_bytes_buffered
;
184 if (!(*obu_buffer
)) return -1;
186 size_t bytes_read
= 0;
187 size_t obu_payload_length
= 0;
188 const int status
= obudec_read_obu_header_and_size(
189 f
, available_buffer_capacity
, is_annexb
, *obu_buffer
+ obu_bytes_buffered
,
190 &bytes_read
, &obu_payload_length
, obu_header
);
191 if (status
< 0) return status
;
193 if (obu_payload_length
> SIZE_MAX
- bytes_read
) return -1;
195 if (obu_payload_length
> 256 * 1024 * 1024) {
196 fprintf(stderr
, "obudec: Read invalid OBU size (%u)\n",
197 (unsigned int)obu_payload_length
);
198 *obu_length
= bytes_read
+ obu_payload_length
;
202 if (bytes_read
+ obu_payload_length
> available_buffer_capacity
) {
203 // TODO(tomfinegan): Add overflow check.
204 const size_t new_capacity
=
205 obu_bytes_buffered
+ bytes_read
+ 2 * obu_payload_length
;
207 #if defined AOM_MAX_ALLOCABLE_MEMORY
208 if (new_capacity
> AOM_MAX_ALLOCABLE_MEMORY
) {
209 fprintf(stderr
, "obudec: OBU size exceeds max alloc size.\n");
214 uint8_t *new_buffer
= (uint8_t *)realloc(*obu_buffer
, new_capacity
);
217 *obu_buffer
= new_buffer
;
218 *obu_buffer_capacity
= new_capacity
;
220 fprintf(stderr
, "obudec: Failed to allocate compressed data buffer\n");
221 *obu_length
= bytes_read
+ obu_payload_length
;
226 if (obu_payload_length
> 0 &&
227 obudec_read_obu_payload(f
, obu_payload_length
,
228 *obu_buffer
+ obu_bytes_buffered
+ bytes_read
,
233 *obu_length
= bytes_read
;
237 int file_is_obu(struct ObuDecInputContext
*obu_ctx
) {
238 if (!obu_ctx
|| !obu_ctx
->avx_ctx
) return 0;
240 struct AvxInputContext
*avx_ctx
= obu_ctx
->avx_ctx
;
241 uint8_t detect_buf
[OBU_DETECTION_SIZE
] = { 0 };
242 const int is_annexb
= obu_ctx
->is_annexb
;
243 FILE *f
= avx_ctx
->file
;
244 size_t payload_length
= 0;
245 ObuHeader obu_header
;
246 memset(&obu_header
, 0, sizeof(obu_header
));
247 size_t length_of_unit_size
= 0;
248 size_t annexb_header_length
= 0;
249 uint64_t unit_size
= 0;
252 // read the size of first temporal unit
253 if (obudec_read_leb128(f
, &detect_buf
[0], &length_of_unit_size
,
255 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
259 // read the size of first frame unit
260 if (obudec_read_leb128(f
, &detect_buf
[length_of_unit_size
],
261 &annexb_header_length
, &unit_size
) != 0) {
262 fprintf(stderr
, "obudec: Failure reading frame unit header\n");
265 annexb_header_length
+= length_of_unit_size
;
268 size_t bytes_read
= 0;
269 if (obudec_read_obu_header_and_size(
270 f
, OBU_DETECTION_SIZE
- annexb_header_length
, is_annexb
,
271 &detect_buf
[annexb_header_length
], &bytes_read
, &payload_length
,
273 fprintf(stderr
, "obudec: Failure reading first OBU.\n");
279 bytes_read
+= annexb_header_length
;
282 if (obu_header
.type
!= OBU_TEMPORAL_DELIMITER
&&
283 obu_header
.type
!= OBU_SEQUENCE_HEADER
) {
287 if (obu_header
.has_length_field
) {
288 if (obu_header
.type
== OBU_TEMPORAL_DELIMITER
&& payload_length
!= 0) {
291 "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
295 } else if (!is_annexb
) {
296 fprintf(stderr
, "obudec: OBU size fields required, cannot decode input.\n");
301 // Appears that input is valid Section 5 AV1 stream.
302 obu_ctx
->buffer
= (uint8_t *)malloc(OBU_BUFFER_SIZE
);
303 if (!obu_ctx
->buffer
) {
304 fprintf(stderr
, "Out of memory.\n");
308 obu_ctx
->buffer_capacity
= OBU_BUFFER_SIZE
;
310 memcpy(obu_ctx
->buffer
, &detect_buf
[0], bytes_read
);
311 obu_ctx
->bytes_buffered
= bytes_read
;
312 // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
313 // We need to read this in so that our buffer only contains complete OBUs.
314 if (payload_length
> 0) {
315 if (payload_length
> (obu_ctx
->buffer_capacity
- bytes_read
)) {
316 fprintf(stderr
, "obudec: First OBU's payload is too large\n");
321 size_t payload_bytes
= 0;
322 const int status
= obudec_read_obu_payload(
323 f
, payload_length
, &obu_ctx
->buffer
[bytes_read
], &payload_bytes
);
328 obu_ctx
->bytes_buffered
+= payload_bytes
;
333 int obudec_read_temporal_unit(struct ObuDecInputContext
*obu_ctx
,
334 uint8_t **buffer
, size_t *bytes_read
,
335 size_t *buffer_size
) {
336 FILE *f
= obu_ctx
->avx_ctx
->file
;
348 size_t length_of_temporal_unit_size
= 0;
349 uint8_t tuheader
[OBU_MAX_LENGTH_FIELD_SIZE
] = { 0 };
351 if (obu_ctx
->is_annexb
) {
354 if (obu_ctx
->bytes_buffered
== 0) {
355 if (obudec_read_leb128(f
, &tuheader
[0], &length_of_temporal_unit_size
,
357 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
360 if (size
== 0 && feof(f
)) {
364 // temporal unit size was already stored in buffer
365 if (aom_uleb_decode(obu_ctx
->buffer
, obu_ctx
->bytes_buffered
, &size
,
366 &length_of_temporal_unit_size
) != 0) {
367 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
372 if (size
> UINT32_MAX
|| size
+ length_of_temporal_unit_size
> UINT32_MAX
) {
373 fprintf(stderr
, "obudec: TU too large.\n");
377 size
+= length_of_temporal_unit_size
;
378 tu_size
= (size_t)size
;
381 ObuHeader obu_header
;
382 memset(&obu_header
, 0, sizeof(obu_header
));
384 if (obudec_read_one_obu(f
, &obu_ctx
->buffer
, obu_ctx
->bytes_buffered
,
385 &obu_ctx
->buffer_capacity
, &obu_size
, &obu_header
,
387 fprintf(stderr
, "obudec: read_one_obu failed in TU loop\n");
391 if (obu_header
.type
== OBU_TEMPORAL_DELIMITER
|| obu_size
== 0 ||
392 (obu_header
.has_extension
&&
393 obu_header
.enhancement_layer_id
> obu_ctx
->last_layer_id
)) {
394 tu_size
= obu_ctx
->bytes_buffered
;
397 obu_ctx
->bytes_buffered
+= obu_size
;
402 #if defined AOM_MAX_ALLOCABLE_MEMORY
403 if (tu_size
> AOM_MAX_ALLOCABLE_MEMORY
) {
404 fprintf(stderr
, "obudec: Temporal Unit size exceeds max alloc size.\n");
408 uint8_t *new_buffer
= (uint8_t *)realloc(*buffer
, tu_size
);
411 fprintf(stderr
, "obudec: Out of memory.\n");
414 *buffer
= new_buffer
;
415 *bytes_read
= tu_size
;
416 *buffer_size
= tu_size
;
418 if (!obu_ctx
->is_annexb
) {
419 memcpy(*buffer
, obu_ctx
->buffer
, tu_size
);
421 // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
422 // points to the end of the buffer.
423 memmove(obu_ctx
->buffer
, obu_ctx
->buffer
+ obu_ctx
->bytes_buffered
,
425 obu_ctx
->bytes_buffered
= obu_size
;
430 if (!obu_ctx
->bytes_buffered
) {
431 data_size
= tu_size
- length_of_temporal_unit_size
;
432 memcpy(*buffer
, &tuheader
[0], length_of_temporal_unit_size
);
433 offset
= length_of_temporal_unit_size
;
435 memcpy(*buffer
, obu_ctx
->buffer
, obu_ctx
->bytes_buffered
);
436 offset
= obu_ctx
->bytes_buffered
;
437 data_size
= tu_size
- obu_ctx
->bytes_buffered
;
438 obu_ctx
->bytes_buffered
= 0;
441 if (fread(*buffer
+ offset
, 1, data_size
, f
) != data_size
) {
442 fprintf(stderr
, "obudec: Failed to read full temporal unit\n");
450 void obudec_free(struct ObuDecInputContext
*obu_ctx
) { free(obu_ctx
->buffer
); }