2009-01-05 13:41:40 +01:00
|
|
|
/*
|
|
|
|
* The sample format system used lin libaf is based on bitmasks.
|
|
|
|
* The format definition only refers to the storage format,
|
|
|
|
* not the resolution.
|
|
|
|
*
|
2015-04-13 09:36:54 +02:00
|
|
|
* This file is part of mpv.
|
2009-01-05 13:41:40 +01:00
|
|
|
*
|
2015-04-13 09:36:54 +02:00
|
|
|
* mpv is free software; you can redistribute it and/or modify
|
2009-01-05 13:41:40 +01:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
2015-04-13 09:36:54 +02:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2009-01-05 13:41:40 +01:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
2015-04-13 09:36:54 +02:00
|
|
|
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2009-01-05 13:41:40 +01:00
|
|
|
*/
|
2008-02-22 10:09:46 +01:00
|
|
|
|
|
|
|
#ifndef MPLAYER_AF_FORMAT_H
|
|
|
|
#define MPLAYER_AF_FORMAT_H
|
2002-11-12 13:33:56 +01:00
|
|
|
|
2015-06-26 23:06:21 +02:00
|
|
|
#include <stddef.h>
|
2013-11-10 23:10:16 +01:00
|
|
|
#include <stdbool.h>
|
2013-12-18 17:12:21 +01:00
|
|
|
|
2013-11-07 22:12:44 +01:00
|
|
|
enum af_format {
|
2015-06-26 23:05:16 +02:00
|
|
|
AF_FORMAT_UNKNOWN = 0,
|
2013-11-07 22:12:44 +01:00
|
|
|
|
2015-06-26 23:05:16 +02:00
|
|
|
AF_FORMAT_U8,
|
|
|
|
AF_FORMAT_S16,
|
|
|
|
AF_FORMAT_S24,
|
|
|
|
AF_FORMAT_S32,
|
|
|
|
AF_FORMAT_FLOAT,
|
|
|
|
AF_FORMAT_DOUBLE,
|
2014-09-23 21:04:37 +02:00
|
|
|
|
2013-11-10 23:10:16 +01:00
|
|
|
// Planar variants
|
2015-06-26 23:05:16 +02:00
|
|
|
AF_FORMAT_U8P,
|
|
|
|
AF_FORMAT_S16P,
|
|
|
|
AF_FORMAT_S32P,
|
|
|
|
AF_FORMAT_FLOATP,
|
|
|
|
AF_FORMAT_DOUBLEP,
|
2006-11-08 19:31:04 +01:00
|
|
|
|
audio: cleanup spdif format definitions
Before this commit, there was AF_FORMAT_AC3 (the original spdif format,
used for AC3 and DTS core), and AF_FORMAT_IEC61937 (used for AC3, DTS
and DTS-HD), which was handled as some sort of superset for
AF_FORMAT_AC3. There also was AF_FORMAT_MPEG2, which used
IEC61937-framing, but still was handled as something "separate".
Technically, all of them are pretty similar, but may use different
bitrates. Since digital passthrough pretends to be PCM (just with
special headers that wrap digital packets), this is easily detectable by
the higher samplerate or higher number of channels, so I don't know why
you'd need a separate "class" of sample formats (AF_FORMAT_AC3 vs.
AF_FORMAT_IEC61937) to distinguish them. Actually, this whole thing is
just a mess.
Simplify this by handling all these formats the same way.
AF_FORMAT_IS_IEC61937() now returns 1 for all spdif formats (even MP3).
All AOs just accept all spdif formats now - whether that works or not is
not really clear (seems inconsistent due to earlier attempts to make
DTS-HD work). But on the other hand, enabling spdif requires manual user
interaction, so it doesn't matter much if initialization fails in
slightly less graceful ways if it can't work at all.
At a later point, we will support passthrough with ao_pulse. It seems
the PulseAudio API wants to know the codec type (or maybe not - feeding
it DTS while telling it it's AC3 works), add separate formats for each
codecs. While this reminds of the earlier chaos, it's stricter, and most
code just uses AF_FORMAT_IS_IEC61937().
Also, modify AF_FORMAT_TYPE_MASK (renamed from AF_FORMAT_POINT_MASK) to
include special formats, so that it always describes the fundamental
sample format type. This also ensures valid AF formats are never 0 (this
was probably broken in one of the earlier commits from today).
2014-09-23 22:44:54 +02:00
|
|
|
// All of these use IEC61937 framing, and otherwise pretend to be like PCM.
|
2015-06-26 23:05:16 +02:00
|
|
|
AF_FORMAT_S_AAC,
|
|
|
|
AF_FORMAT_S_AC3,
|
|
|
|
AF_FORMAT_S_DTS,
|
|
|
|
AF_FORMAT_S_DTSHD,
|
|
|
|
AF_FORMAT_S_EAC3,
|
|
|
|
AF_FORMAT_S_MP3,
|
|
|
|
AF_FORMAT_S_TRUEHD,
|
|
|
|
|
|
|
|
AF_FORMAT_COUNT
|
audio: cleanup spdif format definitions
Before this commit, there was AF_FORMAT_AC3 (the original spdif format,
used for AC3 and DTS core), and AF_FORMAT_IEC61937 (used for AC3, DTS
and DTS-HD), which was handled as some sort of superset for
AF_FORMAT_AC3. There also was AF_FORMAT_MPEG2, which used
IEC61937-framing, but still was handled as something "separate".
Technically, all of them are pretty similar, but may use different
bitrates. Since digital passthrough pretends to be PCM (just with
special headers that wrap digital packets), this is easily detectable by
the higher samplerate or higher number of channels, so I don't know why
you'd need a separate "class" of sample formats (AF_FORMAT_AC3 vs.
AF_FORMAT_IEC61937) to distinguish them. Actually, this whole thing is
just a mess.
Simplify this by handling all these formats the same way.
AF_FORMAT_IS_IEC61937() now returns 1 for all spdif formats (even MP3).
All AOs just accept all spdif formats now - whether that works or not is
not really clear (seems inconsistent due to earlier attempts to make
DTS-HD work). But on the other hand, enabling spdif requires manual user
interaction, so it doesn't matter much if initialization fails in
slightly less graceful ways if it can't work at all.
At a later point, we will support passthrough with ao_pulse. It seems
the PulseAudio API wants to know the codec type (or maybe not - feeding
it DTS while telling it it's AC3 works), add separate formats for each
codecs. While this reminds of the earlier chaos, it's stricter, and most
code just uses AF_FORMAT_IS_IEC61937().
Also, modify AF_FORMAT_TYPE_MASK (renamed from AF_FORMAT_POINT_MASK) to
include special formats, so that it always describes the fundamental
sample format type. This also ensures valid AF formats are never 0 (this
was probably broken in one of the earlier commits from today).
2014-09-23 22:44:54 +02:00
|
|
|
};
|
2010-01-11 20:23:18 +01:00
|
|
|
|
2013-11-07 22:12:36 +01:00
|
|
|
const char *af_fmt_to_str(int format);
|
|
|
|
|
2015-06-26 23:06:37 +02:00
|
|
|
int af_fmt_to_bytes(int format);
|
|
|
|
int af_fmt_change_bytes(int format, int bytes);
|
2013-06-15 08:58:12 +02:00
|
|
|
|
2015-06-26 23:06:37 +02:00
|
|
|
bool af_fmt_is_valid(int format);
|
|
|
|
bool af_fmt_is_unsigned(int format);
|
2015-06-26 23:05:16 +02:00
|
|
|
bool af_fmt_is_float(int format);
|
|
|
|
bool af_fmt_is_int(int format);
|
|
|
|
bool af_fmt_is_planar(int format);
|
|
|
|
bool af_fmt_is_spdif(int format);
|
2015-06-26 23:06:37 +02:00
|
|
|
bool af_fmt_is_pcm(int format);
|
2015-06-16 20:57:43 +02:00
|
|
|
|
2013-11-10 23:10:16 +01:00
|
|
|
int af_fmt_to_planar(int format);
|
|
|
|
int af_fmt_from_planar(int format);
|
|
|
|
|
2013-06-15 08:58:12 +02:00
|
|
|
// Amount of bytes that contain audio of the given duration, aligned to frames.
|
2013-06-16 19:25:10 +02:00
|
|
|
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate);
|
2013-06-15 08:58:12 +02:00
|
|
|
|
2013-11-10 23:05:51 +01:00
|
|
|
void af_fill_silence(void *dst, size_t bytes, int format);
|
|
|
|
|
2015-09-10 23:30:51 +02:00
|
|
|
void af_get_best_sample_formats(int src_format, int out_formats[AF_FORMAT_COUNT]);
|
2016-03-17 07:37:46 +01:00
|
|
|
int af_select_best_samplerate(int src_sampelrate, const int *available);
|
audio/format: add heuristic to estimate loss on format conversion
The added function af_format_conversion_score() can be used to select
the best sample format to convert to in order to reduce loss and extra
conversion work.
It calculates a "loss" score when going from one format to another, and
for each conversion that needs to be done a certain score is subtracted.
Thus, if you have to convert from one format to a set of other formats,
you can calculate the score for each conversion, and pick the one with
the highest score.
Conversion between int and float is considered the worst case. One odd
consequence is that when converting from s32 to u8 or float, u8 will be
picked.
Test program used to develop this follows:
#define MAX_FMT 200
struct entry {
const char *name;
int score;
};
static int compentry(const void *px1, const void *px2)
{
const struct entry *x1 = px1;
const struct entry *x2 = px2;
if (x1->score > x2->score)
return 1;
if (x1->score < x2->score)
return -1;
return 0;
}
int main(int argc, char *argv[])
{
for (int n = 0; af_fmtstr_table[n].name; n++) {
struct entry entry[MAX_FMT];
int entries = 0;
for (int i = 0; af_fmtstr_table[i].name; i++) {
assert(i < MAX_FMT);
entry[entries].name = af_fmtstr_table[i].name;
entry[entries].score =
af_format_conversion_score(af_fmtstr_table[i].format,
af_fmtstr_table[n].format);
entries++;
}
qsort(&entry[0], entries, sizeof(entry[0]), compentry);
for (int i = 0; i < entries; i++) {
printf("%s -> %s: %d \n", af_fmtstr_table[n].name,
entry[i].name, entry[i].score);
}
}
}
2013-11-16 20:18:39 +01:00
|
|
|
|
2015-03-10 15:12:52 +01:00
|
|
|
int af_format_sample_alignment(int format);
|
|
|
|
|
2008-02-22 10:09:46 +01:00
|
|
|
#endif /* MPLAYER_AF_FORMAT_H */
|