All: preliminary support for audio while playing faster/slower (1/4 -> 4).
authorLaurent Aimar <fenrir@videolan.org>
Tue, 12 Jun 2007 19:46:35 +0000 (19:46 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Tue, 12 Jun 2007 19:46:35 +0000 (19:46 +0000)
It use our standard resampler to do it and so we do not keep
pitch yet (I am working on a soundtouch resampler).
Please test any regression.

15 files changed:
include/vlc_aout.h
modules/audio_filter/resampler/bandlimited.c
modules/codec/a52.c
modules/codec/faad.c
modules/codec/ffmpeg/audio.c
modules/codec/mpeg_audio.c
modules/codec/vorbis.c
modules/packetizer/mpeg4audio.c
src/audio_output/aout_internal.h
src/audio_output/dec.c
src/audio_output/filters.c
src/audio_output/input.c
src/input/decoder.c
src/input/es_out.c
src/input/input.c

index 90fcc01..06817b4 100644 (file)
@@ -169,6 +169,9 @@ struct aout_buffer_t
 /* Number of samples in an A/52 frame. */
 #define A52_FRAME_NB 1536
 
+/* Max input rate factor (1/4 -> 4) */
+#define AOUT_MAX_INPUT_RATE (4)
+
 /** date incrementation helper structure without long-term
  * rounding errors
  */
@@ -277,6 +280,8 @@ struct aout_input_t
     /* Did we just change the output format? (expect buffer inconsistencies) */
     vlc_bool_t              b_changed;
 
+    /* last rate from input */
+    int                     i_last_input_rate;
     /* internal caching delay from input */
     int                     i_pts_delay;
     /* desynchronisation delay request by the user */
index 81b923c..bab1cc6 100644 (file)
@@ -123,7 +123,7 @@ static int Create( vlc_object_t *p_this )
 
     /* Calculate worst case for the length of the filter wing */
     d_factor = (double)p_filter->output.i_rate
-                        / p_filter->input.i_rate;
+                        / p_filter->input.i_rate / AOUT_MAX_INPUT_RATE;
     i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
                       * __MAX(1.0, 1.0/d_factor) + 10;
     p_filter->p_sys->i_buf_size = aout_FormatNbChannels( &p_filter->input ) *
index bbff46e..844507a 100644 (file)
@@ -29,6 +29,7 @@
 #include <vlc/vlc.h>
 #include <vlc_codec.h>
 #include <vlc_aout.h>
+#include <vlc_input.h>
 #include <vlc_block_helper.h>
 
 #define A52_HEADER_SIZE 7
@@ -57,6 +58,7 @@ struct decoder_sys_t
     int i_frame_size, i_bit_rate;
     unsigned int i_rate, i_channels, i_channels_conf;
 
+    int i_input_rate;
 };
 
 enum {
@@ -128,6 +130,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     aout_DateSet( &p_sys->end_date, 0 );
 
     p_sys->bytestream = block_BytestreamInit( p_dec );
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -187,6 +190,9 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     }
 
+    if( (*pp_block)->i_rate > 0 )
+        p_sys->i_input_rate = (*pp_block)->i_rate;
+
     block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
@@ -385,7 +391,8 @@ static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
     if( p_buf == NULL ) return NULL;
 
     p_buf->start_date = aout_DateGet( &p_sys->end_date );
-    p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
+    p_buf->end_date = aout_DateIncrement( &p_sys->end_date,
+                                          A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
 
     return p_buf;
 }
@@ -403,8 +410,10 @@ static block_t *GetSoutBuffer( decoder_t *p_dec )
 
     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
-    p_block->i_length = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) -
-        p_block->i_pts;
+    p_block->i_length =
+        aout_DateIncrement( &p_sys->end_date,
+                            A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
+            p_block->i_pts;
 
     return p_block;
 }
index 07beb3e..6fd6e3e 100644 (file)
@@ -69,6 +69,8 @@ struct decoder_sys_t
     uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS];
 
     vlc_bool_t b_sbr, b_ps;
+
+    int i_input_rate;
 };
 
 static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] =
@@ -166,6 +168,8 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_buffer = p_sys->i_buffer_size = 0;
     p_sys->p_buffer = 0;
 
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
+
     /* Faad2 can't deal with truncated data (eg. from MPEG TS) */
     p_dec->b_need_packetized = VLC_TRUE;
 
@@ -191,6 +195,9 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     }
 
+    if( p_block->i_rate > 0 )
+        p_sys->i_input_rate = p_block->i_rate;
+
     /* Append the block to the temporary buffer */
     if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
     {
@@ -374,7 +381,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
         p_out->start_date = aout_DateGet( &p_sys->date );
         p_out->end_date = aout_DateIncrement( &p_sys->date,
-                                              frame.samples / frame.channels );
+            (frame.samples / frame.channels) * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
 
         DoReordering( p_dec, (uint32_t *)p_out->p_buffer, samples,
                       frame.samples / frame.channels, frame.channels,
index 157fee8..6e5b0a1 100644 (file)
@@ -28,6 +28,7 @@
 #include <vlc/vlc.h>
 #include <vlc_aout.h>
 #include <vlc_codec.h>
+#include <vlc_input.h>
 
 /* ffmpeg header */
 #ifdef HAVE_FFMPEG_AVCODEC_H
@@ -75,6 +76,8 @@ struct decoder_sys_t
 
     /* */
     int     i_reject_count;
+
+    int i_input_rate;
 };
 
 /*****************************************************************************
@@ -146,6 +149,7 @@ int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
     p_sys->p_samples = NULL;
     p_sys->i_samples = 0;
     p_sys->i_reject_count = 0;
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
 
     aout_DateSet( &p_sys->end_date, 0 );
     if( p_dec->fmt_in.audio.i_rate )
@@ -178,7 +182,8 @@ static aout_buffer_t *SplitBuffer( decoder_t *p_dec )
     }
 
     p_buffer->start_date = aout_DateGet( &p_sys->end_date );
-    p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
+    p_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
+                                             i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
 
     memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes );
 
@@ -202,6 +207,9 @@ aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
 
     p_block = *pp_block;
 
+    if( p_block->i_rate > 0 )
+        p_sys->i_input_rate = p_block->i_rate;
+
     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
         block_Release( p_block );
index cb645c8..151f88f 100644 (file)
@@ -30,6 +30,7 @@
 #include <vlc/vlc.h>
 #include <vlc_codec.h>
 #include <vlc_aout.h>
+#include <vlc_input.h>
 
 #include <vlc_block_helper.h>
 
@@ -62,6 +63,8 @@ struct decoder_sys_t
     unsigned int i_layer, i_bit_rate;
 
     vlc_bool_t   b_discontinuity;
+
+    int i_input_rate;
 };
 
 enum {
@@ -155,6 +158,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     aout_DateSet( &p_sys->end_date, 0 );
     p_sys->bytestream = block_BytestreamInit( p_dec );
     p_sys->b_discontinuity = VLC_FALSE;
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -220,6 +224,9 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     }
 
+    if( (*pp_block)->i_rate > 0 )
+        p_sys->i_input_rate = (*pp_block)->i_rate;
+
     block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
@@ -535,7 +542,8 @@ static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
 
     p_buf->start_date = aout_DateGet( &p_sys->end_date );
     p_buf->end_date =
-        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
+        aout_DateIncrement( &p_sys->end_date,
+                            p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
     p_buf->b_discontinuity = p_sys->b_discontinuity;
     p_sys->b_discontinuity = VLC_FALSE;
 
@@ -559,8 +567,9 @@ static block_t *GetSoutBuffer( decoder_t *p_dec )
     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
     p_block->i_length =
-        aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) -
-            p_block->i_pts;
+        aout_DateIncrement( &p_sys->end_date,
+                            p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
+                                p_block->i_pts;
 
     return p_block;
 }
index 2c8cbca..e56ae9f 100644 (file)
@@ -78,6 +78,8 @@ struct decoder_sys_t
     audio_date_t end_date;
     int          i_last_block_size;
 
+    int i_input_rate;
+
     /*
     ** Channel reordering
     */
@@ -237,6 +239,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_sys->i_last_block_size = 0;
     p_sys->b_packetizer = VLC_FALSE;
     p_sys->i_headers = 0;
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
 
     /* Take care of vorbis init */
     vorbis_info_init( &p_sys->vi );
@@ -291,6 +294,9 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         /* Block to Ogg packet */
         oggpacket.packet = (*pp_block)->p_buffer;
         oggpacket.bytes = (*pp_block)->i_buffer;
+
+        if( (*pp_block)->i_rate > 0 )
+            p_sys->i_input_rate = (*pp_block)->i_rate;
     }
     else
     {
@@ -563,7 +569,7 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
         /* Date management */
         p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
         p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
-                                                      i_samples );
+                                                      i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
         return p_aout_buffer;
     }
     else
@@ -590,8 +596,9 @@ static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
     p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
 
     if( p_sys->i_headers >= 3 )
-        p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) -
-            p_block->i_pts;
+        p_block->i_length = aout_DateIncrement( &p_sys->end_date,
+            i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
+                p_block->i_pts;
     else
         p_block->i_length = 0;
 
index 24c43f6..0312c05 100644 (file)
@@ -34,6 +34,7 @@
 #include <vlc_block.h>
 #include <vlc_sout.h>
 #include <vlc_codecs.h>
+#include <vlc_input.h>
 
 #include "vlc_block_helper.h"
 
@@ -72,6 +73,8 @@ struct decoder_sys_t
     unsigned int i_raw_blocks;
     unsigned int i_channels;
     unsigned int i_rate, i_frame_length, i_header_size;
+
+    int i_input_rate;
 };
 
 enum {
@@ -146,6 +149,7 @@ static int OpenPacketizer( vlc_object_t *p_this )
     p_sys->i_state = STATE_NOSYNC;
     aout_DateSet( &p_sys->end_date, 0 );
     p_sys->bytestream = block_BytestreamInit( p_dec );
+    p_sys->i_input_rate = INPUT_RATE_DEFAULT;
 
     /* Set output properties */
     p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -241,7 +245,7 @@ static block_t *PacketizeBlock( decoder_t *p_dec, block_t **pp_block )
     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
-        p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
+        p_dec->fmt_out.audio.i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - p_block->i_pts;
 
     return p_block;
 }
@@ -277,6 +281,9 @@ static block_t *ADTSPacketizeBlock( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     }
 
+    if( (*pp_block)->i_rate > 0 )
+        p_sys->i_input_rate = (*pp_block)->i_rate;
+
     block_BytestreamPush( &p_sys->bytestream, *pp_block );
 
     while( 1 )
@@ -443,7 +450,8 @@ static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
 
     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
-                            p_sys->i_frame_length ) - p_block->i_pts;
+                            p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
+                                p_block->i_pts;
 
     *pp_out_buffer = p_block;
     return p_block->p_buffer;
index 7b8011b..523f172 100644 (file)
@@ -79,7 +79,7 @@
 int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input );
 int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input );
 int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                    aout_buffer_t * p_buffer );
+                    aout_buffer_t * p_buffer, int i_input_rate );
 
 /* From filters.c : */
 int aout_FiltersCreatePipeline ( aout_instance_t * p_aout, aout_filter_t ** pp_filters, int * pi_nb_filters, const audio_sample_format_t * p_input_format, const audio_sample_format_t * p_output_format );
@@ -129,5 +129,5 @@ aout_input_t * __aout_DecNew( vlc_object_t *, aout_instance_t **, audio_sample_f
 int aout_DecDelete ( aout_instance_t *, aout_input_t * );
 aout_buffer_t * aout_DecNewBuffer( aout_instance_t *, aout_input_t *, size_t );
 void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * );
-int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t * );
+int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate );
 
index 412a11a..7057493 100644 (file)
@@ -310,7 +310,7 @@ void aout_DecDeleteBuffer( aout_instance_t * p_aout, aout_input_t * p_input,
  * aout_DecPlay : filter & mix the decoded buffer
  *****************************************************************************/
 int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                  aout_buffer_t * p_buffer )
+                  aout_buffer_t * p_buffer, int i_input_rate )
 {
     if ( p_buffer->start_date == 0 )
     {
@@ -319,6 +319,13 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         return -1;
     }
 
+    if( i_input_rate > INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE ||
+        i_input_rate < INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE )
+    {
+        aout_BufferFree( p_buffer );
+        return 0;
+    }
+
     /* Apply the desynchronisation requested by the user */
     p_buffer->start_date += p_input->i_desync;
     p_buffer->end_date += p_input->i_desync;
@@ -375,7 +382,7 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     /* If the buffer is too early, wait a while. */
     mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME );
 
-    if ( aout_InputPlay( p_aout, p_input, p_buffer ) == -1 )
+    if ( aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate ) == -1 )
     {
         vlc_mutex_unlock( &p_input->lock );
         return -1;
index 741336d..975129c 100644 (file)
@@ -293,10 +293,10 @@ void aout_FiltersHintBuffers( aout_instance_t * p_aout,
         aout_filter_t * p_filter = pp_filters[i];
 
         int i_output_size = p_filter->output.i_bytes_per_frame
-                             * p_filter->output.i_rate
+                             * p_filter->output.i_rate * AOUT_MAX_INPUT_RATE
                              / p_filter->output.i_frame_length;
         int i_input_size = p_filter->input.i_bytes_per_frame
-                             * p_filter->input.i_rate
+                             * p_filter->input.i_rate * AOUT_MAX_INPUT_RATE
                              / p_filter->input.i_frame_length;
 
         p_first_alloc->i_bytes_per_sec = __MAX( p_first_alloc->i_bytes_per_sec,
@@ -357,6 +357,9 @@ void aout_FiltersPlay( aout_instance_t * p_aout,
             aout_BufferFree( *pp_input_buffer );
             *pp_input_buffer = p_output_buffer;
         }
+
+        if( p_output_buffer->i_nb_samples <= 0 )
+            break;
     }
 }
 
index cee7495..5ffdbcc 100644 (file)
@@ -44,7 +44,9 @@
 #include "input/input_internal.h"
 
 static void inputFailure( aout_instance_t *, aout_input_t *, const char * );
-static void inputDrop( aout_instance_t *, aout_input_t * );
+static void inputDrop( aout_instance_t *, aout_input_t *, aout_buffer_t * );
+static void inputResamplingStop( aout_input_t *p_input );
+
 static int VisualizationCallback( vlc_object_t *, char const *,
                                   vlc_value_t, vlc_value_t, void * );
 static int EqualizerCallback( vlc_object_t *, char const *,
@@ -364,10 +366,10 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input )
                                     (int)(p_input->input.i_bytes_per_frame
                                      * p_input->input.i_rate
                                      / p_input->input.i_frame_length) );
-
     /* Success */
     p_input->b_error = VLC_FALSE;
     p_input->b_restart = VLC_FALSE;
+    p_input->i_last_input_rate = INPUT_RATE_DEFAULT;
 
     return 0;
 }
@@ -397,8 +399,10 @@ int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
  *****************************************************************************
  * This function must be entered with the input lock.
  *****************************************************************************/
+/* XXX Do not activate it !! */
+//#define AOUT_PROCESS_BEFORE_CHEKS
 int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                    aout_buffer_t * p_buffer )
+                    aout_buffer_t * p_buffer, int i_input_rate )
 {
     mtime_t start_date;
 
@@ -422,6 +426,38 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         vlc_mutex_unlock( &p_aout->mixer_lock );
     }
 
+#ifdef AOUT_PROCESS_BEFORE_CHEKS
+    /* Run pre-filters. */
+    aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters,
+                      &p_buffer );
+
+    /* Actually run the resampler now. */
+    if ( p_input->i_nb_resamplers > 0 )
+    {
+        const mtime_t i_date = p_buffer->start_date;
+        aout_FiltersPlay( p_aout, p_input->pp_resamplers,
+                          p_input->i_nb_resamplers,
+                          &p_buffer );
+    }
+
+    if( p_buffer->i_nb_samples <= 0 )
+    {
+        aout_BufferFree( p_buffer );
+        return 0;
+    }
+#endif
+
+    /* Handle input rate change by modifying resampler input rate */
+    if( i_input_rate != p_input->i_last_input_rate )
+    {
+        unsigned int * const pi_rate = &p_input->pp_resamplers[0]->input.i_rate;
+#define F(r,ir) ( INPUT_RATE_DEFAULT * (r) / (ir) )
+        const int i_delta = *pi_rate - F(p_input->input.i_rate,p_input->i_last_input_rate);
+        *pi_rate = F(p_input->input.i_rate + i_delta, i_input_rate);
+#undef F
+        p_input->i_last_input_rate = i_input_rate;
+    }
+
     /* We don't care if someone changes the start date behind our back after
      * this. We'll deal with that when pushing the buffer, and compensate
      * with the next incoming buffer. */
@@ -442,14 +478,8 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         vlc_mutex_unlock( &p_aout->input_fifos_lock );
         if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
             msg_Warn( p_aout, "timing screwed, stopping resampling" );
-        p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
-        if ( p_input->i_nb_resamplers != 0 )
-        {
-            p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
-            p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
-        }
+        inputResamplingStop( p_input );
         start_date = 0;
-        inputDrop( p_aout, p_input );
     }
 
     if ( p_buffer->start_date < mdate() + AOUT_MIN_PREPARE_TIME )
@@ -459,14 +489,8 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         msg_Warn( p_aout, "PTS is out of range ("I64Fd"), dropping buffer",
                   mdate() - p_buffer->start_date );
 
-        inputDrop( p_aout, p_input );
-        aout_BufferFree( p_buffer );
-        p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
-        if ( p_input->i_nb_resamplers != 0 )
-        {
-            p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
-            p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
-        }
+        inputDrop( p_aout, p_input, p_buffer );
+        inputResamplingStop( p_input );
         return 0;
     }
 
@@ -483,12 +507,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         vlc_mutex_unlock( &p_aout->input_fifos_lock );
         if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
             msg_Warn( p_aout, "timing screwed, stopping resampling" );
-        p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
-        if ( p_input->i_nb_resamplers != 0 )
-        {
-            p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
-            p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
-        }
+        inputResamplingStop( p_input );
         start_date = 0;
     }
     else if ( start_date != 0 &&
@@ -496,17 +515,17 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     {
         msg_Warn( p_aout, "audio drift is too big ("I64Fd"), dropping buffer",
                   start_date - p_buffer->start_date );
-        aout_BufferFree( p_buffer );
-        inputDrop( p_aout, p_input );
+        inputDrop( p_aout, p_input, p_buffer );
         return 0;
     }
 
     if ( start_date == 0 ) start_date = p_buffer->start_date;
 
+#ifndef AOUT_PROCESS_BEFORE_CHEKS
     /* Run pre-filters. */
-
     aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters,
                       &p_buffer );
+#endif
 
     /* Run the resampler if needed.
      * We first need to calculate the output rate of this resampler. */
@@ -555,8 +574,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
 
         /* Check if everything is back to normal, in which case we can stop the
          * resampling */
-        if( p_input->pp_resamplers[0]->input.i_rate ==
-              p_input->input.i_rate )
+        if( p_input->pp_resamplers[0]->input.i_rate == 1000 * p_input->input.i_rate / i_input_rate )
         {
             p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
             msg_Warn( p_aout, "resampling stopped after "I64Fi" usec "
@@ -582,16 +600,11 @@ int aout_InputPlay( aout_instance_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" );
-            p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
-            p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate;
+            inputResamplingStop( p_input );
         }
     }
 
-    /* Adding the start date will be managed by aout_FifoPush(). */
-    p_buffer->end_date = start_date +
-        (p_buffer->end_date - p_buffer->start_date);
-    p_buffer->start_date = start_date;
-
+#ifndef AOUT_PROCESS_BEFORE_CHEKS
     /* Actually run the resampler now. */
     if ( p_input->i_nb_resamplers > 0 )
     {
@@ -600,10 +613,21 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                           &p_buffer );
     }
 
+    if( p_buffer->i_nb_samples <= 0 )
+    {
+        aout_BufferFree( p_buffer );
+        return 0;
+    }
+#endif
+
+    /* Adding the start date will be managed by aout_FifoPush(). */
+    p_buffer->end_date = start_date +
+        (p_buffer->end_date - p_buffer->start_date);
+    p_buffer->start_date = start_date;
+
     vlc_mutex_lock( &p_aout->input_fifos_lock );
     aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
     vlc_mutex_unlock( &p_aout->input_fifos_lock );
-
     return 0;
 }
 
@@ -632,8 +656,10 @@ static void inputFailure( aout_instance_t * p_aout, aout_input_t * p_input,
     p_input->b_error = 1;
 }
 
-static void inputDrop( aout_instance_t *p_aout, aout_input_t *p_input )
+static void inputDrop( aout_instance_t *p_aout, aout_input_t *p_input, aout_buffer_t *p_buffer )
 {
+    aout_BufferFree( p_buffer );
+
     if( !p_input->p_input_thread )
         return;
 
@@ -642,6 +668,17 @@ static void inputDrop( aout_instance_t *p_aout, aout_input_t *p_input )
     vlc_mutex_unlock( &p_input->p_input_thread->p->counters.counters_lock);
 }
 
+static void inputResamplingStop( aout_input_t *p_input )
+{
+    p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
+    if( p_input->i_nb_resamplers != 0 )
+    {
+        p_input->pp_resamplers[0]->input.i_rate = INPUT_RATE_DEFAULT *
+                            p_input->input.i_rate / p_input->i_last_input_rate;
+        p_input->pp_resamplers[0]->b_continuity = VLC_FALSE;
+    }
+}
+
 static int ChangeFiltersString( aout_instance_t * p_aout, const char* psz_variable,
                                  const char *psz_name, vlc_bool_t b_add )
 {
index 079b546..e36ef7f 100644 (file)
@@ -468,6 +468,7 @@ static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
 static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
 {
     input_thread_t *p_input = p_dec->p_owner->p_input;
+    const int i_rate = p_block->i_rate;
     aout_buffer_t *p_aout_buf;
 
     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
@@ -491,7 +492,7 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
         }
         aout_DecPlay( p_dec->p_owner->p_aout,
                       p_dec->p_owner->p_aout_input,
-                      p_aout_buf );
+                      p_aout_buf, i_rate );
     }
 }
 static void VoutDisplayedPicture( vout_thread_t *p_vout, picture_t *p_pic )
@@ -523,7 +524,8 @@ static void VoutFlushPicture( vout_thread_t *p_vout )
     {
         picture_t *p_pic = p_vout->render.pp_picture[i];
 
-        if( p_pic->i_status != READY_PICTURE )
+        if( p_pic->i_status == READY_PICTURE ||
+            p_pic->i_status == DISPLAYED_PICTURE )
         {
             /* We cannot change picture status if it is in READY_PICTURE state,
              * Just make sure they won't be displayed */
index 6637221..f444d95 100644 (file)
@@ -33,6 +33,7 @@
 #include <vlc_input.h>
 #include <vlc_es_out.h>
 #include <vlc_block.h>
+#include <vlc_aout.h>
 
 #include "input_internal.h"
 
@@ -1216,7 +1217,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
             es->i_preroll_end = -1;
     }
 
-    /* +11 -> avoid null value with non null dts/pts */
     if( p_block->i_dts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) )
     {
         p_block->i_dts += i_delay;
@@ -1252,8 +1252,10 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
     p_block->i_rate = p_input->p->i_rate;
 
     /* TODO handle mute */
-    if( es->p_dec && ( es->fmt.i_cat != AUDIO_ES ||
-        p_input->p->i_rate == INPUT_RATE_DEFAULT ) )
+    if( es->p_dec &&
+        ( es->fmt.i_cat != AUDIO_ES ||
+          ( p_input->p->i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE &&
+            p_input->p->i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE ) ) )
     {
         input_DecoderDecode( es->p_dec, p_block );
     }
@@ -1511,7 +1513,6 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
 
             i_pcr = (int64_t)va_arg( args, int64_t );
             /* search program */
-            /* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
             input_ClockSetPCR( p_sys->p_input, &p_pgrm->clock, i_pcr );
             return VLC_SUCCESS;
         }
index 5695301..d5058bd 100644 (file)
@@ -1670,9 +1670,8 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type,
                 val.i_int = i_rate;
                 var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
 
-                /* We will not send audio data if new rate != default */
-                if( i_rate != INPUT_RATE_DEFAULT && p_input->p->i_rate == INPUT_RATE_DEFAULT )
-                    input_EsOutDiscontinuity( p_input->p->p_es_out, VLC_FALSE, VLC_TRUE );
+                input_EsOutDiscontinuity( p_input->p->p_es_out,
+                                          VLC_FALSE, VLC_FALSE );
 
                 p_input->p->i_rate  = i_rate;