]> git.sesse.net Git - vlc/commitdiff
* Finally fixed the segfault when resampling.
authorChristophe Massiot <massiot@videolan.org>
Wed, 28 Aug 2002 22:25:39 +0000 (22:25 +0000)
committerChristophe Massiot <massiot@videolan.org>
Wed, 28 Aug 2002 22:25:39 +0000 (22:25 +0000)
* Reactivated the A/52 demux.
* Wrote a real full-featured float32 mixer.

12 files changed:
configure.in
modules/audio_filter/channel_mixer/trivial.c
modules/audio_filter/resampler/ugly.c
modules/audio_mixer/Makefile
modules/audio_mixer/float32.c [new file with mode: 0644]
modules/codec/mpeg_audio/generic.c
modules/demux/.cvsignore [moved from modules/demux/a52/.cvsignore with 100% similarity]
modules/demux/Makefile [new file with mode: 0644]
modules/demux/a52/Makefile [deleted file]
modules/demux/a52sys.c [moved from modules/demux/a52/demux.c with 95% similarity]
src/audio_output/filters.c
src/audio_output/input.c

index a72c363254e12753b7ce2a36a2546e41e1dff0fb..2d984a9f9007a1da682dc0531dbe52d76c804bdf 100644 (file)
@@ -445,7 +445,7 @@ dnl
 BUILTINS="${BUILTINS}"
 PLUGINS="${PLUGINS} misc/dummy/dummy misc/null"
 PLUGINS="${PLUGINS} control/rc/rc misc/logger/logger access/file misc/memcpy/memcpy"
-PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts"
+PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts demux/a52sys"
 PLUGINS="${PLUGINS} codec/mpeg_video/idct/idct codec/mpeg_video/idct/idctclassic codec/mpeg_video/motion/motion codec/mpeg_video/mpeg_video codec/spudec/spudec codec/spdif codec/mpeg_audio/mpeg_audio"
 PLUGINS="${PLUGINS} codec/a52old/imdct/imdct codec/a52old/downmix/downmix codec/a52old/a52old"
 #PLUGINS="${PLUGINS} codec/lpcm/lpcm"
@@ -453,7 +453,7 @@ PLUGINS="${PLUGINS} video_filter/deinterlace/deinterlace video_filter/invert vid
 PLUGINS="${PLUGINS} audio_filter/converter/float32tos16 audio_filter/converter/float32tos8 audio_filter/converter/float32tou16 audio_filter/converter/float32tou8 audio_filter/converter/a52tospdif audio_filter/converter/fixed32tofloat32 audio_filter/converter/fixed32tos16 audio_filter/converter/s16tofloat32"
 PLUGINS="${PLUGINS} audio_filter/resampler/trivial audio_filter/resampler/ugly"
 PLUGINS="${PLUGINS} audio_filter/channel_mixer/trivial"
-PLUGINS="${PLUGINS} audio_mixer/trivial audio_mixer/spdif"
+PLUGINS="${PLUGINS} audio_mixer/float32 audio_mixer/trivial audio_mixer/spdif"
 PLUGINS="${PLUGINS} audio_output/file"
 #PLUGINS="${PLUGINS} visualization/scope/scope"
 PLUGINS="${PLUGINS} video_chroma/i420_rgb video_chroma/i420_yuy2 video_chroma/i422_yuy2 video_chroma/i420_ymga"
index fab6f3371dcdc079de3ecd9ec7a290f100988d0a..07f92bbe913cab8ad602b3315c75f5aa48ae08aa 100644 (file)
@@ -2,7 +2,7 @@
  * trivial.c : trivial channel mixer plug-in (drops unwanted channels)
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: trivial.c,v 1.1 2002/08/21 22:41:59 massiot Exp $
+ * $Id: trivial.c,v 1.2 2002/08/28 22:25:38 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -87,7 +87,7 @@ static void SparseCopy( s32 * p_dest, const s32 * p_src, size_t i_len,
                         int i_output_stride, int i_input_stride )
 {
     int i;
-    for ( i = 0; i < i_len; i++ )
+    for ( i = i_len; i--; )
     {
         int j;
         for ( j = 0; j < i_output_stride; j++ )
index dd4a52e4cceb03471d1a9cb6e0a53595aaa5175c..8a66223a97cf9664aabe2ece8df86fcb4a906713 100644 (file)
@@ -2,7 +2,7 @@
  * ugly.c : ugly resampler (changes pitch)
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: ugly.c,v 1.1 2002/08/24 20:22:34 sam Exp $
+ * $Id: ugly.c,v 1.2 2002/08/28 22:25:38 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -91,8 +91,9 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
         for( i_chan = p_filter->input.i_channels ; i_chan ; )
         {
             i_chan--;
-            *p_out++ = p_in[i_chan];
+            p_out[i_chan] = p_in[i_chan];
         }
+        p_out += p_filter->input.i_channels;
 
         i_remainder += p_filter->input.i_rate;
         while( i_remainder >= p_filter->output.i_rate )
index ec41380c3fe74ccf7edd9ec5038b8cc39789277e..b7d4f2fa62d5b0658a0e91cf594992ba7b880dba 100644 (file)
@@ -1,2 +1,3 @@
 trivial_SOURCES = trivial.c
+float32_SOURCES = float32.c
 spdif_SOURCES = spdif.c
diff --git a/modules/audio_mixer/float32.c b/modules/audio_mixer/float32.c
new file mode 100644 (file)
index 0000000..3073755
--- /dev/null
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * float32.c : precise float32 audio mixer implementation
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: float32.c,v 1.1 2002/08/28 22:25:38 massiot Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <errno.h>
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <vlc/vlc.h>
+#include "audio_output.h"
+#include "aout_internal.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Create    ( vlc_object_t * );
+
+static void DoWork    ( aout_instance_t *, aout_buffer_t * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( _("float32 audio mixer module") );
+    set_capability( "audio mixer", 10 );
+    set_callbacks( Create, NULL );
+vlc_module_end();
+
+/*****************************************************************************
+ * Create: allocate trivial mixer
+ *****************************************************************************/
+static int Create( vlc_object_t *p_this )
+{
+    aout_instance_t * p_aout = (aout_instance_t *)p_this;
+
+    if ( p_aout->mixer.mixer.i_format != AOUT_FMT_FLOAT32 )
+    {
+        return -1;
+    }
+
+    if ( p_aout->i_nb_inputs == 1 )
+    {
+        /* Tell the trivial mixer to go for it. */
+        return -1;
+    }
+
+    p_aout->mixer.pf_do_work = DoWork;
+
+    return 0;
+}
+
+/*****************************************************************************
+ * ScaleWords: prepare input words for averaging
+ *****************************************************************************/
+static void ScaleWords( float * p_out, const float * p_in, size_t i_nb_words,
+                        int i_nb_inputs )
+{
+    int i;
+
+    for ( i = i_nb_words; i--; )
+    {
+        *p_out++ = *p_in++ / i_nb_inputs;
+    }
+}
+
+/*****************************************************************************
+ * MeanWords: average input words
+ *****************************************************************************/
+static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
+                       int i_nb_inputs )
+{
+    int i;
+
+    for ( i = i_nb_words; i--; )
+    {
+        *p_out++ += *p_in++ / i_nb_inputs;
+    }
+}
+
+/*****************************************************************************
+ * DoWork: mix a new output buffer
+ *****************************************************************************
+ * Terminology : in this function a word designates a single float32, eg.
+ * a stereo sample is consituted of two words.
+ *****************************************************************************/
+static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
+{
+    int i_nb_inputs = p_aout->i_nb_inputs;
+    int i_input;
+
+    for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
+    {
+        int i_nb_words = p_buffer->i_nb_samples
+                          * p_aout->mixer.mixer.i_channels;
+        aout_input_t * p_input = p_aout->pp_inputs[i_input];
+        float * p_out = (float *)p_buffer->p_buffer;
+        float * p_in = (float *)p_input->p_first_byte_to_mix;
+
+        for ( ; ; )
+        {
+            ptrdiff_t i_available_words = (
+                 (float *)p_input->fifo.p_first->p_buffer - p_in)
+                                   + p_input->fifo.p_first->i_nb_samples
+                                   * p_aout->mixer.mixer.i_channels;
+
+            if ( i_available_words < i_nb_words )
+            {
+                aout_buffer_t * p_old_buffer;
+
+                if ( i_available_words > 0 )
+                {
+                    if ( !i_input )
+                    {
+                        ScaleWords( p_out, p_in, i_available_words,
+                                    i_nb_inputs );
+                    }
+                    else
+                    {
+                        MeanWords( p_out, p_in, i_available_words,
+                                   i_nb_inputs );
+                    }
+                }
+
+                i_nb_words -= i_available_words;
+                p_out += i_available_words;
+
+                /* Next buffer */
+                p_old_buffer = aout_FifoPop( p_aout, &p_input->fifo );
+                aout_BufferFree( p_old_buffer );
+                if ( p_input->fifo.p_first == NULL )
+                {
+                    msg_Err( p_aout, "internal amix error" );
+                    return;
+                }
+                p_in = (float *)p_input->fifo.p_first->p_buffer;
+            }
+            else
+            {
+                if ( i_nb_words > 0 )
+                {
+                    if ( !i_input )
+                    {
+                        ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs );
+                    }
+                    else
+                    {
+                        MeanWords( p_out, p_in, i_nb_words, i_nb_inputs );
+                    }
+                }
+                p_input->p_first_byte_to_mix = (void *)(p_in
+                                            + i_nb_words);
+                break;
+            }
+        }
+    }
+}
+
index 2082d8b92853332dcc7dcb6a918e88368623f706..3704909dd1e28ff4e64a15da6f8b19ceb4574734 100644 (file)
@@ -2,7 +2,7 @@
  * generic.c: MPEG audio decoder
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: generic.c,v 1.3 2002/08/26 23:00:22 massiot Exp $
+ * $Id: generic.c,v 1.4 2002/08/28 22:25:38 massiot Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Michel Lespinasse <walken@via.ecp.fr>
@@ -71,7 +71,7 @@ int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info )
 
     u32 header;
     int index;
-    int * bit_rates;
+    const int * bit_rates;
     int sample_rate;
     int bit_rate;
     int frame_size;
diff --git a/modules/demux/Makefile b/modules/demux/Makefile
new file mode 100644 (file)
index 0000000..1966764
--- /dev/null
@@ -0,0 +1 @@
+a52sys_SOURCES = a52sys.c
diff --git a/modules/demux/a52/Makefile b/modules/demux/a52/Makefile
deleted file mode 100644 (file)
index 2872efc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a52_SOURCES = demux.c
similarity index 95%
rename from modules/demux/a52/demux.c
rename to modules/demux/a52sys.c
index f38c0738c9e5516fc8dc5fc25d02077d8cd6b5f1..0ae9c3a6729e5663706cdad067daf364568c075a 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * a52_system.c : A52 input module for vlc
+ * a52sys.c : A/52 input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: demux.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: a52sys.c,v 1.1 2002/08/28 22:25:38 massiot Exp $
  *
  * Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
  *
@@ -50,9 +50,9 @@ static int  Demux ( input_thread_t * );
  *****************************************************************************/
 vlc_module_begin();                                      
     set_description( "A52 demuxer" );                       
-    set_capability( "demux", 150 );
+    set_capability( "demux", 155 );
     set_callbacks( Init, NULL );
-    add_shortcut( "a52sys" );
+    add_shortcut( "a52" );
 vlc_module_end();
 
 /*****************************************************************************
@@ -84,7 +84,7 @@ static int Init( vlc_object_t * p_this )
 
     if( *p_peek != 0x0b || *(p_peek + 1) != 0x77 )
     {
-        if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "a52sys", 3 ) )
+        if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "a52", 3 ) )
         {
             /* User forced */
             msg_Err( p_input, "this doesn't look like an a52 stream, continuing" );
@@ -128,11 +128,16 @@ static int Demux( input_thread_t * p_input )
     pes_packet_t *  p_pes;
     data_packet_t * p_data;
 
+    if( p_fifo == NULL )
+    {
+        return -1;
+    }
+
     i_read = input_SplitBuffer( p_input, &p_data, A52_PACKET_SIZE );
 
     if ( i_read <= 0 )
     {
-        return( i_read );
+        return i_read;
     }
 
     p_pes = input_NewPES( p_input->p_method_data );
@@ -169,6 +174,6 @@ static int Demux( input_thread_t * p_input )
 
     input_DecodePES( p_fifo, p_pes );
 
-    return( 1 );
+    return 1;
 }
 
index c97ffc098a189e6c27981f2f531e665d9718810a..031729e9b372e1b6b1cbf79e9cb41e65f7800e3a 100644 (file)
@@ -2,7 +2,7 @@
  * filters.c : audio output filters management
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: filters.c,v 1.6 2002/08/19 21:54:37 massiot Exp $
+ * $Id: filters.c,v 1.7 2002/08/28 22:25:39 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -316,6 +316,7 @@ void aout_FiltersHintBuffers( aout_instance_t * p_aout,
             p_first_alloc->i_bytes_per_sec = __MAX(
                                          p_first_alloc->i_bytes_per_sec,
                                          i_input_size );
+            p_filter->output_alloc.i_alloc_type = AOUT_ALLOC_NONE;
         }
         else
         {
@@ -344,7 +345,7 @@ void aout_FiltersPlay( aout_instance_t * p_aout,
 
         aout_BufferAlloc( &p_filter->output_alloc,
                           (mtime_t)(*pp_input_buffer)->i_nb_samples * 1000000
-                            / p_filter->output.i_rate, *pp_input_buffer,
+                            / p_filter->input.i_rate, *pp_input_buffer,
                           p_output_buffer );
         if ( p_output_buffer == NULL )
         {
index 98cdf15620ae5c5d968fe62eff8767296dcdd38a..a12db52b9a2c6edf097f4516073623b5cd66ad40 100644 (file)
@@ -2,7 +2,7 @@
  * input.c : internal management of input streams for the audio output
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: input.c,v 1.9 2002/08/26 23:00:23 massiot Exp $
+ * $Id: input.c,v 1.10 2002/08/28 22:25:39 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -268,7 +268,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
          *    synchronization
          * Solution : resample the buffer to avoid a scratch.
          */
-        audio_sample_format_t new_output;
+        audio_sample_format_t new_input;
         int i_ratio, i_nb_filters;
         mtime_t old_duration;
         aout_filter_t * pp_filters[AOUT_MAX_FILTERS];
@@ -279,7 +279,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         msg_Warn( p_aout, "buffer is %lld %s, resampling",
                          drift > 0 ? drift : -drift,
                          drift > 0 ? "in advance" : "late" );
-        memcpy( &new_output, &p_aout->mixer.mixer,
+        memcpy( &new_input, &p_input->input,
                 sizeof(audio_sample_format_t) );
         old_duration = p_buffer->end_date - p_buffer->start_date;
         duration = p_buffer->end_date - start_date;
@@ -293,11 +293,12 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         {
             duration = old_duration * 150 / 100;
         }
-        new_output.i_rate = new_output.i_rate * duration / old_duration;
+        new_input.i_rate = new_input.i_rate * old_duration / duration;
+        aout_FormatPrepare( &new_input );
 
         if ( aout_FiltersCreatePipeline( p_aout, pp_filters,
-                                         &i_nb_filters, &p_input->input,
-                                         &new_output ) < 0 )
+                                         &i_nb_filters, &new_input,
+                                         &p_aout->mixer.mixer ) < 0 )
         {
             msg_Err( p_aout, "couldn't set an input pipeline for resampling" );
             vlc_mutex_lock( &p_aout->mixer_lock );
@@ -318,16 +319,17 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                                  &dummy_alloc );
         dummy_alloc.i_bytes_per_sec = __MAX(
                                     dummy_alloc.i_bytes_per_sec,
-                                    p_input->input.i_bytes_per_frame
-                                     * p_input->input.i_rate
-                                     / p_input->input.i_frame_length );
+                                    new_input.i_bytes_per_frame
+                                     * new_input.i_rate
+                                     / new_input.i_frame_length );
         dummy_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
 
-        aout_BufferAlloc( &dummy_alloc, old_duration, NULL, p_new_buffer );
+        aout_BufferAlloc( &dummy_alloc, duration, NULL, p_new_buffer );
         memcpy( p_new_buffer->p_buffer, p_buffer->p_buffer,
                 p_buffer->i_nb_bytes );
         p_new_buffer->i_nb_samples = p_buffer->i_nb_samples;
         p_new_buffer->i_nb_bytes = p_buffer->i_nb_bytes;
+
         aout_BufferFree( p_buffer );
         p_buffer = p_new_buffer;