FFmpeg coverage


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