blob: 6f60102107ae6fcdda4f1c034a327bb63775f18e [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
Soo-Chul Hanf8589862018-01-24 03:13:14 +000022#define OBU_HEADER_EXTENSION_SIZE_BYTES 1
Tom Fineganccb8cc42018-02-22 14:08:13 -080023
24#if CONFIG_OBU_SIZING
25// Unsigned LEB128 OBU length field has maximum size of 8 bytes.
26#define OBU_MAX_LENGTH_FIELD_SIZE 8
27#define OBU_MAX_HEADER_SIZE \
28 (OBU_HEADER_SIZE_BYTES + OBU_HEADER_EXTENSION_SIZE_BYTES + \
29 OBU_MAX_LENGTH_FIELD_SIZE)
30#else
31#define OBU_MAX_LENGTH_FIELD_SIZE PRE_OBU_SIZE_BYTES
32#define OBU_MAX_HEADER_SIZE \
33 (OBU_HEADER_SIZE_BYTES + OBU_HEADER_EXTENSION_SIZE_BYTES + PRE_OBU_SIZE_BYTES)
Soo-Chul Hanf8589862018-01-24 03:13:14 +000034#endif
Cyril Concolato6c788832017-10-30 16:30:35 -070035
36#if CONFIG_OBU_NO_IVF
Tom Fineganccb8cc42018-02-22 14:08:13 -080037int read_obu_type(uint8_t obu_header, OBU_TYPE *obu_type) {
38 if (!obu_type) return -1;
39 const int obu_type_value = (obu_header >> 3) & 0xF;
40 switch (obu_type_value) {
41 case OBU_SEQUENCE_HEADER: *obu_type = OBU_SEQUENCE_HEADER; break;
42 case OBU_TEMPORAL_DELIMITER: *obu_type = OBU_TEMPORAL_DELIMITER; break;
43 case OBU_FRAME_HEADER: *obu_type = OBU_FRAME_HEADER; break;
44 case OBU_TILE_GROUP: *obu_type = OBU_TILE_GROUP; break;
45 case OBU_METADATA: *obu_type = OBU_METADATA; break;
46 case OBU_PADDING: *obu_type = OBU_PADDING; break;
47 default: return -1;
48 }
49 return 0;
50}
51
52// Reads OBU size from infile and returns 0 upon success. Returns obu_size via
53// output pointer obu_size. Returns -1 when reading or parsing fails. Always
54// returns FILE pointer to position at time of call. Returns 0 and sets obu_size
55// to 0 when end of file is reached.
56int read_obu_size(FILE *infile, uint64_t *obu_size, size_t *length_field_size) {
57 if (!infile || !obu_size) return 1;
58
59 uint8_t read_buffer[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
60 size_t bytes_read = fread(read_buffer, 1, OBU_MAX_LENGTH_FIELD_SIZE, infile);
61 *obu_size = 0;
62
63 if (bytes_read == 0) {
64 return 0;
65 }
66
67 const int seek_pos = (int)bytes_read;
68 if (seek_pos != 0 && fseek(infile, -seek_pos, SEEK_CUR) != 0) return 1;
69
70#if CONFIG_OBU_SIZING
71 if (aom_uleb_decode(read_buffer, bytes_read, obu_size, length_field_size) !=
72 0) {
73 return 1;
74 }
75#else
76 if (length_field_size) *length_field_size = PRE_OBU_SIZE_BYTES;
77 *obu_size = mem_get_le32(read_buffer);
78#endif
79
80 return 0;
81}
82
Cyril Concolato6c788832017-10-30 16:30:35 -070083int obu_read_temporal_unit(FILE *infile, uint8_t **buffer, size_t *bytes_read,
Soo-Chul Hanf8589862018-01-24 03:13:14 +000084#if CONFIG_SCALABILITY
85 size_t *buffer_size, int last_layer_id) {
86#else
Cyril Concolato6c788832017-10-30 16:30:35 -070087 size_t *buffer_size) {
Soo-Chul Hanf8589862018-01-24 03:13:14 +000088#endif
Cyril Concolato6c788832017-10-30 16:30:35 -070089 size_t ret;
Hui Sue19c3212018-02-21 14:32:18 -080090 uint64_t obu_size = 0;
Cyril Concolato6c788832017-10-30 16:30:35 -070091 uint8_t *data = NULL;
92
93 if (feof(infile)) {
94 return 1;
95 }
96
97 *buffer_size = 0;
98 *bytes_read = 0;
99 while (1) {
Tom Fineganccb8cc42018-02-22 14:08:13 -0800100 size_t length_field_size = 0;
101 ret = read_obu_size(infile, &obu_size, &length_field_size);
102 if (ret != 0) {
103 warn("Failed to read OBU size.\n");
Cyril Concolato6c788832017-10-30 16:30:35 -0700104 return 1;
105 }
Tom Fineganccb8cc42018-02-22 14:08:13 -0800106 if (ret == 0 && obu_size == 0) {
107 fprintf(stderr, "Found end of stream, ending temporal unit\n");
108 break;
109 }
Cyril Concolato6c788832017-10-30 16:30:35 -0700110
Tom Fineganccb8cc42018-02-22 14:08:13 -0800111 obu_size += length_field_size;
112
113 // Expand the buffer to contain the full OBU and its length.
114 const uint8_t *old_buffer = *buffer;
Yaowu Xu6d4fee32018-02-27 14:38:34 -0800115 *buffer = (uint8_t *)realloc(*buffer, *buffer_size + (size_t)obu_size);
Tom Fineganccb8cc42018-02-22 14:08:13 -0800116 if (!*buffer) {
117 free((void *)old_buffer);
118 warn("OBU buffer alloc failed.\n");
119 return 1;
120 }
121
122 data = *buffer + (*buffer_size);
123 *buffer_size += obu_size;
Yaowu Xu6d4fee32018-02-27 14:38:34 -0800124 ret = fread(data, 1, (size_t)obu_size, infile);
Tom Fineganccb8cc42018-02-22 14:08:13 -0800125
126 if (ret != obu_size) {
127 warn("Failed to read OBU.\n");
128 return 1;
129 }
130 *bytes_read += obu_size;
131
132 OBU_TYPE obu_type;
133 if (read_obu_type(data[length_field_size], &obu_type) != 0) {
134 warn("Invalid OBU type.\n");
135 return 1;
136 }
137
138 if (obu_type == OBU_TEMPORAL_DELIMITER) {
Cyril Concolato6c788832017-10-30 16:30:35 -0700139 // Stop when a temporal delimiter is found
140 // fprintf(stderr, "Found temporal delimiter, ending temporal unit\n");
141 // prevent decoder to start decoding another frame from this buffer
Tom Fineganccb8cc42018-02-22 14:08:13 -0800142 *bytes_read -= obu_size;
Cyril Concolato6c788832017-10-30 16:30:35 -0700143 break;
144 }
145
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000146#if CONFIG_SCALABILITY
147 // break if obu_extension_flag is found and enhancement_id change
Tom Fineganccb8cc42018-02-22 14:08:13 -0800148 if (data[length_field_size] & 0x1) {
149 const uint8_t obu_extension_header =
150 data[length_field_size + OBU_HEADER_SIZE_BYTES];
151 const int curr_layer_id = (obu_extension_header >> 3) & 0x3;
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000152 if (curr_layer_id && (curr_layer_id > last_layer_id)) {
153 // new enhancement layer
Tom Fineganccb8cc42018-02-22 14:08:13 -0800154 *bytes_read -= obu_size;
155 const int i_obu_size = (int)obu_size;
156 fseek(infile, -i_obu_size, SEEK_CUR);
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000157 break;
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000158 }
159 }
160#endif
Cyril Concolato6c788832017-10-30 16:30:35 -0700161 }
Tom Fineganccb8cc42018-02-22 14:08:13 -0800162
Cyril Concolato6c788832017-10-30 16:30:35 -0700163 return 0;
164}
165
166int file_is_obu(struct AvxInputContext *input_ctx) {
Tom Fineganccb8cc42018-02-22 14:08:13 -0800167 uint8_t obutd[OBU_MAX_HEADER_SIZE] = { 0 };
168 uint64_t size = 0;
169
170 // Parsing of Annex B OBU streams via pipe without framing not supported. This
171 // implementation requires seeking backwards in the input stream. Tell caller
172 // that this input cannot be processed.
173 if (!input_ctx->filename || strcmp(input_ctx->filename, "-") == 0) return 0;
Cyril Concolato6c788832017-10-30 16:30:35 -0700174
Cyril Concolato6c788832017-10-30 16:30:35 -0700175 // Reading the first OBU TD to enable TU end detection at TD start.
Tom Fineganccb8cc42018-02-22 14:08:13 -0800176 const size_t ret = fread(obutd, 1, OBU_MAX_HEADER_SIZE, input_ctx->file);
177 if (ret != OBU_MAX_HEADER_SIZE) {
178 warn("Failed to read OBU Header, not enough data to process header.\n");
Hui Sue19c3212018-02-21 14:32:18 -0800179 return 0;
180 }
Tom Finegan41150ad2018-01-23 11:42:55 -0800181
182#if CONFIG_OBU_SIZING
Tom Fineganccb8cc42018-02-22 14:08:13 -0800183 if (aom_uleb_decode(obutd, OBU_MAX_HEADER_SIZE, &size, NULL) != 0) {
184 warn("OBU size parse failed.\n");
185 return 0;
186 }
187 const size_t obu_header_offset = aom_uleb_size_in_bytes(size);
Tom Finegan41150ad2018-01-23 11:42:55 -0800188#else
Tom Fineganccb8cc42018-02-22 14:08:13 -0800189 const size_t obu_header_offset = PRE_OBU_SIZE_BYTES;
Cyril Concolato6c788832017-10-30 16:30:35 -0700190 size = mem_get_le32(obutd);
Tom Finegan41150ad2018-01-23 11:42:55 -0800191#endif // CONFIG_OBU_SIZING
192
Tom Fineganccb8cc42018-02-22 14:08:13 -0800193 fseek(input_ctx->file, obu_header_offset + OBU_HEADER_SIZE_BYTES, SEEK_SET);
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000194
Tom Fineganccb8cc42018-02-22 14:08:13 -0800195 if (size != 1) {
196 warn("Expected first OBU size to be 1, got %d\n", size);
197 return 0;
198 }
199 OBU_TYPE obu_type;
200 if (read_obu_type(obutd[obu_header_offset], &obu_type) != 0) {
201 warn("Invalid OBU type found while probing for OBU_TEMPORAL_DELIMITER.\n");
202 return 0;
203 }
204 if (obu_type != OBU_TEMPORAL_DELIMITER) {
205 warn("Expected OBU TD at file start, got %d\n", obutd[obu_header_offset]);
206 return 0;
207 }
208
209 // fprintf(stderr, "Starting to parse OBU stream\n");
Cyril Concolato6c788832017-10-30 16:30:35 -0700210 return 1;
211}
212
213#endif