]> git.sesse.net Git - vlc/commitdiff
aout: move actual filtering to filters.c
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 11 Nov 2012 13:50:11 +0000 (15:50 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 11 Nov 2012 13:50:11 +0000 (15:50 +0200)
This leaves only synchronization code in input.c. This patch introduces
a small regression where resampling adjustment have a latency of two
packets instead of currently one. That will be fixed later.

src/audio_output/aout_internal.h
src/audio_output/filters.c
src/audio_output/input.c

index d5da13deeb1af3897a3a44c77e97c9824953cdc2..b5c8dc88806ebbd2584596a7f51768bd0e6b2089 100644 (file)
@@ -79,9 +79,10 @@ typedef struct
     filter_t *rate_filter; /**< The filter adjusting samples count
         (either the scaletempo filter or a resampler) */
     filter_t *resampler; /**< The resampler */
+    int resampling; /**< Current resampling (Hz) */
+    unsigned nb_filters;
     filter_t *filters[AOUT_MAX_FILTERS]; /**< Configured user filters
         (e.g. equalization) and their conversions */
-    unsigned nb_filters;
     unsigned nb_converters;
     filter_t *converters[5]; /**< Converters to the output */
 
@@ -123,6 +124,8 @@ block_t *aout_FiltersPipelinePlay(filter_t *const *, unsigned, block_t *);
 int aout_FiltersNew(audio_output_t *, const audio_sample_format_t *,
                    const audio_sample_format_t *, const aout_request_vout_t *);
 void aout_FiltersDelete(audio_output_t *);
+bool aout_FiltersAdjustResampling(audio_output_t *, int);
+block_t *aout_FiltersPlay(audio_output_t *, block_t *, int rate);
 
 /* From mixer.c : */
 aout_volume_t *aout_volume_New(vlc_object_t *, const audio_replay_gain_t *);
index 881f38339444aa014af5ce3922081eb40f495a2c..c95b93faaf1112e401bdbc34a39e96302836108d 100644 (file)
@@ -37,6 +37,7 @@
 #include <vlc_aout.h>
 #include <vlc_filter.h>
 #include <vlc_vout.h>                  /* for vout_Request */
+#include <vlc_input.h>
 
 #include <libvlc.h>
 #include "aout_internal.h"
@@ -502,6 +503,7 @@ int aout_FiltersNew (audio_output_t *aout,
     owner->resampler->fmt_in.audio.i_rate = rate_bak;
     if (owner->rate_filter == NULL)
         owner->rate_filter = owner->resampler;
+   owner->resampling = 0;
 
     return 0;
 
@@ -534,3 +536,57 @@ void aout_FiltersDelete (audio_output_t *aout)
     owner->recycle_vout = (visual != NULL) && *visual;
     free (visual);
 }
+
+bool aout_FiltersAdjustResampling (audio_output_t *aout, int adjust)
+{
+    aout_owner_t *owner = aout_owner (aout);
+
+    if (owner->resampler == NULL)
+        return false;
+
+    if (adjust)
+        owner->resampling += adjust;
+    else
+        owner->resampling = 0;
+    return !owner->resampling;
+}
+
+block_t *aout_FiltersPlay (audio_output_t *aout, block_t *block, int rate)
+{
+    aout_owner_t *owner = aout_owner (aout);
+    int nominal_rate = 0;
+
+    if (rate != INPUT_RATE_DEFAULT)
+    {
+        filter_t *rate_filter = owner->rate_filter;
+
+        if (rate_filter == NULL)
+            goto drop; /* Without linear, non-nominal rate is impossible. */
+
+        /* Override input rate */
+        nominal_rate = rate_filter->fmt_in.audio.i_rate;
+        rate_filter->fmt_in.audio.i_rate =
+            (nominal_rate * INPUT_RATE_DEFAULT) / rate;
+    }
+
+    block = aout_FiltersPipelinePlay (owner->filters, owner->nb_filters,
+                                      block);
+    if (owner->resampler != NULL)
+    {   /* NOTE: the resampler needs to run even if resampling is 0.
+         * The decoder and output rates can still be different. */
+        owner->resampler->fmt_in.audio.i_rate += owner->resampling;
+        block = aout_FiltersPipelinePlay (&owner->resampler, 1, block);
+        owner->resampler->fmt_in.audio.i_rate -= owner->resampling;
+    }
+
+    if (nominal_rate != 0)
+    {   /* Restore input rate */
+        assert (owner->rate_filter != NULL);
+        owner->rate_filter->fmt_in.audio.i_rate = nominal_rate;
+    }
+    return block;
+
+drop:
+    block_Release (block);
+    return NULL;
+}
index 54a65b68b815ab6ad5a9b840941af92a61077a65..f717957ed6546540f87fa23575fcf52f96eff21a 100644 (file)
@@ -38,7 +38,7 @@
 #include "aout_internal.h"
 
 static void inputDrop( aout_input_t *, block_t * );
-static void inputResamplingStop( audio_output_t *, aout_input_t *, int );
+static void inputResamplingStop( audio_output_t *, aout_input_t * );
 
 /*****************************************************************************
  * aout_InputNew : allocate a new input and rework the filter pipeline
@@ -74,27 +74,9 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
                         block_t *p_buffer, int i_input_rate, date_t *date )
 {
     mtime_t start_date;
-    aout_owner_t *owner = aout_owner(p_aout);
 
     aout_assert_locked( p_aout );
 
-    if( i_input_rate != INPUT_RATE_DEFAULT && owner->rate_filter == NULL )
-    {
-        inputDrop( p_input, p_buffer );
-        return NULL;
-    }
-
-    /* Handle input rate change, but keep drift correction */
-    if( i_input_rate != p_input->i_last_input_rate )
-    {
-        unsigned int * const pi_rate = &owner->rate_filter->fmt_in.audio.i_rate;
-#define F(r,ir) ( INPUT_RATE_DEFAULT * (r) / (ir) )
-        const int i_delta = *pi_rate - F(p_input->samplerate,p_input->i_last_input_rate);
-        *pi_rate = F(p_input->samplerate + i_delta, i_input_rate);
-#undef F
-        p_input->i_last_input_rate = i_input_rate;
-    }
-
     mtime_t now = mdate();
 
     /* We don't care if someone changes the start date behind our back after
@@ -112,7 +94,7 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
         aout_OutputFlush( p_aout, false );
         if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
             msg_Warn( p_aout, "timing screwed, stopping resampling" );
-        inputResamplingStop( p_aout, p_input, i_input_rate );
+        inputResamplingStop( p_aout, p_input );
         p_buffer->i_flags |= BLOCK_FLAG_DISCONTINUITY;
         start_date = VLC_TS_INVALID;
     }
@@ -124,7 +106,7 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
         msg_Warn( p_aout, "PTS is out of range (%"PRId64"), dropping buffer",
                   now - p_buffer->i_pts );
         inputDrop( p_input, p_buffer );
-        inputResamplingStop( p_aout, p_input, i_input_rate );
+        inputResamplingStop( p_aout, p_input );
         return NULL;
     }
 
@@ -145,7 +127,7 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
         aout_OutputFlush( p_aout, false );
         if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
             msg_Warn( p_aout, "timing screwed, stopping resampling" );
-        inputResamplingStop( p_aout, p_input, i_input_rate );
+        inputResamplingStop( p_aout, p_input );
         p_buffer->i_flags |= BLOCK_FLAG_DISCONTINUITY;
         start_date = p_buffer->i_pts;
         date_Set (date, start_date);
@@ -160,17 +142,14 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
         return NULL;
     }
 
-    /* Run pre-filters. */
-    p_buffer = aout_FiltersPipelinePlay( owner->filters, owner->nb_filters,
-                                         p_buffer );
+    p_buffer = aout_FiltersPlay( p_aout, p_buffer, i_input_rate );
     if( !p_buffer )
         return NULL;
 
     /* Run the resampler if needed.
      * We first need to calculate the output rate of this resampler. */
     if ( ( p_input->i_resampling_type == AOUT_RESAMPLING_NONE ) &&
-         ( drift < -AOUT_MAX_PTS_ADVANCE || drift > +AOUT_MAX_PTS_DELAY ) &&
-         owner->resampler != NULL )
+         ( drift < -AOUT_MAX_PTS_ADVANCE || drift > +AOUT_MAX_PTS_DELAY ) )
     {
         /* Can happen in several circumstances :
          * 1. A problem at the input (clock drift)
@@ -192,19 +171,12 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
         /* Resampling has been triggered previously (because of dates
          * mismatch). We want the resampling to happen progressively so
          * it isn't too audible to the listener. */
-
-        if( p_input->i_resampling_type == AOUT_RESAMPLING_UP )
-            owner->resampler->fmt_in.audio.i_rate += 2; /* Hz */
-        else
-            owner->resampler->fmt_in.audio.i_rate -= 2; /* Hz */
+        const int adjust = ( p_input->i_resampling_type == AOUT_RESAMPLING_UP )
+            ? +2 : -2;
 
         /* Check if everything is back to normal, in which case we can stop the
          * resampling */
-        unsigned int i_nominal_rate =
-          (owner->resampler == owner->rate_filter)
-          ? INPUT_RATE_DEFAULT * p_input->samplerate / i_input_rate
-          : p_input->samplerate;
-        if( owner->resampler->fmt_in.audio.i_rate == i_nominal_rate )
+        if( !aout_FiltersAdjustResampling( p_aout, adjust ) )
         {
             p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
             msg_Warn( p_aout, "resampling stopped (drift: %"PRIi64")",
@@ -228,23 +200,11 @@ block_t *aout_InputPlay(audio_output_t *p_aout, aout_input_t *p_input,
             /* If the drift is increasing and not decreasing, than something
              * is bad. We'd better stop the resampling right now. */
             msg_Warn( p_aout, "timing screwed, stopping resampling" );
-            inputResamplingStop( p_aout, p_input, i_input_rate );
+            inputResamplingStop( p_aout, p_input );
             p_buffer->i_flags |= BLOCK_FLAG_DISCONTINUITY;
         }
     }
 
-    /* Actually run the resampler now. */
-    if ( owner->resampler != NULL )
-        p_buffer = aout_FiltersPipelinePlay( &owner->resampler, 1, p_buffer );
-
-    if( !p_buffer )
-        return NULL;
-    if( p_buffer->i_nb_samples <= 0 )
-    {
-        block_Release( p_buffer );
-        return NULL;
-    }
-
     p_buffer->i_pts = start_date;
     return p_buffer;
 }
@@ -260,17 +220,8 @@ static void inputDrop( aout_input_t *p_input, block_t *p_buffer )
     p_input->i_buffer_lost++;
 }
 
-static void inputResamplingStop( audio_output_t *p_aout, aout_input_t *p_input,
-                                 int input_rate )
+static void inputResamplingStop( audio_output_t *p_aout, aout_input_t *p_input )
 {
-    aout_owner_t *owner = aout_owner(p_aout);
-
     p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
-    if( owner->resampler != NULL )
-    {
-        owner->resampler->fmt_in.audio.i_rate =
-            ( owner->resampler == owner->rate_filter )
-            ? INPUT_RATE_DEFAULT * p_input->samplerate / input_rate
-            : p_input->samplerate;
-    }
+    aout_FiltersAdjustResampling( p_aout, 0 );
 }