FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/demux_utils.c
Date: 2026-04-29 17:33:30
Exec Total Coverage
Lines: 89 153 58.2%
Functions: 8 13 61.5%
Branches: 46 94 48.9%

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