FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/demux_utils.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 89 145 61.4%
Functions: 8 11 72.7%
Branches: 46 90 51.1%

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 10184 int avformat_queue_attached_pictures(AVFormatContext *s)
85 {
86 10184 FormatContextInternal *const fci = ff_fc_internal(s);
87 int ret;
88
2/2
✓ Branch 0 taken 11253 times.
✓ Branch 1 taken 10184 times.
21437 for (unsigned i = 0; i < s->nb_streams; i++)
89
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 11197 times.
11253 if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
90
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 s->streams[i]->discard < AVDISCARD_ALL) {
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 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 56 ret = avpriv_packet_list_put(&fci->raw_packet_buffer,
99 56 &s->streams[i]->attached_pic,
100 av_packet_ref, 0);
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (ret < 0)
102 return ret;
103 }
104 10184 return 0;
105 }
106
107 56 int ff_add_attached_pic(AVFormatContext *s, AVStream *st0, AVIOContext *pb,
108 AVBufferRef **buf, int size)
109 {
110 56 AVStream *st = st0;
111 AVPacket *pkt;
112 int ret;
113
114
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
56 if (!st && !(st = avformat_new_stream(s, NULL)))
115 return AVERROR(ENOMEM);
116 56 pkt = &st->attached_pic;
117
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 20 times.
56 if (buf) {
118 av_assert1(*buf);
119 36 av_packet_unref(pkt);
120 36 pkt->buf = *buf;
121 36 pkt->data = (*buf)->data;
122 36 pkt->size = (*buf)->size - AV_INPUT_BUFFER_PADDING_SIZE;
123 36 *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 56 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
130 56 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
131
132 56 pkt->stream_index = st->index;
133 56 pkt->flags |= AV_PKT_FLAG_KEY;
134
135 56 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_play)
176 return ffifmt(s->iformat)->read_play(s);
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_pause)
185 return ffifmt(s->iformat)->read_pause(s);
186 if (s->pb)
187 return avio_pause(s->pb, 1);
188 return AVERROR(ENOSYS);
189 }
190
191 1 int ff_generate_avci_extradata(AVStream *st)
192 {
193 static const uint8_t avci100_1080p_extradata[] = {
194 // SPS
195 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
196 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
197 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
198 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
199 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
200 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
201 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
202 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
203 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 // PPS
205 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
206 0xd0
207 };
208 static const uint8_t avci100_1080i_extradata[] = {
209 // SPS
210 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
211 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
212 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
213 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
214 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
215 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
216 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
217 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
218 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
219 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
220 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
221 // PPS
222 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
223 0xd0
224 };
225 static const uint8_t avci50_1080p_extradata[] = {
226 // SPS
227 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
228 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
229 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
230 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
231 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
232 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
233 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
234 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
235 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
236 // PPS
237 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
238 0x11
239 };
240 static const uint8_t avci50_1080i_extradata[] = {
241 // SPS
242 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
243 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
244 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
245 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
246 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
247 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
248 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
249 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
250 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
251 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
252 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
253 // PPS
254 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
255 0x11
256 };
257 static const uint8_t avci100_720p_extradata[] = {
258 // SPS
259 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
260 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
261 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
262 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
263 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
264 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
265 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
266 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
267 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
268 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
269 // PPS
270 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
271 0x11
272 };
273 static const uint8_t avci50_720p_extradata[] = {
274 // SPS
275 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
276 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
277 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
278 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
279 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
280 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
281 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
282 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
283 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
284 // PPS
285 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
286 0x11
287 };
288
289 1 const uint8_t *data = NULL;
290 1 int ret, size = 0;
291
292
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (st->codecpar->width == 1920) {
293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
294 data = avci100_1080p_extradata;
295 size = sizeof(avci100_1080p_extradata);
296 } else {
297 1 data = avci100_1080i_extradata;
298 1 size = sizeof(avci100_1080i_extradata);
299 }
300 } else if (st->codecpar->width == 1440) {
301 if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
302 data = avci50_1080p_extradata;
303 size = sizeof(avci50_1080p_extradata);
304 } else {
305 data = avci50_1080i_extradata;
306 size = sizeof(avci50_1080i_extradata);
307 }
308 } else if (st->codecpar->width == 1280) {
309 data = avci100_720p_extradata;
310 size = sizeof(avci100_720p_extradata);
311 } else if (st->codecpar->width == 960) {
312 data = avci50_720p_extradata;
313 size = sizeof(avci50_720p_extradata);
314 }
315
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
317 return 0;
318
319
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
320 return ret;
321 1 memcpy(st->codecpar->extradata, data, size);
322
323 1 return 0;
324 }
325
326 648 int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
327 {
328 648 int ret = ff_alloc_extradata(par, size);
329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 648 times.
648 if (ret < 0)
330 return ret;
331 648 ret = ffio_read_size(pb, par->extradata, size);
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 648 times.
648 if (ret < 0) {
333 av_freep(&par->extradata);
334 par->extradata_size = 0;
335 av_log(logctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
336 return ret;
337 }
338
339 648 return ret;
340 }
341
342 1051 int ff_find_stream_index(const AVFormatContext *s, int id)
343 {
344
2/2
✓ Branch 0 taken 2100 times.
✓ Branch 1 taken 54 times.
2154 for (unsigned i = 0; i < s->nb_streams; i++)
345
2/2
✓ Branch 0 taken 997 times.
✓ Branch 1 taken 1103 times.
2100 if (s->streams[i]->id == id)
346 997 return i;
347 54 return -1;
348 }
349