FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/demux_utils.c
Date: 2024-04-19 17:50:32
Exec Total Coverage
Lines: 89 152 58.6%
Functions: 8 12 66.7%
Branches: 46 92 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/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 "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 79 AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base,
43 int64_t start, int64_t end, const char *title)
44 {
45 79 FFFormatContext *const si = ffformatcontext(s);
46 79 AVChapter *chapter = NULL;
47 int ret;
48
49
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) {
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 26 times.
✓ Branch 1 taken 53 times.
79 if (!s->nb_chapters) {
55 26 si->chapter_ids_monotonic = 1;
56
3/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 45 times.
53 } 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 71 times.
✓ Branch 1 taken 8 times.
79 if (!chapter) {
65 71 chapter = av_mallocz(sizeof(*chapter));
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (!chapter)
67 return NULL;
68 71 ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter);
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
71 if (ret < 0) {
70 av_free(chapter);
71 return NULL;
72 }
73 }
74 79 av_dict_set(&chapter->metadata, "title", title, 0);
75 79 chapter->id = id;
76 79 chapter->time_base = time_base;
77 79 chapter->start = start;
78 79 chapter->end = end;
79
80 79 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 9755 int avformat_queue_attached_pictures(AVFormatContext *s)
94 {
95 9755 FFFormatContext *const si = ffformatcontext(s);
96 int ret;
97
2/2
✓ Branch 0 taken 10771 times.
✓ Branch 1 taken 9755 times.
20526 for (unsigned i = 0; i < s->nb_streams; i++)
98
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 10715 times.
10771 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 9755 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sample_rate) {
162 size += 4;
163 flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
164 }
165
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (width || height) {
166 3 size += 8;
167 3 flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
168 }
169 3 data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!data)
171 return AVERROR(ENOMEM);
172 3 bytestream_put_le32(&data, flags);
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sample_rate)
174 bytestream_put_le32(&data, sample_rate);
175
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (width || height) {
176 3 bytestream_put_le32(&data, width);
177 3 bytestream_put_le32(&data, height);
178 }
179 3 return 0;
180 }
181
182 int av_read_play(AVFormatContext *s)
183 {
184 if (ffifmt(s->iformat)->read_play)
185 return ffifmt(s->iformat)->read_play(s);
186 if (s->pb)
187 return avio_pause(s->pb, 0);
188 return AVERROR(ENOSYS);
189 }
190
191 int av_read_pause(AVFormatContext *s)
192 {
193 if (ffifmt(s->iformat)->read_pause)
194 return ffifmt(s->iformat)->read_pause(s);
195 if (s->pb)
196 return avio_pause(s->pb, 1);
197 return AVERROR(ENOSYS);
198 }
199
200 1 int ff_generate_avci_extradata(AVStream *st)
201 {
202 static const uint8_t avci100_1080p_extradata[] = {
203 // SPS
204 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
205 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
206 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
207 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
208 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
209 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
210 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
211 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
212 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 // PPS
214 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
215 0xd0
216 };
217 static const uint8_t avci100_1080i_extradata[] = {
218 // SPS
219 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
220 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
221 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
222 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
223 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
224 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
225 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
226 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
227 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
228 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
229 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
230 // PPS
231 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
232 0xd0
233 };
234 static const uint8_t avci50_1080p_extradata[] = {
235 // SPS
236 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
237 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
238 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
239 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
240 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
241 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
242 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
243 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
244 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
245 // PPS
246 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
247 0x11
248 };
249 static const uint8_t avci50_1080i_extradata[] = {
250 // SPS
251 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
252 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
253 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
254 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
255 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
256 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
257 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
258 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
259 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
260 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
261 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
262 // PPS
263 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
264 0x11
265 };
266 static const uint8_t avci100_720p_extradata[] = {
267 // SPS
268 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
269 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
270 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
271 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
272 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
273 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
274 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
275 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
276 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
277 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
278 // PPS
279 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
280 0x11
281 };
282 static const uint8_t avci50_720p_extradata[] = {
283 // SPS
284 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
285 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
286 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
287 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
288 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
289 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
290 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
291 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
292 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
293 // PPS
294 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
295 0x11
296 };
297
298 1 const uint8_t *data = NULL;
299 1 int ret, size = 0;
300
301
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (st->codecpar->width == 1920) {
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
303 data = avci100_1080p_extradata;
304 size = sizeof(avci100_1080p_extradata);
305 } else {
306 1 data = avci100_1080i_extradata;
307 1 size = sizeof(avci100_1080i_extradata);
308 }
309 } else if (st->codecpar->width == 1440) {
310 if (st->codecpar->field_order == AV_FIELD_PROGRESSIVE) {
311 data = avci50_1080p_extradata;
312 size = sizeof(avci50_1080p_extradata);
313 } else {
314 data = avci50_1080i_extradata;
315 size = sizeof(avci50_1080i_extradata);
316 }
317 } else if (st->codecpar->width == 1280) {
318 data = avci100_720p_extradata;
319 size = sizeof(avci100_720p_extradata);
320 } else if (st->codecpar->width == 960) {
321 data = avci50_720p_extradata;
322 size = sizeof(avci50_720p_extradata);
323 }
324
325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!size)
326 return 0;
327
328
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
329 return ret;
330 1 memcpy(st->codecpar->extradata, data, size);
331
332 1 return 0;
333 }
334
335 586 int ff_get_extradata(void *logctx, AVCodecParameters *par, AVIOContext *pb, int size)
336 {
337 586 int ret = ff_alloc_extradata(par, size);
338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 586 times.
586 if (ret < 0)
339 return ret;
340 586 ret = ffio_read_size(pb, par->extradata, size);
341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 586 times.
586 if (ret < 0) {
342 av_freep(&par->extradata);
343 par->extradata_size = 0;
344 av_log(logctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
345 return ret;
346 }
347
348 586 return ret;
349 }
350
351 1043 int ff_find_stream_index(const AVFormatContext *s, int id)
352 {
353
2/2
✓ Branch 0 taken 2042 times.
✓ Branch 1 taken 52 times.
2094 for (unsigned i = 0; i < s->nb_streams; i++)
354
2/2
✓ Branch 0 taken 991 times.
✓ Branch 1 taken 1051 times.
2042 if (s->streams[i]->id == id)
355 991 return i;
356 52 return -1;
357 }
358