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 |