blob: a0cb85e1d4fb68918c48d76873ad7a36520b4b5f [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#if CONFIG_SCALABILITY
23#define OBU_HEADER_EXTENSION_SIZE_BYTES 1
24#endif
Cyril Concolato6c788832017-10-30 16:30:35 -070025
26#if CONFIG_OBU_NO_IVF
27int obu_read_temporal_unit(FILE *infile, uint8_t **buffer, size_t *bytes_read,
Soo-Chul Hanf8589862018-01-24 03:13:14 +000028#if CONFIG_SCALABILITY
29 size_t *buffer_size, int last_layer_id) {
30#else
Cyril Concolato6c788832017-10-30 16:30:35 -070031 size_t *buffer_size) {
Soo-Chul Hanf8589862018-01-24 03:13:14 +000032#endif
Cyril Concolato6c788832017-10-30 16:30:35 -070033 size_t ret;
34 const size_t obu_length_header_size =
35 PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES;
Hui Sue19c3212018-02-21 14:32:18 -080036 uint64_t obu_size = 0;
Cyril Concolato6c788832017-10-30 16:30:35 -070037 uint8_t *data = NULL;
38
39 if (feof(infile)) {
40 return 1;
41 }
42
43 *buffer_size = 0;
44 *bytes_read = 0;
45 while (1) {
46 // augment the buffer to just contain the next size field
47 // and the first byte of the header
48 *buffer = realloc(*buffer, (*buffer_size) + obu_length_header_size);
49 data = *buffer + (*buffer_size);
50 *buffer_size += obu_length_header_size;
51 ret = fread(data, 1, obu_length_header_size, infile);
52 if (ret == 0) {
53 // fprintf(stderr, "Found end of stream, ending temporal unit\n");
54 break;
55 }
56 if (ret != obu_length_header_size) {
57 warn("Failed to read OBU Header\n");
58 return 1;
59 }
60 *bytes_read += obu_length_header_size;
61
62 if (((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) == OBU_TEMPORAL_DELIMITER) {
63 // Stop when a temporal delimiter is found
64 // fprintf(stderr, "Found temporal delimiter, ending temporal unit\n");
65 // prevent decoder to start decoding another frame from this buffer
66 *bytes_read -= obu_length_header_size;
67 break;
68 }
69
Soo-Chul Hanf8589862018-01-24 03:13:14 +000070#if CONFIG_SCALABILITY
71 // break if obu_extension_flag is found and enhancement_id change
72 if ((data[PRE_OBU_SIZE_BYTES] & 0x1)) {
73 uint8_t obu_extension_header;
Hui Sue19c3212018-02-21 14:32:18 -080074 const int total_obu_header_size =
Soo-Chul Hanf8589862018-01-24 03:13:14 +000075 (int)obu_length_header_size + OBU_HEADER_EXTENSION_SIZE_BYTES;
76 int curr_layer_id;
Hui Sue19c3212018-02-21 14:32:18 -080077 ret = fread(&obu_extension_header, 1, OBU_HEADER_EXTENSION_SIZE_BYTES,
78 infile);
79 if (ret != OBU_HEADER_EXTENSION_SIZE_BYTES) {
80 warn("Failed to read OBU Header Extension\n");
81 return 1;
82 }
Soo-Chul Hanf8589862018-01-24 03:13:14 +000083 curr_layer_id = (obu_extension_header >> 3) & 0x3;
84 if (curr_layer_id && (curr_layer_id > last_layer_id)) {
85 // new enhancement layer
86 *bytes_read -= obu_length_header_size;
87 fseek(infile, -total_obu_header_size, SEEK_CUR);
88 break;
89 } else {
90 fseek(infile, -OBU_HEADER_EXTENSION_SIZE_BYTES, SEEK_CUR);
91 }
92 }
93#endif
94
Tom Finegan41150ad2018-01-23 11:42:55 -080095// otherwise, read the OBU payload into memory
96#if CONFIG_OBU_SIZING
David Barker0debbaa2018-02-23 14:39:01 +000097 aom_uleb_decode(data, PRE_OBU_SIZE_BYTES, &obu_size, NULL);
Tom Finegan41150ad2018-01-23 11:42:55 -080098#else
Cyril Concolato6c788832017-10-30 16:30:35 -070099 obu_size = mem_get_le32(data);
Tom Finegan41150ad2018-01-23 11:42:55 -0800100#endif // CONFIG_OBU_SIZING
101
Cyril Concolato6c788832017-10-30 16:30:35 -0700102 // fprintf(stderr, "Found OBU of type %d and size %d\n",
103 // ((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF), obu_size);
104 obu_size--; // removing the byte of the header already read
105 if (obu_size) {
106 *buffer = realloc(*buffer, (*buffer_size) + obu_size);
107 data = *buffer + (*buffer_size);
108 *buffer_size += obu_size;
109 ret = fread(data, 1, obu_size, infile);
110 if (ret != obu_size) {
111 warn("Failed to read OBU Payload\n");
112 return 1;
113 }
114 *bytes_read += obu_size;
115 }
116 }
117 return 0;
118}
119
120int file_is_obu(struct AvxInputContext *input_ctx) {
121 uint8_t obutd[PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES];
Hui Sue19c3212018-02-21 14:32:18 -0800122 uint64_t size;
Cyril Concolato6c788832017-10-30 16:30:35 -0700123
Cyril Concolato6c788832017-10-30 16:30:35 -0700124 // Reading the first OBU TD to enable TU end detection at TD start.
Hui Sue19c3212018-02-21 14:32:18 -0800125 const size_t obu_length_header_size =
126 PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES;
127 const size_t ret = fread(obutd, 1, obu_length_header_size, input_ctx->file);
128 if (ret != obu_length_header_size) {
129 warn("Failed to read OBU Header\n");
130 return 0;
131 }
Tom Finegan41150ad2018-01-23 11:42:55 -0800132
133#if CONFIG_OBU_SIZING
David Barker0debbaa2018-02-23 14:39:01 +0000134 aom_uleb_decode(obutd, PRE_OBU_SIZE_BYTES, &size, NULL);
Tom Finegan41150ad2018-01-23 11:42:55 -0800135#else
Cyril Concolato6c788832017-10-30 16:30:35 -0700136 size = mem_get_le32(obutd);
Tom Finegan41150ad2018-01-23 11:42:55 -0800137#endif // CONFIG_OBU_SIZING
138
Cyril Concolato6c788832017-10-30 16:30:35 -0700139 if (size != 1) {
140 warn("Expected first OBU size to be 1, got %d", size);
141 return 0;
142 }
143 if (((obutd[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) != OBU_TEMPORAL_DELIMITER) {
144 warn("Expected OBU TD at file start, got %d\n", obutd[PRE_OBU_SIZE_BYTES]);
145 return 0;
146 }
147 // fprintf(stderr, "Starting to parse OBU stream\n");
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000148
Cyril Concolato6c788832017-10-30 16:30:35 -0700149 return 1;
150}
151
152#endif