]> git.sesse.net Git - vlc/commitdiff
transcode: use aout filters instead of filter chain (fixes #8447)
authorRémi Denis-Courmont <remi@remlab.net>
Fri, 26 Apr 2013 17:28:22 +0000 (20:28 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Fri, 26 Apr 2013 17:28:22 +0000 (20:28 +0300)
modules/stream_out/transcode/audio.c
modules/stream_out/transcode/transcode.h

index de7496dc15515671a74a741fbf5b2d838f8cc676..cda26f80acbc22be573d8ee0bd4a07b5a17f16e2 100644 (file)
@@ -31,6 +31,7 @@
 #include "transcode.h"
 
 #include <vlc_aout.h>
+#include <vlc_input.h>
 #include <vlc_meta.h>
 #include <vlc_modules.h>
 
@@ -71,119 +72,11 @@ static block_t *audio_new_buffer( decoder_t *p_dec, int i_samples )
     return p_block;
 }
 
-static int transcode_audio_filter_allocation_init( filter_t *p_filter,
-                                                   void *data )
-{
-    VLC_UNUSED(p_filter);
-    VLC_UNUSED(data);
-    return VLC_SUCCESS;
-}
-
-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;
-        aout_FormatPrepare( &current.audio );
-
-        if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
-        {
-            msg_Err( p_stream, "Failed to find conversion filter to floating point" );
-            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;
-        aout_FormatPrepare( &current.audio );
-        if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
-        {
-            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];
-
-        aout_FormatPrepare( &current.audio );
-        if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
-        {
-            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;
-        aout_FormatPrepare( &current.audio );
-        if( !filter_chain_AppendFilter( p_chain, NULL, NULL, NULL, &current ) )
-        {
-            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, &current ) )
-    {
-        /* 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;
-}
-
-
 int transcode_audio_new( sout_stream_t *p_stream,
                                 sout_stream_id_t *id )
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
-    es_format_t fmt_last;
+    audio_sample_format_t fmt_last;
 
     /*
      * Open decoder
@@ -208,12 +101,12 @@ int transcode_audio_new( sout_stream_t *p_stream,
     id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec;
     id->p_decoder->fmt_out.audio.i_bitspersample =
         aout_BitsPerSample( id->p_decoder->fmt_out.i_codec );
-    fmt_last = id->p_decoder->fmt_out;
+    fmt_last = id->p_decoder->fmt_out.audio;
     /* Fix AAC SBR changing number of channels and sampling rate */
     if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A &&
-        fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
-        fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
-        fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate;
+        fmt_last.i_rate != id->p_encoder->fmt_in.audio.i_rate &&
+        fmt_last.i_channels != id->p_encoder->fmt_in.audio.i_channels) )
+        fmt_last.i_rate = id->p_decoder->fmt_in.audio.i_rate;
 
     /*
      * Open encoder
@@ -253,41 +146,35 @@ int transcode_audio_new( sout_stream_t *p_stream,
     id->p_encoder->fmt_out.i_codec =
         vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec );
 
-
-    /* Load user specified audio filters */
-    if( p_sys->psz_af )
+    /* Fix channels */
+    if( !id->p_encoder->fmt_in.audio.i_physical_channels
+     || !id->p_encoder->fmt_in.audio.i_original_channels )
     {
-        es_format_t fmt_fl32 = fmt_last;
-        fmt_fl32.i_codec =
-        fmt_fl32.audio.i_format = VLC_CODEC_FL32;
-        id->p_uf_chain = filter_chain_New( p_stream, "audio filter", false,
-                                           transcode_audio_filter_allocation_init, NULL, NULL );
-        filter_chain_Reset( id->p_uf_chain, &fmt_last, &fmt_fl32 );
-
-        if( transcode_audio_filter_chain_build( p_stream, id->p_uf_chain,
-                                                &fmt_fl32, &fmt_last ) )
-        {
-            transcode_audio_close( id );
-            return VLC_EGENERIC;
-        }
-        fmt_last = fmt_fl32;
-
-        if( filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af ) > 0 )
-            fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain );
+        if( id->p_encoder->fmt_in.audio.i_channels < 6 )
+            id->p_encoder->fmt_in.audio.i_physical_channels =
+            id->p_encoder->fmt_in.audio.i_original_channels =
+                      pi_channels_maps[id->p_encoder->fmt_in.audio.i_channels];
     }
 
-    /* Load conversion filters */
-    id->p_f_chain = filter_chain_New( p_stream, "audio converter", true,
-                    transcode_audio_filter_allocation_init, NULL, NULL );
-    filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in );
-
-    if( transcode_audio_filter_chain_build( p_stream, id->p_f_chain,
-                                            &id->p_encoder->fmt_in, &fmt_last ) )
+    /* Load user specified audio filters */
+    /* XXX: These variable names come kinda out of nowhere... */
+    var_Create( p_stream, "audio-time-stretch", VLC_VAR_BOOL );
+    var_Create( p_stream, "audio-filter", VLC_VAR_STRING );
+    if( p_sys->psz_af )
+        var_SetString( p_stream, "audio-filter", p_sys->psz_af );
+    id->p_af_chain = aout_FiltersNew( p_stream, &fmt_last,
+                                      &id->p_encoder->fmt_in.audio, NULL );
+    var_Destroy( p_stream, "audio-filter" );
+    var_Destroy( p_stream, "audio-time-stretch" );
+    if( id->p_af_chain == NULL )
     {
-        transcode_audio_close( id );
+        msg_Err( p_stream, "cannot connect audio filters chain" );
+        module_unneed( id->p_encoder, id->p_encoder->p_module );
+        id->p_encoder->p_module = NULL;
+        module_unneed( id->p_decoder, id->p_decoder->p_module );
+        id->p_decoder->p_module = NULL;
         return VLC_EGENERIC;
     }
-    fmt_last = id->p_encoder->fmt_in;
 
     return VLC_SUCCESS;
 }
@@ -309,10 +196,8 @@ void transcode_audio_close( sout_stream_id_t *id )
     id->p_encoder->p_module = NULL;
 
     /* Close filters */
-    if( id->p_uf_chain )
-        filter_chain_Delete( id->p_uf_chain );
-    if( id->p_f_chain )
-        filter_chain_Delete( id->p_f_chain );
+    if( id->p_af_chain != NULL )
+        aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain );
 }
 
 int transcode_audio_process( sout_stream_t *p_stream,
@@ -356,15 +241,8 @@ int transcode_audio_process( sout_stream_t *p_stream,
         p_audio_buf->i_dts = p_audio_buf->i_pts;
 
         /* Run filter chain */
-        if( id->p_uf_chain )
-        {
-            p_audio_buf = filter_chain_AudioFilter( id->p_uf_chain,
-                                                    p_audio_buf );
-            if( !p_audio_buf )
-                abort();
-        }
-
-        p_audio_buf = filter_chain_AudioFilter( id->p_f_chain, p_audio_buf );
+        p_audio_buf = aout_FiltersPlay( id->p_af_chain, p_audio_buf,
+                                        INPUT_RATE_DEFAULT );
         if( !p_audio_buf )
             abort();
 
index fc8bb4135394aecef1ad1f91bfcc0076893d8b17..85651c939ec15dd19c8ed65628801411de74033f 100644 (file)
@@ -72,6 +72,8 @@ struct sout_stream_sys_t
     mtime_t         i_master_drift;
 };
 
+struct aout_filters;
+
 struct sout_stream_id_t
 {
     bool            b_transcode;
@@ -82,10 +84,15 @@ struct sout_stream_id_t
     /* Decoder */
     decoder_t       *p_decoder;
 
-    /* Filters */
-    filter_chain_t  *p_f_chain;
-    /* User specified filters */
-    filter_chain_t  *p_uf_chain;
+    union
+    {
+         struct
+         {
+             filter_chain_t  *p_f_chain; /**< Video filters */
+             filter_chain_t  *p_uf_chain; /**< User-specified video filters */
+         };
+         struct aout_filters *p_af_chain; /**< Audio filters */
+    };
 
     /* Encoder */
     encoder_t       *p_encoder;