Coverage Report

Created: 2025-09-04 07:15

/src/mpv/common/codecs.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * This file is part of mpv.
3
 *
4
 * mpv is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * mpv is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
#include <assert.h>
19
#include "mpv_talloc.h"
20
#include "misc/bstr.h"
21
#include "common/msg.h"
22
#include "codecs.h"
23
24
void mp_add_decoder(struct mp_decoder_list *list, const char *codec,
25
                    const char *decoder, const char *desc)
26
27.1M
{
27
27.1M
    struct mp_decoder_entry entry = {
28
27.1M
        .codec = talloc_strdup(list, codec),
29
27.1M
        .decoder = talloc_strdup(list, decoder),
30
27.1M
        .desc = talloc_strdup(list, desc),
31
27.1M
    };
32
27.1M
    MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry);
33
27.1M
}
34
35
// Add entry, but only if it's not yet on the list, and if the codec matches.
36
// If codec == NULL, don't compare codecs.
37
static void add_new(struct mp_decoder_list *to, struct mp_decoder_entry *entry,
38
                    const char *codec)
39
22.3M
{
40
22.3M
    if (!entry || (codec && strcmp(entry->codec, codec) != 0))
41
18.2M
        return;
42
4.05M
    mp_add_decoder(to, entry->codec, entry->decoder, entry->desc);
43
4.05M
}
44
45
// Select a decoder from the given list for the given codec. The selection
46
// can be influenced by the selection string, which can specify a priority
47
// list of preferred decoders.
48
// This returns a list of decoders to try, with the preferred decoders first.
49
// The selection string corresponds to --vd/--ad directly, and has the
50
// following syntax:
51
//   selection = [<entry> ("," <entry>)*]
52
//       entry = <decoder>       // prefer decoder
53
//       entry = "-" <decoder>   // exclude a decoder
54
//       entry = "-"                            // don't add fallback decoders
55
// Forcing a decoder means it's added even if the codec mismatches.
56
struct mp_decoder_list *mp_select_decoders(struct mp_log *log,
57
                                           struct mp_decoder_list *all,
58
                                           const char *codec,
59
                                           const char *selection)
60
78.0k
{
61
78.0k
    struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
62
78.0k
    if (!codec)
63
0
        codec = "unknown";
64
78.0k
    bool stop = false;
65
78.0k
    bstr sel = bstr0(selection);
66
101k
    while (sel.len) {
67
23.4k
        bstr entry;
68
23.4k
        bstr_split_tok(sel, ",", &entry, &sel);
69
23.4k
        if (bstr_equals0(entry, "-")) {
70
6
            mp_warn(log, "Excluding codecs is deprecated.\n");
71
6
            stop = true;
72
6
            break;
73
6
        }
74
4.99M
        for (int n = 0; n < all->num_entries; n++) {
75
4.96M
            struct mp_decoder_entry *cur = &all->entries[n];
76
4.96M
            if (bstr_equals0(entry, cur->decoder))
77
967
                add_new(list, cur, codec);
78
4.96M
        }
79
23.4k
    }
80
78.0k
    if (!stop) {
81
        // Add the remaining codecs which haven't been added yet
82
18.4M
        for (int n = 0; n < all->num_entries; n++)
83
18.3M
            add_new(list, &all->entries[n], codec);
84
78.0k
    }
85
78.0k
    return list;
86
78.0k
}
87
88
void mp_append_decoders(struct mp_decoder_list *list, struct mp_decoder_list *a)
89
16.9k
{
90
3.98M
    for (int n = 0; n < a->num_entries; n++)
91
3.96M
        add_new(list, &a->entries[n], NULL);
92
16.9k
}
93
94
void mp_print_decoders(struct mp_log *log, int msgl, const char *header,
95
                       struct mp_decoder_list *list)
96
80.9k
{
97
80.9k
    mp_msg(log, msgl, "%s\n", header);
98
864k
    for (int n = 0; n < list->num_entries; n++) {
99
783k
        struct mp_decoder_entry *entry = &list->entries[n];
100
783k
        mp_msg(log, msgl, "    %s", entry->decoder);
101
783k
        if (strcmp(entry->decoder, entry->codec) != 0)
102
93.7k
            mp_msg(log, msgl, " (%s)", entry->codec);
103
783k
        mp_msg(log, msgl, " - %s\n", entry->desc);
104
783k
    }
105
80.9k
    if (list->num_entries == 0)
106
5.38k
        mp_msg(log, msgl, "    (no decoders)\n");
107
80.9k
}