+static bool transcode_audio_filter_needed( const es_format_t *p_fmt1, const es_format_t *p_fmt2 )
+{
+ if( p_fmt1->i_codec != p_fmt2->i_codec ||
+ p_fmt1->audio.i_channels != p_fmt2->audio.i_channels ||
+ p_fmt1->audio.i_rate != p_fmt2->audio.i_rate )
+ return true;
+ return false;
+}
+static int transcode_audio_filter_chain_build( sout_stream_t *p_stream, filter_chain_t *p_chain,
+ const es_format_t *p_dst, const es_format_t *p_src )
+{
+ if( !transcode_audio_filter_needed( p_dst, p_src ) )
+ return VLC_SUCCESS;
+
+ es_format_t current = *p_src;
+
+ msg_Dbg( p_stream, "Looking for filter "
+ "(%4.4s->%4.4s, channels %d->%d, rate %d->%d)",
+ (const char *)&p_src->i_codec,
+ (const char *)&p_dst->i_codec,
+ p_src->audio.i_channels,
+ p_dst->audio.i_channels,
+ p_src->audio.i_rate,
+ p_dst->audio.i_rate );
+
+ /* If any filter is needed, convert to fl32 */
+ if( current.i_codec != VLC_CODEC_FL32 )
+ {
+ /* First step, convert to fl32 */
+ current.i_codec =
+ current.audio.i_format = VLC_CODEC_FL32;
+
+ if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
+ {
+ msg_Err( p_stream, "Failed to find conversion filter to fl32" );
+ return VLC_EGENERIC;
+ }
+ current = *filter_chain_GetFmtOut( p_chain );
+ }
+
+ /* Fix sample rate */
+ if( current.audio.i_rate != p_dst->audio.i_rate )
+ {
+ current.audio.i_rate = p_dst->audio.i_rate;
+ if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
+ {
+ msg_Err( p_stream, "Failed to find conversion filter for resampling" );
+ return VLC_EGENERIC;
+ }
+ current = *filter_chain_GetFmtOut( p_chain );
+ }
+
+ /* Fix channels */
+ if( current.audio.i_channels != p_dst->audio.i_channels )
+ {
+ current.audio.i_channels = p_dst->audio.i_channels;
+ current.audio.i_physical_channels = p_dst->audio.i_physical_channels;
+ current.audio.i_original_channels = p_dst->audio.i_original_channels;
+
+ if( ( !current.audio.i_physical_channels || !current.audio.i_original_channels ) &&
+ current.audio.i_channels < 6 )
+ current.audio.i_physical_channels =
+ current.audio.i_original_channels = pi_channels_maps[current.audio.i_channels];
+
+ if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
+ {
+ msg_Err( p_stream, "Failed to find conversion filter for channel mixing" );
+ return VLC_EGENERIC;
+ }
+ current = *filter_chain_GetFmtOut( p_chain );
+ }
+
+ /* And last step, convert to the requested codec */
+ if( current.i_codec != p_dst->i_codec )
+ {
+ current.i_codec = p_dst->i_codec;
+ if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, ¤t ) )
+ {
+ msg_Err( p_stream, "Failed to find conversion filter to %4.4s",
+ (const char*)&p_dst->i_codec);
+ return VLC_EGENERIC;
+ }
+ current = *filter_chain_GetFmtOut( p_chain );
+ }
+
+ if( transcode_audio_filter_needed( p_dst, ¤t ) )
+ {
+ /* Weird case, a filter has side effects, doomed */
+ msg_Err( p_stream, "Failed to create a valid audio filter chain" );
+ return VLC_EGENERIC;
+ }
+
+ msg_Dbg( p_stream, "Got complete audio filter chain" );
+ return VLC_SUCCESS;
+}
+