BUG FIX: av1_quantize_fp_sse2() matches the c/avx2 version.
[aom.git] / obudec.c
blob902a210efd4b3e0a4764d3cd7ff25923c44d2d4b
1 /*
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.
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 #include "./obudec.h"
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;
36 size_t len;
37 for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
38 const size_t num_read = fread(&value_buffer[len], 1, 1, f);
39 if (num_read == 0) {
40 if (len == 0 && feof(f)) {
41 *value_length = 0;
42 return 0;
44 // Ran out of data before completing read of value.
45 return -1;
47 if ((value_buffer[len] >> 7) == 0) {
48 ++len;
49 *value_length = len;
50 break;
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) {
68 return -1;
70 *bytes_read = fread(obu_data, 1, 1, f);
72 if (feof(f) && *bytes_read == 0) {
73 return 0;
74 } else if (*bytes_read != 1) {
75 fprintf(stderr, "obudec: Failure reading OBU header.\n");
76 return -1;
79 const int has_extension = (obu_data[0] >> 2) & 0x1;
80 if (has_extension) {
81 if (fread(&obu_data[1], 1, 1, f) != 1) {
82 fprintf(stderr, "obudec: Failure reading OBU extension.");
83 return -1;
85 ++*bytes_read;
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");
93 return -1;
96 return 0;
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");
108 return -1;
111 *bytes_read += payload_length;
112 return 0;
115 static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity,
116 int is_annexb, uint8_t *buffer,
117 size_t *bytes_read,
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) {
124 return -1;
127 size_t leb128_length = 0;
128 uint64_t obu_size = 0;
129 if (is_annexb) {
130 if (obudec_read_leb128(f, &buffer[0], &leb128_length, &obu_size) != 0) {
131 fprintf(stderr, "obudec: Failure reading OBU size length.\n");
132 return -1;
133 } else if (leb128_length == 0) {
134 *payload_length = 0;
135 return 0;
137 if (obu_size > UINT32_MAX) {
138 fprintf(stderr, "obudec: OBU payload length too large.\n");
139 return -1;
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) {
147 return -1;
148 } else if (header_size == 0) {
149 *payload_length = 0;
150 return 0;
153 if (is_annexb) {
154 if (obu_size < header_size) {
155 fprintf(stderr, "obudec: OBU size is too small.\n");
156 return -1;
158 *payload_length = (size_t)obu_size - header_size;
159 } else {
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");
164 return -1;
166 if (u64_payload_length > UINT32_MAX) {
167 fprintf(stderr, "obudec: OBU payload length too large.\n");
168 return -1;
171 *payload_length = (size_t)u64_payload_length;
174 *bytes_read = leb128_length + header_size;
175 return 0;
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;
199 return -1;
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");
210 return -1;
212 #endif
214 uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);
216 if (new_buffer) {
217 *obu_buffer = new_buffer;
218 *obu_buffer_capacity = new_capacity;
219 } else {
220 fprintf(stderr, "obudec: Failed to allocate compressed data buffer\n");
221 *obu_length = bytes_read + obu_payload_length;
222 return -1;
226 if (obu_payload_length > 0 &&
227 obudec_read_obu_payload(f, obu_payload_length,
228 *obu_buffer + obu_bytes_buffered + bytes_read,
229 &bytes_read) != 0) {
230 return -1;
233 *obu_length = bytes_read;
234 return 0;
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;
251 if (is_annexb) {
252 // read the size of first temporal unit
253 if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
254 &unit_size) != 0) {
255 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
256 return 0;
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");
263 return 0;
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,
272 &obu_header) != 0) {
273 fprintf(stderr, "obudec: Failure reading first OBU.\n");
274 rewind(f);
275 return 0;
278 if (is_annexb) {
279 bytes_read += annexb_header_length;
282 if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
283 obu_header.type != OBU_SEQUENCE_HEADER) {
284 return 0;
287 if (obu_header.has_length_field) {
288 if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
289 fprintf(
290 stderr,
291 "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
292 rewind(f);
293 return 0;
295 } else if (!is_annexb) {
296 fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
297 rewind(f);
298 return 0;
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");
305 rewind(f);
306 return 0;
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");
317 rewind(f);
318 return 0;
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);
324 if (status < 0) {
325 rewind(f);
326 return 0;
328 obu_ctx->bytes_buffered += payload_bytes;
330 return 1;
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;
337 if (!f) return -1;
339 *buffer_size = 0;
340 *bytes_read = 0;
342 if (feof(f)) {
343 return 1;
346 size_t tu_size;
347 size_t obu_size = 0;
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) {
352 uint64_t size = 0;
354 if (obu_ctx->bytes_buffered == 0) {
355 if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
356 &size) != 0) {
357 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
358 return -1;
360 if (size == 0 && feof(f)) {
361 return 1;
363 } else {
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");
368 return -1;
372 if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
373 fprintf(stderr, "obudec: TU too large.\n");
374 return -1;
377 size += length_of_temporal_unit_size;
378 tu_size = (size_t)size;
379 } else {
380 while (1) {
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,
386 0) != 0) {
387 fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
388 return -1;
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;
395 break;
396 } else {
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");
405 return -1;
407 #endif
408 uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
409 if (!new_buffer) {
410 free(*buffer);
411 fprintf(stderr, "obudec: Out of memory.\n");
412 return -1;
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,
424 obu_size);
425 obu_ctx->bytes_buffered = obu_size;
426 } else {
427 if (!feof(f)) {
428 size_t data_size;
429 size_t offset;
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;
434 } else {
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");
443 return -1;
447 return 0;
450 void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }