Coverage Report

Created: 2026-09-14 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/format.c
Line
Count
Source
1
/*
2
 * Format register and lookup
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 "libavutil/avstring.h"
25
#include "libavutil/mem.h"
26
#include "libavutil/opt.h"
27
28
#include "avio_internal.h"
29
#include "avformat.h"
30
#include "demux.h"
31
#include "id3v2.h"
32
#include "internal.h"
33
#include "url.h"
34
35
36
/**
37
 * @file
38
 * Format register and lookup
39
 */
40
41
int av_match_ext(const char *filename, const char *extensions)
42
169M
{
43
169M
    const char *ext;
44
45
169M
    if (!filename)
46
142M
        return 0;
47
48
27.5M
    ext = strrchr(filename, '.');
49
27.5M
    if (ext)
50
2.39M
        return av_match_name(ext + 1, extensions);
51
25.1M
    return 0;
52
27.5M
}
53
54
int ff_match_url_ext(const char *url, const char *extensions)
55
5.14k
{
56
5.14k
    const char *ext;
57
5.14k
    URLComponents uc;
58
5.14k
    int ret;
59
5.14k
    char scratchpad[128];
60
61
5.14k
    if (!url)
62
662
        return 0;
63
64
4.48k
    ret = ff_url_decompose(&uc, url, NULL);
65
4.48k
    if (ret < 0 || !URL_COMPONENT_HAVE(uc, scheme))
66
1.69k
        return ret;
67
135k
    for (ext = uc.query; *ext != '.' && ext > uc.path; ext--)
68
132k
        ;
69
70
2.79k
    if (*ext != '.')
71
580
        return 0;
72
2.21k
    if (uc.query - ext > sizeof(scratchpad))
73
216
        return AVERROR(ENOMEM); //not enough memory in our scratchpad
74
1.99k
    av_strlcpy(scratchpad, ext + 1, uc.query - ext);
75
76
1.99k
    return av_match_name(scratchpad, extensions);
77
2.21k
}
78
79
const AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
80
                                      const char *mime_type)
81
0
{
82
0
    const AVOutputFormat *fmt = NULL;
83
0
    const AVOutputFormat *fmt_found = NULL;
84
0
    void *i = 0;
85
0
    int score_max, score;
86
87
    /* specific test for image sequences */
88
#if CONFIG_IMAGE2_MUXER
89
    if (!short_name && filename &&
90
        av_filename_number_test(filename) &&
91
        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
92
        return av_guess_format("image2", NULL, NULL);
93
    }
94
#endif
95
    /* Find the proper file type. */
96
0
    score_max = 0;
97
0
    while ((fmt = av_muxer_iterate(&i))) {
98
0
        if (fmt->flags & AVFMT_EXPERIMENTAL && !short_name)
99
0
            continue;
100
0
        score = 0;
101
0
        if (fmt->name && short_name && av_match_name(short_name, fmt->name))
102
0
            score += 100;
103
0
        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
104
0
            score += 10;
105
0
        if (filename && fmt->extensions &&
106
0
            av_match_ext(filename, fmt->extensions)) {
107
0
            score += 5;
108
0
        }
109
0
        if (score > score_max) {
110
0
            score_max = score;
111
0
            fmt_found = fmt;
112
0
        }
113
0
    }
114
0
    return fmt_found;
115
0
}
116
117
enum AVCodecID av_guess_codec(const AVOutputFormat *fmt, const char *short_name,
118
                              const char *filename, const char *mime_type,
119
                              enum AVMediaType type)
120
0
{
121
0
    if (av_match_name("segment", fmt->name) || av_match_name("ssegment", fmt->name)) {
122
0
        const AVOutputFormat *fmt2 = av_guess_format(NULL, filename, NULL);
123
0
        if (fmt2)
124
0
            fmt = fmt2;
125
0
    }
126
127
0
    if (type == AVMEDIA_TYPE_VIDEO) {
128
0
        enum AVCodecID codec_id = AV_CODEC_ID_NONE;
129
130
#if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
131
        if (!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")) {
132
            codec_id = ff_guess_image2_codec(filename);
133
        }
134
#endif
135
0
        if (codec_id == AV_CODEC_ID_NONE)
136
0
            codec_id = fmt->video_codec;
137
0
        return codec_id;
138
0
    } else if (type == AVMEDIA_TYPE_AUDIO)
139
0
        return fmt->audio_codec;
140
0
    else if (type == AVMEDIA_TYPE_SUBTITLE)
141
0
        return fmt->subtitle_codec;
142
0
    else
143
0
        return AV_CODEC_ID_NONE;
144
0
}
145
146
const AVInputFormat *av_find_input_format(const char *short_name)
147
100
{
148
100
    const AVInputFormat *fmt = NULL;
149
100
    void *i = 0;
150
17.2k
    while ((fmt = av_demuxer_iterate(&i)))
151
17.2k
        if (av_match_name(short_name, fmt->name))
152
100
            return fmt;
153
0
    return NULL;
154
100
}
155
156
const AVInputFormat *av_probe_input_format3(const AVProbeData *pd,
157
                                            int is_opened, int *score_ret)
158
966k
{
159
966k
    AVProbeData lpd = *pd;
160
966k
    const AVInputFormat *fmt1 = NULL;
161
966k
    const AVInputFormat *fmt = NULL;
162
966k
    int score, score_max = 0;
163
966k
    void *i = 0;
164
966k
    const static uint8_t zerobuffer[AVPROBE_PADDING_SIZE];
165
966k
    enum nodat {
166
966k
        NO_ID3,
167
966k
        ID3_ALMOST_GREATER_PROBE,
168
966k
        ID3_GREATER_PROBE,
169
966k
        ID3_GREATER_MAX_PROBE,
170
966k
    } nodat = NO_ID3;
171
172
966k
    if (!lpd.buf)
173
6.75k
        lpd.buf = (unsigned char *) zerobuffer;
174
175
976k
    while (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
176
25.0k
        int id3len = ff_id3v2_tag_len(lpd.buf);
177
25.0k
        if (lpd.buf_size > id3len + 16) {
178
10.3k
            if (lpd.buf_size < 2LL*id3len + 16)
179
2.17k
                nodat = ID3_ALMOST_GREATER_PROBE;
180
10.3k
            lpd.buf      += id3len;
181
10.3k
            lpd.buf_size -= id3len;
182
14.7k
        } else if (id3len >= PROBE_BUF_MAX) {
183
9.39k
            nodat = ID3_GREATER_MAX_PROBE;
184
9.39k
            break;
185
9.39k
        } else {
186
5.32k
            nodat = ID3_GREATER_PROBE;
187
5.32k
            break;
188
5.32k
        }
189
25.0k
    }
190
191
347M
    while ((fmt1 = av_demuxer_iterate(&i))) {
192
346M
        if (fmt1->flags & AVFMT_EXPERIMENTAL)
193
0
            continue;
194
346M
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE) && strcmp(fmt1->name, "image2"))
195
980k
            continue;
196
345M
        score = 0;
197
345M
        if (ffifmt(fmt1)->read_probe) {
198
298M
            score = ffifmt(fmt1)->read_probe(&lpd);
199
298M
            if (score)
200
968k
                av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);
201
298M
            if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) {
202
11.9k
                switch (nodat) {
203
11.6k
                case NO_ID3:
204
11.6k
                    score = FFMAX(score, 1);
205
11.6k
                    break;
206
131
                case ID3_GREATER_PROBE:
207
177
                case ID3_ALMOST_GREATER_PROBE:
208
177
                    score = FFMAX(score, AVPROBE_SCORE_EXTENSION / 2 - 1);
209
177
                    break;
210
105
                case ID3_GREATER_MAX_PROBE:
211
105
                    score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
212
105
                    break;
213
11.9k
                }
214
11.9k
            }
215
298M
        } else if (fmt1->extensions) {
216
26.0M
            if (av_match_ext(lpd.filename, fmt1->extensions))
217
858
                score = AVPROBE_SCORE_EXTENSION;
218
26.0M
        }
219
345M
        if (av_match_name(lpd.mime_type, fmt1->mime_type)) {
220
0
            int old_score = score;
221
0
            score += AVPROBE_SCORE_MIME_BONUS;
222
0
            if (score > AVPROBE_SCORE_MAX) score = AVPROBE_SCORE_MAX;
223
0
            av_log(NULL, AV_LOG_DEBUG, "Probing %s score:%d increased to %d due to MIME type\n", fmt1->name, old_score, score);
224
0
        }
225
345M
        if (score > score_max) {
226
809k
            score_max = score;
227
809k
            fmt       = fmt1;
228
344M
        } else if (score == score_max)
229
217M
            fmt = NULL;
230
345M
    }
231
966k
    if (nodat == ID3_GREATER_PROBE)
232
5.32k
        score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
233
966k
    *score_ret = score_max;
234
235
966k
    return fmt;
236
966k
}
237
238
const AVInputFormat *av_probe_input_format2(const AVProbeData *pd,
239
                                            int is_opened, int *score_max)
240
136k
{
241
136k
    int score_ret;
242
136k
    const AVInputFormat *fmt = av_probe_input_format3(pd, is_opened, &score_ret);
243
136k
    if (score_ret > *score_max) {
244
81.6k
        *score_max = score_ret;
245
81.6k
        return fmt;
246
81.6k
    } else
247
55.3k
        return NULL;
248
136k
}
249
250
const AVInputFormat *av_probe_input_format(const AVProbeData *pd, int is_opened)
251
0
{
252
0
    int score = 0;
253
0
    return av_probe_input_format2(pd, is_opened, &score);
254
0
}
255
256
int av_probe_input_buffer2(AVIOContext *pb, const AVInputFormat **fmt,
257
                           const char *filename, void *logctx,
258
                           unsigned int offset, unsigned int max_probe_size)
259
85.2k
{
260
85.2k
    AVProbeData pd = { filename ? filename : "" };
261
85.2k
    uint8_t *buf = NULL;
262
85.2k
    int ret = 0, probe_size, buf_offset = 0;
263
85.2k
    int score = 0;
264
85.2k
    int ret2;
265
85.2k
    int eof = 0;
266
267
85.2k
    if (!max_probe_size)
268
478
        max_probe_size = PROBE_BUF_MAX;
269
84.8k
    else if (max_probe_size < PROBE_BUF_MIN) {
270
0
        av_log(logctx, AV_LOG_ERROR,
271
0
               "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN);
272
0
        return AVERROR(EINVAL);
273
0
    }
274
275
85.2k
    if (offset >= max_probe_size)
276
0
        return AVERROR(EINVAL);
277
278
85.2k
    if (pb->av_class) {
279
0
        uint8_t *mime_type_opt = NULL;
280
0
        char *semi;
281
0
        av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt);
282
0
        pd.mime_type = (const char *)mime_type_opt;
283
0
        semi = pd.mime_type ? strchr(mime_type_opt, ';') : NULL;
284
0
        if (semi) {
285
0
            *semi = '\0';
286
0
        }
287
0
    }
288
289
218k
    for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt && !eof;
290
133k
         probe_size = FFMIN(probe_size << 1,
291
134k
                            FFMAX(max_probe_size, probe_size + 1))) {
292
134k
        score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0;
293
294
        /* Read probe data. */
295
134k
        if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0)
296
0
            goto fail;
297
134k
        if ((ret = avio_read(pb, buf + buf_offset,
298
134k
                             probe_size - buf_offset)) < 0) {
299
            /* Fail if error was not end of file, otherwise, lower score. */
300
22.5k
            if (ret != AVERROR_EOF)
301
474
                goto fail;
302
303
22.1k
            score = 0;
304
22.1k
            ret   = 0;          /* error was end of file, nothing read */
305
22.1k
            eof   = 1;
306
22.1k
        }
307
133k
        buf_offset += ret;
308
133k
        if (buf_offset < offset)
309
0
            continue;
310
133k
        pd.buf_size = buf_offset - offset;
311
133k
        pd.buf = &buf[offset];
312
313
133k
        memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);
314
315
        /* Guess file format. */
316
133k
        *fmt = av_probe_input_format2(&pd, 1, &score);
317
133k
        if (*fmt) {
318
            /* This can only be true in the last iteration. */
319
78.5k
            if (score <= AVPROBE_SCORE_RETRY) {
320
15.9k
                av_log(logctx, AV_LOG_WARNING,
321
15.9k
                       "Format %s detected only with low score of %d, "
322
15.9k
                       "misdetection possible!\n", (*fmt)->name, score);
323
15.9k
            } else
324
62.5k
                av_log(logctx, AV_LOG_DEBUG,
325
62.5k
                       "Format %s probed with size=%d and score=%d\n",
326
62.5k
                       (*fmt)->name, probe_size, score);
327
#if 0
328
            FILE *f = fopen("probestat.tmp", "ab");
329
            fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename);
330
            fclose(f);
331
#endif
332
78.5k
        }
333
133k
    }
334
335
84.8k
    if (!*fmt)
336
6.28k
        ret = AVERROR_INVALIDDATA;
337
338
85.2k
fail:
339
    /* Rewind. Reuse probe buffer to avoid seeking. */
340
85.2k
    ret2 = ffio_rewind_with_probe_data(pb, &buf, buf_offset);
341
85.2k
    if (ret >= 0)
342
78.5k
        ret = ret2;
343
344
85.2k
    av_freep(&pd.mime_type);
345
85.2k
    return ret < 0 ? ret : score;
346
84.8k
}
347
348
int av_probe_input_buffer(AVIOContext *pb, const AVInputFormat **fmt,
349
                          const char *filename, void *logctx,
350
                          unsigned int offset, unsigned int max_probe_size)
351
478
{
352
478
    int ret = av_probe_input_buffer2(pb, fmt, filename, logctx, offset, max_probe_size);
353
478
    return ret < 0 ? ret : 0;
354
478
}