[vlc-devel] [PATCH V3 2/4] aout: add "audio-bitexact" option
Thomas Guillem
thomas at gllm.fr
Tue Nov 26 16:31:24 CET 2019
---
include/vlc_aout.h | 8 +++
src/audio_output/aout_internal.h | 1 +
src/audio_output/dec.c | 5 +-
src/audio_output/filters.c | 87 +++++++++++++++++++-------------
src/audio_output/output.c | 11 ++++
src/libvlc-module.c | 18 +++++++
6 files changed, 94 insertions(+), 36 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 49527f30fb5..0e76923d1bd 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -112,6 +112,12 @@
/* FIXME to remove once aout.h is cleaned a bit more */
#include <vlc_block.h>
+enum vlc_aout_bitexact_mode {
+ VLC_AOUT_BITEXACT_OFF,
+ VLC_AOUT_BITEXACT_ON,
+ VLC_AOUT_BITEXACT_CONVERT,
+};
+
struct vlc_audio_output_events {
void (*timing_report)(audio_output_t *, vlc_tick_t system_now, vlc_tick_t pts);
void (*volume_report)(audio_output_t *, float);
@@ -504,11 +510,13 @@ typedef struct
* binauralizer audio filter).
*/
bool headphones;
+ enum vlc_aout_bitexact_mode bitexact_mode;
} aout_filters_cfg_t;
#define AOUT_FILTERS_CFG_INIT (aout_filters_cfg_t) \
{ .remap = AOUT_CHAN_REMAP_INIT, \
.headphones = false, \
+ .bitexact_mode = VLC_AOUT_BITEXACT_OFF, \
};
typedef struct aout_filters aout_filters_t;
diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index a94d0864105..29744884ca5 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -46,6 +46,7 @@ typedef struct
module_t *module; /**< Output plugin (or NULL if inactive) */
aout_filters_t *filters;
aout_volume_t *volume;
+ enum vlc_aout_bitexact_mode bitexact_mode;
struct
{
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index d89fedbf62c..5d3da1211b3 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -89,7 +89,8 @@ int aout_DecNew(audio_output_t *p_aout, const audio_sample_format_t *p_format,
aout_owner_t *owner = aout_owner(p_aout);
/* Create the audio output stream */
- owner->volume = aout_volume_New (p_aout, p_replay_gain);
+ if (owner->bitexact_mode == VLC_AOUT_BITEXACT_OFF)
+ owner->volume = aout_volume_New (p_aout, p_replay_gain);
atomic_store_explicit(&owner->restart, 0, memory_order_relaxed);
owner->input_profile = profile;
@@ -98,6 +99,7 @@ int aout_DecNew(audio_output_t *p_aout, const audio_sample_format_t *p_format,
owner->sync.clock = clock;
owner->filters_cfg = AOUT_FILTERS_CFG_INIT;
+ owner->filters_cfg.bitexact_mode = owner->bitexact_mode;
if (aout_OutputNew (p_aout))
goto error;
aout_volume_SetFormat (owner->volume, owner->mixer_format.i_format);
@@ -164,6 +166,7 @@ static int aout_CheckReady (audio_output_t *aout)
aout_OutputDelete (aout);
owner->filter_format = owner->mixer_format = owner->input_format;
owner->filters_cfg = AOUT_FILTERS_CFG_INIT;
+ owner->filters_cfg.bitexact_mode = owner->bitexact_mode;
if (aout_OutputNew (aout))
owner->mixer_format.i_format = 0;
aout_volume_SetFormat (owner->volume,
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index 168c97f707f..f162b185cdf 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -586,41 +586,55 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
assert(input_format.channel_type == AUDIO_CHANNEL_TYPE_BITMAP);
- /* parse user filter lists */
- if (var_InheritBool (obj, "audio-time-stretch"))
+ if (cfg->bitexact_mode == VLC_AOUT_BITEXACT_ON)
{
- if (AppendFilter(obj, "audio filter", "scaletempo",
- filters, &input_format, &output_format, NULL) == 0)
- filters->rate_filter = filters->tab[filters->count - 1];
+ /* Bit-exact mode is only possible if input and output formats are
+ * matching */
+ if (!AOUT_FMTS_IDENTICAL(&input_format, &output_format))
+ goto error;
+ /* Bypass all filters */
+ return filters;
}
+ else if (cfg->bitexact_mode == VLC_AOUT_BITEXACT_OFF)
+ {
+ /* parse user filter lists */
+ if (var_InheritBool (obj, "audio-time-stretch"))
+ {
+ if (AppendFilter(obj, "audio filter", "scaletempo",
+ filters, &input_format, &output_format, NULL) == 0)
+ filters->rate_filter = filters->tab[filters->count - 1];
+ }
- AppendRemapFilter(obj, filters, &input_format, &output_format,
- cfg->remap);
+ AppendRemapFilter(obj, filters, &input_format, &output_format,
+ cfg->remap);
- if (input_format.i_channels > 2 && cfg->headphones)
- AppendFilter(obj, "audio filter", "binauralizer", filters,
- &input_format, &output_format, NULL);
+ if (input_format.i_channels > 2 && cfg->headphones)
+ AppendFilter(obj, "audio filter", "binauralizer", filters,
+ &input_format, &output_format, NULL);
- /* Now add user filters */
- char *str = var_InheritString (obj, "audio-filter");
- if (str != NULL)
- {
- char *p = str, *name;
- while ((name = strsep (&p, " :")) != NULL)
+ /* Now add user filters */
+ char *str = var_InheritString (obj, "audio-filter");
+ if (str != NULL)
{
- AppendFilter(obj, "audio filter", name, filters,
- &input_format, &output_format, NULL);
+ char *p = str, *name;
+ while ((name = strsep (&p, " :")) != NULL)
+ {
+ AppendFilter(obj, "audio filter", name, filters,
+ &input_format, &output_format, NULL);
+ }
+ free (str);
}
- free (str);
- }
- char *visual = var_InheritString(obj, "audio-visual");
- if (visual != NULL && strcasecmp(visual, "none"))
- AppendFilter(obj, "visualization", visual, filters,
- &input_format, &output_format, NULL);
- free(visual);
+ char *visual = var_InheritString(obj, "audio-visual");
+ if (visual != NULL && strcasecmp(visual, "none"))
+ AppendFilter(obj, "visualization", visual, filters,
+ &input_format, &output_format, NULL);
+ free(visual);
+ }
- /* convert to the output format (minus resampling) if necessary */
+ /* Convert to the output format (minus resampling) if necessary. */
+ assert(cfg->bitexact_mode == VLC_AOUT_BITEXACT_OFF
+ || cfg->bitexact_mode == VLC_AOUT_BITEXACT_CONVERT);
output_format.i_rate = input_format.i_rate;
if (aout_FiltersPipelineCreate (obj, filters->tab, &filters->count,
AOUT_MAX_FILTERS, &input_format, &output_format, false))
@@ -631,17 +645,20 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
input_format = output_format;
/* insert the resampler */
- output_format.i_rate = outfmt->i_rate;
- assert (AOUT_FMTS_IDENTICAL(&output_format, outfmt));
- filters->resampler = FindResampler (obj, &input_format,
- &output_format);
- if (filters->resampler == NULL && input_format.i_rate != outfmt->i_rate)
+ if (cfg->bitexact_mode == VLC_AOUT_BITEXACT_OFF)
{
- msg_Err (obj, "cannot setup a resampler");
- goto error;
+ output_format.i_rate = outfmt->i_rate;
+ assert (AOUT_FMTS_IDENTICAL(&output_format, outfmt));
+ filters->resampler = FindResampler (obj, &input_format,
+ &output_format);
+ if (filters->resampler == NULL && input_format.i_rate != outfmt->i_rate)
+ {
+ msg_Err (obj, "cannot setup a resampler");
+ goto error;
+ }
+ if (filters->rate_filter == NULL)
+ filters->rate_filter = filters->resampler;
}
- if (filters->rate_filter == NULL)
- filters->rate_filter = filters->resampler;
return filters;
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index fe782d6e1d7..a7f0a4a7c2b 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -338,6 +338,17 @@ audio_output_t *aout_New (vlc_object_t *parent)
var_Create (aout, "equalizer-bands", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
var_Create (aout, "equalizer-preset", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
+ char *bitexact_str = var_InheritString (aout, "audio-bitexact");
+ if (!bitexact_str)
+ owner->bitexact_mode = VLC_AOUT_BITEXACT_OFF;
+ else if (strcmp(bitexact_str, "on") == 0)
+ owner->bitexact_mode = VLC_AOUT_BITEXACT_ON;
+ else if (strcmp(bitexact_str, "convert") == 0)
+ owner->bitexact_mode = VLC_AOUT_BITEXACT_CONVERT;
+ else
+ owner->bitexact_mode = VLC_AOUT_BITEXACT_OFF;
+ free (bitexact_str);
+
return aout;
}
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 9dc892e82bf..36a3a704212 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -124,6 +124,14 @@ static const char *const ppsz_snap_formats[] =
#define ROLE_TEXT N_("Media role")
#define ROLE_LONGTEXT N_("Media (player) role for operating system policy.")
+#define AUDIO_BITEXACT_TEXT N_("Bit-exact mode (pure mode)")
+#define AUDIO_BITEXACT_LONGTEXT N_( \
+ "'on' will disable all audio filters, even audio converters. " \
+ "This may result on audio not working if the output can't adapt to the " \
+ "input format. 'off' is the default, any filters and converters " \
+ "can be used'. 'convert' will only enable audio converters in order " \
+ "to adapt the input format to the output.")
+
#define AUDIO_TEXT N_("Enable audio")
#define AUDIO_LONGTEXT N_( \
"You can completely disable the audio output. The audio " \
@@ -139,6 +147,13 @@ static const char *ppsz_roles_text[] = {
N_("Accessibility"), N_("Test"),
};
+static const char *ppsz_audio_bitexact[] = {
+ "on", "convert", "off"
+};
+static const char *ppsz_audio_bitexact_text[] = {
+ N_("On"), N_("With conversion (adapt to the output)"), N_("Off"),
+};
+
#define GAIN_TEXT N_("Audio gain")
#define GAIN_LONGTEXT N_( \
"This linear gain will be applied to outputted audio.")
@@ -1619,6 +1634,9 @@ vlc_module_begin ()
change_string_list( ppsz_roles, ppsz_roles_text )
set_subcategory( SUBCAT_AUDIO_AFILTER )
+ add_string( "audio-bitexact", "off", AUDIO_BITEXACT_TEXT,
+ AUDIO_BITEXACT_LONGTEXT, false )
+ change_string_list( ppsz_audio_bitexact, ppsz_audio_bitexact_text )
add_module_list("audio-filter", "audio filter", NULL,
AUDIO_FILTER_TEXT, AUDIO_FILTER_LONGTEXT)
set_subcategory( SUBCAT_AUDIO_VISUAL )
--
2.20.1
More information about the vlc-devel
mailing list