Add sse2/ssse3 intra predictors for 16x4
[aom.git] / obudec.c
blob988457b1beb944297e057c8555f91050324b81a7
1 /*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
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.
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 #include "./obudec.h"
18 #include "aom_ports/mem_ops.h"
19 #include "av1/common/common.h"
20 #include "av1/decoder/obu.h"
22 #define OBU_BUFFER_SIZE (500 * 1024)
24 #define OBU_HEADER_SIZE 1
25 #define OBU_EXTENSION_SIZE 1
26 #define OBU_MAX_LENGTH_FIELD_SIZE 8
27 #define OBU_DETECTION_SIZE \
28 (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 2 * OBU_MAX_LENGTH_FIELD_SIZE)
30 // Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
31 // Stores raw bytes in 'value_buffer', length of the number in 'value_length',
32 // and decoded value in 'value'.
33 static int obudec_read_leb128(FILE *f, uint8_t *value_buffer,
34 size_t *value_length, uint64_t *value) {
35 if (!f || !value_buffer || !value_length || !value) return -1;
36 for (int len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
37 const size_t num_read = fread(&value_buffer[len], 1, 1, f);
38 if (num_read == 0 && feof(f)) {
39 *value_length = 0;
40 return 0;
42 if (num_read != 1) {
43 // Ran out of data before completing read of value.
44 return -1;
46 if ((value_buffer[len] >> 7) == 0) {
47 *value_length = (size_t)(len + 1);
48 break;
52 return aom_uleb_decode(value_buffer, OBU_MAX_LENGTH_FIELD_SIZE, value, NULL);
55 // Reads OBU size from infile and returns 0 upon success. Returns obu_size via
56 // output pointer obu_size. Returns -1 when reading or parsing fails. Always
57 // returns FILE pointer to position at time of call. Returns 0 and sets obu_size
58 // to 0 when end of file is reached.
59 static int obudec_read_obu_size(FILE *infile, uint64_t *obu_size,
60 size_t *length_field_size) {
61 if (!infile || !obu_size) return 1;
63 uint8_t read_buffer[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
64 size_t bytes_read = fread(read_buffer, 1, OBU_MAX_LENGTH_FIELD_SIZE, infile);
65 *obu_size = 0;
67 if (bytes_read == 0) {
68 return 0;
71 const int seek_pos = (int)bytes_read;
72 if (seek_pos != 0 && fseek(infile, -seek_pos, SEEK_CUR) != 0) return 1;
74 if (aom_uleb_decode(read_buffer, bytes_read, obu_size, length_field_size) !=
75 0) {
76 return 1;
79 return 0;
82 // Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
83 // enough to store an OBU header with extension (2 bytes). Raw OBU data is
84 // written to 'obu_data', parsed OBU header values are written to 'obu_header',
85 // and total bytes read from file are written to 'bytes_read'. Returns 0 for
86 // success, and non-zero on failure. When end of file is reached, the return
87 // value is 0 and the 'bytes_read' value is set to 0.
88 static int obudec_read_obu_header(FILE *f, size_t buffer_capacity,
89 int is_annexb, uint8_t *obu_data,
90 ObuHeader *obu_header, size_t *bytes_read) {
91 if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
92 !obu_data || !obu_header || !bytes_read) {
93 return -1;
95 *bytes_read = fread(obu_data, 1, 1, f);
97 if (feof(f) && *bytes_read == 0) {
98 return 0;
99 } else if (*bytes_read != 1) {
100 fprintf(stderr, "obudec: Failure reading OBU header.\n");
101 return -1;
104 const int has_extension = (obu_data[0] >> 2) & 0x1;
105 if (has_extension) {
106 if (fread(&obu_data[1], 1, 1, f) != 1) {
107 fprintf(stderr, "obudec: Failure reading OBU extension.");
108 return -1;
110 ++*bytes_read;
113 size_t obu_bytes_parsed = 0;
114 const aom_codec_err_t parse_result = aom_read_obu_header(
115 obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
116 if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
117 fprintf(stderr, "obudec: Error parsing OBU header.\n");
118 return -1;
121 return 0;
124 // Reads OBU payload from 'f' and returns 0 for success when all payload bytes
125 // are read from the file. Payload data is written to 'obu_data', and actual
126 // bytes read written to 'bytes_read'.
127 static int obudec_read_obu_payload(FILE *f, uint64_t payload_length,
128 uint8_t *obu_data, size_t *bytes_read) {
129 if (!f || payload_length == 0 || !obu_data || !bytes_read) return -1;
131 if (fread(obu_data, 1, (size_t)payload_length, f) != payload_length) {
132 fprintf(stderr, "obudec: Failure reading OBU payload.\n");
133 return -1;
136 *bytes_read += (size_t)payload_length;
137 return 0;
140 static int obudec_read_one_obu(FILE *f, size_t buffer_capacity, int is_annexb,
141 uint8_t *obu_data, uint64_t *obu_length,
142 ObuHeader *obu_header) {
143 const size_t kMinimumBufferSize = OBU_DETECTION_SIZE;
144 if (!f || !obu_data || !obu_length || !obu_header ||
145 buffer_capacity < kMinimumBufferSize) {
146 return -1;
149 uint64_t obu_payload_length = 0;
150 size_t leb128_length = 0;
151 uint64_t obu_size = 0;
152 if (is_annexb) {
153 if (obudec_read_leb128(f, &obu_data[0], &leb128_length, &obu_size) != 0) {
154 fprintf(stderr, "obudec: Failure reading OBU size length.\n");
155 return -1;
156 } else if (leb128_length == 0) {
157 *obu_length = 0;
158 return 0;
162 size_t bytes_read = 0;
163 if (obudec_read_obu_header(f, buffer_capacity, is_annexb,
164 obu_data + leb128_length, obu_header,
165 &bytes_read) != 0) {
166 return -1;
167 } else if (bytes_read == 0) {
168 *obu_length = 0;
169 return 0;
172 if (!is_annexb) {
173 if (obudec_read_leb128(f, &obu_data[bytes_read], &leb128_length,
174 &obu_payload_length) != 0) {
175 fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
176 return -1;
180 if (is_annexb) {
181 obu_payload_length = obu_size - bytes_read;
184 bytes_read += leb128_length;
186 if (UINT64_MAX - bytes_read < obu_payload_length) return -1;
187 if (bytes_read + obu_payload_length > buffer_capacity) {
188 *obu_length = bytes_read + obu_payload_length;
189 return -1;
192 if (obu_payload_length > 0 &&
193 obudec_read_obu_payload(f, obu_payload_length, &obu_data[bytes_read],
194 &bytes_read) != 0) {
195 return -1;
198 *obu_length = bytes_read;
199 return 0;
202 int file_is_obu(struct ObuDecInputContext *obu_ctx) {
203 if (!obu_ctx || !obu_ctx->avx_ctx) return 0;
205 struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
206 uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
207 const int is_annexb = obu_ctx->is_annexb;
208 FILE *f = avx_ctx->file;
209 uint64_t obu_length = 0;
210 ObuHeader obu_header;
211 memset(&obu_header, 0, sizeof(obu_header));
212 size_t length_of_unit_size = 0;
213 uint64_t unit_size;
214 size_t annexb_header_length = 0;
216 if (is_annexb) {
217 // read the size of first temporal unit
218 if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
219 &unit_size) != 0) {
220 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
221 return 0;
224 // read the size of first frame unit
225 if (obudec_read_leb128(f, &detect_buf[length_of_unit_size],
226 &annexb_header_length, &unit_size) != 0) {
227 fprintf(stderr, "obudec: Failure reading frame unit header\n");
228 return 0;
230 annexb_header_length += length_of_unit_size;
233 if (obudec_read_one_obu(f, OBU_DETECTION_SIZE, is_annexb,
234 &detect_buf[annexb_header_length], &obu_length,
235 &obu_header) != 0) {
236 fprintf(stderr, "obudec: Failure reading first OBU.\n");
237 rewind(f);
238 return 0;
241 if (obu_header.type != OBU_TEMPORAL_DELIMITER) return 0;
243 if (obu_header.has_length_field) {
244 uint64_t obu_payload_length = 0;
245 size_t leb128_length = 0;
246 const size_t obu_length_offset = obu_header.has_length_field ? 1 : 2;
247 if (aom_uleb_decode(&detect_buf[obu_length_offset], sizeof(leb128_length),
248 &obu_payload_length, &leb128_length) != 0) {
249 fprintf(stderr, "obudec: Failure decoding OBU payload length.\n");
250 rewind(f);
251 return 0;
253 if (obu_payload_length != 0) {
254 fprintf(
255 stderr,
256 "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
257 rewind(f);
258 return 0;
260 } else if (!is_annexb) {
261 fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
262 rewind(f);
263 return (0);
266 // Appears that input is valid Section 5 AV1 stream.
267 obu_ctx->buffer = (uint8_t *)calloc(OBU_BUFFER_SIZE, 1);
268 if (!obu_ctx->buffer) {
269 fprintf(stderr, "Out of memory.\n");
270 rewind(f);
271 return 0;
273 obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
275 if (is_annexb) {
276 obu_length += annexb_header_length;
278 memcpy(obu_ctx->buffer, &detect_buf[0], (size_t)obu_length);
279 obu_ctx->bytes_buffered = (size_t)obu_length;
281 return 1;
284 int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
285 uint8_t **buffer, size_t *bytes_read,
286 size_t *buffer_size) {
287 FILE *f = obu_ctx->avx_ctx->file;
288 if (!f) return -1;
290 *buffer_size = 0;
291 *bytes_read = 0;
293 if (feof(f)) {
294 return 1;
297 size_t tu_size;
298 uint64_t obu_size = 0;
299 uint8_t *data = obu_ctx->buffer;
300 size_t length_of_temporal_unit_size = 0;
301 uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
303 if (obu_ctx->is_annexb) {
304 uint64_t size = 0;
306 if (obu_ctx->bytes_buffered == 0) {
307 if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
308 &size) != 0) {
309 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
310 return -1;
312 if (size == 0 && feof(f)) {
313 return 1;
315 } else {
316 // temporal unit size was already stored in buffer
317 if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
318 &length_of_temporal_unit_size) != 0) {
319 fprintf(stderr, "obudec: Failure reading temporal unit header\n");
320 return -1;
324 size += length_of_temporal_unit_size;
325 tu_size = (size_t)size;
326 } else {
327 while (1) {
328 ObuHeader obu_header;
329 memset(&obu_header, 0, sizeof(obu_header));
331 data = obu_ctx->buffer + obu_ctx->bytes_buffered;
332 const size_t capacity =
333 obu_ctx->buffer_capacity - obu_ctx->bytes_buffered;
335 if (obudec_read_one_obu(f, capacity, 0, data, &obu_size, &obu_header) !=
336 0) {
337 fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
338 return -1;
341 if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0 ||
342 (obu_header.has_extension &&
343 obu_header.enhancement_layer_id > obu_ctx->last_layer_id)) {
344 tu_size = obu_ctx->bytes_buffered;
345 break;
346 } else {
347 obu_ctx->bytes_buffered += (size_t)obu_size;
352 #if defined AOM_MAX_ALLOCABLE_MEMORY
353 if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
354 fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
355 return -1;
357 #endif
358 uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
359 if (!new_buffer) {
360 free(*buffer);
361 fprintf(stderr, "obudec: Out of memory.\n");
362 return -1;
364 *buffer = new_buffer;
365 *bytes_read = tu_size;
366 *buffer_size = tu_size;
368 if (!obu_ctx->is_annexb) {
369 memcpy(*buffer, obu_ctx->buffer, tu_size);
370 memmove(obu_ctx->buffer, data, (size_t)obu_size);
371 obu_ctx->bytes_buffered = (size_t)obu_size;
372 } else {
373 if (!feof(f)) {
374 size_t data_size;
375 size_t offset;
376 if (!obu_ctx->bytes_buffered) {
377 data_size = (uint32_t)(tu_size - length_of_temporal_unit_size);
378 memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
379 offset = length_of_temporal_unit_size;
380 } else {
381 memcpy(*buffer, obu_ctx->buffer, obu_ctx->bytes_buffered);
382 offset = obu_ctx->bytes_buffered;
383 data_size = tu_size - obu_ctx->bytes_buffered;
384 obu_ctx->bytes_buffered = 0;
387 if (fread(new_buffer + offset, 1, data_size, f) != data_size) {
388 fprintf(stderr, "obudec: Failed to read full temporal unit\n");
389 return -1;
393 return 0;
396 void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }