blob: 6b53b003beae6df75edab7378ba8924fdba4a9b1 [file] [log] [blame]
Sebastien Alaiwane9644be2017-12-19 18:20:12 +01001/*
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 <assert.h>
13
14#include "./aom_config.h"
15
16#include "aom/aom_codec.h"
17#include "aom_dsp/bitreader_buffer.h"
18#include "aom_ports/mem_ops.h"
19
20#include "av1/common/common.h"
21#include "av1/decoder/decoder.h"
22#include "av1/decoder/decodeframe.h"
Tom Finegan04450b12018-03-19 18:12:28 -070023#include "av1/decoder/obu.h"
Sebastien Alaiwane9644be2017-12-19 18:20:12 +010024
Tom Finegan9540d592018-02-06 10:04:31 -080025// Picture prediction structures (0-12 are predefined) in scalability metadata.
Soo-Chul Hanf8589862018-01-24 03:13:14 +000026typedef enum {
27 SCALABILITY_L1T2 = 0,
28 SCALABILITY_L1T3 = 1,
29 SCALABILITY_L2T1 = 2,
30 SCALABILITY_L2T2 = 3,
31 SCALABILITY_L2T3 = 4,
32 SCALABILITY_S2T1 = 5,
33 SCALABILITY_S2T2 = 6,
34 SCALABILITY_S2T3 = 7,
35 SCALABILITY_L2T2h = 8,
36 SCALABILITY_L2T3h = 9,
37 SCALABILITY_S2T1h = 10,
38 SCALABILITY_S2T2h = 11,
39 SCALABILITY_S2T3h = 12,
40 SCALABILITY_SS = 13
41} SCALABILITY_STRUCTURES;
Soo-Chul Hanf8589862018-01-24 03:13:14 +000042
Tom Finegan13ee28c2018-02-26 19:37:41 -080043int get_obu_type(uint8_t obu_header, OBU_TYPE *obu_type) {
44 if (!obu_type) return -1;
45 *obu_type = (OBU_TYPE)((obu_header >> 3) & 0xF);
46 switch (*obu_type) {
Tom Finegane4e2d092018-03-01 22:21:23 -080047 case OBU_SEQUENCE_HEADER:
48 case OBU_TEMPORAL_DELIMITER:
49 case OBU_FRAME_HEADER:
Tom Fineganf9273812018-03-14 09:49:45 -070050 case OBU_REDUNDANT_FRAME_HEADER:
Tom Fineganf9273812018-03-14 09:49:45 -070051 case OBU_FRAME:
Tom Finegane4e2d092018-03-01 22:21:23 -080052 case OBU_TILE_GROUP:
53 case OBU_METADATA:
Tom Finegan13ee28c2018-02-26 19:37:41 -080054 case OBU_PADDING: break;
55 default: return -1;
56 }
57 return 0;
58}
59
Tom Finegane4e2d092018-03-01 22:21:23 -080060// Returns 1 when OBU type is valid, and 0 otherwise.
61static int valid_obu_type(int obu_type) {
62 int valid_type = 0;
63 switch (obu_type) {
64 case OBU_SEQUENCE_HEADER:
65 case OBU_TEMPORAL_DELIMITER:
66 case OBU_FRAME_HEADER:
Tom Fineganf9273812018-03-14 09:49:45 -070067 case OBU_REDUNDANT_FRAME_HEADER:
Vignesh Venkatasubramanianb2ce34e2018-03-05 16:57:40 -080068 case OBU_FRAME:
Tom Fineganf9273812018-03-14 09:49:45 -070069 case OBU_TILE_GROUP:
Tom Finegane4e2d092018-03-01 22:21:23 -080070 case OBU_METADATA:
71 case OBU_PADDING: valid_type = 1; break;
72 default: break;
73 }
74 return valid_type;
75}
76
Vignesh Venkatasubramanian2faf53d2018-03-14 11:25:50 -070077// Parses OBU header and stores values in 'header'.
78static aom_codec_err_t read_obu_header(struct aom_read_bit_buffer *rb,
Soo-Chul Han29c46fb2018-03-23 16:02:00 -040079 int is_annexb, ObuHeader *header) {
Tom Finegane4e2d092018-03-01 22:21:23 -080080 if (!rb || !header) return AOM_CODEC_INVALID_PARAM;
81
82 header->size = 1;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +010083
84 // first bit is obu_forbidden_bit (0) according to R19
85 aom_rb_read_bit(rb);
86
Tom Finegane4e2d092018-03-01 22:21:23 -080087 header->type = (OBU_TYPE)aom_rb_read_literal(rb, 4);
88
89 if (!valid_obu_type(header->type)) return AOM_CODEC_CORRUPT_FRAME;
90
Tom Finegane4e2d092018-03-01 22:21:23 -080091 header->has_extension = aom_rb_read_bit(rb);
Tom Finegan04450b12018-03-19 18:12:28 -070092 header->has_length_field = aom_rb_read_bit(rb);
Soo-Chul Han29c46fb2018-03-23 16:02:00 -040093
94 if (!header->has_length_field && !is_annexb) {
95 // section 5 obu streams must have length field set.
Vignesh Venkatasubramanian2faf53d2018-03-14 11:25:50 -070096 return AOM_CODEC_UNSUP_BITSTREAM;
97 }
Tom Finegan5427be12018-03-14 18:45:39 -070098
Vignesh Venkatasubramanian726f7952018-03-08 15:03:35 -080099 aom_rb_read_bit(rb); // reserved
Vignesh Venkatasubramanian726f7952018-03-08 15:03:35 -0800100
Tom Finegan04450b12018-03-19 18:12:28 -0700101 const ptrdiff_t bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer;
102 if (header->has_extension && bit_buffer_byte_length > 1) {
Tom Finegane4e2d092018-03-01 22:21:23 -0800103 header->size += 1;
104 header->temporal_layer_id = aom_rb_read_literal(rb, 3);
105 header->enhancement_layer_id = aom_rb_read_literal(rb, 2);
106 aom_rb_read_literal(rb, 3); // reserved
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100107 }
108
Tom Finegane4e2d092018-03-01 22:21:23 -0800109 return AOM_CODEC_OK;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100110}
111
Tom Finegan04450b12018-03-19 18:12:28 -0700112aom_codec_err_t aom_read_obu_header(uint8_t *buffer, size_t buffer_length,
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400113 size_t *consumed, ObuHeader *header,
114 int is_annexb) {
Tom Finegan04450b12018-03-19 18:12:28 -0700115 if (buffer_length < 1 || !consumed || !header) return AOM_CODEC_INVALID_PARAM;
116
117 // TODO(tomfinegan): Set the error handler here and throughout this file, and
118 // confirm parsing work done via aom_read_bit_buffer is successful.
119 struct aom_read_bit_buffer rb = { buffer, buffer + buffer_length, 0, NULL,
120 NULL };
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400121 aom_codec_err_t parse_result = read_obu_header(&rb, is_annexb, header);
Tom Finegan04450b12018-03-19 18:12:28 -0700122 if (parse_result == AOM_CODEC_OK) *consumed = header->size;
123 return parse_result;
124}
125
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400126static int is_obu_in_current_operating_point(AV1Decoder *pbi,
127 ObuHeader obu_header) {
128 if (!pbi->current_operating_point) {
129 return 1;
130 }
131
132 if ((pbi->current_operating_point >> obu_header.temporal_layer_id) & 0x1 &&
133 (pbi->current_operating_point >> (obu_header.enhancement_layer_id + 8)) &
134 0x1) {
135 return 1;
136 }
137 return 0;
138}
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400139
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100140static uint32_t read_temporal_delimiter_obu() { return 0; }
141
142static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
143 struct aom_read_bit_buffer *rb) {
144 AV1_COMMON *const cm = &pbi->common;
145 uint32_t saved_bit_offset = rb->bit_offset;
146
147 cm->profile = av1_read_profile(rb);
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400148
Debargha Mukherjee5d6e3fb2018-04-03 13:05:54 -0700149 SequenceHeader *seq_params = &cm->seq_params;
150
151 // Still picture or not
152 seq_params->still_picture = aom_rb_read_bit(rb);
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700153 seq_params->reduced_still_picture_hdr = aom_rb_read_bit(rb);
154 // Video must have reduced_still_picture_hdr = 0
155 if (!cm->seq_params.still_picture &&
156 cm->seq_params.reduced_still_picture_hdr) {
157 return AOM_CODEC_UNSUP_BITSTREAM;
158 }
Debargha Mukherjee5d6e3fb2018-04-03 13:05:54 -0700159
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700160 if (seq_params->reduced_still_picture_hdr) {
161 pbi->common.enhancement_layers_cnt = 1;
162 seq_params->operating_point_idc[0] = 0;
Debargha Mukherjeeacd41f92018-04-11 07:58:34 -0700163 seq_params->level[0] = aom_rb_read_literal(rb, LEVEL_BITS);
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700164 seq_params->decoder_rate_model_param_present_flag[0] = 0;
165 } else {
Debargha Mukherjee112c5822018-04-09 09:42:29 -0700166 uint8_t operating_points_minus1_cnt =
167 aom_rb_read_literal(rb, OP_POINTS_MINUS1_BITS);
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700168 pbi->common.enhancement_layers_cnt = operating_points_minus1_cnt + 1;
169 for (int i = 0; i < operating_points_minus1_cnt + 1; i++) {
Debargha Mukherjee112c5822018-04-09 09:42:29 -0700170 seq_params->operating_point_idc[i] =
171 aom_rb_read_literal(rb, OP_POINTS_IDC_BITS);
172 seq_params->level[i] = aom_rb_read_literal(rb, LEVEL_BITS);
Andrey Norkin795ba872018-03-06 13:24:14 -0800173#if !CONFIG_BUFFER_MODEL
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700174 seq_params->decoder_rate_model_param_present_flag[i] =
175 aom_rb_read_literal(rb, 1);
176 if (seq_params->decoder_rate_model_param_present_flag[i]) {
177 seq_params->decode_to_display_rate_ratio[i] =
178 aom_rb_read_literal(rb, 12);
179 seq_params->initial_display_delay[i] = aom_rb_read_literal(rb, 24);
180 seq_params->extra_frame_buffers[i] = aom_rb_read_literal(rb, 4);
181 }
Andrey Norkin795ba872018-03-06 13:24:14 -0800182#endif
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400183 }
184 }
185 // This decoder supports all levels. Choose the first operating point
186 pbi->current_operating_point = seq_params->operating_point_idc[0];
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000187
Thomas Davies0cbcf792018-03-15 14:10:02 +0000188 read_sequence_header(cm, rb);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100189
190 av1_read_bitdepth_colorspace_sampling(cm, rb, pbi->allow_lowbitdepth);
191
Andrey Norkin795ba872018-03-06 13:24:14 -0800192#if !CONFIG_BUFFER_MODEL
Debargha Mukherjeec6f24c22018-04-07 08:43:08 -0700193 if (!seq_params->reduced_still_picture_hdr)
194 av1_read_timing_info_header(cm, rb);
195 else
196 cm->timing_info_present = 0;
Andrey Norkin795ba872018-03-06 13:24:14 -0800197#else
198 if (!seq_params->reduced_still_picture_hdr)
199 cm->timing_info_present = aom_rb_read_bit(rb); // timing info present flag
200 else
201 cm->timing_info_present = 0;
202
203 if (cm->timing_info_present) {
204 av1_read_timing_info_header(cm, rb);
205
206 cm->decoder_model_info_present_flag = aom_rb_read_bit(rb);
207 if (cm->decoder_model_info_present_flag)
208 av1_read_decoder_model_info(cm, rb);
209 }
210 int operating_points_decoder_model_present = aom_rb_read_bit(rb);
211 if (operating_points_decoder_model_present) {
212 cm->operating_points_decoder_model_cnt = aom_rb_read_literal(rb, 5) + 1;
213 } else {
214 cm->operating_points_decoder_model_cnt = 0;
215 }
216 for (int op_num = 0; op_num < cm->operating_points_decoder_model_cnt;
217 ++op_num) {
218 cm->op_params[op_num].decoder_model_operating_point_idc =
219 aom_rb_read_literal(rb, 12);
220 cm->op_params[op_num].display_model_param_present_flag =
221 aom_rb_read_bit(rb);
222 if (cm->op_params[op_num].display_model_param_present_flag) {
223 cm->op_params[op_num].initial_display_delay =
224 aom_rb_read_literal(rb, 4) + 1;
225 if (cm->op_params[op_num].initial_display_delay > 10)
226 aom_internal_error(
227 &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
228 "AV1 does not support more than 10 decoded frames delay");
229 }
230 if (cm->decoder_model_info_present_flag) {
231 cm->op_params[op_num].decoder_model_param_present_flag =
232 aom_rb_read_bit(rb);
233 if (cm->op_params[op_num].decoder_model_param_present_flag)
234 av1_read_op_parameters_info(cm, rb, op_num);
235 }
236 }
237#endif
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800238
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800239 cm->film_grain_params_present = aom_rb_read_bit(rb);
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800240
Jingning Han53995e12018-03-23 08:02:57 -0700241 av1_check_trailing_bits(pbi, rb);
Jingning Han8a59bd52018-03-22 21:30:31 -0700242
David Barker3a7b5c22018-03-21 12:06:16 +0000243 pbi->sequence_header_ready = 1;
Hui Su224cf962018-03-11 12:28:10 -0700244
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100245 return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
246}
247
Cyril Concolato2dab2752018-02-26 14:25:47 -0800248static uint32_t read_frame_header_obu(AV1Decoder *pbi,
Cyril Concolato2dab2752018-02-26 14:25:47 -0800249 struct aom_read_bit_buffer *rb,
Cyril Concolato2dab2752018-02-26 14:25:47 -0800250 const uint8_t *data,
Vignesh Venkatasubramanianbd7b0e32018-04-10 11:31:59 -0700251 const uint8_t **p_data_end,
252 int trailing_bits_present) {
253 av1_decode_frame_headers_and_setup(pbi, rb, data, p_data_end,
254 trailing_bits_present);
Yunqing Wange7142e12018-01-17 11:20:12 -0800255 return (uint32_t)(pbi->uncomp_hdr_size);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100256}
257
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700258static int32_t read_tile_group_header(AV1Decoder *pbi,
259 struct aom_read_bit_buffer *rb,
260 int *startTile, int *endTile,
261 int tile_start_implicit) {
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100262 AV1_COMMON *const cm = &pbi->common;
263 uint32_t saved_bit_offset = rb->bit_offset;
Vignesh Venkatasubramanian2a06b412018-03-01 15:18:06 -0800264 int tile_start_and_end_present_flag = 0;
265 const int num_tiles = pbi->common.tile_rows * pbi->common.tile_cols;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100266
Vignesh Venkatasubramanian2a06b412018-03-01 15:18:06 -0800267 if (!pbi->common.large_scale_tile && num_tiles > 1) {
268 tile_start_and_end_present_flag = aom_rb_read_bit(rb);
269 }
270 if (pbi->common.large_scale_tile || num_tiles == 1 ||
271 !tile_start_and_end_present_flag) {
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100272 *startTile = 0;
Vignesh Venkatasubramanian2a06b412018-03-01 15:18:06 -0800273 *endTile = num_tiles - 1;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100274 return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
275 }
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700276 if (tile_start_implicit && tile_start_and_end_present_flag) {
277 return -1;
278 }
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100279 *startTile = aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols);
280 *endTile = aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols);
281
282 return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
283}
284
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700285static uint32_t read_one_tile_group_obu(
286 AV1Decoder *pbi, struct aom_read_bit_buffer *rb, int is_first_tg,
287 const uint8_t *data, const uint8_t *data_end, const uint8_t **p_data_end,
288 int *is_last_tg, int tile_start_implicit) {
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100289 AV1_COMMON *const cm = &pbi->common;
290 int startTile, endTile;
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700291 int32_t header_size, tg_payload_size;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100292
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700293 header_size = read_tile_group_header(pbi, rb, &startTile, &endTile,
294 tile_start_implicit);
295 if (header_size == -1) return 0;
Hui Sua94c7752018-03-12 11:43:41 -0700296 if (startTile > endTile) return header_size;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100297 data += header_size;
298 av1_decode_tg_tiles_and_wrapup(pbi, data, data_end, p_data_end, startTile,
299 endTile, is_first_tg);
Frank Bossenebcf3e52018-03-27 12:19:20 -0400300
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100301 tg_payload_size = (uint32_t)(*p_data_end - data);
302
303 // TODO(shan): For now, assume all tile groups received in order
304 *is_last_tg = endTile == cm->tile_rows * cm->tile_cols - 1;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100305 return header_size + tg_payload_size;
306}
307
308static void read_metadata_private_data(const uint8_t *data, size_t sz) {
309 for (size_t i = 0; i < sz; i++) {
310 mem_get_le16(data);
311 data += 2;
312 }
313}
314
315static void read_metadata_hdr_cll(const uint8_t *data) {
316 mem_get_le16(data);
317 mem_get_le16(data + 2);
318}
319
320static void read_metadata_hdr_mdcv(const uint8_t *data) {
321 for (int i = 0; i < 3; i++) {
322 mem_get_le16(data);
323 data += 2;
324 mem_get_le16(data);
325 data += 2;
326 }
327
328 mem_get_le16(data);
329 data += 2;
330 mem_get_le16(data);
331 data += 2;
332 mem_get_le16(data);
333 data += 2;
334 mem_get_le16(data);
335}
336
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000337static void scalability_structure(struct aom_read_bit_buffer *rb) {
338 int enhancement_layers_cnt = aom_rb_read_literal(rb, 2);
339 int enhancement_layer_dimensions_present_flag = aom_rb_read_literal(rb, 1);
340 int enhancement_layer_description_present_flag = aom_rb_read_literal(rb, 1);
341 int temporal_group_description_flag = aom_rb_read_literal(rb, 1);
342 aom_rb_read_literal(rb, 3); // reserved
343
344 if (enhancement_layer_dimensions_present_flag) {
345 int i;
346 for (i = 0; i < enhancement_layers_cnt + 1; i++) {
347 aom_rb_read_literal(rb, 16);
348 aom_rb_read_literal(rb, 16);
349 }
350 }
351 if (enhancement_layer_description_present_flag) {
352 int i;
353 for (i = 0; i < enhancement_layers_cnt + 1; i++) {
354 aom_rb_read_literal(rb, 8);
355 }
356 }
357 if (temporal_group_description_flag) {
358 int i, j, temporal_group_size;
359 temporal_group_size = aom_rb_read_literal(rb, 8);
360 for (i = 0; i < temporal_group_size; i++) {
361 aom_rb_read_literal(rb, 3);
362 aom_rb_read_literal(rb, 1);
363 int temporal_group_ref_cnt = aom_rb_read_literal(rb, 2);
364 aom_rb_read_literal(rb, 2);
365 for (j = 0; j < temporal_group_ref_cnt; j++) {
366 aom_rb_read_literal(rb, 8);
367 }
368 }
369 }
370}
371
372static void read_metadata_scalability(const uint8_t *data, size_t sz) {
373 struct aom_read_bit_buffer rb = { data, data + sz, 0, NULL, NULL };
374 int scalability_mode_idc = aom_rb_read_literal(&rb, 8);
375 if (scalability_mode_idc == SCALABILITY_SS) {
376 scalability_structure(&rb);
377 }
378}
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000379
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100380static size_t read_metadata(const uint8_t *data, size_t sz) {
Hui Suc3b42aa2018-03-12 10:20:39 -0700381 if (sz < 2) return sz; // Invalid data size.
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100382 const OBU_METADATA_TYPE metadata_type = (OBU_METADATA_TYPE)mem_get_le16(data);
383
384 if (metadata_type == OBU_METADATA_TYPE_PRIVATE_DATA) {
385 read_metadata_private_data(data + 2, sz - 2);
386 } else if (metadata_type == OBU_METADATA_TYPE_HDR_CLL) {
387 read_metadata_hdr_cll(data + 2);
388 } else if (metadata_type == OBU_METADATA_TYPE_HDR_MDCV) {
389 read_metadata_hdr_mdcv(data + 2);
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000390 } else if (metadata_type == OBU_METADATA_TYPE_SCALABILITY) {
391 read_metadata_scalability(data + 2, sz - 2);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100392 }
393
394 return sz;
395}
396
Vignesh Venkatasubramanianea0257d2018-02-28 14:43:34 -0800397static aom_codec_err_t read_obu_size(const uint8_t *data,
398 size_t bytes_available,
399 size_t *const obu_size,
400 size_t *const length_field_size) {
401 uint64_t u_obu_size = 0;
402 if (aom_uleb_decode(data, bytes_available, &u_obu_size, length_field_size) !=
403 0) {
404 return AOM_CODEC_CORRUPT_FRAME;
405 }
406
407 *obu_size = (size_t)u_obu_size;
408 return AOM_CODEC_OK;
409}
Vignesh Venkatasubramanianea0257d2018-02-28 14:43:34 -0800410
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100411void av1_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
412 const uint8_t *data_end,
413 const uint8_t **p_data_end) {
414 AV1_COMMON *const cm = &pbi->common;
415 int frame_decoding_finished = 0;
416 int is_first_tg_obu_received = 1;
417 int frame_header_received = 0;
418 int frame_header_size = 0;
Yaowu Xu5018f6a2018-03-01 16:21:03 -0800419 int seq_header_received = 0;
420 size_t seq_header_size = 0;
Tom Finegane4e2d092018-03-01 22:21:23 -0800421 ObuHeader obu_header;
422 memset(&obu_header, 0, sizeof(obu_header));
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100423
Hui Sub4d6b1c2018-01-08 13:43:12 -0800424 if (data_end < data) {
425 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
426 return;
427 }
428
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100429 // decode frame as a series of OBUs
430 while (!frame_decoding_finished && !cm->error.error_code) {
431 struct aom_read_bit_buffer rb;
David Barker3bb1f2a2017-10-09 14:57:17 +0100432 size_t payload_size = 0;
433 size_t decoded_payload_size = 0;
Vignesh Venkatasubramanianb2ce34e2018-03-05 16:57:40 -0800434 size_t obu_payload_offset = 0;
Tom Fineganf2d40f62018-02-01 11:52:49 -0800435 const size_t bytes_available = data_end - data;
436
437 if (bytes_available < 1) {
438 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
439 return;
440 }
Tom Finegan41150ad2018-01-23 11:42:55 -0800441
Vignesh Venkatasubramanian6198ebc2018-03-02 12:47:33 -0800442 size_t length_field_size = 0;
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400443 size_t obu_size = 0;
444 if (cm->is_annexb) {
445 if (read_obu_size(data, bytes_available, &obu_size, &length_field_size) !=
446 AOM_CODEC_OK) {
447 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
448 return;
449 }
450 }
Hui Su9c84d422018-03-11 15:48:09 -0700451 if (data_end < data + length_field_size) {
452 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
453 return;
454 }
Tom Fineganf2d40f62018-02-01 11:52:49 -0800455 av1_init_read_bit_buffer(pbi, &rb, data + length_field_size, data_end);
456
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400457 const aom_codec_err_t status =
458 read_obu_header(&rb, cm->is_annexb, &obu_header);
Vignesh Venkatasubramanian2faf53d2018-03-14 11:25:50 -0700459 if (status != AOM_CODEC_OK) {
460 cm->error.error_code = status;
Tom Finegane4e2d092018-03-01 22:21:23 -0800461 return;
462 }
463
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400464 if (!cm->is_annexb) {
Hui Su5c9751e2018-04-06 14:08:22 -0700465 if (data_end < data + obu_header.size) {
466 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
467 return;
468 }
Soo-Chul Han29c46fb2018-03-23 16:02:00 -0400469 if (read_obu_size(data + obu_header.size,
470 bytes_available - obu_header.size, &payload_size,
471 &length_field_size) != AOM_CODEC_OK) {
472 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
473 return;
474 }
475 av1_init_read_bit_buffer(
476 pbi, &rb, data + length_field_size + obu_header.size, data_end);
477 } else {
478 payload_size = obu_size - obu_header.size;
Vignesh Venkatasubramanianea0257d2018-02-28 14:43:34 -0800479 }
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000480
Tom Finegane4e2d092018-03-01 22:21:23 -0800481 data += length_field_size + obu_header.size;
Hui Sub4d6b1c2018-01-08 13:43:12 -0800482 if (data_end < data) {
483 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
484 return;
485 }
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000486
Tom Finegane4e2d092018-03-01 22:21:23 -0800487 cm->temporal_layer_id = obu_header.temporal_layer_id;
488 cm->enhancement_layer_id = obu_header.enhancement_layer_id;
Soo-Chul Hanf8589862018-01-24 03:13:14 +0000489
Tom Finegane4e2d092018-03-01 22:21:23 -0800490 switch (obu_header.type) {
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100491 case OBU_TEMPORAL_DELIMITER:
David Barker3bb1f2a2017-10-09 14:57:17 +0100492 decoded_payload_size = read_temporal_delimiter_obu();
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100493 break;
494 case OBU_SEQUENCE_HEADER:
Yaowu Xu5018f6a2018-03-01 16:21:03 -0800495 if (!seq_header_received) {
David Barker3bb1f2a2017-10-09 14:57:17 +0100496 decoded_payload_size = read_sequence_header_obu(pbi, &rb);
497 seq_header_size = decoded_payload_size;
Yaowu Xu5018f6a2018-03-01 16:21:03 -0800498 seq_header_received = 1;
499 } else {
500 // Seeing another sequence header, skip as all sequence headers
501 // are requred to be identical.
David Barker3bb1f2a2017-10-09 14:57:17 +0100502 if (payload_size != seq_header_size) {
Yaowu Xu5018f6a2018-03-01 16:21:03 -0800503 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
504 return;
505 }
David Barker3bb1f2a2017-10-09 14:57:17 +0100506 decoded_payload_size = seq_header_size;
Yaowu Xu5018f6a2018-03-01 16:21:03 -0800507 }
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100508 break;
Tom Finegan542aa322018-03-14 18:03:17 -0700509 case OBU_FRAME_HEADER:
Tom Fineganf9273812018-03-14 09:49:45 -0700510 case OBU_REDUNDANT_FRAME_HEADER:
Tom Finegan542aa322018-03-14 18:03:17 -0700511 case OBU_FRAME:
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400512 // don't decode obu if it's not in current operating mode
513 if (!is_obu_in_current_operating_point(pbi, obu_header)) {
514 decoded_payload_size = payload_size;
515 break;
516 }
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100517 // Only decode first frame header received
518 if (!frame_header_received) {
Cyril Concolato2dab2752018-02-26 14:25:47 -0800519 av1_init_read_bit_buffer(pbi, &rb, data, data_end);
Vignesh Venkatasubramanianbd7b0e32018-04-10 11:31:59 -0700520 frame_header_size = read_frame_header_obu(
521 pbi, &rb, data, p_data_end, obu_header.type != OBU_FRAME);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100522 frame_header_received = 1;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100523 }
David Barker3bb1f2a2017-10-09 14:57:17 +0100524 decoded_payload_size = frame_header_size;
Vignesh Venkatasubramanianb2ce34e2018-03-05 16:57:40 -0800525 if (cm->show_existing_frame) {
526 frame_decoding_finished = 1;
527 break;
528 }
David Barker163f0f02018-03-20 16:23:33 +0000529 if (obu_header.type != OBU_FRAME) break;
Vignesh Venkatasubramanianb2ce34e2018-03-05 16:57:40 -0800530 obu_payload_offset = frame_header_size;
531 AOM_FALLTHROUGH_INTENDED; // fall through to read tile group.
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100532 case OBU_TILE_GROUP:
Yaowu Xucc7b4482018-02-28 07:03:01 -0800533 if (!frame_header_received) {
534 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
535 return;
536 }
Hui Su9c84d422018-03-11 15:48:09 -0700537 if (data_end < data + obu_payload_offset ||
538 data_end < data + payload_size) {
539 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
540 return;
541 }
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400542 // don't decode obu if it's not in current operating mode
543 if (!is_obu_in_current_operating_point(pbi, obu_header)) {
544 decoded_payload_size = payload_size;
545 break;
546 }
Vignesh Venkatasubramanianb2ce34e2018-03-05 16:57:40 -0800547 decoded_payload_size += read_one_tile_group_obu(
548 pbi, &rb, is_first_tg_obu_received, data + obu_payload_offset,
Vignesh Venkatasubramanian386d9c32018-04-10 12:39:02 -0700549 data + payload_size, p_data_end, &frame_decoding_finished,
550 obu_header.type == OBU_FRAME);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100551 is_first_tg_obu_received = 0;
552 break;
553 case OBU_METADATA:
Soo-Chul Han79a501a2018-03-19 15:24:40 -0400554 // don't decode obu if it's not in current operating mode
555 if (!is_obu_in_current_operating_point(pbi, obu_header)) {
556 decoded_payload_size = payload_size;
557 break;
558 }
Hui Su5c9751e2018-04-06 14:08:22 -0700559 if (data_end < data + payload_size) {
560 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
561 return;
562 }
David Barker3bb1f2a2017-10-09 14:57:17 +0100563 decoded_payload_size = read_metadata(data, payload_size);
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100564 break;
Yaowu Xu993f7be2018-02-28 08:54:36 -0800565 case OBU_PADDING:
566 default:
David Barker3bb1f2a2017-10-09 14:57:17 +0100567 // Skip unrecognized OBUs
568 decoded_payload_size = payload_size;
Yaowu Xu993f7be2018-02-28 08:54:36 -0800569 break;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100570 }
Tom Fineganf2d40f62018-02-01 11:52:49 -0800571
David Barker3bb1f2a2017-10-09 14:57:17 +0100572 // Check that the signalled OBU size matches the actual amount of data read
David Barkercbba79c2018-03-28 14:29:38 +0100573 if (decoded_payload_size > payload_size) {
David Barker3bb1f2a2017-10-09 14:57:17 +0100574 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
575 return;
576 }
577
Hui Su5c9751e2018-04-06 14:08:22 -0700578 if (data_end < data + payload_size) {
579 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
580 return;
581 }
582
David Barkercbba79c2018-03-28 14:29:38 +0100583 // If there are extra padding bytes, they should all be zero
584 while (decoded_payload_size < payload_size) {
585 uint8_t padding_byte = data[decoded_payload_size++];
586 if (padding_byte != 0) {
587 cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
588 return;
589 }
590 }
591
David Barker3bb1f2a2017-10-09 14:57:17 +0100592 data += payload_size;
Sebastien Alaiwane9644be2017-12-19 18:20:12 +0100593 }
594}