FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/demux_utils.c
Date: 2026-09-27 12:50:02
Exec Total Coverage
Lines: 87 165 52.7%
Functions: 8 14 57.1%
Branches: 49 106 46.2%

Line Branch Exec Source
1 /*
2 * Various utility demuxing functions
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
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 <inttypes.h>
23
24 #include "libavutil/mem.h"
25
26 #include "libavutil/avassert.h"
27 #include "libavutil/avstring.h"
28 #include "libavcodec/bytestream.h"
29 #include "packet_internal.h"
30 #include "avformat.h"
31 #include "avformat_internal.h"
32 #include "avio_internal.h"
33 #include "demux.h"
34 #include "internal.h"
35
36 38 struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
37 {
38 38 return cffstream(st)->parser;
39 }
40
41 ✗ void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type)
42 {
43 ✗ ffstream(st)->need_parsing = type;
44 ✗ }
45
46 142 AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base,
47 int64_t start, int64_t end, const char *title)
48 {
49 142 FormatContextInternal *const fci = ff_fc_internal(s);
50 142 AVChapter *chapter = NULL;
51 int ret;
52
53
3/4
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
142 if (end != AV_NOPTS_VALUE && start > end) {
54 ✗ av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start);
55 ✗ return NULL;
56 }
57
58
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 85 times.
142 if (!s->nb_chapters) {
59 57 fci->chapter_ids_monotonic = 1;
60
3/4
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 77 times.
85 } else if (!fci->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) {
61
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (unsigned i = 0; i < s->nb_chapters; i++)
62
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 24 times.
32 if (s->chapters[i]->id == id)
63 8 chapter = s->chapters[i];
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!chapter)
65 ✗ fci->chapter_ids_monotonic = 0;
66 }
67
68
2/2
✓ Branch 0 taken 134 times.
✓ Branch 1 taken 8 times.
142 if (!chapter) {
69 134 chapter = av_mallocz(sizeof(*chapter));
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134 times.
134 if (!chapter)
71 ✗ return NULL;
72 134 ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter);
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134 times.
134 if (ret < 0) {
74 ✗ av_free(chapter);
75 ✗ return NULL;
76 }
77 }
78 142 av_dict_set(&chapter->metadata, "title", title, 0);
79 142 chapter->id = id;
80 142 chapter->time_base = time_base;
81 142 chapter->start = start;
82 142 chapter->end = end;
83
84 142 return chapter;
85 }
86
87 10952 int avformat_queue_attached_pictures(AVFormatContext *s)
88 {
89 10952 FormatContextInternal *const fci = ff_fc_internal(s);
90 int ret;
91
2/2
✓ Branch 0 taken 12239 times.
✓ Branch 1 taken 10952 times.
23191 for (unsigned i = 0; i < s->nb_streams; i++)
92
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 12173 times.
12239 if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
93
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 s->streams[i]->discard < AVDISCARD_ALL) {
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (s->streams[i]->attached_pic.size <= 0) {
95 ✗ av_log(s, AV_LOG_WARNING,
96 "Attached picture on stream %d has invalid size, "
97 "ignoring\n", i);
98 ✗ continue;
99 }
100
101 66 ret = ff_packet_list_put(&fci->raw_packet_buffer,
102 66 &s->streams[i]->attached_pic,
103 av_packet_ref, 0);
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (ret < 0)
105 ✗ return ret;
106 }
107 10952 return 0;
108 }
109
110 66 int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
111 AVBufferRef **buf, int size)
112 {
113 66 AVStream *st = st0;
114 AVPacket *pkt;
115 int ret;
116
117
3/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
66 if (!st && !(st = avformat_new_stream(s, NULL)))
118 ✗ return AVERROR(ENOMEM);
119 66 pkt = &st->attached_pic;
120
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 22 times.
66 if (buf) {
121 av_assert1(*buf);
122 44 av_packet_unref(pkt);
123 44 pkt->buf = *buf;
124 44 pkt->data = (*buf)->data;
125 44 pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
126 44 *buf = NULL;
127 } else {
128 22 ret = av_get_packet(pb, pkt, size);
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (ret < 0)
130 ✗ goto fail;
131 }
132 66 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
133 66 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
134
135 66 pkt->stream_index = st->index;
136 66 pkt->flags |= AV_PKT_FLAG_KEY;
137
138 66 return 0;
139 ✗ fail:
140 ✗ if (!st0)
141 ✗ ff_remove_stream(s, st);
142 ✗ return ret;
143 }
144
145 3 int ff_add_param_change(AVPacket *pkt, int32_t channels,
146 uint64_t channel_layout, int32_t sample_rate,
147 int32_t width, int32_t height)
148 {
149 3 uint32_t flags = 0;
150 3 int size = 4;
151 uint8_t *data;
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!pkt)
153 ✗ return AVERROR(EINVAL);
154
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sample_rate) {
156 ✗ size += 4;
157 ✗ flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
158 }
159
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (width || height) {
160 3 size += 8;
161 3 flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
162 }
163 3 data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!data)
165 ✗ return AVERROR(ENOMEM);
166 3 bytestream_put_le32(&data, flags);
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sample_rate)
168 ✗ bytestream_put_le32(&data, sample_rate);
169
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (width || height) {
170 3 bytestream_put_le32(&data, width);
171 3 bytestream_put_le32(&data, height);
172 }
173 3 return 0;
174 }
175
176 ✗ int av_read_play(AVFormatContext *s)
177 {
178 ✗ if (ffifmt(s->iformat)->read_set_state)
179 ✗ return ffifmt(s->iformat)->read_set_state(s, FF_INFMT_STATE_PLAY);
180 ✗ if (s->pb)
181 ✗ return avio_pause(s->pb, 0);
182 ✗ return AVERROR(ENOSYS);
183 }
184
185 ✗ int av_read_pause(AVFormatContext *s)
186 {
187 ✗ if (ffifmt(s->iformat)->read_set_state)
188 ✗ return ffifmt(s->iformat)->read_set_state(s, FF_INFMT_STATE_PAUSE);
189 ✗ if (s->pb)
190 ✗ return avio_pause(s->pb, 1);
191 ✗ return AVERROR(ENOSYS);
192 }
193
194 ✗ int avformat_send_command(AVFormatContext *s, enum AVFormatCommandID id, void *data)
195 {
196 ✗ if (ffifmt(s->iformat)->handle_command)
197 ✗ return ffifmt(s->iformat)->handle_command(s, FF_INFMT_COMMAND_SUBMIT, id, data);
198 ✗ return AVERROR(ENOSYS);
199 }
200
201 ✗ int avformat_receive_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
202 {
203 ✗ if (ffifmt(s->iformat)->handle_command)
204 ✗ return ffifmt(s->iformat)->handle_command(s, FF_INFMT_COMMAND_GET_REPLY, id, data_out);
205 ✗ return AVERROR(ENOSYS);
206 }
207
208 ✗ int ff_generate_avci_extradata(AVStream *st)
209 {
210 static const uint8_t avci100_1080p_extradata[] = {
211 // SPS
212 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
213 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
214 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
215 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
216 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
217 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
218 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
219 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
220 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 // PPS
222 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
223 0xd0
224 };
225 static const uint8_t avci100_1080i_extradata[] = {
226 // SPS
227 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
228 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
229 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
230 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
231 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
232 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
233 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
234 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
235 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
236 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
237 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
238 // PPS
239 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
240 0xd0
241 };
242 static const uint8_t avci50_1080p_extradata[] = {
243 // SPS
244 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
245 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
246 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
247 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
248 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
249 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
250 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
251 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
252 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
253 // PPS
254 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
255 0x11
256 };
257 static const uint8_t avci50_1080i_extradata[] = {
258 // SPS
259 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
260 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
261 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
262 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
263 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
264 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
265 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
266 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
267 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
268 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
269 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
270 // PPS
271 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
272 0x11
273 };
274 static const uint8_t avci100_720p_extradata[] = {
275 // SPS
276 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
277 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
278 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
279 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
280 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
281 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
282 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
283 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
284 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
285 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
286 // PPS
287 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
288 0x11
289 };
290 static const uint8_t avci50_720p_extradata[] = {
291 // SPS
292 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
293 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
294 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
295 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
296 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
297 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
298 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
299 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
300 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
301 // PPS
302 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
303 0x11
304 };
305
306 ✗ const uint8_t *data = NULL;
307 ✗ int ret, size = 0;
308
309 ✗ if (st->codecpar->width == 1920) {
310 ✗ if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
311 ✗ data = avci100_1080p_extradata;
312 ✗ size = sizeof(avci100_1080p_extradata);
313 } else {
314 ✗ data = avci100_1080i_extradata;
315 ✗ size = sizeof(avci100_1080i_extradata);
316 }
317 ✗ } else if (st->codecpar->width == 1440) {
318 ✗ if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
319 ✗ data = avci50_1080p_extradata;
320 ✗ size = sizeof(avci50_1080p_extradata);
321 } else {
322 ✗ data = avci50_1080i_extradata;
323 ✗ size = sizeof(avci50_1080i_extradata);
324 }
325 ✗ } else if (st->codecpar->width == 1280) {
326 ✗ data = avci100_720p_extradata;
327 ✗ size = sizeof(avci100_720p_extradata);
328 ✗ } else if (st->codecpar->width == 960) {
329 ✗ data = avci50_720p_extradata;
330 ✗ size = sizeof(avci50_720p_extradata);
331 }
332
333 ✗ if (!size)
334 ✗ return 0;
335
336 ✗ if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
337 ✗ return ret;
338 ✗ memcpy(st->codecpar->extradata, data, size);
339
340 ✗ return 0;
341 }
342
343 794 int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
344 {
345 794 int ret = ff_alloc_extradata(par, size);
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 794 times.
794 if (ret < 0)
347 ✗ return ret;
348 794 ret = ffio_read_size(pb, par->extradata, size);
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 794 times.
794 if (ret < 0) {
350 ✗ av_freep(&par->extradata);
351 ✗ par->extradata_size = 0;
352 ✗ av_log(logctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
353 ✗ return ret;
354 }
355
356 794 return ret;
357 }
358
359 1051 int ff_find_stream_index(const AVFormatContext *s, int id)
360 {
361
2/2
✓ Branch 0 taken 2100 times.
✓ Branch 1 taken 54 times.
2154 for (unsigned i = 0; i < s->nb_streams; i++)
362
2/2
✓ Branch 0 taken 997 times.
✓ Branch 1 taken 1103 times.
2100 if (s->streams[i]->id == id)
363 997 return i;
364 54 return -1;
365 }
366
367 /* Over nine months at 44.1 kHz; keeps sums and rescalings in range. */
368 #define SMPB_MAX_SAMPLES (INT64_C(1) << 40)
369
370 56 int ff_itunes_parse_smpb(const char *value, int64_t *priming,
371 int64_t *remainder, int64_t *samples)
372 {
373 uint64_t reserved, p, r, s;
374 int end[4];
375
376 /* 16 digits is the widest an uint64_t can take, and what the tag writes. */
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (sscanf(value, "%16"SCNx64"%n %16"SCNx64"%n %16"SCNx64"%n %16"SCNx64"%n",
378 &reserved, &end[0], &p, &end[1], &r, &end[2], &s, &end[3]) != 4)
379 ✗ return AVERROR_INVALIDDATA;
380
381 /* A field cut short at 16 digits would shift every field after it. */
382
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 56 times.
280 for (int i = 0; i < 4; i++)
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
224 if (av_isxdigit(value[end[i]]))
384 ✗ return AVERROR_INVALIDDATA;
385
386
3/6
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
56 if (p > SMPB_MAX_SAMPLES || r > SMPB_MAX_SAMPLES || s > SMPB_MAX_SAMPLES)
387 ✗ return AVERROR_INVALIDDATA;
388
389 56 *priming = p;
390 56 *remainder = r;
391 56 *samples = s;
392
393 56 return 0;
394 }
395