FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/av1dec.c
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 159 225 70.7%
Functions: 9 11 81.8%
Branches: 93 160 58.1%

Line Branch Exec Source
1 /*
2 * AV1 Annex B demuxer
3 * Copyright (c) 2019 James Almer <jamrial@gmail.com>
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 "config_components.h"
23
24 #include "libavutil/common.h"
25 #include "libavutil/opt.h"
26 #include "libavcodec/av1_parse.h"
27 #include "libavcodec/bsf.h"
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "demux.h"
31 #include "internal.h"
32
33 typedef struct AV1DemuxContext {
34 const AVClass *class;
35 AVBSFContext *bsf;
36 AVRational framerate;
37 uint32_t temporal_unit_size;
38 uint32_t frame_unit_size;
39 int64_t pos;
40 } AV1DemuxContext;
41
42 //return < 0 if we need more data
43 7 static int get_score(int type, int *seq)
44 {
45
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
7 switch (type) {
46 4 case AV1_OBU_SEQUENCE_HEADER:
47 4 *seq = 1;
48 4 return -1;
49 1 case AV1_OBU_FRAME:
50 case AV1_OBU_FRAME_HEADER:
51
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return *seq ? AVPROBE_SCORE_EXTENSION + 1 : 0;
52 case AV1_OBU_METADATA:
53 case AV1_OBU_PADDING:
54 return -1;
55 2 default:
56 2 break;
57 }
58 2 return 0;
59 }
60
61 1 static int av1_read_header(AVFormatContext *s)
62 {
63 1 AV1DemuxContext *const c = s->priv_data;
64 1 const AVBitStreamFilter *filter = av_bsf_get_by_name("av1_frame_merge");
65 AVStream *st;
66 FFStream *sti;
67 int ret;
68
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!filter) {
70 av_log(s, AV_LOG_ERROR, "av1_frame_merge bitstream filter "
71 "not found. This is a bug, please report it.\n");
72 return AVERROR_BUG;
73 }
74
75 1 st = avformat_new_stream(s, NULL);
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!st)
77 return AVERROR(ENOMEM);
78 1 sti = ffstream(st);
79
80 1 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
81 1 st->codecpar->codec_id = AV_CODEC_ID_AV1;
82 1 sti->need_parsing = AVSTREAM_PARSE_HEADERS;
83
84 1 st->avg_frame_rate = c->framerate;
85 // taken from rawvideo demuxers
86 1 avpriv_set_pts_info(st, 64, 1, 1200000);
87
88 1 ret = av_bsf_alloc(filter, &c->bsf);
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
90 return ret;
91
92 1 ret = avcodec_parameters_copy(c->bsf->par_in, st->codecpar);
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
94 return ret;
95
96 1 ret = av_bsf_init(c->bsf);
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
98 return ret;
99
100 1 return 0;
101 }
102
103 1 static int av1_read_close(AVFormatContext *s)
104 {
105 1 AV1DemuxContext *const c = s->priv_data;
106
107 1 av_bsf_free(&c->bsf);
108 1 return 0;
109 }
110
111 #define DEC AV_OPT_FLAG_DECODING_PARAM
112 #define OFFSET(x) offsetof(AV1DemuxContext, x)
113 static const AVOption av1_options[] = {
114 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
115 { NULL },
116 };
117 #undef OFFSET
118
119 static const AVClass av1_demuxer_class = {
120 .class_name = "AV1 Annex B/low overhead OBU demuxer",
121 .item_name = av_default_item_name,
122 .option = av1_options,
123 .version = LIBAVUTIL_VERSION_INT,
124 };
125
126 #if CONFIG_AV1_DEMUXER
127
128 16330 static int leb(AVIOContext *pb, uint32_t *len, int eof) {
129 16330 int more, i = 0;
130 16330 *len = 0;
131 do {
132 unsigned bits;
133 17289 int byte = avio_r8(pb);
134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17289 times.
17289 if (pb->error)
135 return pb->error;
136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17288 times.
17289 if (pb->eof_reached)
137
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return (eof && !i) ? AVERROR_EOF : AVERROR_INVALIDDATA;
138 17288 more = byte & 0x80;
139 17288 bits = byte & 0x7f;
140
5/6
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 17236 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 30 times.
17288 if (i <= 3 || (i == 4 && bits < (1 << 4)))
141 17258 *len |= bits << (i * 7);
142
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 else if (bits)
143 30 return AVERROR_INVALIDDATA;
144
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17258 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17258 if (++i == 8 && more)
145 return AVERROR_INVALIDDATA;
146
2/2
✓ Branch 0 taken 959 times.
✓ Branch 1 taken 16299 times.
17258 } while (more);
147 16299 return i;
148 }
149
150 1265 static int read_obu(const uint8_t *buf, int size, int64_t *obu_size, int *type)
151 {
152 int start_pos, temporal_id, spatial_id;
153 int len;
154
155 1265 len = parse_obu_header(buf, size, obu_size, &start_pos,
156 type, &temporal_id, &spatial_id);
157
2/2
✓ Branch 0 taken 741 times.
✓ Branch 1 taken 524 times.
1265 if (len < 0)
158 741 return len;
159
160 524 return 0;
161 }
162
163 7235 static int annexb_probe(const AVProbeData *p)
164 {
165 FFIOContext ctx;
166 7235 AVIOContext *const pb = &ctx.pub;
167 int64_t obu_size;
168 uint32_t temporal_unit_size, frame_unit_size, obu_unit_size;
169 7235 int seq = 0;
170 7235 int ret, type, cnt = 0;
171
172 7235 ffio_init_read_context(&ctx, p->buf, p->buf_size);
173
174 7235 ret = leb(pb, &temporal_unit_size, 1);
175
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7222 times.
7235 if (ret < 0)
176 13 return 0;
177 7222 cnt += ret;
178 7222 ret = leb(pb, &frame_unit_size, 0);
179
4/4
✓ Branch 0 taken 7205 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 5386 times.
✓ Branch 3 taken 1819 times.
7222 if (ret < 0 || ((int64_t)frame_unit_size + ret) > temporal_unit_size)
180 5403 return 0;
181 1819 cnt += ret;
182 1819 ret = leb(pb, &obu_unit_size, 0);
183
3/4
✓ Branch 0 taken 1819 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 559 times.
✓ Branch 3 taken 1260 times.
1819 if (ret < 0 || ((int64_t)obu_unit_size + ret) >= frame_unit_size)
184 559 return 0;
185 1260 cnt += ret;
186
187 1260 frame_unit_size -= obu_unit_size + ret;
188
189 1260 avio_skip(pb, obu_unit_size);
190
3/4
✓ Branch 0 taken 1258 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1258 times.
1260 if (pb->eof_reached || pb->error)
191 2 return 0;
192
193 // Check that the first OBU is a Temporal Delimiter.
194 1258 ret = read_obu(p->buf + cnt, FFMIN(p->buf_size - cnt, obu_unit_size), &obu_size, &type);
195
6/6
✓ Branch 0 taken 517 times.
✓ Branch 1 taken 741 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 488 times.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 6 times.
1258 if (ret < 0 || type != AV1_OBU_TEMPORAL_DELIMITER || obu_size > 0)
196 1252 return 0;
197 6 cnt += obu_unit_size;
198
199 do {
200 10 ret = leb(pb, &obu_unit_size, 0);
201
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (ret < 0 || ((int64_t)obu_unit_size + ret) > frame_unit_size)
202 return 0;
203 10 cnt += ret;
204
205 10 avio_skip(pb, obu_unit_size);
206
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
10 if (pb->eof_reached || pb->error)
207 3 return 0;
208
209 7 ret = read_obu(p->buf + cnt, FFMIN(p->buf_size - cnt, obu_unit_size), &obu_size, &type);
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
211 return 0;
212 7 cnt += obu_unit_size;
213
214 7 ret = get_score(type, &seq);
215
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (ret >= 0)
216 3 return ret;
217
218 4 frame_unit_size -= obu_unit_size + ret;
219
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } while (frame_unit_size);
220
221 return 0;
222 }
223
224 12 static int annexb_read_packet(AVFormatContext *s, AVPacket *pkt)
225 {
226 12 AV1DemuxContext *const c = s->priv_data;
227 uint32_t obu_unit_size;
228 12 int64_t pos = c->pos;
229 int ret, len;
230
231 25 retry:
232
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23 times.
25 if (avio_feof(s->pb)) {
233
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (c->temporal_unit_size || c->frame_unit_size)
234 return AVERROR_INVALIDDATA;
235 2 goto end;
236 }
237
238
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 12 times.
23 if (!c->temporal_unit_size) {
239 11 c->pos = avio_tell(s->pb);
240 11 len = leb(s->pb, &c->temporal_unit_size, 1);
241
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (len == AVERROR_EOF) goto end;
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 else if (len < 0) return len;
243 }
244
245
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (!c->frame_unit_size) {
246 11 len = leb(s->pb, &c->frame_unit_size, 0);
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (len < 0)
248 return len;
249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (((int64_t)c->frame_unit_size + len) > c->temporal_unit_size)
250 return AVERROR_INVALIDDATA;
251 11 c->temporal_unit_size -= len;
252 }
253
254 22 len = leb(s->pb, &obu_unit_size, 0);
255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (len < 0)
256 return len;
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (((int64_t)obu_unit_size + len) > c->frame_unit_size)
258 return AVERROR_INVALIDDATA;
259
260 22 ret = av_get_packet(s->pb, pkt, obu_unit_size);
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (ret < 0)
262 return ret;
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (ret != obu_unit_size)
264 return AVERROR_INVALIDDATA;
265
266 22 c->temporal_unit_size -= obu_unit_size + len;
267 22 c->frame_unit_size -= obu_unit_size + len;
268
269 25 end:
270 25 ret = av_bsf_send_packet(c->bsf, pkt);
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0) {
272 av_log(s, AV_LOG_ERROR, "Failed to send packet to "
273 "av1_frame_merge filter\n");
274 return ret;
275 }
276
277 25 ret = av_bsf_receive_packet(c->bsf, pkt);
278
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 10 times.
25 if (ret < 0) {
279
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
15 if (ret == AVERROR(EAGAIN))
280 13 goto retry;
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret != AVERROR_EOF)
282 av_log(s, AV_LOG_ERROR, "av1_frame_merge filter failed to "
283 "send output packet\n");
284 2 return ret;
285 }
286
287 10 pkt->pos = pos;
288
289 10 return 0;
290 }
291
292 const FFInputFormat ff_av1_demuxer = {
293 .p.name = "av1",
294 .p.long_name = NULL_IF_CONFIG_SMALL("AV1 Annex B"),
295 .p.extensions = "obu",
296 .p.flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS,
297 .p.priv_class = &av1_demuxer_class,
298 .priv_data_size = sizeof(AV1DemuxContext),
299 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
300 .read_probe = annexb_probe,
301 .read_header = av1_read_header,
302 .read_packet = annexb_read_packet,
303 .read_close = av1_read_close,
304 };
305 #endif
306
307 #if CONFIG_OBU_DEMUXER
308 //For low overhead obu, we can't foresee the obu size before we parsed the header.
309 //So, we can't use parse_obu_header here, since it will check size <= buf_size
310 //see c27c7b49dc for more details
311 7239 static int read_obu_with_size(const uint8_t *buf, int buf_size, int64_t *obu_size, int *type)
312 {
313 GetBitContext gb;
314 int ret, extension_flag, start_pos;
315 int64_t size;
316
317 7239 ret = init_get_bits8(&gb, buf, FFMIN(buf_size, MAX_OBU_HEADER_SIZE));
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7239 times.
7239 if (ret < 0)
319 return ret;
320
321
2/2
✓ Branch 1 taken 257 times.
✓ Branch 2 taken 6982 times.
7239 if (get_bits1(&gb) != 0) // obu_forbidden_bit
322 257 return AVERROR_INVALIDDATA;
323
324 6982 *type = get_bits(&gb, 4);
325 6982 extension_flag = get_bits1(&gb);
326
2/2
✓ Branch 1 taken 4806 times.
✓ Branch 2 taken 2176 times.
6982 if (!get_bits1(&gb)) // has_size_flag
327 4806 return AVERROR_INVALIDDATA;
328 2176 skip_bits1(&gb); // obu_reserved_1bit
329
330
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1616 times.
2176 if (extension_flag) {
331 560 get_bits(&gb, 3); // temporal_id
332 560 get_bits(&gb, 2); // spatial_id
333 560 skip_bits(&gb, 3); // extension_header_reserved_3bits
334 }
335
336 2176 *obu_size = get_leb128(&gb);
337
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2173 times.
2176 if (*obu_size > INT_MAX)
338 3 return AVERROR_INVALIDDATA;
339
340
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2173 times.
2173 if (get_bits_left(&gb) < 0)
341 return AVERROR_INVALIDDATA;
342
343 2173 start_pos = get_bits_count(&gb) / 8;
344
345 2173 size = *obu_size + start_pos;
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2173 times.
2173 if (size > INT_MAX)
347 return AVERROR_INVALIDDATA;
348 2173 return size;
349 }
350
351 7235 static int obu_probe(const AVProbeData *p)
352 {
353 int64_t obu_size;
354 7235 int seq = 0;
355 int ret, type, cnt;
356
357 // Check that the first OBU is a Temporal Delimiter.
358 7235 cnt = read_obu_with_size(p->buf, p->buf_size, &obu_size, &type);
359
6/6
✓ Branch 0 taken 2173 times.
✓ Branch 1 taken 5062 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 2157 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 12 times.
7235 if (cnt < 0 || type != AV1_OBU_TEMPORAL_DELIMITER || obu_size != 0)
360 7231 return 0;
361
362 while (1) {
363 4 ret = read_obu_with_size(p->buf + cnt, p->buf_size - cnt, &obu_size, &type);
364
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (ret < 0 || obu_size <= 0)
365 4 return 0;
366 cnt += FFMIN(ret, p->buf_size - cnt);
367
368 ret = get_score(type, &seq);
369 if (ret >= 0)
370 return ret;
371 }
372 return 0;
373 }
374
375 static int obu_get_packet(AVFormatContext *s, AVPacket *pkt)
376 {
377 AV1DemuxContext *const c = s->priv_data;
378 uint8_t header[MAX_OBU_HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
379 int64_t obu_size;
380 int size;
381 int ret, len, type;
382
383 if ((ret = ffio_ensure_seekback(s->pb, MAX_OBU_HEADER_SIZE)) < 0)
384 return ret;
385 size = avio_read(s->pb, header, MAX_OBU_HEADER_SIZE);
386 if (size < 0)
387 return size;
388
389 memset(header + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
390 len = read_obu_with_size(header, size, &obu_size, &type);
391 if (len < 0) {
392 av_log(c, AV_LOG_ERROR, "Failed to read obu\n");
393 return len;
394 }
395 avio_seek(s->pb, -size, SEEK_CUR);
396
397 ret = av_get_packet(s->pb, pkt, len);
398 if (ret != len) {
399 av_log(c, AV_LOG_ERROR, "Failed to get packet for obu\n");
400 return ret < 0 ? ret : AVERROR_INVALIDDATA;
401 }
402 return 0;
403 }
404
405 static int obu_read_packet(AVFormatContext *s, AVPacket *pkt)
406 {
407 AV1DemuxContext *const c = s->priv_data;
408 int ret;
409
410 if (s->io_repositioned) {
411 av_bsf_flush(c->bsf);
412 s->io_repositioned = 0;
413 }
414 while (1) {
415 ret = obu_get_packet(s, pkt);
416 /* In case of AVERROR_EOF we need to flush the BSF. Conveniently
417 * obu_get_packet() returns a blank pkt in this case which
418 * can be used to signal that the BSF should be flushed. */
419 if (ret < 0 && ret != AVERROR_EOF)
420 return ret;
421 ret = av_bsf_send_packet(c->bsf, pkt);
422 if (ret < 0) {
423 av_log(s, AV_LOG_ERROR, "Failed to send packet to "
424 "av1_frame_merge filter\n");
425 return ret;
426 }
427 ret = av_bsf_receive_packet(c->bsf, pkt);
428 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
429 av_log(s, AV_LOG_ERROR, "av1_frame_merge filter failed to "
430 "send output packet\n");
431 if (ret != AVERROR(EAGAIN))
432 break;
433 }
434
435 return ret;
436 }
437
438 const FFInputFormat ff_obu_demuxer = {
439 .p.name = "obu",
440 .p.long_name = NULL_IF_CONFIG_SMALL("AV1 low overhead OBU"),
441 .p.extensions = "obu",
442 .p.flags = AVFMT_GENERIC_INDEX | AVFMT_NO_BYTE_SEEK | AVFMT_NOTIMESTAMPS,
443 .p.priv_class = &av1_demuxer_class,
444 .priv_data_size = sizeof(AV1DemuxContext),
445 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
446 .read_probe = obu_probe,
447 .read_header = av1_read_header,
448 .read_packet = obu_read_packet,
449 .read_close = av1_read_close,
450 };
451 #endif
452