| /* |
| * 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 "./obudec.h" |
| |
| #include "aom_ports/mem_ops.h" |
| #include "av1/common/common.h" |
| |
| #define OBU_HEADER_SIZE_BYTES 1 |
| |
| #if CONFIG_OBU_NO_IVF |
| int obu_read_temporal_unit(FILE *infile, uint8_t **buffer, size_t *bytes_read, |
| size_t *buffer_size) { |
| size_t ret; |
| const size_t obu_length_header_size = |
| PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES; |
| uint32_t obu_size = 0; |
| uint8_t *data = NULL; |
| |
| if (feof(infile)) { |
| return 1; |
| } |
| |
| *buffer_size = 0; |
| *bytes_read = 0; |
| while (1) { |
| // augment the buffer to just contain the next size field |
| // and the first byte of the header |
| *buffer = realloc(*buffer, (*buffer_size) + obu_length_header_size); |
| data = *buffer + (*buffer_size); |
| *buffer_size += obu_length_header_size; |
| ret = fread(data, 1, obu_length_header_size, infile); |
| if (ret == 0) { |
| // fprintf(stderr, "Found end of stream, ending temporal unit\n"); |
| break; |
| } |
| if (ret != obu_length_header_size) { |
| warn("Failed to read OBU Header\n"); |
| return 1; |
| } |
| *bytes_read += obu_length_header_size; |
| |
| if (((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) == OBU_TEMPORAL_DELIMITER) { |
| // Stop when a temporal delimiter is found |
| // fprintf(stderr, "Found temporal delimiter, ending temporal unit\n"); |
| // prevent decoder to start decoding another frame from this buffer |
| *bytes_read -= obu_length_header_size; |
| break; |
| } |
| |
| // otherwise, read the OBU payload into memory |
| obu_size = mem_get_le32(data); |
| // fprintf(stderr, "Found OBU of type %d and size %d\n", |
| // ((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF), obu_size); |
| obu_size--; // removing the byte of the header already read |
| if (obu_size) { |
| *buffer = realloc(*buffer, (*buffer_size) + obu_size); |
| data = *buffer + (*buffer_size); |
| *buffer_size += obu_size; |
| ret = fread(data, 1, obu_size, infile); |
| if (ret != obu_size) { |
| warn("Failed to read OBU Payload\n"); |
| return 1; |
| } |
| *bytes_read += obu_size; |
| } |
| } |
| return 0; |
| } |
| |
| int file_is_obu(struct AvxInputContext *input_ctx) { |
| uint8_t obutd[PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES]; |
| int size; |
| |
| #if !CONFIG_OBU |
| warn("obudec.c requires CONFIG_OBU"); |
| return 0; |
| #endif |
| |
| // Reading the first OBU TD to enable TU end detection at TD start. |
| fread(obutd, 1, PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES, input_ctx->file); |
| size = mem_get_le32(obutd); |
| if (size != 1) { |
| warn("Expected first OBU size to be 1, got %d", size); |
| return 0; |
| } |
| if (((obutd[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) != OBU_TEMPORAL_DELIMITER) { |
| warn("Expected OBU TD at file start, got %d\n", obutd[PRE_OBU_SIZE_BYTES]); |
| return 0; |
| } |
| // fprintf(stderr, "Starting to parse OBU stream\n"); |
| return 1; |
| } |
| |
| #endif |