summaryrefslogtreecommitdiffstats
path: root/third_party/aom/common/obudec.c
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2020-04-07 23:30:51 -0400
committerwolfbeast <mcwerewolf@wolfbeast.com>2020-04-14 13:26:42 +0200
commit277f2116b6660e9bbe7f5d67524be57eceb49b8b (patch)
tree4595f7cc71418f71b9a97dfaeb03a30aa60f336a /third_party/aom/common/obudec.c
parentd270404436f6e84ffa3b92af537ac721bf10d66e (diff)
downloadUXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.gz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.lz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.tar.xz
UXP-277f2116b6660e9bbe7f5d67524be57eceb49b8b.zip
Move aom source to a sub-directory under media/libaom
There is no damned reason to treat this differently than any other media lib given its license and there never was.
Diffstat (limited to 'third_party/aom/common/obudec.c')
-rw-r--r--third_party/aom/common/obudec.c448
1 files changed, 0 insertions, 448 deletions
diff --git a/third_party/aom/common/obudec.c b/third_party/aom/common/obudec.c
deleted file mode 100644
index acbd12e0c..000000000
--- a/third_party/aom/common/obudec.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (c) 2017, Alliance for Open Media. All rights reserved
- *
- * This source code is subject to the terms of the BSD 2 Clause License and
- * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
- * was not distributed with this source code in the LICENSE file, you can
- * obtain it at www.aomedia.org/license/software. If the Alliance for Open
- * Media Patent License 1.0 was not distributed with this source code in the
- * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "common/obudec.h"
-
-#include "aom_ports/mem_ops.h"
-#include "av1/common/common.h"
-#include "av1/common/obu_util.h"
-
-#define OBU_BUFFER_SIZE (500 * 1024)
-
-#define OBU_HEADER_SIZE 1
-#define OBU_EXTENSION_SIZE 1
-#define OBU_MAX_LENGTH_FIELD_SIZE 8
-#define OBU_DETECTION_SIZE \
- (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 3 * OBU_MAX_LENGTH_FIELD_SIZE)
-
-// Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
-// Stores raw bytes in 'value_buffer', length of the number in 'value_length',
-// and decoded value in 'value'.
-static int obudec_read_leb128(FILE *f, uint8_t *value_buffer,
- size_t *value_length, uint64_t *value) {
- if (!f || !value_buffer || !value_length || !value) return -1;
- size_t len;
- for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
- const size_t num_read = fread(&value_buffer[len], 1, 1, f);
- if (num_read == 0) {
- if (len == 0 && feof(f)) {
- *value_length = 0;
- return 0;
- }
- // Ran out of data before completing read of value.
- return -1;
- }
- if ((value_buffer[len] >> 7) == 0) {
- ++len;
- *value_length = len;
- break;
- }
- }
-
- return aom_uleb_decode(value_buffer, len, value, NULL);
-}
-
-// Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
-// enough to store an OBU header with extension (2 bytes). Raw OBU data is
-// written to 'obu_data', parsed OBU header values are written to 'obu_header',
-// and total bytes read from file are written to 'bytes_read'. Returns 0 for
-// success, and non-zero on failure. When end of file is reached, the return
-// value is 0 and the 'bytes_read' value is set to 0.
-static int obudec_read_obu_header(FILE *f, size_t buffer_capacity,
- int is_annexb, uint8_t *obu_data,
- ObuHeader *obu_header, size_t *bytes_read) {
- if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
- !obu_data || !obu_header || !bytes_read) {
- return -1;
- }
- *bytes_read = fread(obu_data, 1, 1, f);
-
- if (feof(f) && *bytes_read == 0) {
- return 0;
- } else if (*bytes_read != 1) {
- fprintf(stderr, "obudec: Failure reading OBU header.\n");
- return -1;
- }
-
- const int has_extension = (obu_data[0] >> 2) & 0x1;
- if (has_extension) {
- if (fread(&obu_data[1], 1, 1, f) != 1) {
- fprintf(stderr, "obudec: Failure reading OBU extension.");
- return -1;
- }
- ++*bytes_read;
- }
-
- size_t obu_bytes_parsed = 0;
- const aom_codec_err_t parse_result = aom_read_obu_header(
- obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
- if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
- fprintf(stderr, "obudec: Error parsing OBU header.\n");
- return -1;
- }
-
- return 0;
-}
-
-// Reads OBU payload from 'f' and returns 0 for success when all payload bytes
-// are read from the file. Payload data is written to 'obu_data', and actual
-// bytes read added to 'bytes_read'.
-static int obudec_read_obu_payload(FILE *f, size_t payload_length,
- uint8_t *obu_data, size_t *bytes_read) {
- if (!f || payload_length == 0 || !obu_data || !bytes_read) return -1;
-
- if (fread(obu_data, 1, payload_length, f) != payload_length) {
- fprintf(stderr, "obudec: Failure reading OBU payload.\n");
- return -1;
- }
-
- *bytes_read += payload_length;
- return 0;
-}
-
-static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity,
- int is_annexb, uint8_t *buffer,
- size_t *bytes_read,
- size_t *payload_length,
- ObuHeader *obu_header) {
- const size_t kMinimumBufferSize =
- (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + OBU_MAX_LENGTH_FIELD_SIZE);
- if (!f || !buffer || !bytes_read || !payload_length || !obu_header ||
- buffer_capacity < kMinimumBufferSize) {
- return -1;
- }
-
- size_t leb128_length = 0;
- uint64_t obu_size = 0;
- if (is_annexb) {
- if (obudec_read_leb128(f, &buffer[0], &leb128_length, &obu_size) != 0) {
- fprintf(stderr, "obudec: Failure reading OBU size length.\n");
- return -1;
- } else if (leb128_length == 0) {
- *payload_length = 0;
- return 0;
- }
- if (obu_size > UINT32_MAX) {
- fprintf(stderr, "obudec: OBU payload length too large.\n");
- return -1;
- }
- }
-
- size_t header_size = 0;
- if (obudec_read_obu_header(f, buffer_capacity - leb128_length, is_annexb,
- buffer + leb128_length, obu_header,
- &header_size) != 0) {
- return -1;
- } else if (header_size == 0) {
- *payload_length = 0;
- return 0;
- }
-
- if (is_annexb) {
- if (obu_size < header_size) {
- fprintf(stderr, "obudec: OBU size is too small.\n");
- return -1;
- }
- *payload_length = (size_t)obu_size - header_size;
- } else {
- uint64_t u64_payload_length = 0;
- if (obudec_read_leb128(f, &buffer[header_size], &leb128_length,
- &u64_payload_length) != 0) {
- fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
- return -1;
- }
- if (u64_payload_length > UINT32_MAX) {
- fprintf(stderr, "obudec: OBU payload length too large.\n");
- return -1;
- }
-
- *payload_length = (size_t)u64_payload_length;
- }
-
- *bytes_read = leb128_length + header_size;
- return 0;
-}
-
-static int 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, int is_annexb) {
- size_t available_buffer_capacity = *obu_buffer_capacity - obu_bytes_buffered;
-
- if (!(*obu_buffer)) return -1;
-
- size_t bytes_read = 0;
- size_t obu_payload_length = 0;
- const int status = obudec_read_obu_header_and_size(
- f, available_buffer_capacity, is_annexb, *obu_buffer + obu_bytes_buffered,
- &bytes_read, &obu_payload_length, obu_header);
- if (status < 0) return status;
-
- if (obu_payload_length > SIZE_MAX - bytes_read) return -1;
-
- if (obu_payload_length > 256 * 1024 * 1024) {
- fprintf(stderr, "obudec: Read invalid OBU size (%u)\n",
- (unsigned int)obu_payload_length);
- *obu_length = bytes_read + obu_payload_length;
- return -1;
- }
-
- if (bytes_read + obu_payload_length > available_buffer_capacity) {
- // TODO(tomfinegan): Add overflow check.
- const size_t new_capacity =
- obu_bytes_buffered + bytes_read + 2 * obu_payload_length;
-
-#if defined AOM_MAX_ALLOCABLE_MEMORY
- if (new_capacity > AOM_MAX_ALLOCABLE_MEMORY) {
- fprintf(stderr, "obudec: OBU size exceeds max alloc size.\n");
- return -1;
- }
-#endif
-
- uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);
-
- if (new_buffer) {
- *obu_buffer = new_buffer;
- *obu_buffer_capacity = new_capacity;
- } else {
- fprintf(stderr, "obudec: Failed to allocate compressed data buffer\n");
- *obu_length = bytes_read + obu_payload_length;
- return -1;
- }
- }
-
- if (obu_payload_length > 0 &&
- obudec_read_obu_payload(f, obu_payload_length,
- *obu_buffer + obu_bytes_buffered + bytes_read,
- &bytes_read) != 0) {
- return -1;
- }
-
- *obu_length = bytes_read;
- return 0;
-}
-
-int file_is_obu(struct ObuDecInputContext *obu_ctx) {
- if (!obu_ctx || !obu_ctx->avx_ctx) return 0;
-
- struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
- uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
- const int is_annexb = obu_ctx->is_annexb;
- FILE *f = avx_ctx->file;
- size_t payload_length = 0;
- ObuHeader obu_header;
- memset(&obu_header, 0, sizeof(obu_header));
- size_t length_of_unit_size = 0;
- size_t annexb_header_length = 0;
- uint64_t unit_size = 0;
-
- if (is_annexb) {
- // read the size of first temporal unit
- if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
- &unit_size) != 0) {
- fprintf(stderr, "obudec: Failure reading temporal unit header\n");
- return 0;
- }
-
- // read the size of first frame unit
- if (obudec_read_leb128(f, &detect_buf[length_of_unit_size],
- &annexb_header_length, &unit_size) != 0) {
- fprintf(stderr, "obudec: Failure reading frame unit header\n");
- return 0;
- }
- annexb_header_length += length_of_unit_size;
- }
-
- size_t bytes_read = 0;
- if (obudec_read_obu_header_and_size(
- f, OBU_DETECTION_SIZE - annexb_header_length, is_annexb,
- &detect_buf[annexb_header_length], &bytes_read, &payload_length,
- &obu_header) != 0) {
- fprintf(stderr, "obudec: Failure reading first OBU.\n");
- rewind(f);
- return 0;
- }
-
- if (is_annexb) {
- bytes_read += annexb_header_length;
- }
-
- if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
- obu_header.type != OBU_SEQUENCE_HEADER) {
- return 0;
- }
-
- if (obu_header.has_size_field) {
- if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
- fprintf(
- stderr,
- "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
- rewind(f);
- return 0;
- }
- } else if (!is_annexb) {
- fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
- rewind(f);
- return 0;
- }
-
- // Appears that input is valid Section 5 AV1 stream.
- obu_ctx->buffer = (uint8_t *)malloc(OBU_BUFFER_SIZE);
- if (!obu_ctx->buffer) {
- fprintf(stderr, "Out of memory.\n");
- rewind(f);
- return 0;
- }
- obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
-
- memcpy(obu_ctx->buffer, &detect_buf[0], bytes_read);
- obu_ctx->bytes_buffered = bytes_read;
- // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
- // We need to read this in so that our buffer only contains complete OBUs.
- if (payload_length > 0) {
- if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
- fprintf(stderr, "obudec: First OBU's payload is too large\n");
- rewind(f);
- return 0;
- }
-
- size_t payload_bytes = 0;
- const int status = obudec_read_obu_payload(
- f, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes);
- if (status < 0) {
- rewind(f);
- return 0;
- }
- obu_ctx->bytes_buffered += payload_bytes;
- }
- return 1;
-}
-
-int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
- uint8_t **buffer, size_t *bytes_read,
- size_t *buffer_size) {
- FILE *f = obu_ctx->avx_ctx->file;
- if (!f) return -1;
-
- *buffer_size = 0;
- *bytes_read = 0;
-
- if (feof(f)) {
- return 1;
- }
-
- size_t tu_size;
- size_t obu_size = 0;
- size_t length_of_temporal_unit_size = 0;
- uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
-
- if (obu_ctx->is_annexb) {
- uint64_t size = 0;
-
- if (obu_ctx->bytes_buffered == 0) {
- if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
- &size) != 0) {
- fprintf(stderr, "obudec: Failure reading temporal unit header\n");
- return -1;
- }
- if (size == 0 && feof(f)) {
- return 1;
- }
- } else {
- // temporal unit size was already stored in buffer
- if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
- &length_of_temporal_unit_size) != 0) {
- fprintf(stderr, "obudec: Failure reading temporal unit header\n");
- return -1;
- }
- }
-
- if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
- fprintf(stderr, "obudec: TU too large.\n");
- return -1;
- }
-
- size += length_of_temporal_unit_size;
- tu_size = (size_t)size;
- } else {
- while (1) {
- ObuHeader obu_header;
- memset(&obu_header, 0, sizeof(obu_header));
-
- if (obudec_read_one_obu(f, &obu_ctx->buffer, obu_ctx->bytes_buffered,
- &obu_ctx->buffer_capacity, &obu_size, &obu_header,
- 0) != 0) {
- fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
- return -1;
- }
-
- if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0) {
- tu_size = obu_ctx->bytes_buffered;
- break;
- } else {
- obu_ctx->bytes_buffered += obu_size;
- }
- }
- }
-
-#if defined AOM_MAX_ALLOCABLE_MEMORY
- if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
- fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
- return -1;
- }
-#endif
- uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
- if (!new_buffer) {
- free(*buffer);
- fprintf(stderr, "obudec: Out of memory.\n");
- return -1;
- }
- *buffer = new_buffer;
- *bytes_read = tu_size;
- *buffer_size = tu_size;
-
- if (!obu_ctx->is_annexb) {
- memcpy(*buffer, obu_ctx->buffer, tu_size);
-
- // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
- // points to the end of the buffer.
- memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered,
- obu_size);
- obu_ctx->bytes_buffered = obu_size;
- } else {
- if (!feof(f)) {
- size_t data_size;
- size_t offset;
- if (!obu_ctx->bytes_buffered) {
- data_size = tu_size - length_of_temporal_unit_size;
- memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
- offset = length_of_temporal_unit_size;
- } else {
- memcpy(*buffer, obu_ctx->buffer, obu_ctx->bytes_buffered);
- offset = obu_ctx->bytes_buffered;
- data_size = tu_size - obu_ctx->bytes_buffered;
- obu_ctx->bytes_buffered = 0;
- }
-
- if (fread(*buffer + offset, 1, data_size, f) != data_size) {
- fprintf(stderr, "obudec: Failed to read full temporal unit\n");
- return -1;
- }
- }
- }
- return 0;
-}
-
-void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }