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 + 2 * 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;
36 for (int len
= 0; len
< OBU_MAX_LENGTH_FIELD_SIZE
; ++len
) {
37 const size_t num_read
= fread(&value_buffer
[len
], 1, 1, f
);
38 if (num_read
== 0 && feof(f
)) {
43 // Ran out of data before completing read of value.
46 if ((value_buffer
[len
] >> 7) == 0) {
47 *value_length
= (size_t)(len
+ 1);
52 return aom_uleb_decode(value_buffer
, OBU_MAX_LENGTH_FIELD_SIZE
, value
, NULL
);
55 // Reads OBU size from infile and returns 0 upon success. Returns obu_size via
56 // output pointer obu_size. Returns -1 when reading or parsing fails. Always
57 // returns FILE pointer to position at time of call. Returns 0 and sets obu_size
58 // to 0 when end of file is reached.
59 static int obudec_read_obu_size(FILE *infile
, uint64_t *obu_size
,
60 size_t *length_field_size
) {
61 if (!infile
|| !obu_size
) return 1;
63 uint8_t read_buffer
[OBU_MAX_LENGTH_FIELD_SIZE
] = { 0 };
64 size_t bytes_read
= fread(read_buffer
, 1, OBU_MAX_LENGTH_FIELD_SIZE
, infile
);
67 if (bytes_read
== 0) {
71 const int seek_pos
= (int)bytes_read
;
72 if (seek_pos
!= 0 && fseek(infile
, -seek_pos
, SEEK_CUR
) != 0) return 1;
74 if (aom_uleb_decode(read_buffer
, bytes_read
, obu_size
, length_field_size
) !=
82 // Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
83 // enough to store an OBU header with extension (2 bytes). Raw OBU data is
84 // written to 'obu_data', parsed OBU header values are written to 'obu_header',
85 // and total bytes read from file are written to 'bytes_read'. Returns 0 for
86 // success, and non-zero on failure. When end of file is reached, the return
87 // value is 0 and the 'bytes_read' value is set to 0.
88 static int obudec_read_obu_header(FILE *f
, size_t buffer_capacity
,
89 int is_annexb
, uint8_t *obu_data
,
90 ObuHeader
*obu_header
, size_t *bytes_read
) {
91 if (!f
|| buffer_capacity
< (OBU_HEADER_SIZE
+ OBU_EXTENSION_SIZE
) ||
92 !obu_data
|| !obu_header
|| !bytes_read
) {
95 *bytes_read
= fread(obu_data
, 1, 1, f
);
97 if (feof(f
) && *bytes_read
== 0) {
99 } else if (*bytes_read
!= 1) {
100 fprintf(stderr
, "obudec: Failure reading OBU header.\n");
104 const int has_extension
= (obu_data
[0] >> 2) & 0x1;
106 if (fread(&obu_data
[1], 1, 1, f
) != 1) {
107 fprintf(stderr
, "obudec: Failure reading OBU extension.");
113 size_t obu_bytes_parsed
= 0;
114 const aom_codec_err_t parse_result
= aom_read_obu_header(
115 obu_data
, *bytes_read
, &obu_bytes_parsed
, obu_header
, is_annexb
);
116 if (parse_result
!= AOM_CODEC_OK
|| *bytes_read
!= obu_bytes_parsed
) {
117 fprintf(stderr
, "obudec: Error parsing OBU header.\n");
124 // Reads OBU payload from 'f' and returns 0 for success when all payload bytes
125 // are read from the file. Payload data is written to 'obu_data', and actual
126 // bytes read written to 'bytes_read'.
127 static int obudec_read_obu_payload(FILE *f
, uint64_t payload_length
,
128 uint8_t *obu_data
, size_t *bytes_read
) {
129 if (!f
|| payload_length
== 0 || !obu_data
|| !bytes_read
) return -1;
131 if (fread(obu_data
, 1, (size_t)payload_length
, f
) != payload_length
) {
132 fprintf(stderr
, "obudec: Failure reading OBU payload.\n");
136 *bytes_read
+= (size_t)payload_length
;
140 static int obudec_read_one_obu(FILE *f
, size_t buffer_capacity
, int is_annexb
,
141 uint8_t *obu_data
, uint64_t *obu_length
,
142 ObuHeader
*obu_header
) {
143 const size_t kMinimumBufferSize
= OBU_DETECTION_SIZE
;
144 if (!f
|| !obu_data
|| !obu_length
|| !obu_header
||
145 buffer_capacity
< kMinimumBufferSize
) {
149 uint64_t obu_payload_length
= 0;
150 size_t leb128_length
= 0;
151 uint64_t obu_size
= 0;
153 if (obudec_read_leb128(f
, &obu_data
[0], &leb128_length
, &obu_size
) != 0) {
154 fprintf(stderr
, "obudec: Failure reading OBU size length.\n");
156 } else if (leb128_length
== 0) {
162 size_t bytes_read
= 0;
163 if (obudec_read_obu_header(f
, buffer_capacity
, is_annexb
,
164 obu_data
+ leb128_length
, obu_header
,
167 } else if (bytes_read
== 0) {
173 if (obudec_read_leb128(f
, &obu_data
[bytes_read
], &leb128_length
,
174 &obu_payload_length
) != 0) {
175 fprintf(stderr
, "obudec: Failure reading OBU payload length.\n");
181 obu_payload_length
= obu_size
- bytes_read
;
184 bytes_read
+= leb128_length
;
186 if (UINT64_MAX
- bytes_read
< obu_payload_length
) return -1;
187 if (bytes_read
+ obu_payload_length
> buffer_capacity
) {
188 *obu_length
= bytes_read
+ obu_payload_length
;
192 if (obu_payload_length
> 0 &&
193 obudec_read_obu_payload(f
, obu_payload_length
, &obu_data
[bytes_read
],
198 *obu_length
= bytes_read
;
202 int file_is_obu(struct ObuDecInputContext
*obu_ctx
) {
203 if (!obu_ctx
|| !obu_ctx
->avx_ctx
) return 0;
205 struct AvxInputContext
*avx_ctx
= obu_ctx
->avx_ctx
;
206 uint8_t detect_buf
[OBU_DETECTION_SIZE
] = { 0 };
207 const int is_annexb
= obu_ctx
->is_annexb
;
208 FILE *f
= avx_ctx
->file
;
209 uint64_t obu_length
= 0;
210 ObuHeader obu_header
;
211 memset(&obu_header
, 0, sizeof(obu_header
));
212 size_t length_of_unit_size
= 0;
214 size_t annexb_header_length
= 0;
217 // read the size of first temporal unit
218 if (obudec_read_leb128(f
, &detect_buf
[0], &length_of_unit_size
,
220 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
224 // read the size of first frame unit
225 if (obudec_read_leb128(f
, &detect_buf
[length_of_unit_size
],
226 &annexb_header_length
, &unit_size
) != 0) {
227 fprintf(stderr
, "obudec: Failure reading frame unit header\n");
230 annexb_header_length
+= length_of_unit_size
;
233 if (obudec_read_one_obu(f
, OBU_DETECTION_SIZE
, is_annexb
,
234 &detect_buf
[annexb_header_length
], &obu_length
,
236 fprintf(stderr
, "obudec: Failure reading first OBU.\n");
241 if (obu_header
.type
!= OBU_TEMPORAL_DELIMITER
) return 0;
243 if (obu_header
.has_length_field
) {
244 uint64_t obu_payload_length
= 0;
245 size_t leb128_length
= 0;
246 const size_t obu_length_offset
= obu_header
.has_length_field
? 1 : 2;
247 if (aom_uleb_decode(&detect_buf
[obu_length_offset
], sizeof(leb128_length
),
248 &obu_payload_length
, &leb128_length
) != 0) {
249 fprintf(stderr
, "obudec: Failure decoding OBU payload length.\n");
253 if (obu_payload_length
!= 0) {
256 "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
260 } else if (!is_annexb
) {
261 fprintf(stderr
, "obudec: OBU size fields required, cannot decode input.\n");
266 // Appears that input is valid Section 5 AV1 stream.
267 obu_ctx
->buffer
= (uint8_t *)calloc(OBU_BUFFER_SIZE
, 1);
268 if (!obu_ctx
->buffer
) {
269 fprintf(stderr
, "Out of memory.\n");
273 obu_ctx
->buffer_capacity
= OBU_BUFFER_SIZE
;
276 obu_length
+= annexb_header_length
;
278 memcpy(obu_ctx
->buffer
, &detect_buf
[0], (size_t)obu_length
);
279 obu_ctx
->bytes_buffered
= (size_t)obu_length
;
284 int obudec_read_temporal_unit(struct ObuDecInputContext
*obu_ctx
,
285 uint8_t **buffer
, size_t *bytes_read
,
286 size_t *buffer_size
) {
287 FILE *f
= obu_ctx
->avx_ctx
->file
;
298 uint64_t obu_size
= 0;
299 uint8_t *data
= obu_ctx
->buffer
;
300 size_t length_of_temporal_unit_size
= 0;
301 uint8_t tuheader
[OBU_MAX_LENGTH_FIELD_SIZE
] = { 0 };
303 if (obu_ctx
->is_annexb
) {
306 if (obu_ctx
->bytes_buffered
== 0) {
307 if (obudec_read_leb128(f
, &tuheader
[0], &length_of_temporal_unit_size
,
309 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
312 if (size
== 0 && feof(f
)) {
316 // temporal unit size was already stored in buffer
317 if (aom_uleb_decode(obu_ctx
->buffer
, obu_ctx
->bytes_buffered
, &size
,
318 &length_of_temporal_unit_size
) != 0) {
319 fprintf(stderr
, "obudec: Failure reading temporal unit header\n");
324 size
+= length_of_temporal_unit_size
;
325 tu_size
= (size_t)size
;
328 ObuHeader obu_header
;
329 memset(&obu_header
, 0, sizeof(obu_header
));
331 data
= obu_ctx
->buffer
+ obu_ctx
->bytes_buffered
;
332 const size_t capacity
=
333 obu_ctx
->buffer_capacity
- obu_ctx
->bytes_buffered
;
335 if (obudec_read_one_obu(f
, capacity
, 0, data
, &obu_size
, &obu_header
) !=
337 fprintf(stderr
, "obudec: read_one_obu failed in TU loop\n");
341 if (obu_header
.type
== OBU_TEMPORAL_DELIMITER
|| obu_size
== 0 ||
342 (obu_header
.has_extension
&&
343 obu_header
.enhancement_layer_id
> obu_ctx
->last_layer_id
)) {
344 tu_size
= obu_ctx
->bytes_buffered
;
347 obu_ctx
->bytes_buffered
+= (size_t)obu_size
;
352 #if defined AOM_MAX_ALLOCABLE_MEMORY
353 if (tu_size
> AOM_MAX_ALLOCABLE_MEMORY
) {
354 fprintf(stderr
, "obudec: Temporal Unit size exceeds max alloc size.\n");
358 uint8_t *new_buffer
= (uint8_t *)realloc(*buffer
, tu_size
);
361 fprintf(stderr
, "obudec: Out of memory.\n");
364 *buffer
= new_buffer
;
365 *bytes_read
= tu_size
;
366 *buffer_size
= tu_size
;
368 if (!obu_ctx
->is_annexb
) {
369 memcpy(*buffer
, obu_ctx
->buffer
, tu_size
);
370 memmove(obu_ctx
->buffer
, data
, (size_t)obu_size
);
371 obu_ctx
->bytes_buffered
= (size_t)obu_size
;
376 if (!obu_ctx
->bytes_buffered
) {
377 data_size
= (uint32_t)(tu_size
- length_of_temporal_unit_size
);
378 memcpy(*buffer
, &tuheader
[0], length_of_temporal_unit_size
);
379 offset
= length_of_temporal_unit_size
;
381 memcpy(*buffer
, obu_ctx
->buffer
, obu_ctx
->bytes_buffered
);
382 offset
= obu_ctx
->bytes_buffered
;
383 data_size
= tu_size
- obu_ctx
->bytes_buffered
;
384 obu_ctx
->bytes_buffered
= 0;
387 if (fread(new_buffer
+ offset
, 1, data_size
, f
) != data_size
) {
388 fprintf(stderr
, "obudec: Failed to read full temporal unit\n");
396 void obudec_free(struct ObuDecInputContext
*obu_ctx
) { free(obu_ctx
->buffer
); }