blob: 9cc907a9392c2f57fe8aa8544912d4c4f5cefb53 [file] [log] [blame]
Cyril Concolato6c788832017-10-30 16:30:35 -07001/*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3 *
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.
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "./obudec.h"
17
18#include "aom_ports/mem_ops.h"
19#include "av1/common/common.h"
20
21#define OBU_HEADER_SIZE_BYTES 1
22
23#if CONFIG_OBU_NO_IVF
24int obu_read_temporal_unit(FILE *infile, uint8_t **buffer, size_t *bytes_read,
25 size_t *buffer_size) {
26 size_t ret;
27 const size_t obu_length_header_size =
28 PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES;
29 uint32_t obu_size = 0;
30 uint8_t *data = NULL;
31
32 if (feof(infile)) {
33 return 1;
34 }
35
36 *buffer_size = 0;
37 *bytes_read = 0;
38 while (1) {
39 // augment the buffer to just contain the next size field
40 // and the first byte of the header
41 *buffer = realloc(*buffer, (*buffer_size) + obu_length_header_size);
42 data = *buffer + (*buffer_size);
43 *buffer_size += obu_length_header_size;
44 ret = fread(data, 1, obu_length_header_size, infile);
45 if (ret == 0) {
46 // fprintf(stderr, "Found end of stream, ending temporal unit\n");
47 break;
48 }
49 if (ret != obu_length_header_size) {
50 warn("Failed to read OBU Header\n");
51 return 1;
52 }
53 *bytes_read += obu_length_header_size;
54
55 if (((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) == OBU_TEMPORAL_DELIMITER) {
56 // Stop when a temporal delimiter is found
57 // fprintf(stderr, "Found temporal delimiter, ending temporal unit\n");
58 // prevent decoder to start decoding another frame from this buffer
59 *bytes_read -= obu_length_header_size;
60 break;
61 }
62
63 // otherwise, read the OBU payload into memory
64 obu_size = mem_get_le32(data);
65 // fprintf(stderr, "Found OBU of type %d and size %d\n",
66 // ((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF), obu_size);
67 obu_size--; // removing the byte of the header already read
68 if (obu_size) {
69 *buffer = realloc(*buffer, (*buffer_size) + obu_size);
70 data = *buffer + (*buffer_size);
71 *buffer_size += obu_size;
72 ret = fread(data, 1, obu_size, infile);
73 if (ret != obu_size) {
74 warn("Failed to read OBU Payload\n");
75 return 1;
76 }
77 *bytes_read += obu_size;
78 }
79 }
80 return 0;
81}
82
83int file_is_obu(struct AvxInputContext *input_ctx) {
84 uint8_t obutd[PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES];
85 int size;
86
Tom Fineganff863952017-12-22 11:41:14 -080087#if !CONFIG_OBU
88 warn("obudec.c requires CONFIG_OBU");
Cyril Concolato6c788832017-10-30 16:30:35 -070089 return 0;
90#endif
91
92 // Reading the first OBU TD to enable TU end detection at TD start.
93 fread(obutd, 1, PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES, input_ctx->file);
94 size = mem_get_le32(obutd);
95 if (size != 1) {
96 warn("Expected first OBU size to be 1, got %d", size);
97 return 0;
98 }
99 if (((obutd[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) != OBU_TEMPORAL_DELIMITER) {
100 warn("Expected OBU TD at file start, got %d\n", obutd[PRE_OBU_SIZE_BYTES]);
101 return 0;
102 }
103 // fprintf(stderr, "Starting to parse OBU stream\n");
104 return 1;
105}
106
107#endif