FFmpeg coverage


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