[vlc-commits] aout: add support for unknown channel layout
Thomas Guillem
git at videolan.org
Mon Jul 10 17:14:10 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Jul 7 11:30:43 2017 +0200| [d07a089dad5d7691c1f9cefff96b53e3de4d24b3] | committer: Thomas Guillem
aout: add support for unknown channel layout
If the input doesn't have a valid channel layout, use the wave one and drop
extra channels via the trivial mixer.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d07a089dad5d7691c1f9cefff96b53e3de4d24b3
---
src/audio_output/aout_internal.h | 14 ++++++++++++++
src/audio_output/dec.c | 18 ++++++++++++++----
src/audio_output/filters.c | 36 ++++++++++++++++++++++++++++++++++--
3 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index 8516d4cd40..4088d1a956 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -152,6 +152,20 @@ static inline void aout_InputRequestRestart(audio_output_t *aout)
aout_RequestRestart(aout, AOUT_RESTART_FILTERS);
}
+static inline void aout_SetWavePhysicalChannels(audio_sample_format_t *fmt)
+{
+ static const uint32_t wave_channels[] = {
+ AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
+ AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
+ AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, AOUT_CHAN_REARCENTER };
+
+ fmt->i_physical_channels = 0;
+ for (int i = 0; i < fmt->i_channels && i < AOUT_CHAN_MAX; ++i)
+ fmt->i_physical_channels |= wave_channels[i];
+ fmt->i_original_channels = fmt->i_physical_channels;
+ aout_FormatPrepare(fmt);
+}
+
/* From filters.c */
bool aout_FiltersCanResample (aout_filters_t *filters);
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index 157443635e..bceb817faf 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -45,11 +45,14 @@ int aout_DecNew( audio_output_t *p_aout,
const audio_replay_gain_t *p_replay_gain,
const aout_request_vout_t *p_request_vout )
{
- /* Sanitize audio format */
- unsigned i_channels = aout_FormatNbChannels( p_format );
- if( i_channels != p_format->i_channels && AOUT_FMT_LINEAR( p_format ) )
+
+ /* Sanitize audio format, input need to have a valid physical channels
+ * layout or a valid number of channels. */
+ int i_map_channels = aout_FormatNbChannels( p_format );
+ if( ( i_map_channels == 0 && p_format->i_channels == 0 )
+ || i_map_channels > AOUT_CHAN_MAX || p_format->i_channels > INPUT_CHAN_MAX )
{
- msg_Err( p_aout, "incompatible audio channels count with layout mask" );
+ msg_Err( p_aout, "invalid audio channels count" );
return -1;
}
@@ -82,6 +85,13 @@ int aout_DecNew( audio_output_t *p_aout,
atomic_store (&owner->restart, 0);
owner->input_format = *p_format;
owner->mixer_format = owner->input_format;
+
+ if (i_map_channels == 0)
+ {
+ /* The output channel map is unknown, use the WAVE one. */
+ assert(owner->mixer_format.i_channels > 0);
+ aout_SetWavePhysicalChannels(&owner->mixer_format);
+ }
owner->request_vout = *p_request_vout;
if (aout_OutputNew (p_aout, &owner->mixer_format))
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index 400d6e72f7..9944d0f2e0 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -56,6 +56,16 @@ static filter_t *CreateFilter (vlc_object_t *obj, const char *type,
filter->fmt_in.i_codec = infmt->i_format;
filter->fmt_out.audio = *outfmt;
filter->fmt_out.i_codec = outfmt->i_format;
+
+#ifndef NDEBUG
+ /* Assure that infmt/oufmt are well prepared and that channels
+ * configurations are valid*/
+ if( infmt->i_physical_channels != 0 )
+ assert( aout_FormatNbChannels( infmt ) == infmt->i_channels );
+ if( outfmt->i_physical_channels != 0 )
+ assert( aout_FormatNbChannels( outfmt ) == outfmt->i_channels );
+#endif
+
filter->p_module = module_need (filter, type, name, false);
if (filter->p_module == NULL)
{
@@ -442,12 +452,34 @@ aout_filters_t *aout_FiltersNew (vlc_object_t *obj,
}
return filters;
}
- if (aout_FormatNbChannels(infmt) == 0 || aout_FormatNbChannels(outfmt) == 0)
+ if (aout_FormatNbChannels(outfmt) == 0)
{
- msg_Warn (obj, "No channel mask, cannot setup filters");
+ msg_Warn (obj, "No ouput channel mask, cannot setup filters");
goto error;
}
+ if (aout_FormatNbChannels(&input_format) == 0)
+ {
+ /* The input channel map is unknown, use the WAVE one and add a
+ * converter that will drop extra channels that are not handled by VLC
+ * */
+ msg_Info(obj, "unknown channel map, using the WAVE channel layout.");
+
+ assert(input_format.i_channels > 0);
+ audio_sample_format_t input_phys_format = input_format;
+ aout_SetWavePhysicalChannels(&input_phys_format);
+
+ filter_t *f = FindConverter (obj, &input_format, &input_phys_format);
+ if (f == NULL)
+ {
+ msg_Err (obj, "cannot find channel converter");
+ goto error;
+ }
+
+ input_format = input_phys_format;
+ filters->tab[filters->count++] = f;
+ }
+
/* parse user filter lists */
if (var_InheritBool (obj, "audio-time-stretch"))
{
More information about the vlc-commits
mailing list