From b5ab493010868a16115777076b7ed431f8a5739c Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Wed, 28 Aug 2002 22:25:39 +0000 Subject: [PATCH] * Finally fixed the segfault when resampling. * Reactivated the A/52 demux. * Wrote a real full-featured float32 mixer. --- configure.in | 4 +- modules/audio_filter/channel_mixer/trivial.c | 4 +- modules/audio_filter/resampler/ugly.c | 5 +- modules/audio_mixer/Makefile | 1 + modules/audio_mixer/float32.c | 179 +++++++++++++++++++ modules/codec/mpeg_audio/generic.c | 4 +- modules/demux/{a52 => }/.cvsignore | 0 modules/demux/Makefile | 1 + modules/demux/a52/Makefile | 1 - modules/demux/{a52/demux.c => a52sys.c} | 19 +- src/audio_output/filters.c | 5 +- src/audio_output/input.c | 22 +-- 12 files changed, 217 insertions(+), 28 deletions(-) create mode 100644 modules/audio_mixer/float32.c rename modules/demux/{a52 => }/.cvsignore (100%) create mode 100644 modules/demux/Makefile delete mode 100644 modules/demux/a52/Makefile rename modules/demux/{a52/demux.c => a52sys.c} (95%) diff --git a/configure.in b/configure.in index a72c363254..2d984a9f90 100644 --- a/configure.in +++ b/configure.in @@ -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" diff --git a/modules/audio_filter/channel_mixer/trivial.c b/modules/audio_filter/channel_mixer/trivial.c index fab6f3371d..07f92bbe91 100644 --- a/modules/audio_filter/channel_mixer/trivial.c +++ b/modules/audio_filter/channel_mixer/trivial.c @@ -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 * @@ -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++ ) diff --git a/modules/audio_filter/resampler/ugly.c b/modules/audio_filter/resampler/ugly.c index dd4a52e4cc..8a66223a97 100644 --- a/modules/audio_filter/resampler/ugly.c +++ b/modules/audio_filter/resampler/ugly.c @@ -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 * @@ -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 ) diff --git a/modules/audio_mixer/Makefile b/modules/audio_mixer/Makefile index ec41380c3f..b7d4f2fa62 100644 --- a/modules/audio_mixer/Makefile +++ b/modules/audio_mixer/Makefile @@ -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 index 0000000000..3073755dcd --- /dev/null +++ b/modules/audio_mixer/float32.c @@ -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 + * + * 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 +#include /* malloc(), free() */ +#include + +#include +#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; + } + } + } +} + diff --git a/modules/codec/mpeg_audio/generic.c b/modules/codec/mpeg_audio/generic.c index 2082d8b928..3704909dd1 100644 --- a/modules/codec/mpeg_audio/generic.c +++ b/modules/codec/mpeg_audio/generic.c @@ -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 * Michel Lespinasse @@ -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/a52/.cvsignore b/modules/demux/.cvsignore similarity index 100% rename from modules/demux/a52/.cvsignore rename to modules/demux/.cvsignore diff --git a/modules/demux/Makefile b/modules/demux/Makefile new file mode 100644 index 0000000000..19667644f8 --- /dev/null +++ b/modules/demux/Makefile @@ -0,0 +1 @@ +a52sys_SOURCES = a52sys.c diff --git a/modules/demux/a52/Makefile b/modules/demux/a52/Makefile deleted file mode 100644 index 2872efc6c3..0000000000 --- a/modules/demux/a52/Makefile +++ /dev/null @@ -1 +0,0 @@ -a52_SOURCES = demux.c diff --git a/modules/demux/a52/demux.c b/modules/demux/a52sys.c similarity index 95% rename from modules/demux/a52/demux.c rename to modules/demux/a52sys.c index f38c0738c9..0ae9c3a672 100644 --- a/modules/demux/a52/demux.c +++ b/modules/demux/a52sys.c @@ -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 * @@ -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; } diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c index c97ffc098a..031729e9b3 100644 --- a/src/audio_output/filters.c +++ b/src/audio_output/filters.c @@ -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 * @@ -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 ) { diff --git a/src/audio_output/input.c b/src/audio_output/input.c index 98cdf15620..a12db52b9a 100644 --- a/src/audio_output/input.c +++ b/src/audio_output/input.c @@ -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 * @@ -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; -- 2.39.2