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