blob: acd3b27eed878fc3c0d7587df73b6b1a025bc745 [file] [log] [blame]
/*
* 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_ADD_4BYTES_OBUSIZE || !CONFIG_OBU
warn("obudec.c requires CONFIG_ADD_4BYTES_OBUSIZE and 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