From 0596bf59205445d3056437d6213b989a0928c071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Stenac?= Date: Mon, 18 Aug 2003 13:16:43 +0000 Subject: [PATCH] * src/audio_output/input.c src/libvlc.h : First try to implement "user audio filters" You can provide a list of audio filters that you want to add to the pipeline (only the "headphone", at that time). (use --audio-filter filter1,filter2,...) ***Warning*** It seems to work, but no guarantee at all. Perhaps all is bad and the commit should be reverted, as it could break audio output * modules/codec/libmpeg2.c : Fixed a segfault when vout creation fails --- modules/codec/libmpeg2.c | 10 +- src/audio_output/input.c | 199 +++++++++++++++++++++++++++++++++++++-- src/libvlc.h | 12 ++- 3 files changed, 207 insertions(+), 14 deletions(-) diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c index 5f0290d5a1..6711989d63 100755 --- a/modules/codec/libmpeg2.c +++ b/modules/codec/libmpeg2.c @@ -2,7 +2,7 @@ * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2. ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: libmpeg2.c,v 1.24 2003/08/08 17:08:32 gbazin Exp $ + * $Id: libmpeg2.c,v 1.25 2003/08/18 13:16:43 zorglub Exp $ * * Authors: Gildas Bazin * @@ -299,7 +299,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) p_dec->p_info->sequence->width, p_dec->p_info->sequence->height, VLC_FOURCC('Y','V','1','2'), i_aspect ); - + + if(p_dec->p_vout == NULL ) + { + msg_Err( p_dec->p_fifo , "cannot create vout" ); + return -1; + } + msg_Dbg( p_dec->p_fifo, "%dx%d, aspect %d, %u.%03u fps", p_dec->p_info->sequence->width, p_dec->p_info->sequence->height, i_aspect, diff --git a/src/audio_output/input.c b/src/audio_output/input.c index 2dc0b4daa9..7109ce1a1e 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.34 2003/04/06 23:44:53 massiot Exp $ + * $Id: input.c,v 1.35 2003/08/18 13:16:43 zorglub Exp $ * * Authors: Christophe Massiot * @@ -36,15 +36,34 @@ #include "audio_output.h" #include "aout_internal.h" +typedef struct user_filter_t +{ + char *psz_name; + aout_filter_t * p_filter; + audio_sample_format_t filter_inter_format; + struct user_filter_t *p_next; +} user_filter_t; + + /***************************************************************************** * aout_InputNew : allocate a new input and rework the filter pipeline *****************************************************************************/ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) { - audio_sample_format_t intermediate_format, headphone_intermediate_format; + audio_sample_format_t intermediate_format; +#if 0 + headphone_intermediate_format; aout_filter_t * p_headphone_filter; vlc_bool_t b_use_headphone_filter = VLC_FALSE; - +#endif + + vlc_bool_t b_end=VLC_FALSE; + + user_filter_t* p_first_filter=NULL; + user_filter_t* p_current_filter=NULL; + + char * psz_filters, *psz_eof; + aout_FormatPrint( p_aout, "input", &p_input->input ); /* Prepare FIFO. */ @@ -56,10 +75,94 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) sizeof(audio_sample_format_t) ); intermediate_format.i_rate = p_input->input.i_rate; + + /* Build the list of user filters */ + psz_filters = config_GetPsz( p_aout , "audio-filter" ); + + p_first_filter = (user_filter_t *)malloc( sizeof( user_filter_t ) ); + if( !p_first_filter ) + { + msg_Err( p_aout, "Out of memory" ); + return -1; + } + p_current_filter = p_first_filter; + p_current_filter->p_next = NULL; + memcpy( &p_current_filter->filter_inter_format, + &p_aout->mixer.mixer,sizeof(audio_sample_format_t)); + p_current_filter->filter_inter_format.i_rate= p_input->input.i_rate; + + if(psz_filters != NULL) + { + msg_Dbg(p_aout,"Building list of user filters"); + while(1) + { + psz_eof = strchr( psz_filters , ',' ); + if( !psz_eof ) + { + b_end = VLC_TRUE; + psz_eof = strchr( psz_filters,'\0'); + } + if( psz_eof ) + { + *psz_eof = '\0'; + } + + msg_Dbg(p_aout,"Adding user filter: %s",psz_filters); + + /* Append the new filter to the list */ + p_current_filter->p_next = + (user_filter_t *)malloc(sizeof(user_filter_t)); + if( !p_current_filter->p_next ) + { + msg_Err( p_aout, "Out of memory" ); + return -1; + } + + memcpy( &p_current_filter->p_next->filter_inter_format, + &p_current_filter->filter_inter_format, + sizeof(audio_sample_format_t) ); + + p_current_filter->p_next->filter_inter_format.i_rate = + p_current_filter->filter_inter_format.i_rate; + + p_current_filter->p_next-> + filter_inter_format.i_physical_channels = + p_current_filter->filter_inter_format.i_physical_channels; + + p_current_filter->p_next-> + filter_inter_format.i_original_channels = + p_current_filter->filter_inter_format.i_original_channels; + + p_current_filter->p_next->filter_inter_format.i_bytes_per_frame = + p_current_filter->p_next-> + filter_inter_format.i_bytes_per_frame * + aout_FormatNbChannels(&p_current_filter->p_next-> + filter_inter_format) / + aout_FormatNbChannels( &intermediate_format); + + /* Go to next filter */ + p_current_filter = p_current_filter->p_next; + + p_current_filter->p_next= NULL; + + p_current_filter->psz_name = strdup(psz_filters); + + psz_filters = psz_eof; + + psz_filters++; + + if(!*psz_filters || b_end == VLC_TRUE) + break; + } + } + +#if 0 /* Headphone filter add-ons. */ + memcpy( &headphone_intermediate_format, &p_aout->mixer.mixer, - sizeof(audio_sample_format_t) ); - headphone_intermediate_format.i_rate = p_input->input.i_rate; + sizeof(audio_sample_format_t) ); + headphone_intermediate_format.i_rate = + p_input->input.i_rate; if ( config_GetInt( p_aout , "headphone-opt" ) ) { /* Do we use heaphone filter ? */ @@ -75,8 +178,10 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) if ( b_use_headphone_filter == VLC_TRUE ) { /* Split the filter pipeline. */ - headphone_intermediate_format.i_physical_channels = p_input->input.i_physical_channels; - headphone_intermediate_format.i_original_channels = p_input->input.i_original_channels; + headphone_intermediate_format.i_physical_channels = + p_input->input.i_physical_channels; + headphone_intermediate_format.i_original_channels = + p_input->input.i_original_channels; headphone_intermediate_format.i_bytes_per_frame = headphone_intermediate_format.i_bytes_per_frame * aout_FormatNbChannels( &headphone_intermediate_format ) @@ -86,7 +191,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) /* Create filters. */ if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, &p_input->i_nb_filters, &p_input->input, - &headphone_intermediate_format ) < 0 ) + &intermediate_format ) < 0 ) { msg_Err( p_aout, "couldn't set an input pipeline" ); @@ -95,8 +200,80 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) return -1; } +#endif + /* Create filters. */ + if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, + &p_input->i_nb_filters, + &p_input->input, + &intermediate_format + ) < 0 ) + { + msg_Err( p_aout, "couldn't set an input pipeline" ); - /* Headphone filter add-ons. */ + aout_FifoDestroy( p_aout, &p_input->fifo ); + p_input->b_error = 1; + } + + if( p_first_filter->p_next) + { + msg_Dbg(p_aout,"Searching user filters..."); + p_current_filter = p_first_filter->p_next; + + /* Ok, we now start to get the filters, from the first one */ + while( p_current_filter ) + { + /* Create a VLC object */ + p_current_filter->p_filter = vlc_object_create( p_aout, + sizeof(aout_filter_t) ); + if(p_current_filter->p_filter == NULL ) + { + msg_Err( p_aout, "couldn't open the requested filter module" ); + aout_FifoDestroy( p_aout, &p_input->fifo ); + p_input->b_error = 1; + return -1; + } + vlc_object_attach( p_current_filter->p_filter , p_aout ); + memcpy(&p_current_filter->p_filter->input, + &p_current_filter->filter_inter_format, + sizeof(audio_sample_format_t) ); + + if( p_current_filter->p_next) + { + memcpy(&p_current_filter->p_filter->output, + &p_current_filter->p_next->filter_inter_format, + sizeof(audio_sample_format_t) ); + } + else + { + memcpy(&p_current_filter->p_filter->output, + &intermediate_format, + sizeof(audio_sample_format_t) ); + } + p_current_filter->p_filter->p_module = + module_Need(p_current_filter->p_filter,"audio filter", + p_current_filter->psz_name); + if(p_current_filter->p_filter->p_module== NULL ) + { + vlc_object_detach( p_current_filter->p_filter); + vlc_object_destroy( p_current_filter->p_filter); + + msg_Err( p_aout, "couldn't open the requested module" ); + aout_FifoDestroy( p_aout, &p_input->fifo ); + p_input->b_error = 1; + return -1; + } + /* success */ + p_current_filter->p_filter->b_continuity = VLC_FALSE; + p_input->pp_filters[p_input->i_nb_filters++] = + p_current_filter->p_filter; + + /* Go to next */ + p_current_filter = p_current_filter->p_next; + } + } + +#if 0 + /* Headphone filter add-ons. */ if ( b_use_headphone_filter == VLC_TRUE ) { /* create a vlc object */ @@ -133,7 +310,8 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) p_headphone_filter->b_continuity = VLC_FALSE; p_input->pp_filters[p_input->i_nb_filters++] = p_headphone_filter; } - +#endif + /* Prepare hints for the buffer allocator. */ p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP; p_input->input_alloc.i_bytes_per_sec = -1; @@ -272,6 +450,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, if ( start_date == 0 ) start_date = p_buffer->start_date; /* Run pre-filters. */ + aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters, &p_buffer ); diff --git a/src/libvlc.h b/src/libvlc.h index a879bceba4..1c532265ce 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -2,7 +2,7 @@ * libvlc.h: main libvlc header ***************************************************************************** * Copyright (C) 1998-2002 VideoLAN - * $Id: libvlc.h,v 1.79 2003/08/17 20:58:45 alexis Exp $ + * $Id: libvlc.h,v 1.80 2003/08/18 13:16:43 zorglub Exp $ * * Authors: Vincent Seguin * Samuel Hocevar @@ -139,6 +139,11 @@ static char *ppsz_language[] = { "auto", "en", "en_GB", "de", "fr", "it", "This option allows you to use the S/PDIF audio output by default when " \ "your hardware supports it as well as the audio stream being played.") +#define AUDIO_FILTER_TEXT N_("Audio filters") +#define AUDIO_FILTER_LONGTEXT N_( \ + "This allows you to add audio postprocessing filters, to modify" \ + "the sound.") + #define HEADPHONE_TEXT N_("Headphone virtual spatialization effect") #define HEADPHONE_LONGTEXT N_( \ "This effect gives you the feeling that you are standing in a room " \ @@ -148,6 +153,7 @@ static char *ppsz_language[] = { "auto", "en", "en_GB", "de", "fr", "it", "long periods of time.\nIt works with any source format from mono " \ "to 5.1.") + #define VOUT_TEXT N_("Video output module") #define VOUT_LONGTEXT N_( \ "This option allows you to select the video output method used by VLC. " \ @@ -524,7 +530,9 @@ vlc_module_begin(); add_integer( "desync", 0, NULL, DESYNC_TEXT, DESYNC_LONGTEXT, VLC_TRUE ); add_bool( "spdif", 0, NULL, SPDIF_TEXT, SPDIF_LONGTEXT, VLC_FALSE ); add_bool( "headphone-opt", 0, NULL, HEADPHONE_TEXT, HEADPHONE_LONGTEXT, VLC_FALSE ); - + add_string("audio-filter",0,NULL,AUDIO_FILTER_TEXT, + AUDIO_FILTER_LONGTEXT,VLC_FALSE); + /* Video options */ add_category_hint( N_("Video"), NULL, VLC_FALSE ); add_module_with_short( "vout", 'V', "video output", NULL, NULL,