FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/avformat.c
Date: 2026-08-15 14:54:27
Exec Total Coverage
Lines: 386 611 63.2%
Functions: 24 27 88.9%
Branches: 248 544 45.6%

Line Branch Exec Source
1 /*
2 * Various functions used by both muxers and demuxers
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 "config_components.h"
23
24 #include <math.h>
25 #include "libavutil/avassert.h"
26 #include "libavutil/avstring.h"
27 #include "libavutil/channel_layout.h"
28 #include "libavutil/frame.h"
29 #include "libavutil/iamf.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/pixfmt.h"
33 #include "libavutil/samplefmt.h"
34 #include "libavcodec/avcodec.h"
35 #include "libavcodec/codec.h"
36 #include "libavcodec/bsf.h"
37 #include "libavcodec/codec_desc.h"
38 #include "packet_internal.h"
39 #include "avformat.h"
40 #include "avformat_internal.h"
41 #include "avio.h"
42 #include "demux.h"
43 #include "mux.h"
44 #include "internal.h"
45 #include "url.h"
46
47 18364 void ff_free_stream(AVStream **pst)
48 {
49 18364 AVStream *st = *pst;
50 18364 FFStream *const sti = ffstream(st);
51
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18364 times.
18364 if (!st)
53 return;
54
55
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 18301 times.
18364 if (st->attached_pic.data)
56 63 av_packet_unref(&st->attached_pic);
57
58 18364 av_parser_close(sti->parser);
59 18364 avcodec_free_context(&sti->avctx);
60 18364 av_bsf_free(&sti->bsfc);
61 18364 av_freep(&sti->index_entries);
62 18364 av_freep(&sti->probe_data.buf);
63
64 18364 av_packet_free(&sti->parse_pkt);
65
66 18364 av_bsf_free(&sti->extract_extradata.bsf);
67
68
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 18331 times.
18364 if (sti->info) {
69 33 av_freep(&sti->info->duration_error);
70 33 av_freep(&sti->info);
71 }
72
73 18364 av_dict_free(&st->metadata);
74 18364 avcodec_parameters_free(&st->codecpar);
75 18364 av_freep(&st->priv_data);
76
77 18364 av_freep(pst);
78 }
79
80 147 void ff_free_stream_group(AVStreamGroup **pstg)
81 {
82 147 AVStreamGroup *stg = *pstg;
83
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 147 times.
147 if (!stg)
85 return;
86
87 147 av_freep(&stg->streams);
88 147 av_dict_free(&stg->metadata);
89 147 av_freep(&stg->priv_data);
90
5/6
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
147 switch (stg->type) {
91 52 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
92 52 av_iamf_audio_element_free(&stg->params.iamf_audio_element);
93 52 break;
94 }
95 49 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
96 49 av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation);
97 49 break;
98 }
99 9 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
100 9 av_opt_free(stg->params.tile_grid);
101 9 av_freep(&stg->params.tile_grid->offsets);
102 9 av_packet_side_data_free(&stg->params.tile_grid->coded_side_data,
103 9 &stg->params.tile_grid->nb_coded_side_data);
104 9 av_freep(&stg->params.tile_grid);
105 9 break;
106 29 case AV_STREAM_GROUP_PARAMS_TREF:
107 29 av_opt_free(stg->params.tref);
108 29 av_freep(&stg->params.tref);
109 29 break;
110 8 case AV_STREAM_GROUP_PARAMS_LCEVC:
111 case AV_STREAM_GROUP_PARAMS_DOLBY_VISION:
112 8 av_opt_free(stg->params.layered_video);
113 8 av_freep(&stg->params.layered_video);
114 8 break;
115 default:
116 break;
117 }
118
119 147 av_freep(pstg);
120 }
121
122 10 void ff_remove_stream(AVFormatContext *s, AVStream *st)
123 {
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 av_assert0(s->nb_streams>0);
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 av_assert0(s->streams[ s->nb_streams - 1 ] == st);
126
127 10 ff_free_stream(&s->streams[ --s->nb_streams ]);
128 10 }
129
130 void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg)
131 {
132 av_assert0(s->nb_stream_groups > 0);
133 av_assert0(s->stream_groups[ s->nb_stream_groups - 1 ] == stg);
134
135 ff_free_stream_group(&s->stream_groups[ --s->nb_stream_groups ]);
136 }
137
138 /* XXX: suppress the packet queue */
139 13157 void ff_flush_packet_queue(AVFormatContext *s)
140 {
141 13157 FormatContextInternal *const fci = ff_fc_internal(s);
142 13157 FFFormatContext *const si = &fci->fc;
143 13157 ff_packet_list_free(&fci->parse_queue);
144 13157 ff_packet_list_free(&si->packet_buffer);
145 13157 ff_packet_list_free(&fci->raw_packet_buffer);
146
147 13157 fci->raw_packet_buffer_size = 0;
148 13157 }
149
150 17528 void avformat_free_context(AVFormatContext *s)
151 {
152 FormatContextInternal *fci;
153 FFFormatContext *si;
154
155
2/2
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 16942 times.
17528 if (!s)
156 586 return;
157 16942 fci = ff_fc_internal(s);
158 16942 si = &fci->fc;
159
160
5/6
✓ Branch 0 taken 8806 times.
✓ Branch 1 taken 8136 times.
✓ Branch 3 taken 4456 times.
✓ Branch 4 taken 4350 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4456 times.
16942 if (s->oformat && ffofmt(s->oformat)->deinit && fci->initialized)
161 ffofmt(s->oformat)->deinit(s);
162
163 16942 av_opt_free(s);
164
5/6
✓ Branch 0 taken 8116 times.
✓ Branch 1 taken 8826 times.
✓ Branch 2 taken 7004 times.
✓ Branch 3 taken 1112 times.
✓ Branch 4 taken 7004 times.
✗ Branch 5 not taken.
16942 if (s->iformat && s->iformat->priv_class && s->priv_data)
165 7004 av_opt_free(s->priv_data);
166
6/6
✓ Branch 0 taken 8806 times.
✓ Branch 1 taken 8136 times.
✓ Branch 2 taken 4520 times.
✓ Branch 3 taken 4286 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 4519 times.
16942 if (s->oformat && s->oformat->priv_class && s->priv_data)
167 1 av_opt_free(s->priv_data);
168
169
2/2
✓ Branch 0 taken 18354 times.
✓ Branch 1 taken 16942 times.
35296 for (unsigned i = 0; i < s->nb_streams; i++)
170 18354 ff_free_stream(&s->streams[i]);
171
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 16942 times.
17089 for (unsigned i = 0; i < s->nb_stream_groups; i++)
172 147 ff_free_stream_group(&s->stream_groups[i]);
173 16942 s->nb_stream_groups = 0;
174 16942 s->nb_streams = 0;
175
176
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 16942 times.
17038 for (unsigned i = 0; i < s->nb_programs; i++) {
177 96 av_dict_free(&s->programs[i]->metadata);
178 96 av_freep(&s->programs[i]->stream_index);
179 96 av_freep(&s->programs[i]);
180 }
181 16942 s->nb_programs = 0;
182
183 16942 av_freep(&s->programs);
184 16942 av_freep(&s->priv_data);
185
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 16942 times.
17147 while (s->nb_chapters--) {
186 205 av_dict_free(&s->chapters[s->nb_chapters]->metadata);
187 205 av_freep(&s->chapters[s->nb_chapters]);
188 }
189 16942 av_freep(&s->chapters);
190 16942 av_dict_free(&s->metadata);
191 16942 av_dict_free(&si->id3v2_meta);
192 #if CONFIG_LIBCURL_PROTOCOL
193 16942 ff_curl_loop_free(&si->curl_loop);
194 #endif
195 16942 av_packet_free(&si->pkt);
196 16942 av_packet_free(&si->parse_pkt);
197 16942 ff_packet_list_free(&si->packet_buffer);
198 16942 av_freep(&s->streams);
199 16942 av_freep(&s->stream_groups);
200
2/2
✓ Branch 0 taken 8116 times.
✓ Branch 1 taken 8826 times.
16942 if (s->iformat)
201 8116 ff_flush_packet_queue(s);
202 16942 av_freep(&s->url);
203 16942 av_freep(&s->name);
204 16942 av_free(s);
205 }
206
207 /**
208 * Copy all stream parameters from source to destination stream, with the
209 * exception of the index field, which is usually set by avformat_new_stream().
210 *
211 * @param dst pointer to destination AVStream
212 * @param src pointer to source AVStream
213 * @return >=0 on success, AVERROR code on error
214 */
215 20 static int stream_params_copy(AVStream *dst, const AVStream *src)
216 {
217 int ret;
218
219 20 dst->id = src->id;
220 20 dst->time_base = src->time_base;
221 20 dst->start_time = src->start_time;
222 20 dst->duration = src->duration;
223 20 dst->nb_frames = src->nb_frames;
224 20 dst->disposition = src->disposition;
225 20 dst->discard = src->discard;
226 20 dst->sample_aspect_ratio = src->sample_aspect_ratio;
227 20 dst->avg_frame_rate = src->avg_frame_rate;
228 20 dst->event_flags = src->event_flags;
229 20 dst->r_frame_rate = src->r_frame_rate;
230 20 dst->pts_wrap_bits = src->pts_wrap_bits;
231
232 20 av_dict_free(&dst->metadata);
233 20 ret = av_dict_copy(&dst->metadata, src->metadata, 0);
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (ret < 0)
235 return ret;
236
237 20 ret = avcodec_parameters_copy(dst->codecpar, src->codecpar);
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (ret < 0)
239 return ret;
240
241 20 av_packet_unref(&dst->attached_pic);
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (src->attached_pic.data) {
243 ret = av_packet_ref(&dst->attached_pic, &src->attached_pic);
244 if (ret < 0)
245 return ret;
246 }
247
248 20 return 0;
249 }
250
251 20 AVStream *ff_stream_clone(AVFormatContext *dst_ctx, const AVStream *src)
252 {
253 AVStream *st;
254 int ret;
255
256 20 st = avformat_new_stream(dst_ctx, NULL);
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (!st)
258 return NULL;
259
260 20 ret = stream_params_copy(st, src);
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (ret < 0) {
262 ff_remove_stream(dst_ctx, st);
263 return NULL;
264 }
265
266 20 return st;
267 }
268
269 116 const char *avformat_stream_group_name(enum AVStreamGroupParamsType type)
270 {
271
6/7
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
116 switch(type) {
272 38 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: return "IAMF Audio Element";
273 36 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: return "IAMF Mix Presentation";
274 9 case AV_STREAM_GROUP_PARAMS_TILE_GRID: return "Tile Grid";
275 6 case AV_STREAM_GROUP_PARAMS_LCEVC: return "LCEVC (Split video and enhancement)";
276 26 case AV_STREAM_GROUP_PARAMS_TREF: return "Track Reference";
277 1 case AV_STREAM_GROUP_PARAMS_DOLBY_VISION: return "Dolby Vision (Split base and enhancement layer)";
278 }
279 return NULL;
280 }
281
282 565 AVProgram *av_new_program(AVFormatContext *ac, int id)
283 {
284 565 AVProgram *program = NULL;
285 int ret;
286
287 565 av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id);
288
289
2/2
✓ Branch 0 taken 469 times.
✓ Branch 1 taken 565 times.
1034 for (unsigned i = 0; i < ac->nb_programs; i++)
290
1/2
✓ Branch 0 taken 469 times.
✗ Branch 1 not taken.
469 if (ac->programs[i]->id == id)
291 469 program = ac->programs[i];
292
293
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 469 times.
565 if (!program) {
294 96 program = av_mallocz(sizeof(*program));
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (!program)
296 return NULL;
297 96 ret = av_dynarray_add_nofree(&ac->programs, &ac->nb_programs, program);
298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (ret < 0) {
299 av_free(program);
300 return NULL;
301 }
302 96 program->discard = AVDISCARD_NONE;
303 96 program->pmt_version = -1;
304 96 program->id = id;
305 96 program->pts_wrap_reference = AV_NOPTS_VALUE;
306 96 program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
307 96 program->start_time =
308 96 program->end_time = AV_NOPTS_VALUE;
309 }
310 565 return program;
311 }
312
313 738 int av_program_add_stream_index2(AVFormatContext *ac, int progid, unsigned idx)
314 {
315 738 AVProgram *program = NULL;
316 void *tmp;
317
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 738 times.
738 if (idx >= ac->nb_streams) {
319 av_log(ac, AV_LOG_ERROR, "stream index %d is greater than stream count %d\n", idx, ac->nb_streams);
320 return AVERROR(EINVAL);
321 }
322
323
1/2
✓ Branch 0 taken 738 times.
✗ Branch 1 not taken.
738 for (unsigned i = 0; i < ac->nb_programs; i++) {
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 738 times.
738 if (ac->programs[i]->id != progid)
325 continue;
326 738 program = ac->programs[i];
327
2/2
✓ Branch 0 taken 1016 times.
✓ Branch 1 taken 463 times.
1479 for (unsigned j = 0; j < program->nb_stream_indexes; j++)
328
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 741 times.
1016 if (program->stream_index[j] == idx)
329 275 return 0;
330
331 463 tmp = av_realloc_array(program->stream_index, program->nb_stream_indexes+1, sizeof(unsigned int));
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 463 times.
463 if (!tmp)
333 return AVERROR(ENOMEM);
334 463 program->stream_index = tmp;
335 463 program->stream_index[program->nb_stream_indexes++] = idx;
336 463 return 0;
337 }
338
339 av_log(ac, AV_LOG_ERROR, "no program with id %d found\n", progid);
340 return AVERROR(EINVAL);
341 }
342
343 738 void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
344 {
345 738 av_program_add_stream_index2(ac, progid, idx);
346 738 return;
347 }
348
349 int av_program_copy(AVFormatContext *dst, const AVFormatContext *src, int progid, int flags)
350 {
351 const AVProgram *src_prog = NULL;
352 AVProgram *dst_prog = NULL;
353 int ret, idx = -1, match = -1;
354 int overwrite = flags & AVFMT_PROGCOPY_OVERWRITE;
355
356 if ((flags & AVFMT_PROGCOPY_MATCH_BY_ID) && (flags & AVFMT_PROGCOPY_MATCH_BY_INDEX))
357 return AVERROR(EINVAL);
358 else if (flags & AVFMT_PROGCOPY_MATCH_BY_ID)
359 match = 0;
360 else if (flags & AVFMT_PROGCOPY_MATCH_BY_INDEX)
361 match = 1;
362
363 for (unsigned i = 0; i < src->nb_programs; i++) {
364 if (src->programs[i]->id == progid) {
365 if (src_prog) {
366 av_log(dst, AV_LOG_ERROR, "multiple programs found in source with same id 0x%04x. Not copying.\n", progid);
367 return AVERROR(EINVAL);
368 } else {
369 src_prog = src->programs[i];
370 }
371 }
372 }
373
374 if (!src_prog) {
375 av_log(dst, AV_LOG_ERROR, "source program not found: id=0x%04x\n", progid);
376 return AVERROR(EINVAL);
377 }
378
379 for (unsigned i = 0; i < dst->nb_programs; i++) {
380 if (dst->programs[i]->id == progid) {
381 if (idx > -1) {
382 av_log(dst, AV_LOG_ERROR, "multiple programs found in target with same id 0x%04x. Not copying.\n", progid);
383 return AVERROR(EINVAL);
384 } else {
385 idx = i;
386 }
387 }
388 }
389
390 if (idx >= 0 && !overwrite)
391 return AVERROR(EEXIST);
392
393 av_log(dst, AV_LOG_TRACE, "%s program: id=0x%04x\n", idx >= 0 ? "overwriting" : "copying", progid);
394
395 if (idx >= 0) {
396 dst_prog = dst->programs[idx];
397 av_dict_free(&dst_prog->metadata);
398 av_freep(&dst_prog->stream_index);
399 dst_prog->nb_stream_indexes = 0;
400 } else {
401 dst_prog = av_new_program(dst, progid);
402 if (!dst_prog)
403 return AVERROR(ENOMEM);
404 }
405
406 /* public fields */
407 dst_prog->id = src_prog->id;
408 dst_prog->flags = src_prog->flags;
409 dst_prog->discard = src_prog->discard;
410 dst_prog->program_num = src_prog->program_num;
411 dst_prog->pmt_pid = src_prog->pmt_pid;
412 dst_prog->pcr_pid = src_prog->pcr_pid;
413 dst_prog->pmt_version = src_prog->pmt_version;
414
415 if (match == -1 && src->nb_streams) {
416 match = 0;
417 for (unsigned i = 0; i < src->nb_streams && !match; i++) {
418 int src_id = src->streams[i]->id;
419 if (!src_id) {
420 match = 1;
421 break;
422 }
423 for (unsigned j=i+1; j < src->nb_streams; j++) {
424 int sib_id = src->streams[j]->id;
425 if (src_id == sib_id) {
426 match = 1;
427 break;
428 }
429 }
430 }
431 }
432
433 for (unsigned i = 0; i < dst->nb_streams; i++) {
434 int dst_val = match ? i : dst->streams[i]->id;
435
436 for (unsigned j = 0; j < src_prog->nb_stream_indexes; j++) {
437 int src_val = match ? src_prog->stream_index[j] : src->streams[src_prog->stream_index[j]]->id;
438
439 if (dst_val == src_val) {
440 ret = av_program_add_stream_index2(dst, dst_prog->id, i);
441 if (ret < 0)
442 return ret;
443 }
444 }
445 }
446
447 ret = av_dict_copy(&dst_prog->metadata, src_prog->metadata, 0);
448 if (ret < 0)
449 return ret;
450
451 return 0;
452 }
453
454 15898 AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
455 {
456
2/2
✓ Branch 0 taken 2727 times.
✓ Branch 1 taken 14583 times.
17310 for (unsigned i = 0; i < ic->nb_programs; i++) {
457
2/2
✓ Branch 0 taken 1409 times.
✓ Branch 1 taken 1318 times.
2727 if (ic->programs[i] == last) {
458 1409 last = NULL;
459 } else {
460
1/2
✓ Branch 0 taken 1318 times.
✗ Branch 1 not taken.
1318 if (!last)
461
2/2
✓ Branch 0 taken 2471 times.
✓ Branch 1 taken 3 times.
2474 for (unsigned j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
462
2/2
✓ Branch 0 taken 1315 times.
✓ Branch 1 taken 1156 times.
2471 if (ic->programs[i]->stream_index[j] == s)
463 1315 return ic->programs[i];
464 }
465 }
466 14583 return NULL;
467 }
468
469 2007 int av_find_default_stream_index(AVFormatContext *s)
470 {
471 2007 int best_stream = 0;
472 2007 int best_score = INT_MIN;
473
474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2007 times.
2007 if (s->nb_streams <= 0)
475 return -1;
476
2/2
✓ Branch 0 taken 2442 times.
✓ Branch 1 taken 2007 times.
4449 for (unsigned i = 0; i < s->nb_streams; i++) {
477 2442 const AVStream *const st = s->streams[i];
478 2442 const FFStream *const sti = cffstream(st);
479 2442 int score = 0;
480
2/2
✓ Branch 0 taken 1407 times.
✓ Branch 1 taken 1035 times.
2442 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
481
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1400 times.
1407 if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
482 7 score -= 400;
483
3/4
✓ Branch 0 taken 1314 times.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 1314 times.
✗ Branch 3 not taken.
1407 if (st->codecpar->width && st->codecpar->height)
484 1314 score += 50;
485 1407 score+= 25;
486 }
487
2/2
✓ Branch 0 taken 1004 times.
✓ Branch 1 taken 1438 times.
2442 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
488
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 33 times.
1004 if (st->codecpar->sample_rate)
489 971 score += 50;
490 }
491
2/2
✓ Branch 0 taken 2017 times.
✓ Branch 1 taken 425 times.
2442 if (sti->codec_info_nb_frames)
492 2017 score += 12;
493
494
2/2
✓ Branch 0 taken 2437 times.
✓ Branch 1 taken 5 times.
2442 if (st->discard != AVDISCARD_ALL)
495 2437 score += 200;
496
497
2/2
✓ Branch 0 taken 2062 times.
✓ Branch 1 taken 380 times.
2442 if (score > best_score) {
498 2062 best_score = score;
499 2062 best_stream = i;
500 }
501 }
502 2007 return best_stream;
503 }
504
505 19 int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,
506 int wanted_stream_nb, int related_stream,
507 const AVCodec **decoder_ret, int flags)
508 {
509 19 int nb_streams = ic->nb_streams;
510 19 int ret = AVERROR_STREAM_NOT_FOUND;
511 19 int best_count = -1, best_multiframe = -1, best_disposition = -1;
512 int count, multiframe, disposition;
513 19 int64_t best_bitrate = -1;
514 int64_t bitrate;
515 19 unsigned *program = NULL;
516 19 const AVCodec *decoder = NULL, *best_decoder = NULL;
517
518
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if (related_stream >= 0 && wanted_stream_nb < 0) {
519 AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
520 if (p) {
521 program = p->stream_index;
522 nb_streams = p->nb_stream_indexes;
523 }
524 }
525
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 19 times.
41 for (unsigned i = 0; i < nb_streams; i++) {
526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 int real_stream_index = program ? program[i] : i;
527 22 AVStream *st = ic->streams[real_stream_index];
528 22 AVCodecParameters *par = st->codecpar;
529
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 19 times.
22 if (par->codec_type != type)
530 3 continue;
531
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb)
532 continue;
533
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
19 if (type == AVMEDIA_TYPE_AUDIO && !(par->ch_layout.nb_channels && par->sample_rate))
534 continue;
535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (decoder_ret) {
536 decoder = ff_find_decoder(ic, st, par->codec_id);
537 if (!decoder) {
538 if (ret < 0)
539 ret = AVERROR_DECODER_NOT_FOUND;
540 continue;
541 }
542 }
543 19 disposition = !(st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED | AV_DISPOSITION_VISUAL_IMPAIRED))
544 19 + !! (st->disposition & AV_DISPOSITION_DEFAULT);
545 19 count = ffstream(st)->codec_info_nb_frames;
546 19 bitrate = par->bit_rate;
547 19 multiframe = FFMIN(5, count);
548
2/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 if ((best_disposition > disposition) ||
549
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
19 (best_disposition == disposition && best_multiframe > multiframe) ||
550
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19 times.
19 (best_disposition == disposition && best_multiframe == multiframe && best_bitrate > bitrate) ||
551 (best_disposition == disposition && best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
552 continue;
553 19 best_disposition = disposition;
554 19 best_count = count;
555 19 best_bitrate = bitrate;
556 19 best_multiframe = multiframe;
557 19 ret = real_stream_index;
558 19 best_decoder = decoder;
559
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19 if (program && i == nb_streams - 1 && ret < 0) {
560 program = NULL;
561 nb_streams = ic->nb_streams;
562 /* no related stream found, try again with everything */
563 i = 0;
564 }
565 }
566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (decoder_ret)
567 *decoder_ret = best_decoder;
568 19 return ret;
569 }
570
571 /**
572 * Matches a stream specifier (but ignores requested index).
573 *
574 * @param indexptr set to point to the requested stream index if there is one
575 *
576 * @return <0 on error
577 * 0 if st is NOT a matching stream
578 * >0 if st is a matching stream
579 */
580 69 static int match_stream_specifier(const AVFormatContext *s, const AVStream *st,
581 const char *spec, const char **indexptr,
582 const AVStreamGroup **g, const AVProgram **p)
583 {
584 69 int match = 1; /* Stores if the specifier matches so far. */
585
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 47 times.
136 while (*spec) {
586
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
89 if (*spec <= '9' && *spec >= '0') { /* opt:index */
587
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 7 times.
22 if (indexptr)
588 15 *indexptr = spec;
589 22 return match;
590
7/8
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
67 } else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
591
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
67 *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
592 enum AVMediaType type;
593 61 int nopic = 0;
594
595
3/7
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
61 switch (*spec++) {
596 39 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
597 18 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
598 4 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
599 case 'd': type = AVMEDIA_TYPE_DATA; break;
600 case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
601 case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
602 default: av_assert0(0);
603 }
604
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
61 if (*spec && *spec++ != ':') /* If we are not at the end, then another specifier must follow. */
605 return AVERROR(EINVAL);
606
607
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 47 times.
61 if (type != st->codecpar->codec_type)
608 14 match = 0;
609
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
61 if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
610 match = 0;
611
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 } else if (*spec == 'g' && *(spec + 1) == ':') {
612 int64_t group_idx = -1, group_id = -1;
613 int found = 0;
614 char *endptr;
615 spec += 2;
616 if (*spec == '#' || (*spec == 'i' && *(spec + 1) == ':')) {
617 spec += 1 + (*spec == 'i');
618 group_id = strtol(spec, &endptr, 0);
619 if (spec == endptr || (*endptr && *endptr++ != ':'))
620 return AVERROR(EINVAL);
621 spec = endptr;
622 } else {
623 group_idx = strtol(spec, &endptr, 0);
624 /* Disallow empty id and make sure that if we are not at the end, then another specifier must follow. */
625 if (spec == endptr || (*endptr && *endptr++ != ':'))
626 return AVERROR(EINVAL);
627 spec = endptr;
628 }
629 if (match) {
630 if (group_id > 0) {
631 for (unsigned i = 0; i < s->nb_stream_groups; i++) {
632 if (group_id == s->stream_groups[i]->id) {
633 group_idx = i;
634 break;
635 }
636 }
637 }
638 if (group_idx < 0 || group_idx >= s->nb_stream_groups)
639 return AVERROR(EINVAL);
640 for (unsigned j = 0; j < s->stream_groups[group_idx]->nb_streams; j++) {
641 if (st->index == s->stream_groups[group_idx]->streams[j]->index) {
642 found = 1;
643 if (g)
644 *g = s->stream_groups[group_idx];
645 break;
646 }
647 }
648 }
649 if (!found)
650 match = 0;
651
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 } else if (*spec == 'p' && *(spec + 1) == ':') {
652 int prog_id;
653 6 int found = 0;
654 char *endptr;
655 6 spec += 2;
656 6 prog_id = strtol(spec, &endptr, 0);
657 /* Disallow empty id and make sure that if we are not at the end, then another specifier must follow. */
658
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (spec == endptr || (*endptr && *endptr++ != ':'))
659 return AVERROR(EINVAL);
660 6 spec = endptr;
661
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (match) {
662
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (unsigned i = 0; i < s->nb_programs; i++) {
663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (s->programs[i]->id != prog_id)
664 continue;
665
666
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 for (unsigned j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
667
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
8 if (st->index == s->programs[i]->stream_index[j]) {
668 5 found = 1;
669
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (p)
670 2 *p = s->programs[i];
671 5 i = s->nb_programs;
672 5 break;
673 }
674 }
675 }
676 }
677
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (!found)
678 1 match = 0;
679 } else if (*spec == '#' ||
680 (*spec == 'i' && *(spec + 1) == ':')) {
681 int stream_id;
682 char *endptr;
683 spec += 1 + (*spec == 'i');
684 stream_id = strtol(spec, &endptr, 0);
685 if (spec == endptr || *endptr) /* Disallow empty id and make sure we are at the end. */
686 return AVERROR(EINVAL);
687 return match && (stream_id == st->id);
688 } else if (*spec == 'm' && *(spec + 1) == ':') {
689 const AVDictionaryEntry *tag;
690 int ret;
691
692 if (match) {
693 spec += 2;
694 const char *val = strchr(spec, ':');
695
696 char *key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
697 if (!key)
698 return AVERROR(ENOMEM);
699
700 tag = av_dict_get(st->metadata, key, NULL, 0);
701 if (tag) {
702 if (!val || !strcmp(tag->value, val + 1))
703 ret = 1;
704 else
705 ret = 0;
706 } else
707 ret = 0;
708
709 av_freep(&key);
710 }
711 return match && ret;
712 } else if (*spec == 'u' && *(spec + 1) == '\0') {
713 const AVCodecParameters *par = st->codecpar;
714 int val;
715 switch (par->codec_type) {
716 case AVMEDIA_TYPE_AUDIO:
717 val = par->sample_rate && par->ch_layout.nb_channels;
718 if (par->format == AV_SAMPLE_FMT_NONE)
719 return 0;
720 break;
721 case AVMEDIA_TYPE_VIDEO:
722 val = par->width && par->height;
723 if (par->format == AV_PIX_FMT_NONE)
724 return 0;
725 break;
726 case AVMEDIA_TYPE_UNKNOWN:
727 val = 0;
728 break;
729 default:
730 val = 1;
731 break;
732 }
733 return match && (par->codec_id != AV_CODEC_ID_NONE && val != 0);
734 } else {
735 return AVERROR(EINVAL);
736 }
737 }
738
739 47 return match;
740 }
741
742 62 int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
743 const char *spec)
744 {
745 int ret, index;
746 char *endptr;
747 62 const char *indexptr = NULL;
748 62 const AVStreamGroup *g = NULL;
749 62 const AVProgram *p = NULL;
750 int nb_streams;
751
752 62 ret = match_stream_specifier(s, st, spec, &indexptr, &g, &p);
753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0)
754 goto error;
755
756
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 15 times.
62 if (!indexptr)
757 47 return ret;
758
759 15 index = strtol(indexptr, &endptr, 0);
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (*endptr) { /* We can't have anything after the requested index. */
761 ret = AVERROR(EINVAL);
762 goto error;
763 }
764
765 /* This is not really needed but saves us a loop for simple stream index specifiers. */
766
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7 times.
15 if (spec == indexptr)
767 8 return (index == st->index);
768
769 /* If we requested a matching stream index, we have to ensure st is that. */
770
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
7 nb_streams = g ? g->nb_streams : (p ? p->nb_stream_indexes : s->nb_streams);
771
3/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 4 times.
11 for (int i = 0; i < nb_streams && index >= 0; i++) {
772
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
7 unsigned idx = g ? g->streams[i]->index : (p ? p->stream_index[i] : i);
773 7 const AVStream *candidate = s->streams[idx];
774 7 ret = match_stream_specifier(s, candidate, spec, NULL, NULL, NULL);
775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
776 goto error;
777
4/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4 times.
7 if (ret > 0 && index-- == 0 && st == candidate)
778 3 return 1;
779 }
780 4 return 0;
781
782 error:
783 if (ret == AVERROR(EINVAL))
784 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
785 return ret;
786 }
787
788 817 AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
789 {
790 817 AVRational undef = {0, 1};
791
1/2
✓ Branch 0 taken 817 times.
✗ Branch 1 not taken.
817 AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef;
792
2/4
✓ Branch 0 taken 817 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 817 times.
✗ Branch 3 not taken.
817 AVRational codec_sample_aspect_ratio = stream && stream->codecpar ? stream->codecpar->sample_aspect_ratio : undef;
793
2/2
✓ Branch 0 taken 676 times.
✓ Branch 1 taken 141 times.
817 AVRational frame_sample_aspect_ratio = frame ? frame->sample_aspect_ratio : codec_sample_aspect_ratio;
794
795 817 av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den,
796 817 stream_sample_aspect_ratio.num, stream_sample_aspect_ratio.den, INT_MAX);
797
3/4
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 262 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 555 times.
817 if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0)
798 262 stream_sample_aspect_ratio = undef;
799
800 817 av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den,
801 817 frame_sample_aspect_ratio.num, frame_sample_aspect_ratio.den, INT_MAX);
802
3/4
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 307 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 510 times.
817 if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0)
803 307 frame_sample_aspect_ratio = undef;
804
805
2/2
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 262 times.
817 if (stream_sample_aspect_ratio.num)
806 555 return stream_sample_aspect_ratio;
807 else
808 262 return frame_sample_aspect_ratio;
809 }
810
811 5710 AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
812 {
813 5710 AVRational fr = st->r_frame_rate;
814 5710 const AVCodecDescriptor *desc = cffstream(st)->codec_desc;
815 5710 AVRational avg_fr = st->avg_frame_rate;
816
817
7/10
✓ Branch 0 taken 5064 times.
✓ Branch 1 taken 646 times.
✓ Branch 2 taken 5064 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5064 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5064 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5039 times.
✓ Branch 9 taken 25 times.
10774 if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 &&
818
2/2
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 4647 times.
10103 av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) {
819 392 fr = avg_fr;
820 }
821
822
3/4
✓ Branch 0 taken 5710 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 325 times.
✓ Branch 3 taken 5385 times.
5710 if (desc && (desc->props & AV_CODEC_PROP_FIELDS)) {
823 325 const AVCodecContext *const avctx = ffstream(st)->avctx;
824 325 AVRational codec_fr = avctx->framerate;
825
826
3/4
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 129 times.
✗ Branch 3 not taken.
325 if ( codec_fr.num > 0 && codec_fr.den > 0 &&
827
5/6
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 37 times.
✓ Branch 5 taken 92 times.
✓ Branch 7 taken 35 times.
✓ Branch 8 taken 2 times.
129 (fr.num == 0 || av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1))
828 35 fr = codec_fr;
829 }
830
831 5710 return fr;
832 }
833
834 22289 void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits,
835 unsigned int pts_num, unsigned int pts_den)
836 {
837 22289 FFStream *const sti = ffstream(st);
838 AVRational new_tb;
839
1/2
✓ Branch 1 taken 22289 times.
✗ Branch 2 not taken.
22289 if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) {
840
2/2
✓ Branch 0 taken 567 times.
✓ Branch 1 taken 21722 times.
22289 if (new_tb.num != pts_num)
841 567 av_log(NULL, AV_LOG_DEBUG,
842 "st:%d removing common factor %d from timebase\n",
843 567 st->index, pts_num / new_tb.num);
844 } else
845 av_log(NULL, AV_LOG_WARNING,
846 "st:%d has too large timebase, reducing\n", st->index);
847
848
3/4
✓ Branch 0 taken 22288 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22288 times.
22289 if (new_tb.num <= 0 || new_tb.den <= 0) {
849 1 av_log(NULL, AV_LOG_ERROR,
850 "Ignoring attempt to set invalid timebase %d/%d for st:%d\n",
851 new_tb.num, new_tb.den,
852 st->index);
853 1 return;
854 }
855 22288 st->time_base = new_tb;
856
2/2
✓ Branch 0 taken 18006 times.
✓ Branch 1 taken 4282 times.
22288 if (sti->avctx)
857 18006 sti->avctx->pkt_timebase = new_tb;
858 22288 st->pts_wrap_bits = pts_wrap_bits;
859 }
860
861 10022 const AVCodec *ff_find_decoder(AVFormatContext *s, const AVStream *st,
862 enum AVCodecID codec_id)
863 {
864
4/4
✓ Branch 0 taken 6893 times.
✓ Branch 1 taken 2860 times.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 165 times.
10022 switch (st->codecpar->codec_type) {
865 6893 case AVMEDIA_TYPE_VIDEO:
866
2/2
✓ Branch 0 taken 3150 times.
✓ Branch 1 taken 3743 times.
6893 if (s->video_codec) return s->video_codec;
867 3743 break;
868 2860 case AVMEDIA_TYPE_AUDIO:
869
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 2843 times.
2860 if (s->audio_codec) return s->audio_codec;
870 2843 break;
871 104 case AVMEDIA_TYPE_SUBTITLE:
872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 if (s->subtitle_codec) return s->subtitle_codec;
873 104 break;
874 }
875
876 6855 return avcodec_find_decoder(codec_id);
877 }
878
879 88 int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
880 {
881 #define OFF(field) offsetof(AVFormatContext, field)
882 static const unsigned offsets[] = {
883 OFF(codec_whitelist), OFF(format_whitelist),
884 OFF(protocol_whitelist), OFF(protocol_blacklist),
885 };
886 #undef OFF
887
4/8
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 88 times.
88 av_assert0(!dst->codec_whitelist &&
888 !dst->format_whitelist &&
889 !dst->protocol_whitelist &&
890 !dst->protocol_blacklist);
891
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 88 times.
440 for (unsigned i = 0; i < FF_ARRAY_ELEMS(offsets); i++) {
892 352 const char *src_str = *(char *const*)((const char*)src + offsets[i]);
893
894
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 264 times.
352 if (src_str) {
895 88 char *dst_str = av_strdup(src_str);
896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (!dst_str) {
897 av_log(dst, AV_LOG_ERROR, "Failed to duplicate black/whitelist\n");
898 return AVERROR(ENOMEM);
899 }
900
901 88 *(char **)((char*)dst + offsets[i]) = dst_str;
902 }
903 }
904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (src->recursion_limit <= 0) {
905 av_log(dst, AV_LOG_ERROR, "Too deep recursion\n");
906 return AVERROR_INVALIDDATA;
907 }
908 88 dst->recursion_limit = src->recursion_limit - 1;
909 88 return 0;
910 }
911
912 665577 int ff_is_intra_only(enum AVCodecID id)
913 {
914 665577 const AVCodecDescriptor *d = avcodec_descriptor_get(id);
915
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 665512 times.
665577 if (!d)
916 65 return 0;
917
4/4
✓ Branch 0 taken 390291 times.
✓ Branch 1 taken 275221 times.
✓ Branch 2 taken 386836 times.
✓ Branch 3 taken 3455 times.
665512 if ((d->type == AVMEDIA_TYPE_VIDEO || d->type == AVMEDIA_TYPE_AUDIO) &&
918
2/2
✓ Branch 0 taken 209748 times.
✓ Branch 1 taken 452309 times.
662057 !(d->props & AV_CODEC_PROP_INTRA_ONLY))
919 209748 return 0;
920 455764 return 1;
921 }
922
923 102 void ff_format_set_url(AVFormatContext *s, char *url)
924 {
925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 av_assert0(url);
926 102 av_freep(&s->url);
927 102 s->url = url;
928 102 }
929
930 int ff_format_check_set_url(AVFormatContext *s, const char *url)
931 {
932 URLComponents uc;
933 av_assert0(url);
934 char proto[64];
935
936 int ret = ff_url_decompose(&uc, url, NULL);
937 if (ret < 0)
938 return ret;
939 av_strlcpy(proto, uc.scheme, FFMIN(sizeof(proto), uc.url_component_end_scheme - uc.scheme));
940
941 if (s->protocol_whitelist && av_match_list(proto, s->protocol_whitelist, ',') <= 0) {
942 av_log(s, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", proto, s->protocol_whitelist);
943 return AVERROR(EINVAL);
944 }
945
946 if (s->protocol_blacklist && av_match_list(proto, s->protocol_blacklist, ',') > 0) {
947 av_log(s, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", proto, s->protocol_blacklist);
948 return AVERROR(EINVAL);
949 }
950
951 char *urldup = av_strdup(url);
952 if (!urldup)
953 return AVERROR(ENOMEM);
954
955 av_freep(&s->url);
956 s->url = urldup;
957 return 0;
958 }
959
960
961 126860 int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
962 {
963 126860 int ret = 0;
964
2/2
✓ Branch 0 taken 123311 times.
✓ Branch 1 taken 3549 times.
126860 if (*pb)
965 123311 ret = s->io_close2(s, *pb);
966 126860 *pb = NULL;
967 126860 return ret;
968 }
969