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 | } |