Coverage Report

Created: 2026-11-11 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpv/audio/format.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2005 Alex Beregszaszi
3
 *
4
 * This file is part of mpv.
5
 *
6
 * mpv is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * mpv is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include <limits.h>
21
22
#include "common/common.h"
23
#include "format.h"
24
25
// number of bytes per sample, 0 if invalid/unknown
26
int af_fmt_to_bytes(int format)
27
19.4M
{
28
19.4M
    switch (af_fmt_from_planar(format)) {
29
106k
    case AF_FORMAT_U8:      return 1;
30
6.43M
    case AF_FORMAT_S16:     return 2;
31
56.9k
    case AF_FORMAT_S32:     return 4;
32
123k
    case AF_FORMAT_S64:     return 8;
33
12.7M
    case AF_FORMAT_FLOAT:   return 4;
34
1.39k
    case AF_FORMAT_DOUBLE:  return 8;
35
19.4M
    }
36
0
    if (format == AF_FORMAT_S_DOP)
37
0
        return 4;
38
0
    if (format == AF_FORMAT_DSD)
39
0
        return 1;
40
0
    if (af_fmt_is_spdif(format))
41
0
        return 2;
42
0
    return 0;
43
0
}
44
45
// All formats are considered signed, except explicitly unsigned int formats.
46
bool af_fmt_is_unsigned(int format)
47
10.2M
{
48
10.2M
    return format == AF_FORMAT_U8 || format == AF_FORMAT_U8P;
49
10.2M
}
50
51
bool af_fmt_is_float(int format)
52
8.42k
{
53
8.42k
    format = af_fmt_from_planar(format);
54
8.42k
    return format == AF_FORMAT_FLOAT || format == AF_FORMAT_DOUBLE;
55
8.42k
}
56
57
// true for both unsigned and signed ints
58
bool af_fmt_is_int(int format)
59
0
{
60
0
    return format && af_fmt_is_pcm(format) && !af_fmt_is_float(format) &&
61
0
           format != AF_FORMAT_DSD;
62
0
}
63
64
// true for IEC61937 wrapped formats only (not other bitstream formats)
65
bool af_fmt_is_spdif(int format)
66
605k
{
67
605k
    return af_format_sample_alignment(format) > 1;
68
605k
}
69
70
bool af_fmt_is_pcm(int format)
71
605k
{
72
605k
    return af_fmt_is_valid(format) && !af_fmt_is_spdif(format) &&
73
605k
           format != AF_FORMAT_S_DOP;
74
605k
}
75
76
static const int planar_formats[][2] = {
77
    {AF_FORMAT_U8P,     AF_FORMAT_U8},
78
    {AF_FORMAT_S16P,    AF_FORMAT_S16},
79
    {AF_FORMAT_S32P,    AF_FORMAT_S32},
80
    {AF_FORMAT_S64P,    AF_FORMAT_S64},
81
    {AF_FORMAT_FLOATP,  AF_FORMAT_FLOAT},
82
    {AF_FORMAT_DOUBLEP, AF_FORMAT_DOUBLE},
83
};
84
85
bool af_fmt_is_planar(int format)
86
55.4M
{
87
259M
    for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
88
252M
        if (planar_formats[n][0] == format)
89
48.7M
            return true;
90
252M
    }
91
6.69M
    return false;
92
55.4M
}
93
94
// Return the planar format corresponding to the given format.
95
// If the format is already planar or if there's no equivalent,
96
// return it.
97
int af_fmt_to_planar(int format)
98
0
{
99
0
    for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
100
0
        if (planar_formats[n][1] == format)
101
0
            return planar_formats[n][0];
102
0
    }
103
0
    return format;
104
0
}
105
106
// Return the interleaved format corresponding to the given format.
107
// If the format is already interleaved or if there's no equivalent,
108
// return it.
109
int af_fmt_from_planar(int format)
110
24.3M
{
111
112M
    for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
112
108M
        if (planar_formats[n][0] == format)
113
21.1M
            return planar_formats[n][1];
114
108M
    }
115
3.18M
    return format;
116
24.3M
}
117
118
bool af_fmt_is_valid(int format)
119
605k
{
120
605k
    return format > 0 && format < AF_FORMAT_COUNT;
121
605k
}
122
123
const char *af_fmt_to_str(int format)
124
452k
{
125
452k
    switch (format) {
126
9.79k
    case AF_FORMAT_U8:          return "u8";
127
121k
    case AF_FORMAT_S16:         return "s16";
128
8.54k
    case AF_FORMAT_S32:         return "s32";
129
9.51k
    case AF_FORMAT_S64:         return "s64";
130
8.55k
    case AF_FORMAT_FLOAT:       return "float";
131
7.35k
    case AF_FORMAT_DOUBLE:      return "double";
132
8.85k
    case AF_FORMAT_U8P:         return "u8p";
133
67.0k
    case AF_FORMAT_S16P:        return "s16p";
134
7.62k
    case AF_FORMAT_S32P:        return "s32p";
135
7.18k
    case AF_FORMAT_S64P:        return "s64p";
136
128k
    case AF_FORMAT_FLOATP:      return "floatp";
137
6.84k
    case AF_FORMAT_DOUBLEP:     return "doublep";
138
6.82k
    case AF_FORMAT_S_AAC:       return "spdif-aac";
139
6.82k
    case AF_FORMAT_S_AC3:       return "spdif-ac3";
140
6.82k
    case AF_FORMAT_S_DTS:       return "spdif-dts";
141
6.82k
    case AF_FORMAT_S_DTSHD:     return "spdif-dtshd";
142
6.82k
    case AF_FORMAT_S_EAC3:      return "spdif-eac3";
143
6.82k
    case AF_FORMAT_S_MP3:       return "spdif-mp3";
144
6.82k
    case AF_FORMAT_S_TRUEHD:    return "spdif-truehd";
145
6.82k
    case AF_FORMAT_S_DOP:       return "dop";
146
6.82k
    case AF_FORMAT_DSD:         return "dsd";
147
452k
    }
148
0
    return "??";
149
452k
}
150
151
void af_fill_silence(void *dst, size_t bytes, int format)
152
10.2M
{
153
10.2M
    int fill = 0;
154
10.2M
    if (af_fmt_is_unsigned(format))
155
169k
        fill = 0x80;
156
10.2M
    if (format == AF_FORMAT_DSD)
157
0
        fill = 0x69; // only ultrasonic tones, filtered out on playback
158
10.2M
    memset(dst, fill, bytes);
159
10.2M
}
160
161
// Returns a "score" that serves as heuristic how lossy or hard a conversion is.
162
// If the formats are equal, 1024 is returned. If they are gravely incompatible
163
// (like s16<->ac3), INT_MIN is returned. If there is implied loss of precision
164
// (like s16->s8), a value <0 is returned.
165
int af_format_conversion_score(int dst_format, int src_format)
166
59.6k
{
167
59.6k
    if (dst_format == AF_FORMAT_UNKNOWN || src_format == AF_FORMAT_UNKNOWN)
168
0
        return INT_MIN;
169
59.6k
    if (dst_format == src_format)
170
56.3k
        return 1024;
171
3.29k
    if (src_format == AF_FORMAT_DSD) {
172
0
        return af_fmt_is_pcm(dst_format) && dst_format != AF_FORMAT_DSD
173
0
               ? af_format_conversion_score(dst_format, AF_FORMAT_FLOAT) - 1
174
0
               : INT_MIN;
175
0
    }
176
3.29k
    if (dst_format == AF_FORMAT_DSD)
177
0
        return INT_MIN;
178
    // Can't be normally converted
179
3.29k
    if (!af_fmt_is_pcm(dst_format) || !af_fmt_is_pcm(src_format))
180
4
        return INT_MIN;
181
3.28k
    int score = 1024;
182
3.28k
    if (af_fmt_is_planar(dst_format) != af_fmt_is_planar(src_format))
183
2.38k
        score -= 1;     // has to (de-)planarize
184
3.28k
    if (af_fmt_is_float(dst_format) != af_fmt_is_float(src_format)) {
185
1.84k
        int dst_bytes = af_fmt_to_bytes(dst_format);
186
1.84k
        if (af_fmt_is_float(dst_format)) {
187
            // For int->float, consider a lower bound on the precision difference.
188
1.68k
            int bytes = (dst_bytes == 4 ? 3 : 6) - af_fmt_to_bytes(src_format);
189
1.68k
            if (bytes >= 0) {
190
1.67k
                score -= 8 * bytes;          // excess precision
191
1.67k
            } else {
192
3
                score += 1024 * (bytes - 1); // precision is lost (i.e. s32 -> float)
193
3
            }
194
1.68k
        } else {
195
            // float->int is the worst case. Penalize heavily and
196
            // prefer highest bit depth int.
197
165
            score -= 1048576 * (8 - dst_bytes);
198
165
        }
199
1.84k
        score -= 512; // penalty for any float <-> int conversion
200
1.84k
    } else {
201
1.44k
        int bytes = af_fmt_to_bytes(dst_format) - af_fmt_to_bytes(src_format);
202
1.44k
        if (bytes > 0) {
203
704
            score -= 8 * bytes;          // has to add padding
204
737
        } else if (bytes < 0) {
205
586
            score += 1024 * (bytes - 1); // has to reduce bit depth
206
586
        }
207
1.44k
    }
208
3.28k
    return score;
209
3.29k
}
210
211
struct mp_entry {
212
    int fmt;
213
    int score;
214
};
215
216
static int cmp_entry(const void *a, const void *b)
217
0
{
218
0
#define CMP_INT(a, b) (a > b ? 1 : (a < b ? -1 : 0))
219
0
    return -CMP_INT(((struct mp_entry *)a)->score, ((struct mp_entry *)b)->score);
220
0
}
221
222
// Return a list of sample format compatible to src_format, sorted by order
223
// of preference. out_formats[0] will be src_format (as long as it's valid),
224
// and the list is terminated with 0 (AF_FORMAT_UNKNOWN).
225
// Keep in mind that this also returns formats with flipped interleaving
226
// (e.g. for s16, it returns [s16, s16p, ...]).
227
// out_formats must be an int[AF_FORMAT_COUNT + 1] array.
228
void af_get_best_sample_formats(int src_format, int *out_formats)
229
0
{
230
0
    int num = 0;
231
0
    struct mp_entry e[AF_FORMAT_COUNT + 1];
232
0
    for (int fmt = 1; fmt < AF_FORMAT_COUNT; fmt++) {
233
0
        int score = af_format_conversion_score(fmt, src_format);
234
0
        if (score > INT_MIN)
235
0
            e[num++] = (struct mp_entry){fmt, score};
236
0
    }
237
0
    qsort(e, num, sizeof(e[0]), cmp_entry);
238
0
    for (int n = 0; n < num; n++)
239
0
        out_formats[n] = e[n].fmt;
240
0
    out_formats[num] = 0;
241
0
}
242
243
// Return the best match to src_samplerate from the list provided in the array
244
// *available, which must be terminated by 0, or itself NULL. If *available is
245
// empty or NULL, return a negative value. Exact match to src_samplerate is
246
// most preferred, followed by the lowest integer multiple, followed by the
247
// maximum of *available.
248
int af_select_best_samplerate(int src_samplerate, const int *available)
249
54.8k
{
250
54.8k
    if (!available)
251
4.80k
        return -1;
252
253
50.0k
    int min_mult_rate = INT_MAX;
254
50.0k
    int max_rate      = INT_MIN;
255
52.0k
    for (int i = 0; available[i]; i++) {
256
50.0k
        if (available[i] == src_samplerate)
257
47.9k
            return available[i];
258
259
2.04k
        if (!(available[i] % src_samplerate))
260
4
            min_mult_rate = MPMIN(min_mult_rate, available[i]);
261
262
2.04k
        max_rate = MPMAX(max_rate, available[i]);
263
2.04k
    }
264
265
2.04k
    if (min_mult_rate < INT_MAX)
266
4
        return min_mult_rate;
267
268
2.04k
    if (max_rate > INT_MIN)
269
2.04k
        return max_rate;
270
271
0
    return -1;
272
2.04k
}
273
274
// Return the number of samples that make up one frame in this format.
275
// You get the byte size by multiplying them with sample size and channel count.
276
int af_format_sample_alignment(int format)
277
652k
{
278
652k
    switch (format) {
279
0
    case AF_FORMAT_S_AAC:       return 16384 / 4;
280
0
    case AF_FORMAT_S_AC3:       return 6144 / 4;
281
4
    case AF_FORMAT_S_DTSHD:     return 32768 / 16;
282
0
    case AF_FORMAT_S_DTS:       return 2048 / 4;
283
0
    case AF_FORMAT_S_EAC3:      return 24576 / 4;
284
0
    case AF_FORMAT_S_MP3:       return 4608 / 4;
285
0
    case AF_FORMAT_S_TRUEHD:    return 61440 / 16;
286
652k
    default:                    return 1;
287
652k
    }
288
652k
}