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
af_fmt_to_bytes(int format)26 int af_fmt_to_bytes(int format)
27 {
28 switch (af_fmt_from_planar(format)) {
29 case AF_FORMAT_U8: return 1;
30 case AF_FORMAT_S16: return 2;
31 case AF_FORMAT_S32: return 4;
32 case AF_FORMAT_S64: return 8;
33 case AF_FORMAT_FLOAT: return 4;
34 case AF_FORMAT_DOUBLE: return 8;
35 }
36 if (af_fmt_is_spdif(format))
37 return 2;
38 return 0;
39 }
40
41 // All formats are considered signed, except explicitly unsigned int formats.
af_fmt_is_unsigned(int format)42 bool af_fmt_is_unsigned(int format)
43 {
44 return format == AF_FORMAT_U8 || format == AF_FORMAT_U8P;
45 }
46
af_fmt_is_float(int format)47 bool af_fmt_is_float(int format)
48 {
49 format = af_fmt_from_planar(format);
50 return format == AF_FORMAT_FLOAT || format == AF_FORMAT_DOUBLE;
51 }
52
53 // true for both unsigned and signed ints
af_fmt_is_int(int format)54 bool af_fmt_is_int(int format)
55 {
56 return format && !af_fmt_is_spdif(format) && !af_fmt_is_float(format);
57 }
58
af_fmt_is_spdif(int format)59 bool af_fmt_is_spdif(int format)
60 {
61 return af_format_sample_alignment(format) > 1;
62 }
63
af_fmt_is_pcm(int format)64 bool af_fmt_is_pcm(int format)
65 {
66 return af_fmt_is_valid(format) && !af_fmt_is_spdif(format);
67 }
68
69 static const int planar_formats[][2] = {
70 {AF_FORMAT_U8P, AF_FORMAT_U8},
71 {AF_FORMAT_S16P, AF_FORMAT_S16},
72 {AF_FORMAT_S32P, AF_FORMAT_S32},
73 {AF_FORMAT_S64P, AF_FORMAT_S64},
74 {AF_FORMAT_FLOATP, AF_FORMAT_FLOAT},
75 {AF_FORMAT_DOUBLEP, AF_FORMAT_DOUBLE},
76 };
77
af_fmt_is_planar(int format)78 bool af_fmt_is_planar(int format)
79 {
80 for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
81 if (planar_formats[n][0] == format)
82 return true;
83 }
84 return false;
85 }
86
87 // Return the planar format corresponding to the given format.
88 // If the format is already planar or if there's no equivalent,
89 // return it.
af_fmt_to_planar(int format)90 int af_fmt_to_planar(int format)
91 {
92 for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
93 if (planar_formats[n][1] == format)
94 return planar_formats[n][0];
95 }
96 return format;
97 }
98
99 // Return the interleaved format corresponding to the given format.
100 // If the format is already interleaved or if there's no equivalent,
101 // return it.
af_fmt_from_planar(int format)102 int af_fmt_from_planar(int format)
103 {
104 for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
105 if (planar_formats[n][0] == format)
106 return planar_formats[n][1];
107 }
108 return format;
109 }
110
af_fmt_is_valid(int format)111 bool af_fmt_is_valid(int format)
112 {
113 return format > 0 && format < AF_FORMAT_COUNT;
114 }
115
af_fmt_to_str(int format)116 const char *af_fmt_to_str(int format)
117 {
118 switch (format) {
119 case AF_FORMAT_U8: return "u8";
120 case AF_FORMAT_S16: return "s16";
121 case AF_FORMAT_S32: return "s32";
122 case AF_FORMAT_S64: return "s64";
123 case AF_FORMAT_FLOAT: return "float";
124 case AF_FORMAT_DOUBLE: return "double";
125 case AF_FORMAT_U8P: return "u8p";
126 case AF_FORMAT_S16P: return "s16p";
127 case AF_FORMAT_S32P: return "s32p";
128 case AF_FORMAT_S64P: return "s64p";
129 case AF_FORMAT_FLOATP: return "floatp";
130 case AF_FORMAT_DOUBLEP: return "doublep";
131 case AF_FORMAT_S_AAC: return "spdif-aac";
132 case AF_FORMAT_S_AC3: return "spdif-ac3";
133 case AF_FORMAT_S_DTS: return "spdif-dts";
134 case AF_FORMAT_S_DTSHD: return "spdif-dtshd";
135 case AF_FORMAT_S_EAC3: return "spdif-eac3";
136 case AF_FORMAT_S_MP3: return "spdif-mp3";
137 case AF_FORMAT_S_TRUEHD: return "spdif-truehd";
138 }
139 return "??";
140 }
141
af_fill_silence(void * dst,size_t bytes,int format)142 void af_fill_silence(void *dst, size_t bytes, int format)
143 {
144 memset(dst, af_fmt_is_unsigned(format) ? 0x80 : 0, bytes);
145 }
146
147 // Returns a "score" that serves as heuristic how lossy or hard a conversion is.
148 // If the formats are equal, 1024 is returned. If they are gravely incompatible
149 // (like s16<->ac3), INT_MIN is returned. If there is implied loss of precision
150 // (like s16->s8), a value <0 is returned.
af_format_conversion_score(int dst_format,int src_format)151 int af_format_conversion_score(int dst_format, int src_format)
152 {
153 if (dst_format == AF_FORMAT_UNKNOWN || src_format == AF_FORMAT_UNKNOWN)
154 return INT_MIN;
155 if (dst_format == src_format)
156 return 1024;
157 // Can't be normally converted
158 if (!af_fmt_is_pcm(dst_format) || !af_fmt_is_pcm(src_format))
159 return INT_MIN;
160 int score = 1024;
161 if (af_fmt_is_planar(dst_format) != af_fmt_is_planar(src_format))
162 score -= 1; // has to (de-)planarize
163 if (af_fmt_is_float(dst_format) != af_fmt_is_float(src_format)) {
164 int dst_bytes = af_fmt_to_bytes(dst_format);
165 if (af_fmt_is_float(dst_format)) {
166 // For int->float, consider a lower bound on the precision difference.
167 int bytes = (dst_bytes == 4 ? 3 : 6) - af_fmt_to_bytes(src_format);
168 if (bytes >= 0) {
169 score -= 8 * bytes; // excess precision
170 } else {
171 score += 1024 * (bytes - 1); // precision is lost (i.e. s32 -> float)
172 }
173 } else {
174 // float->int is the worst case. Penalize heavily and
175 // prefer highest bit depth int.
176 score -= 1048576 * (8 - dst_bytes);
177 }
178 score -= 512; // penalty for any float <-> int conversion
179 } else {
180 int bytes = af_fmt_to_bytes(dst_format) - af_fmt_to_bytes(src_format);
181 if (bytes > 0) {
182 score -= 8 * bytes; // has to add padding
183 } else if (bytes < 0) {
184 score += 1024 * (bytes - 1); // has to reduce bit depth
185 }
186 }
187 return score;
188 }
189
190 struct entry {
191 int fmt;
192 int score;
193 };
194
cmp_entry(const void * a,const void * b)195 static int cmp_entry(const void *a, const void *b)
196 {
197 #define CMP_INT(a, b) (a > b ? 1 : (a < b ? -1 : 0))
198 return -CMP_INT(((struct entry *)a)->score, ((struct entry *)b)->score);
199 }
200
201 // Return a list of sample format compatible to src_format, sorted by order
202 // of preference. out_formats[0] will be src_format (as long as it's valid),
203 // and the list is terminated with 0 (AF_FORMAT_UNKNOWN).
204 // Keep in mind that this also returns formats with flipped interleaving
205 // (e.g. for s16, it returns [s16, s16p, ...]).
206 // out_formats must be an int[AF_FORMAT_COUNT + 1] array.
af_get_best_sample_formats(int src_format,int * out_formats)207 void af_get_best_sample_formats(int src_format, int *out_formats)
208 {
209 int num = 0;
210 struct entry e[AF_FORMAT_COUNT + 1];
211 for (int fmt = 1; fmt < AF_FORMAT_COUNT; fmt++) {
212 int score = af_format_conversion_score(fmt, src_format);
213 if (score > INT_MIN)
214 e[num++] = (struct entry){fmt, score};
215 }
216 qsort(e, num, sizeof(e[0]), cmp_entry);
217 for (int n = 0; n < num; n++)
218 out_formats[n] = e[n].fmt;
219 out_formats[num] = 0;
220 }
221
222 // Return the best match to src_samplerate from the list provided in the array
223 // *available, which must be terminated by 0, or itself NULL. If *available is
224 // empty or NULL, return a negative value. Exact match to src_samplerate is
225 // most preferred, followed by the lowest integer multiple, followed by the
226 // maximum of *available.
af_select_best_samplerate(int src_samplerate,const int * available)227 int af_select_best_samplerate(int src_samplerate, const int *available)
228 {
229 if (!available)
230 return -1;
231
232 int min_mult_rate = INT_MAX;
233 int max_rate = INT_MIN;
234 for (int i = 0; available[i]; i++) {
235 if (available[i] == src_samplerate)
236 return available[i];
237
238 if (!(available[i] % src_samplerate))
239 min_mult_rate = MPMIN(min_mult_rate, available[i]);
240
241 max_rate = MPMAX(max_rate, available[i]);
242 }
243
244 if (min_mult_rate < INT_MAX)
245 return min_mult_rate;
246
247 if (max_rate > INT_MIN)
248 return max_rate;
249
250 return -1;
251 }
252
253 // Return the number of samples that make up one frame in this format.
254 // You get the byte size by multiplying them with sample size and channel count.
af_format_sample_alignment(int format)255 int af_format_sample_alignment(int format)
256 {
257 switch (format) {
258 case AF_FORMAT_S_AAC: return 16384 / 4;
259 case AF_FORMAT_S_AC3: return 6144 / 4;
260 case AF_FORMAT_S_DTSHD: return 32768 / 16;
261 case AF_FORMAT_S_DTS: return 2048 / 4;
262 case AF_FORMAT_S_EAC3: return 24576 / 4;
263 case AF_FORMAT_S_MP3: return 4608 / 4;
264 case AF_FORMAT_S_TRUEHD: return 61440 / 16;
265 default: return 1;
266 }
267 }
268