blob: cc8918e5770f4807a530d0578585b71d03c45156 [file] [log] [blame]
James Almer9888a192018-07-07 19:35:321/*
2 * AV1 helper functions for muxers
3 * Copyright (c) 2018 James Almer <[email protected]>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/mem.h"
23#include "libavcodec/av1.h"
24#include "libavcodec/av1_parse.h"
James Almer8d5604a2018-08-16 21:01:4425#include "libavcodec/profiles.h"
26#include "libavcodec/put_bits.h"
James Almer9888a192018-07-07 19:35:3227#include "av1.h"
28#include "avio.h"
29
30int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
31{
32 const uint8_t *end = buf + size;
33 int64_t obu_size;
34 int start_pos, type, temporal_id, spatial_id;
35
36 size = 0;
37 while (buf < end) {
James Almer692e3232018-07-30 18:14:2438 int len = parse_obu_header(buf, end - buf, &obu_size, &start_pos,
James Almer9888a192018-07-07 19:35:3239 &type, &temporal_id, &spatial_id);
James Almer692e3232018-07-30 18:14:2440 if (len < 0)
41 return len;
James Almer9888a192018-07-07 19:35:3242
43 switch (type) {
44 case AV1_OBU_TEMPORAL_DELIMITER:
45 case AV1_OBU_REDUNDANT_FRAME_HEADER:
James Almerf00964e2018-08-17 18:26:0546 case AV1_OBU_TILE_LIST:
James Almer9888a192018-07-07 19:35:3247 case AV1_OBU_PADDING:
48 break;
49 default:
James Almer692e3232018-07-30 18:14:2450 avio_write(pb, buf, len);
51 size += len;
James Almer9888a192018-07-07 19:35:3252 break;
53 }
James Almer692e3232018-07-30 18:14:2454 buf += len;
James Almer9888a192018-07-07 19:35:3255 }
56
57 return size;
58}
59
60int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size)
61{
62 AVIOContext *pb;
63 int ret;
64
65 ret = avio_open_dyn_buf(&pb);
66 if (ret < 0)
67 return ret;
68
69 ret = ff_av1_filter_obus(pb, buf, *size);
70 if (ret < 0)
71 return ret;
72
73 av_freep(out);
74 *size = avio_close_dyn_buf(pb, out);
75
76 return ret;
77}
78
James Almer8d5604a2018-08-16 21:01:4479static inline void uvlc(GetBitContext *gb)
80{
81 int leading_zeros = 0;
82
83 while (get_bits_left(gb)) {
84 if (get_bits1(gb))
85 break;
86 leading_zeros++;
87 }
88
89 if (leading_zeros >= 32)
90 return;
91
92 skip_bits_long(gb, leading_zeros);
93}
94
95static int parse_color_config(AV1SequenceParameters *seq_params, GetBitContext *gb)
96{
James Almer8d5604a2018-08-16 21:01:4497 seq_params->high_bitdepth = get_bits1(gb);
98 if (seq_params->seq_profile == FF_PROFILE_AV1_PROFESSIONAL && seq_params->high_bitdepth)
99 seq_params->twelve_bit = get_bits1(gb);
James Almer8d5604a2018-08-16 21:01:44100
101 if (seq_params->seq_profile == FF_PROFILE_AV1_HIGH)
102 seq_params->monochrome = 0;
103 else
104 seq_params->monochrome = get_bits1(gb);
105
James Almer0c7cfd22019-07-30 14:43:02106 seq_params->color_description_present_flag = get_bits1(gb);
107 if (seq_params->color_description_present_flag) {
108 seq_params->color_primaries = get_bits(gb, 8);
109 seq_params->transfer_characteristics = get_bits(gb, 8);
110 seq_params->matrix_coefficients = get_bits(gb, 8);
James Almer8d5604a2018-08-16 21:01:44111 } else {
James Almer0c7cfd22019-07-30 14:43:02112 seq_params->color_primaries = AVCOL_PRI_UNSPECIFIED;
113 seq_params->transfer_characteristics = AVCOL_TRC_UNSPECIFIED;
114 seq_params->matrix_coefficients = AVCOL_SPC_UNSPECIFIED;
James Almer8d5604a2018-08-16 21:01:44115 }
116
117 if (seq_params->monochrome) {
James Almer0c7cfd22019-07-30 14:43:02118 seq_params->color_range = get_bits1(gb);
James Almer8d5604a2018-08-16 21:01:44119 seq_params->chroma_subsampling_x = 1;
120 seq_params->chroma_subsampling_y = 1;
121 seq_params->chroma_sample_position = 0;
122 return 0;
James Almer0c7cfd22019-07-30 14:43:02123 } else if (seq_params->color_primaries == AVCOL_PRI_BT709 &&
124 seq_params->transfer_characteristics == AVCOL_TRC_IEC61966_2_1 &&
125 seq_params->matrix_coefficients == AVCOL_SPC_RGB) {
James Almer8d5604a2018-08-16 21:01:44126 seq_params->chroma_subsampling_x = 0;
127 seq_params->chroma_subsampling_y = 0;
128 } else {
James Almer0c7cfd22019-07-30 14:43:02129 seq_params->color_range = get_bits1(gb);
James Almer8d5604a2018-08-16 21:01:44130
131 if (seq_params->seq_profile == FF_PROFILE_AV1_MAIN) {
132 seq_params->chroma_subsampling_x = 1;
133 seq_params->chroma_subsampling_y = 1;
134 } else if (seq_params->seq_profile == FF_PROFILE_AV1_HIGH) {
135 seq_params->chroma_subsampling_x = 0;
136 seq_params->chroma_subsampling_y = 0;
137 } else {
138 if (seq_params->twelve_bit) {
139 seq_params->chroma_subsampling_x = get_bits1(gb);
140 if (seq_params->chroma_subsampling_x)
141 seq_params->chroma_subsampling_y = get_bits1(gb);
142 else
143 seq_params->chroma_subsampling_y = 0;
144 } else {
145 seq_params->chroma_subsampling_x = 1;
146 seq_params->chroma_subsampling_y = 0;
147 }
148 }
149 if (seq_params->chroma_subsampling_x && seq_params->chroma_subsampling_y)
150 seq_params->chroma_sample_position = get_bits(gb, 2);
151 }
152
153 skip_bits1(gb); // separate_uv_delta_q
154
155 return 0;
156}
157
158static int parse_sequence_header(AV1SequenceParameters *seq_params, const uint8_t *buf, int size)
159{
160 GetBitContext gb;
161 int reduced_still_picture_header;
162 int frame_width_bits_minus_1, frame_height_bits_minus_1;
163 int size_bits, ret;
164
165 size_bits = get_obu_bit_length(buf, size, AV1_OBU_SEQUENCE_HEADER);
166 if (size_bits < 0)
167 return size_bits;
168
169 ret = init_get_bits(&gb, buf, size_bits);
170 if (ret < 0)
171 return ret;
172
James Almer11cec342018-09-03 02:27:51173 memset(seq_params, 0, sizeof(*seq_params));
174
James Almer8d5604a2018-08-16 21:01:44175 seq_params->seq_profile = get_bits(&gb, 3);
176
177 skip_bits1(&gb); // still_picture
178 reduced_still_picture_header = get_bits1(&gb);
179
180 if (reduced_still_picture_header) {
181 seq_params->seq_level_idx_0 = get_bits(&gb, 5);
182 seq_params->seq_tier_0 = 0;
183 } else {
184 int initial_display_delay_present_flag, operating_points_cnt_minus_1;
185 int decoder_model_info_present_flag, buffer_delay_length_minus_1;
186
187 if (get_bits1(&gb)) { // timing_info_present_flag
188 skip_bits_long(&gb, 32); // num_units_in_display_tick
189 skip_bits_long(&gb, 32); // time_scale
190
191 if (get_bits1(&gb)) // equal_picture_interval
192 uvlc(&gb); // num_ticks_per_picture_minus_1
193
194 decoder_model_info_present_flag = get_bits1(&gb);
195 if (decoder_model_info_present_flag) {
196 buffer_delay_length_minus_1 = get_bits(&gb, 5);
197 skip_bits_long(&gb, 32); // num_units_in_decoding_tick
198 skip_bits(&gb, 10); // buffer_removal_time_length_minus_1 (5)
199 // frame_presentation_time_length_minus_1 (5)
200 }
201 } else
202 decoder_model_info_present_flag = 0;
203
204 initial_display_delay_present_flag = get_bits1(&gb);
205
206 operating_points_cnt_minus_1 = get_bits(&gb, 5);
207 for (int i = 0; i <= operating_points_cnt_minus_1; i++) {
208 int seq_level_idx, seq_tier;
209
210 skip_bits(&gb, 12); // operating_point_idc
211 seq_level_idx = get_bits(&gb, 5);
212
213 if (seq_level_idx > 7)
214 seq_tier = get_bits1(&gb);
215 else
216 seq_tier = 0;
217
218 if (decoder_model_info_present_flag) {
219 if (get_bits1(&gb)) { // decoder_model_present_for_this_op
220 skip_bits_long(&gb, buffer_delay_length_minus_1 + 1); // decoder_buffer_delay
221 skip_bits_long(&gb, buffer_delay_length_minus_1 + 1); // encoder_buffer_delay
222 skip_bits1(&gb); // low_delay_mode_flag
223 }
224 }
225
226 if (initial_display_delay_present_flag) {
227 if (get_bits1(&gb)) // initial_display_delay_present_for_this_op
228 skip_bits(&gb, 4); // initial_display_delay_minus_1
229 }
230
231 if (i == 0) {
232 seq_params->seq_level_idx_0 = seq_level_idx;
233 seq_params->seq_tier_0 = seq_tier;
234 }
235 }
236 }
237
238 frame_width_bits_minus_1 = get_bits(&gb, 4);
239 frame_height_bits_minus_1 = get_bits(&gb, 4);
240
241 skip_bits(&gb, frame_width_bits_minus_1 + 1); // max_frame_width_minus_1
242 skip_bits(&gb, frame_height_bits_minus_1 + 1); // max_frame_height_minus_1
243
244 if (!reduced_still_picture_header) {
245 if (get_bits1(&gb)) // frame_id_numbers_present_flag
246 skip_bits(&gb, 7); // delta_frame_id_length_minus_2 (4), additional_frame_id_length_minus_1 (3)
247 }
248
249 skip_bits(&gb, 3); // use_128x128_superblock (1), enable_filter_intra (1), enable_intra_edge_filter (1)
250
251 if (!reduced_still_picture_header) {
252 int enable_order_hint, seq_force_screen_content_tools;
253
254 skip_bits(&gb, 4); // enable_intraintra_compound (1), enable_masked_compound (1)
255 // enable_warped_motion (1), enable_dual_filter (1)
256
257 enable_order_hint = get_bits1(&gb);
258 if (enable_order_hint)
259 skip_bits(&gb, 2); // enable_jnt_comp (1), enable_ref_frame_mvs (1)
260
261 if (get_bits1(&gb)) // seq_choose_screen_content_tools
262 seq_force_screen_content_tools = 2;
263 else
264 seq_force_screen_content_tools = get_bits1(&gb);
265
266 if (seq_force_screen_content_tools) {
267 if (!get_bits1(&gb)) // seq_choose_integer_mv
268 skip_bits1(&gb); // seq_force_integer_mv
269 }
270
271 if (enable_order_hint)
272 skip_bits(&gb, 3); // order_hint_bits_minus_1
273 }
274
275 skip_bits(&gb, 3); // enable_superres (1), enable_cdef (1), enable_restoration (1)
276
277 parse_color_config(seq_params, &gb);
278
279 skip_bits1(&gb); // film_grain_params_present
280
281 if (get_bits_left(&gb))
282 return AVERROR_INVALIDDATA;
283
284 return 0;
285}
286
James Almer68e48e52019-07-30 15:08:44287int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int size)
288{
289 int64_t obu_size;
290 int start_pos, type, temporal_id, spatial_id;
291
292 if (size <= 0)
293 return AVERROR_INVALIDDATA;
294
295 while (size > 0) {
296 int len = parse_obu_header(buf, size, &obu_size, &start_pos,
297 &type, &temporal_id, &spatial_id);
298 if (len < 0)
299 return len;
300
301 switch (type) {
302 case AV1_OBU_SEQUENCE_HEADER:
303 if (!obu_size)
304 return AVERROR_INVALIDDATA;
305
306 return parse_sequence_header(seq, buf + start_pos, obu_size);
307 default:
308 break;
309 }
310 size -= len;
311 buf += len;
312 }
313
314 return AVERROR_INVALIDDATA;
315}
316
James Almer9888a192018-07-07 19:35:32317int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
318{
James Almerded339f2018-07-30 18:15:43319 AVIOContext *seq_pb = NULL, *meta_pb = NULL;
James Almer8d5604a2018-08-16 21:01:44320 AV1SequenceParameters seq_params;
321 PutBitContext pbc;
322 uint8_t header[4];
James Almerded339f2018-07-30 18:15:43323 uint8_t *seq = NULL, *meta = NULL;
James Almer9888a192018-07-07 19:35:32324 int64_t obu_size;
325 int start_pos, type, temporal_id, spatial_id;
James Almerded339f2018-07-30 18:15:43326 int ret, nb_seq = 0, seq_size, meta_size;
James Almer9888a192018-07-07 19:35:32327
James Almer1e126562018-07-23 16:15:06328 if (size <= 0)
329 return AVERROR_INVALIDDATA;
330
James Almerded339f2018-07-30 18:15:43331 ret = avio_open_dyn_buf(&seq_pb);
332 if (ret < 0)
333 return ret;
334 ret = avio_open_dyn_buf(&meta_pb);
335 if (ret < 0)
336 goto fail;
337
James Almer9888a192018-07-07 19:35:32338 while (size > 0) {
James Almer692e3232018-07-30 18:14:24339 int len = parse_obu_header(buf, size, &obu_size, &start_pos,
James Almer9888a192018-07-07 19:35:32340 &type, &temporal_id, &spatial_id);
James Almerded339f2018-07-30 18:15:43341 if (len < 0) {
342 ret = len;
343 goto fail;
344 }
James Almer9888a192018-07-07 19:35:32345
346 switch (type) {
347 case AV1_OBU_SEQUENCE_HEADER:
James Almerded339f2018-07-30 18:15:43348 nb_seq++;
349 if (!obu_size || nb_seq > 1) {
350 ret = AVERROR_INVALIDDATA;
351 goto fail;
352 }
James Almer8d5604a2018-08-16 21:01:44353 ret = parse_sequence_header(&seq_params, buf + start_pos, obu_size);
354 if (ret < 0)
355 goto fail;
356
James Almerded339f2018-07-30 18:15:43357 avio_write(seq_pb, buf, len);
358 break;
James Almer9888a192018-07-07 19:35:32359 case AV1_OBU_METADATA:
James Almerded339f2018-07-30 18:15:43360 if (!obu_size) {
361 ret = AVERROR_INVALIDDATA;
362 goto fail;
363 }
364 avio_write(meta_pb, buf, len);
James Almer9888a192018-07-07 19:35:32365 break;
366 default:
367 break;
368 }
James Almer692e3232018-07-30 18:14:24369 size -= len;
370 buf += len;
James Almer9888a192018-07-07 19:35:32371 }
372
James Almerded339f2018-07-30 18:15:43373 seq_size = avio_close_dyn_buf(seq_pb, &seq);
374 if (!seq_size) {
375 ret = AVERROR_INVALIDDATA;
376 goto fail;
377 }
James Almer8d5604a2018-08-16 21:01:44378
379 init_put_bits(&pbc, header, sizeof(header));
380
381 put_bits(&pbc, 1, 1); // marker
382 put_bits(&pbc, 7, 1); // version
383 put_bits(&pbc, 3, seq_params.seq_profile);
384 put_bits(&pbc, 5, seq_params.seq_level_idx_0);
385 put_bits(&pbc, 1, seq_params.seq_tier_0);
386 put_bits(&pbc, 1, seq_params.high_bitdepth);
387 put_bits(&pbc, 1, seq_params.twelve_bit);
388 put_bits(&pbc, 1, seq_params.monochrome);
389 put_bits(&pbc, 1, seq_params.chroma_subsampling_x);
390 put_bits(&pbc, 1, seq_params.chroma_subsampling_y);
391 put_bits(&pbc, 2, seq_params.chroma_sample_position);
Jeremy Dorfman via ffmpeg-develbb5efd12019-04-08 12:14:27392 put_bits(&pbc, 8, 0); // padding
James Almer8d5604a2018-08-16 21:01:44393 flush_put_bits(&pbc);
394
395 avio_write(pb, header, sizeof(header));
James Almerded339f2018-07-30 18:15:43396 avio_write(pb, seq, seq_size);
397
398 meta_size = avio_close_dyn_buf(meta_pb, &meta);
399 if (meta_size)
400 avio_write(pb, meta, meta_size);
401
402fail:
403 if (!seq)
404 avio_close_dyn_buf(seq_pb, &seq);
405 if (!meta)
406 avio_close_dyn_buf(meta_pb, &meta);
407 av_free(seq);
408 av_free(meta);
409
410 return ret;
James Almer9888a192018-07-07 19:35:32411}