vlc | branch: master | Thomas Guillem <[email protected]> | 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")) { _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
