FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mux_utils.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 48 78 61.5%
Functions: 5 5 100.0%
Branches: 20 48 41.7%

Line Branch Exec Source
1 /*
2 * Various muxing utility 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/dict.h"
23 #include "libavutil/internal.h"
24 #include "libavutil/log.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/parseutils.h"
27 #include "avformat.h"
28 #include "avio.h"
29 #include "internal.h"
30 #include "mux.h"
31
32 6031 int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
33 int std_compliance)
34 {
35
1/2
✓ Branch 0 taken 6031 times.
✗ Branch 1 not taken.
6031 if (ofmt) {
36 unsigned int codec_tag;
37
2/2
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 5940 times.
6031 if (ffofmt(ofmt)->query_codec)
38 6031 return ffofmt(ofmt)->query_codec(codec_id, std_compliance);
39
2/2
✓ Branch 0 taken 3203 times.
✓ Branch 1 taken 2737 times.
5940 else if (ofmt->codec_tag)
40 3203 return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
41
1/2
✓ Branch 0 taken 2737 times.
✗ Branch 1 not taken.
2737 else if (codec_id != AV_CODEC_ID_NONE &&
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2737 times.
2737 (codec_id == ofmt->video_codec ||
43 codec_id == ofmt->audio_codec ||
44 codec_id == ofmt->subtitle_codec))
45 2737 return 1;
46 else if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_ONLY_DEFAULT_CODECS)
47 return 0;
48 else if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_MAX_ONE_OF_EACH) {
49 enum AVMediaType type = avcodec_get_type(codec_id);
50 switch (type) {
51 case AVMEDIA_TYPE_AUDIO:
52 if (ofmt->audio_codec == AV_CODEC_ID_NONE)
53 return 0;
54 break;
55 case AVMEDIA_TYPE_VIDEO:
56 if (ofmt->video_codec == AV_CODEC_ID_NONE)
57 return 0;
58 break;
59 case AVMEDIA_TYPE_SUBTITLE:
60 if (ofmt->subtitle_codec == AV_CODEC_ID_NONE)
61 return 0;
62 break;
63 default:
64 return 0;
65 }
66 }
67 }
68 return AVERROR_PATCHWELCOME;
69 }
70
71 10 int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
72 {
73 int ret;
74 int64_t pos, pos_end;
75 uint8_t *buf, *read_buf[2];
76 10 int read_buf_id = 0;
77 int read_size[2];
78 AVIOContext *read_pb;
79
80 10 buf = av_malloc_array(shift_size, 2);
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!buf)
82 return AVERROR(ENOMEM);
83 10 read_buf[0] = buf;
84 10 read_buf[1] = buf + shift_size;
85
86 /* Shift the data: the AVIO context of the output can only be used for
87 * writing, so we re-open the same output, but for reading. It also avoids
88 * a read/seek/write/seek back and forth. */
89 10 avio_flush(s->pb);
90 10 ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0) {
92 av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for shifting data\n", s->url);
93 goto end;
94 }
95
96 /* mark the end of the shift to up to the last data we wrote, and get ready
97 * for writing */
98 10 pos_end = avio_tell(s->pb);
99 10 avio_seek(s->pb, read_start + shift_size, SEEK_SET);
100
101 10 avio_seek(read_pb, read_start, SEEK_SET);
102 10 pos = avio_tell(read_pb);
103
104 #define READ_BLOCK do { \
105 read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
106 read_buf_id ^= 1; \
107 } while (0)
108
109 /* shift data by chunk of at most shift_size */
110 10 READ_BLOCK;
111 do {
112 int n;
113 28635 READ_BLOCK;
114 28635 n = read_size[read_buf_id];
115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28635 times.
28635 if (n <= 0)
116 break;
117 28635 avio_write(s->pb, read_buf[read_buf_id], n);
118 28635 pos += n;
119
2/2
✓ Branch 0 taken 28625 times.
✓ Branch 1 taken 10 times.
28635 } while (pos < pos_end);
120 10 ret = ff_format_io_close(s, &read_pb);
121
122 10 end:
123 10 av_free(buf);
124 10 return ret;
125 }
126
127 51 int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **options)
128 {
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (!s->oformat)
130 return AVERROR(EINVAL);
131
132
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 49 times.
51 if (!(s->oformat->flags & AVFMT_NOFILE))
133 2 return s->io_open(s, &s->pb, url, AVIO_FLAG_WRITE, options);
134 49 return 0;
135 }
136
137 3031 int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
138 {
139 AVDictionaryEntry *entry;
140 int64_t parsed_timestamp;
141 int ret;
142
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3030 times.
3031 if ((entry = av_dict_get(s->metadata, "creation_time", NULL, 0))) {
143
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if ((ret = av_parse_time(&parsed_timestamp, entry->value, 0)) >= 0) {
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 *timestamp = return_seconds ? parsed_timestamp / 1000000 : parsed_timestamp;
145 1 return 1;
146 } else {
147 av_log(s, AV_LOG_WARNING, "Failed to parse creation_time %s\n", entry->value);
148 return ret;
149 }
150 }
151 3030 return 0;
152 }
153
154 2732 int ff_standardize_creation_time(AVFormatContext *s)
155 {
156 int64_t timestamp;
157 2732 int ret = ff_parse_creation_time_metadata(s, &timestamp, 0);
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2732 times.
2732 if (ret == 1)
159 return ff_dict_set_timestamp(&s->metadata, "creation_time", timestamp);
160 2732 return ret;
161 }
162