FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/demux_utils.c
Date: 2026-09-15 03:49:06
Exec Total Coverage
Lines: 98 165 59.4%
Functions: 9 14 64.3%
Branches: 53 106 50.0%

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 139 AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base,
47 int64_t start, int64_t end, const char *title)
48 {
49 139 FormatContextInternal *const fci = ff_fc_internal(s);
50 139 AVChapter *chapter = NULL;
51 int ret;
52
53
3/4
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81 times.
139 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 56 times.
✓ Branch 1 taken 83 times.
139 if (!s->nb_chapters) {
59 56 fci->chapter_ids_monotonic = 1;
60
3/4
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 75 times.
83 } 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 131 times.
✓ Branch 1 taken 8 times.
139 if (!chapter) {
69 131 chapter = av_mallocz(sizeof(*chapter));
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
131 if (!chapter)
71 return NULL;
72 131 ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter);
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131 times.
131 if (ret < 0) {
74 av_free(chapter);
75 return NULL;
76 }
77 }
78 139 av_dict_set(&chapter->metadata, "title", title, 0);
79 139 chapter->id = id;
80 139 chapter->time_base = time_base;
81 139 chapter->start = start;
82 139 chapter->end = end;
83
84 139 return chapter;
85 }
86
87 10924 int avformat_queue_attached_pictures(AVFormatContext *s)
88 {
89 10924 FormatContextInternal *const fci = ff_fc_internal(s);
90 int ret;
91
2/2
✓ Branch 0 taken 12110 times.
✓ Branch 1 taken 10924 times.
23034 for (unsigned i = 0; i < s->nb_streams; i++)
92
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 12045 times.
12110 if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
93
1/2
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
65 s->streams[i]->discard < AVDISCARD_ALL) {
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 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 65 ret = ff_packet_list_put(&fci->raw_packet_buffer,
102 65 &s->streams[i]->attached_pic,
103 av_packet_ref, 0);
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (ret < 0)
105 return ret;
106 }
107 10924 return 0;
108 }
109
110 65 int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
111 AVBufferRef **buf, int size)
112 {
113 65 AVStream *st = st0;
114 AVPacket *pkt;
115 int ret;
116
117
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
65 if (!st && !(st = avformat_new_stream(s, NULL)))
118 return AVERROR(ENOMEM);
119 65 pkt = &st->attached_pic;
120
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 22 times.
65 if (buf) {
121 av_assert1(*buf);
122 43 av_packet_unref(pkt);
123 43 pkt->buf = *buf;
124 43 pkt->data = (*buf)->data;
125 43 pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
126 43 *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 65 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
133 65 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
134
135 65 pkt->stream_index = st->index;
136 65 pkt->flags |= AV_PKT_FLAG_KEY;
137
138 65 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 1 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 1 const uint8_t *data = NULL;
307 1 int ret, size = 0;
308
309
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (st->codecpar->width == 1920) {
310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
311 data = avci100_1080p_extradata;
312 size = sizeof(avci100_1080p_extradata);
313 } else {
314 1 data = avci100_1080i_extradata;
315 1 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
334 return 0;
335
336
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
337 return ret;
338 1 memcpy(st->codecpar->extradata, data, size);
339
340 1 return 0;
341 }
342
343 783 int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
344 {
345 783 int ret = ff_alloc_extradata(par, size);
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 783 times.
783 if (ret < 0)
347 return ret;
348 783 ret = ffio_read_size(pb, par->extradata, size);
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 783 times.
783 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 783 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