From 54929735f8c480fcbdecb870e97405670acc6ce8 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Sun, 20 Oct 2002 12:23:48 +0000 Subject: [PATCH] * modules/demux/mpeg: Added DVB stream type for A/52 streams (0x6), * include/vlc_threads.h: Avoid locking the interface, * ALL: reworked all audio output plug-ins to correctly take into account i_channels. At present this is known to break OSS, probably others. --- include/aout_internal.h | 4 +- include/audio_output.h | 3 +- include/vlc_threads.h | 4 +- modules/audio_filter/converter/a52tofloat32.c | 5 +- modules/audio_output/alsa.c | 312 +++++++++--------- modules/audio_output/arts.c | 29 +- modules/audio_output/directx.c | 32 +- modules/audio_output/esd.c | 19 +- modules/audio_output/file.c | 7 +- modules/audio_output/oss.c | 234 ++++++++----- modules/audio_output/waveout.c | 34 +- modules/codec/mpeg_video/idct/idctaltivec.c | 4 +- modules/codec/mpeg_video/synchro.c | 8 +- modules/demux/mpeg/system.c | 3 +- modules/demux/mpeg/system.h | 3 +- modules/demux/mpeg/ts.c | 5 +- src/audio_output/common.c | 62 +++- src/audio_output/filters.c | 8 +- src/audio_output/input.c | 6 +- src/audio_output/intf.c | 15 +- src/audio_output/mixer.c | 10 +- src/audio_output/output.c | 17 +- 22 files changed, 502 insertions(+), 322 deletions(-) diff --git a/include/aout_internal.h b/include/aout_internal.h index a1210fbb1a..4dbb532479 100644 --- a/include/aout_internal.h +++ b/include/aout_internal.h @@ -2,7 +2,7 @@ * aout_internal.h : internal defines for audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: aout_internal.h,v 1.22 2002/09/27 23:38:04 massiot Exp $ + * $Id: aout_internal.h,v 1.23 2002/10/20 12:23:47 massiot Exp $ * * Authors: Christophe Massiot * @@ -260,6 +260,8 @@ VLC_EXPORT( aout_buffer_t *, aout_OutputNextBuffer, ( aout_instance_t *, mtime_t /* From common.c : */ VLC_EXPORT( int, aout_FormatNbChannels, ( audio_sample_format_t * p_format ) ); void aout_FormatPrepare( audio_sample_format_t * p_format ); +VLC_EXPORT( void, aout_FormatPrint, ( aout_instance_t * p_aout, const char * psz_text, audio_sample_format_t * p_format ) ); +VLC_EXPORT( void, aout_FormatsPrint, ( aout_instance_t * p_aout, const char * psz_text, audio_sample_format_t * p_format1, audio_sample_format_t * p_format2 ) ); void aout_FifoInit( aout_instance_t *, aout_fifo_t *, u32 ); mtime_t aout_FifoNextStart( aout_instance_t *, aout_fifo_t * ); void aout_FifoPush( aout_instance_t *, aout_fifo_t *, aout_buffer_t * ); diff --git a/include/audio_output.h b/include/audio_output.h index 1f413c4d89..716245c82f 100644 --- a/include/audio_output.h +++ b/include/audio_output.h @@ -2,7 +2,7 @@ * audio_output.h : audio output interface ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: audio_output.h,v 1.68 2002/09/30 21:32:31 massiot Exp $ + * $Id: audio_output.h,v 1.69 2002/10/20 12:23:47 massiot Exp $ * * Authors: Christophe Massiot * @@ -178,4 +178,5 @@ VLC_EXPORT( int, aout_VolumeInfos, ( aout_instance_t *, audio_volume_t * ) ); VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, audio_volume_t * ) ); VLC_EXPORT( int, aout_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) ); VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) ); +VLC_EXPORT( void, aout_FindAndRestart, ( vlc_object_t * p_this ) ); diff --git a/include/vlc_threads.h b/include/vlc_threads.h index 7efab72c3b..88f89ce1f9 100644 --- a/include/vlc_threads.h +++ b/include/vlc_threads.h @@ -3,7 +3,7 @@ * This header provides portable declarations for mutexes & conditions ***************************************************************************** * Copyright (C) 1999, 2002 VideoLAN - * $Id: vlc_threads.h,v 1.14 2002/10/08 22:48:25 massiot Exp $ + * $Id: vlc_threads.h,v 1.15 2002/10/20 12:23:47 massiot Exp $ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -72,7 +72,7 @@ # define VLC_THREAD_PRIORITY_INPUT 37 # define VLC_THREAD_PRIORITY_AUDIO 38 # define VLC_THREAD_PRIORITY_VIDEO 31 -# define VLC_THREAD_PRIORITY_OUTPUT 38 +# define VLC_THREAD_PRIORITY_OUTPUT 31 #elif defined(WIN32) # define VLC_THREAD_PRIORITY_LOW 0 diff --git a/modules/audio_filter/converter/a52tofloat32.c b/modules/audio_filter/converter/a52tofloat32.c index 7b096824c2..dbdacde84c 100644 --- a/modules/audio_filter/converter/a52tofloat32.c +++ b/modules/audio_filter/converter/a52tofloat32.c @@ -4,7 +4,7 @@ * (http://liba52.sf.net/). ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: a52tofloat32.c,v 1.3 2002/09/30 21:32:32 massiot Exp $ + * $Id: a52tofloat32.c,v 1.4 2002/10/20 12:23:47 massiot Exp $ * * Authors: Gildas Bazin * Christophe Massiot @@ -194,7 +194,8 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, { msg_Err( p_filter, "liba52 couldn't do the requested downmix 0x%x->0x%x", - p_sys->i_flags, i_flags ); + p_sys->i_flags & A52_CHANNEL_MASK, + i_flags & A52_CHANNEL_MASK ); memset( p_out_buf->p_buffer, 0, i_bytes_per_block * 6 ); return; } diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c index 4cf8200b3a..c5d1b0e125 100644 --- a/modules/audio_output/alsa.c +++ b/modules/audio_output/alsa.c @@ -2,7 +2,7 @@ * alsa.c : alsa plugin for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: alsa.c,v 1.13 2002/10/05 03:44:50 bozo Exp $ + * $Id: alsa.c,v 1.14 2002/10/20 12:23:47 massiot Exp $ * * Authors: Henri Fallon - Original Author * Jeffrey Baker - Port to ALSA 1.0 API @@ -49,11 +49,8 @@ struct aout_sys_t { snd_pcm_t * p_snd_pcm; - snd_pcm_sframes_t i_buffer_size; int i_period_time; - volatile vlc_bool_t b_can_sleek; - #ifdef DEBUG snd_output_t * p_snd_stderr; #endif @@ -69,6 +66,7 @@ struct aout_sys_t #define ALSA_DEFAULT_BUFFER_SIZE ( ALSA_DEFAULT_PERIOD_SIZE << 4 ) #define ALSA_SPDIF_PERIOD_SIZE A52_FRAME_NB #define ALSA_SPDIF_BUFFER_SIZE ( ALSA_SPDIF_PERIOD_SIZE << 4 ) +/* Why << 4 ? --Meuuh */ /***************************************************************************** * Local prototypes @@ -84,7 +82,8 @@ static void ALSAFill ( aout_instance_t * ); *****************************************************************************/ vlc_module_begin(); add_category_hint( N_("ALSA"), NULL ); - add_string( "alsa-device", NULL, NULL, N_("device name"), NULL ); + add_string( "alsa-device", "default", aout_FindAndRestart, + N_("device name"), NULL ); set_description( _("ALSA audio module") ); set_capability( "audio output", 50 ); set_callbacks( Open, Close ); @@ -99,21 +98,16 @@ static int Open( vlc_object_t *p_this ) { aout_instance_t * p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys; + char * psz_device; + int i_buffer_size; - int i_snd_rc = -1; - - char * psz_device = NULL; - char psz_alsadev[128]; - char * psz_userdev; + snd_pcm_hw_params_t *p_hw; + snd_pcm_sw_params_t *p_sw; - int i_format_tries[2]; - int i_tries_count, i; + int i_snd_rc = -1; int i_format; - int i_channels; - snd_pcm_hw_params_t *p_hw; - snd_pcm_sw_params_t *p_sw; /* Allocate structures */ p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) ); @@ -123,179 +117,180 @@ static int Open( vlc_object_t *p_this ) return -1; } - p_aout->output.pf_play = Play; + /* Get device name */ + if( (psz_device = config_GetPsz( p_aout, "dspdev" )) == NULL ) + { + msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" ); + free( p_sys ); + return VLC_EGENERIC; + } #ifdef DEBUG snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 ); #endif - i_tries_count = 0; - i_format_tries[i_tries_count++] = p_aout->output.output.i_format; - if( i_format_tries[0] == VLC_FOURCC('s','p','d','i') ) + /* Open the device */ + if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) + && !strcmp( "default", psz_device ) ) { - /* Try S/PDIF, and then FLOAT32 */ - i_format_tries[i_tries_count++] = VLC_FOURCC('f','l','3','2'); - } + /* ALSA doesn't understand "default" for S/PDIF. Cheat a little. */ + char psz_iecdev[128]; - /* Read in ALSA device preferences from configuration */ - psz_userdev = config_GetPsz( p_aout, "alsa-device" ); - - for( i = 0 ; ( i_snd_rc < 0 ) && ( i < i_tries_count ) ; ++i ) - { - if( i_format_tries[i] == VLC_FOURCC('s','p','d','i') ) + if ( !strcmp( "default", psz_device ) ) { - if( psz_userdev ) - { - psz_device = psz_userdev; - } - else - { - /* Will probably need some little modification in the case - we want to send some data at a different rate - (32000, 44100 and 48000 are the possibilities) -- bozo */ - unsigned char s[4]; - s[0] = IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO; - s[1] = IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER; - s[2] = 0; - s[3] = IEC958_AES3_CON_FS_48000; - sprintf( psz_alsadev, - "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", - s[0], s[1], s[2], s[3] ); - psz_device = psz_alsadev; - } + snprintf( psz_iecdev, sizeof(psz_iecdev), + "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", + IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO, + IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, + 0, + (p_aout->output.output.i_rate == 48000 ? + IEC958_AES3_CON_FS_48000 : + (p_aout->output.output.i_rate == 44100 ? + IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000)) ); } else { - if( psz_userdev ) - psz_device = psz_userdev; - else - psz_device = "default"; + strncat( psz_iecdev, psz_device, sizeof(psz_iecdev) ); } - /* Open device */ - i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device, - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - } + if ( (i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iecdev, + SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0 ) + { + /* No S/PDIF. */ + msg_Warn( p_aout, "cannot open S/PDIF ALSA device `%s' (%s)", + psz_device, snd_strerror(i_snd_rc) ); + p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2'); + } + else + { + i_buffer_size = ALSA_SPDIF_BUFFER_SIZE; + i_format = SND_PCM_FORMAT_S16_NE; - if( i_snd_rc < 0 ) - { - msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", - psz_device, snd_strerror(i_snd_rc) ); - if( psz_userdev ) - free( psz_userdev ); - p_sys->p_snd_pcm = NULL; - return -1; + p_aout->output.i_nb_samples = ALSA_SPDIF_PERIOD_SIZE; + p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); + p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; + p_aout->output.output.i_frame_length = A52_FRAME_NB; + + aout_VolumeNoneInit( p_aout ); + } } - if( psz_userdev ) - free( psz_userdev ); + if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) + { + if ( (i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device, + SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0 ) + { + msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", + psz_device, snd_strerror(i_snd_rc) ); + free( p_sys ); + free( psz_device ); + return VLC_EGENERIC; + } - p_aout->output.output.i_format = i_format_tries[i - 1]; + if ( p_aout->p_libvlc->i_cpu & CPU_CAPABILITY_FPU ) + { + p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2'); + i_format = SND_PCM_FORMAT_FLOAT; + } + else + { + p_aout->output.output.i_format = AOUT_FMT_S16_NE; + i_format = SND_PCM_FORMAT_S16_NE; + } - /* Default settings */ - p_sys->b_can_sleek = VLC_FALSE; - i_channels = p_aout->output.output.i_channels; - if ( p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i') ) - { - p_sys->i_buffer_size = ALSA_SPDIF_BUFFER_SIZE; - p_aout->output.i_nb_samples = ALSA_SPDIF_PERIOD_SIZE; - aout_VolumeNoneInit( p_aout ); - } - else - { - p_sys->i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE; + i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE; p_aout->output.i_nb_samples = ALSA_DEFAULT_PERIOD_SIZE; + aout_VolumeSoftInit( p_aout ); } - /* Compute the settings */ - switch (p_aout->output.output.i_format) - { - case VLC_FOURCC('f','l','3','2'): - i_format = SND_PCM_FORMAT_FLOAT; - break; - - case VLC_FOURCC('s','p','d','i'): - /* Override some settings to make S/PDIF work */ - p_sys->b_can_sleek = VLC_TRUE; - i_format = SND_PCM_FORMAT_S16_LE; - i_channels = 2; - p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; - p_aout->output.output.i_frame_length = ALSA_SPDIF_PERIOD_SIZE; - break; - default: - msg_Err( p_aout, "audio output format '%.4s' not supported", - &p_aout->output.output.i_format ); - return -1; - break; - } + free( psz_device ); + p_aout->output.pf_play = Play; snd_pcm_hw_params_alloca(&p_hw); snd_pcm_sw_params_alloca(&p_sw); - i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ); - if( i_snd_rc < 0 ) + if ( snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) < 0 ) { msg_Err( p_aout, "unable to retrieve initial hardware parameters" ); - return -1; + goto error; } - i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw, - SND_PCM_ACCESS_RW_INTERLEAVED ); - if( i_snd_rc < 0 ) - { - msg_Err( p_aout, "unable to set interleaved stream format" ); - return -1; - } - - i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw, i_format ); - if( i_snd_rc < 0 ) + /* Set format. */ + if ( snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw, i_format ) < 0 ) { msg_Err( p_aout, "unable to set stream sample size and word order" ); - return -1; + goto error; } - i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw, - i_channels ); - if( i_snd_rc < 0 ) + if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { - msg_Err( p_aout, "unable to set number of output channels" ); - return -1; - } + int i_nb_channels; - i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw, - p_aout->output.output.i_rate, - NULL ); - if( i_snd_rc < 0 ) - { - msg_Err( p_aout, "unable to set sample rate" ); - return -1; + if ( snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw, + SND_PCM_ACCESS_RW_INTERLEAVED ) < 0 ) + { + msg_Err( p_aout, "unable to set interleaved stream format" ); + goto error; + } + + /* Set channels. */ + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + + if ( (i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, + p_hw, i_nb_channels )) < 0 ) + { + msg_Err( p_aout, "unable to set number of output channels" ); + goto error; + } + if ( i_snd_rc != i_nb_channels ) + { + switch ( i_snd_rc ) + { + case 1: p_aout->output.output.i_channels = AOUT_CHAN_MONO; break; + case 2: p_aout->output.output.i_channels = AOUT_CHAN_STEREO; break; + case 4: p_aout->output.output.i_channels = AOUT_CHAN_2F2R; break; + default: + msg_Err( p_aout, "Unsupported downmixing (%d)", i_snd_rc ); + goto error; + } + } + + /* Set rate. */ + if ( (i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, + p_hw, p_aout->output.output.i_rate, + NULL )) < 0 ) + { + msg_Err( p_aout, "unable to set sample rate" ); + goto error; + } + p_aout->output.output.i_rate = i_snd_rc; } - p_aout->output.output.i_rate = i_snd_rc; + /* Set buffer size. */ i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, p_hw, p_sys->i_buffer_size ); if( i_snd_rc < 0 ) { - msg_Err( p_aout, "unable to set buffer time" ); - return -1; + msg_Err( p_aout, "unable to set buffer size" ); + goto error; } - p_sys->i_buffer_size = i_snd_rc; + /* Set period size. */ i_snd_rc = snd_pcm_hw_params_set_period_size_near( - p_sys->p_snd_pcm, p_hw, p_aout->output.i_nb_samples, NULL ); + p_sys->p_snd_pcm, p_hw, p_aout->output.i_nb_samples, NULL ); if( i_snd_rc < 0 ) { msg_Err( p_aout, "unable to set period size" ); - return -1; + goto error; } p_aout->output.i_nb_samples = i_snd_rc; - i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ); - if (i_snd_rc < 0) + /* Write hardware configuration. */ + if ( snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) < 0 ) { msg_Err( p_aout, "unable to set hardware configuration" ); - return -1; + goto error; } p_sys->i_period_time = snd_pcm_hw_params_get_period_time( p_hw, NULL ); @@ -306,11 +301,11 @@ static int Open( vlc_object_t *p_this ) i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw, p_aout->output.i_nb_samples ); - i_snd_rc = snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ); - if( i_snd_rc < 0 ) + /* Write software configuration. */ + if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 ) { msg_Err( p_aout, "unable to set software configuration" ); - return -1; + goto error; } #ifdef DEBUG @@ -326,11 +321,18 @@ static int Open( vlc_object_t *p_this ) VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) ) { msg_Err( p_aout, "cannot create ALSA thread (%s)", strerror(errno) ); - free( p_sys ); - return -1; + goto error; } return 0; + +error: + snd_pcm_close( p_sys->p_snd_pcm ); +#ifdef DEBUG + snd_output_close( p_sys->p_snd_stderr ); +#endif + free( p_sys ); + return VLC_EGENERIC; } /***************************************************************************** @@ -341,7 +343,7 @@ static void Play( aout_instance_t *p_aout ) } /***************************************************************************** - * Close: close the Alsa device + * Close: close the ALSA device *****************************************************************************/ static void Close( vlc_object_t *p_this ) { @@ -352,15 +354,12 @@ static void Close( vlc_object_t *p_this ) p_aout->b_die = 1; vlc_thread_join( p_aout ); - if( p_sys->p_snd_pcm ) - { - i_snd_rc = snd_pcm_close( p_sys->p_snd_pcm ); + i_snd_rc = snd_pcm_close( p_sys->p_snd_pcm ); - if( i_snd_rc > 0 ) - { - msg_Err( p_aout, "failed closing ALSA device (%s)", - snd_strerror( i_snd_rc ) ); - } + if( i_snd_rc > 0 ) + { + msg_Err( p_aout, "failed closing ALSA device (%s)", + snd_strerror( i_snd_rc ) ); } #ifdef DEBUG @@ -383,6 +382,8 @@ static int ALSAThread( aout_instance_t * p_aout ) /* Sleep during less than one period to avoid a lot of buffer underruns */ + + /* Why do we need to sleep ? --Meuuh */ msleep( p_sys->i_period_time >> 2 ); } @@ -409,13 +410,13 @@ static void ALSAFill( aout_instance_t * p_aout ) i_snd_rc = snd_pcm_wait( p_sys->p_snd_pcm, THREAD_SLEEP ); if( i_snd_rc < 0 ) { - msg_Err( p_aout, "alsa device not ready !!! (%s)", + msg_Err( p_aout, "ALSA device not ready !!! (%s)", snd_strerror( i_snd_rc ) ); return; } /* Fill in the buffer until space or audio output buffer shortage */ - while( VLC_TRUE ) + for ( ; ; ) { /* Get the status */ i_snd_rc = snd_pcm_status( p_sys->p_snd_pcm, p_status ); @@ -466,7 +467,8 @@ static void ALSAFill( aout_instance_t * p_aout ) next_date = (mtime_t)ts_next.tv_sec * 1000000 + ts_next.tv_usec; p_buffer = aout_OutputNextBuffer( p_aout, next_date, - p_sys->b_can_sleek ); + (p_aout->output.output.i_format != + VLC_FOURCC('s','p','d','i')) ); /* Audio output buffer shortage -> stop the fill process and wait in ALSAThread */ @@ -481,10 +483,8 @@ static void ALSAFill( aout_instance_t * p_aout ) msg_Err( p_aout, "write failed (%s)", snd_strerror( i_snd_rc ) ); } - else - { - aout_BufferFree( p_buffer ); - } + + aout_BufferFree( p_buffer ); } } } diff --git a/modules/audio_output/arts.c b/modules/audio_output/arts.c index e24c08a955..71b82920d6 100644 --- a/modules/audio_output/arts.c +++ b/modules/audio_output/arts.c @@ -2,7 +2,7 @@ * arts.c : aRts module ***************************************************************************** * Copyright (C) 2001-2002 VideoLAN - * $Id: arts.c,v 1.13 2002/10/04 18:07:21 sam Exp $ + * $Id: arts.c,v 1.14 2002/10/20 12:23:47 massiot Exp $ * * Authors: Emmanuel Blindauer * Samuel Hocevar @@ -77,6 +77,7 @@ static int Open( vlc_object_t *p_this ) aout_instance_t *p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys; int i_err; + int i_nb_channels; /* Allocate structure */ p_sys = malloc( sizeof( aout_sys_t ) ); @@ -99,19 +100,22 @@ static int Open( vlc_object_t *p_this ) p_aout->output.pf_play = Play; aout_VolumeSoftInit( p_aout ); - p_sys->stream = NULL; - - if( p_sys->stream ) + p_aout->output.output.i_format = AOUT_FMT_S16_NE; + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + if ( i_nb_channels > 2 ) { - arts_close_stream( p_sys->stream ); + /* aRts doesn't support more than two channels. */ + i_nb_channels = 2; + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; } /* Open a socket for playing a stream, set format to 16 bits */ p_sys->stream = arts_play_stream( p_aout->output.output.i_rate, 16, - p_aout->output.output.i_channels, "vlc" ); + i_nb_channels, "vlc" ); if( p_sys->stream == NULL ) { msg_Err( p_aout, "cannot open aRts socket" ); + free( p_sys ); return -1; } @@ -128,16 +132,15 @@ static int Open( vlc_object_t *p_this ) arts_stream_get( p_sys->stream, ARTS_P_PACKET_COUNT ), arts_stream_get( p_sys->stream, ARTS_P_PACKET_SIZE ) ); - p_aout->output.output.i_format = AOUT_FMT_S16_NE; - p_aout->output.i_nb_samples = p_sys->i_size - / sizeof(u16) - / p_aout->output.output.i_channels; + p_aout->output.i_nb_samples = p_sys->i_size / sizeof(u16) / i_nb_channels; /* Create aRts thread and wait for its readiness. */ if( vlc_thread_create( p_aout, "aout", aRtsThread, VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) ) { msg_Err( p_aout, "cannot create aRts thread (%s)", strerror(errno) ); + arts_close_stream( p_sys->stream ); + arts_free(); free( p_sys ); return -1; } @@ -164,11 +167,7 @@ static void Close( vlc_object_t *p_this ) p_aout->b_die = 1; vlc_thread_join( p_aout ); - if( p_sys->stream ) - { - arts_close_stream( p_sys->stream ); - } - + arts_close_stream( p_sys->stream ); arts_free(); free( p_sys ); } diff --git a/modules/audio_output/directx.c b/modules/audio_output/directx.c index ad8684eba2..fb3d4262d5 100644 --- a/modules/audio_output/directx.c +++ b/modules/audio_output/directx.c @@ -1,8 +1,8 @@ /***************************************************************************** - * aout.c: Windows DirectX audio output method + * directx.c: Windows DirectX audio output method ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: directx.c,v 1.3 2002/10/11 10:08:06 gbazin Exp $ + * $Id: directx.c,v 1.4 2002/10/20 12:23:47 massiot Exp $ * * Authors: Gildas Bazin * @@ -130,7 +130,7 @@ static int OpenAudio( vlc_object_t *p_this ) if( p_aout->output.p_sys == NULL ) { msg_Err( p_aout, "out of memory" ); - return 1; + return VLC_EGENERIC; } /* Initialize some variables */ @@ -223,7 +223,7 @@ static int OpenAudio( vlc_object_t *p_this ) error: CloseAudio( VLC_OBJECT(p_aout) ); - return 1; + return VLC_EGENERIC; } /***************************************************************************** @@ -269,12 +269,7 @@ static void CloseAudio( vlc_object_t *p_this ) if( p_aout->output.p_sys->hdsound_dll ) FreeLibrary( p_aout->output.p_sys->hdsound_dll ); - /* Close the Output. */ - if ( p_aout->output.p_sys ) - { - free( p_aout->output.p_sys ); - p_aout->output.p_sys = NULL; - } + free( p_aout->output.p_sys ); } /***************************************************************************** @@ -355,14 +350,19 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout ) WAVEFORMATEX waveformat; DSBUFFERDESC dsbdesc; DSBCAPS dsbcaps; + int i_nb_channels; - if( p_aout->output.output.i_channels > 2 ) - p_aout->output.output.i_channels = 2; + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + if ( i_nb_channels > 2 ) + { + i_nb_channels = 2; + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + } /* First set the buffer format */ memset(&waveformat, 0, sizeof(WAVEFORMATEX)); waveformat.wFormatTag = WAVE_FORMAT_PCM; - waveformat.nChannels = p_aout->output.output.i_channels; + waveformat.nChannels = i_nb_channels; waveformat.nSamplesPerSec = p_aout->output.output.i_rate; waveformat.wBitsPerSample = 16; waveformat.nBlockAlign = waveformat.wBitsPerSample / 8 * @@ -377,7 +377,7 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout ) | DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */ | DSBCAPS_GLOBALFOCUS; /* Allows background playing */ dsbdesc.dwBufferBytes = FRAME_SIZE * 2 /* frames*/ * /* buffer size */ - sizeof(s16) * p_aout->output.output.i_channels; + sizeof(s16) * i_nb_channels; dsbdesc.lpwfxFormat = &waveformat; if( IDirectSound_CreateSoundBuffer( p_aout->output.p_sys->p_dsobject, @@ -391,7 +391,7 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout ) /* backup the size of a frame */ p_aout->output.p_sys->p_notif->i_buffer_size = FRAME_SIZE * sizeof(s16) - * p_aout->output.output.i_channels; + * i_nb_channels; memset(&dsbcaps, 0, sizeof(DSBCAPS)); dsbcaps.dwSize = sizeof(DSBCAPS); @@ -439,7 +439,7 @@ static int DirectxCreateSecondaryBuffer( aout_instance_t *p_aout ) IDirectSoundBuffer_Release( p_aout->output.p_sys->p_dsbuffer ); p_aout->output.p_sys->p_dsnotify = NULL; } - return 1; + return VLC_EGENERIC; } /***************************************************************************** diff --git a/modules/audio_output/esd.c b/modules/audio_output/esd.c index 496f1c9f6b..055a1a8d90 100644 --- a/modules/audio_output/esd.c +++ b/modules/audio_output/esd.c @@ -2,7 +2,7 @@ * esd.c : EsounD module ***************************************************************************** * Copyright (C) 2000, 2001 VideoLAN - * $Id: esd.c,v 1.13 2002/09/18 21:21:23 massiot Exp $ + * $Id: esd.c,v 1.14 2002/10/20 12:23:47 massiot Exp $ * * Authors: Samuel Hocevar * @@ -75,6 +75,7 @@ static int Open( vlc_object_t *p_this ) { aout_instance_t *p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys; + int i_nb_channels; /* Allocate structure */ p_sys = malloc( sizeof( aout_sys_t ) ); @@ -93,7 +94,16 @@ static int Open( vlc_object_t *p_this ) p_sys->esd_format = ESD_BITS16 | ESD_STREAM | ESD_PLAY; p_sys->esd_format &= ~ESD_MASK_CHAN; - switch( p_aout->output.output.i_channels ) + p_aout->output.output.i_format = AOUT_FMT_S16_NE; + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + if ( i_nb_channels > 2 ) + { + /* EsounD doesn't support more than two channels. */ + i_nb_channels = 2; + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + } + + switch( i_nb_channels ) { case 1: p_sys->esd_format |= ESD_MONO; @@ -101,8 +111,6 @@ static int Open( vlc_object_t *p_this ) case 2: p_sys->esd_format |= ESD_STEREO; break; - default: - return -1; } /* open a socket for playing a stream @@ -113,10 +121,10 @@ static int Open( vlc_object_t *p_this ) { msg_Err( p_aout, "cannot open esound socket (format 0x%08x at %ld Hz)", p_sys->esd_format, p_aout->output.output.i_rate ); + free( p_sys ); return -1; } - p_aout->output.output.i_format = AOUT_FMT_S16_NE; p_aout->output.i_nb_samples = ESD_BUF_SIZE * 2; /* ESD latency is calculated for 44100 Hz. We don't have any way to get the @@ -135,6 +143,7 @@ static int Open( vlc_object_t *p_this ) VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) ) { msg_Err( p_aout, "cannot create ESD thread (%s)", strerror(errno) ); + close( p_sys->i_fd ); free( p_sys ); return -1; } diff --git a/modules/audio_output/file.c b/modules/audio_output/file.c index 500a0cdef0..83e362871d 100644 --- a/modules/audio_output/file.c +++ b/modules/audio_output/file.c @@ -2,7 +2,7 @@ * file.c : audio output which writes the samples to a file ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: file.c,v 1.12 2002/09/30 21:32:32 massiot Exp $ + * $Id: file.c,v 1.13 2002/10/20 12:23:47 massiot Exp $ * * Authors: Christophe Massiot * @@ -98,7 +98,6 @@ static int Open( vlc_object_t * p_this ) if ( p_file == NULL ) return -1; p_aout->output.pf_play = Play; - aout_VolumeSoftInit( p_aout ); while ( *ppsz_compare != NULL ) { @@ -117,15 +116,17 @@ static int Open( vlc_object_t * p_this ) } p_aout->output.output.i_format = format_int[i]; - if ( p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i') ) + if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { p_aout->output.i_nb_samples = A52_FRAME_NB; p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->output.output.i_frame_length = A52_FRAME_NB; + aout_VolumeNoneInit( p_aout ); } else { p_aout->output.i_nb_samples = FRAME_SIZE; + aout_VolumeSoftInit( p_aout ); } return 0; } diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c index eda9e56c95..9204b1569f 100644 --- a/modules/audio_output/oss.c +++ b/modules/audio_output/oss.c @@ -2,7 +2,7 @@ * oss.c : OSS /dev/dsp module for vlc ***************************************************************************** * Copyright (C) 2000-2002 VideoLAN - * $Id: oss.c,v 1.29 2002/10/02 15:37:58 sigmunau Exp $ + * $Id: oss.c,v 1.30 2002/10/20 12:23:47 massiot Exp $ * * Authors: Michel Kaempf * Samuel Hocevar @@ -64,6 +64,7 @@ struct aout_sys_t int i_fd; }; +/* This must be a power of 2. */ #define FRAME_SIZE 1024 #define FRAME_COUNT 8 #define A52_FRAME_NB 1536 @@ -82,10 +83,11 @@ static int OSSThread ( aout_instance_t * ); *****************************************************************************/ vlc_module_begin(); add_category_hint( N_("OSS"), NULL ); - add_file( "dspdev", "/dev/dsp", NULL, N_("OSS dsp device"), NULL ); + add_file( "dspdev", "/dev/dsp", aout_FindAndRestart, + N_("OSS dsp device"), NULL ); set_description( _("Linux OSS /dev/dsp module") ); set_capability( "audio output", 100 ); - add_shortcut( "dsp" ); + add_shortcut( "oss" ); set_callbacks( Open, Close ); vlc_module_end(); @@ -100,11 +102,6 @@ static int Open( vlc_object_t *p_this ) aout_instance_t * p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys; char * psz_device; - int i_format, i_format_orig; - int i_rate; - int i_frame_size; - int i_fragments; - vlc_bool_t b_stereo; /* Allocate structure */ p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) ); @@ -114,7 +111,7 @@ static int Open( vlc_object_t *p_this ) return VLC_ENOMEM; } - /* Initialize some variables */ + /* Get device name */ if( (psz_device = config_GetPsz( p_aout, "dspdev" )) == NULL ) { msg_Err( p_aout, "no audio device given (maybe /dev/dsp ?)" ); @@ -138,98 +135,187 @@ static int Open( vlc_object_t *p_this ) if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 ) { msg_Err( p_aout, "cannot reset OSS audio device" ); + close( p_sys->i_fd ); + free( p_sys ); return VLC_EGENERIC; } - /* Set the fragment size - * i_fragment = xxxxyyyy where: xxxx is fragtotal - * 1 << yyyy is fragsize */ - i_fragments = 0; - i_frame_size = FRAME_SIZE; - while( i_frame_size >>= 1 ) - { - ++i_fragments; - } - i_fragments |= FRAME_COUNT << 16; - if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFRAGMENT, &i_fragments ) < 0 ) - { - msg_Err( p_aout, "cannot set fragment size (%.8x)", i_fragments ); - return VLC_EGENERIC; - } - /* Set the output format */ - if ( p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i') ) + if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { - i_format = AFMT_AC3; - i_format_orig = AFMT_AC3; - p_aout->output.i_nb_samples = A52_FRAME_NB; - p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; - p_aout->output.output.i_frame_length = A52_FRAME_NB; + int i_format = AFMT_AC3; - aout_VolumeNoneInit( p_aout ); + if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 + || i_format != AFMT_AC3 ) + { + p_aout->output.output.i_format = AOUT_FMT_S16_NE; + } + else + { + p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); + p_aout->output.i_nb_samples = A52_FRAME_NB; + p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; + p_aout->output.output.i_frame_length = A52_FRAME_NB; + + aout_VolumeNoneInit( p_aout ); + } } - else + + if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { + int i_format = AFMT_S16_NE; + int i_frame_size, i_fragments; + int i_rate; + int i_nb_channels; + + if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 ) + { + msg_Err( p_aout, "cannot set audio output format" ); + close( p_sys->i_fd ); + free( p_sys ); + return VLC_EGENERIC; + } + + switch ( i_format ) + { + case AFMT_U8: + p_aout->output.output.i_format = VLC_FOURCC('u','8',' ',' '); + break; + case AFMT_S8: + p_aout->output.output.i_format = VLC_FOURCC('s','8',' ',' '); + break; + case AFMT_U16_LE: + p_aout->output.output.i_format = VLC_FOURCC('u','1','6','l'); + break; + case AFMT_S16_LE: + p_aout->output.output.i_format = VLC_FOURCC('s','1','6','l'); + break; + case AFMT_U16_BE: + p_aout->output.output.i_format = VLC_FOURCC('u','1','6','b'); + break; + case AFMT_S16_BE: + p_aout->output.output.i_format = VLC_FOURCC('s','1','6','b'); + break; + default: + msg_Err( p_aout, "OSS fell back to an unknown format (%d)", + i_format ); + close( p_sys->i_fd ); + free( p_sys ); + return VLC_EGENERIC; + } + p_aout->output.output.i_format = AOUT_FMT_S16_NE; - i_format = AFMT_S16_NE; - i_format_orig = AFMT_S16_NE; p_aout->output.i_nb_samples = FRAME_SIZE; aout_VolumeSoftInit( p_aout ); - } - if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 - || i_format != i_format_orig ) - { - if ( i_format_orig == AFMT_AC3 ) + /* Set the fragment size + * i_fragment = xxxxyyyy where: xxxx is fragtotal + * 1 << yyyy is fragsize */ + i_fragments = 0; + i_frame_size = FRAME_SIZE; + while( i_frame_size >>= 1 ) { - /* Retry with S16 */ - msg_Warn( p_aout, "cannot set audio output format (%i)", i_format_orig ); - p_aout->output.output.i_format = AOUT_FMT_S16_NE; - i_format = AFMT_S16_NE; - i_format_orig = AFMT_S16_NE; - p_aout->output.i_nb_samples = FRAME_SIZE; - if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 - || i_format != i_format_orig ) - { - msg_Err( p_aout, "cannot set audio output format (%i)", - i_format_orig ); - return VLC_EGENERIC; - } + ++i_fragments; } - else + i_fragments |= FRAME_COUNT << 16; + if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFRAGMENT, &i_fragments ) < 0 ) { - msg_Err( p_aout, "cannot set audio output format (%i)", i_format_orig ); - return VLC_EGENERIC; + msg_Warn( p_aout, "cannot set fragment size (%.8x)", i_fragments ); } - } - if ( p_aout->output.output.i_format != VLC_FOURCC('s','p','d','i') ) - { - /* FIXME */ - if ( p_aout->output.output.i_channels > 2 ) + /* These cases are desperate because of the OSS API and A/52 spec. */ + switch ( p_aout->output.output.i_channels ) { - msg_Warn( p_aout, "only two channels are supported at the moment" ); - /* Trigger downmixing */ - p_aout->output.output.i_channels = 2; + case AOUT_CHAN_3F: + case AOUT_CHAN_2F1R: + case AOUT_CHAN_3F1R: + case AOUT_CHAN_STEREO | AOUT_CHAN_LFE: + case AOUT_CHAN_2F1R | AOUT_CHAN_LFE: + case AOUT_CHAN_3F1R | AOUT_CHAN_LFE: + case AOUT_CHAN_DOLBY | AOUT_CHAN_LFE: + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + break; + case AOUT_CHAN_CHANNEL | AOUT_CHAN_LFE: + case AOUT_CHAN_CHANNEL1 | AOUT_CHAN_LFE: + case AOUT_CHAN_CHANNEL2 | AOUT_CHAN_LFE: + case AOUT_CHAN_MONO | AOUT_CHAN_LFE: + case AOUT_CHAN_2F2R | AOUT_CHAN_LFE: + p_aout->output.output.i_channels &= ~AOUT_CHAN_LFE; + break; + case AOUT_CHAN_3F2R: + p_aout->output.output.i_channels = AOUT_CHAN_2F2R; + break; } + /* In a nutshell, possible types : AOUT_CHAN_STEREO (and al.), + AOUT_CHAN_2F2R, AOUT_CHAN_3F1R | AOUT_CHAN_LFE. */ - /* Set the number of channels */ - b_stereo = p_aout->output.output.i_channels - 1; + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + + if ( i_nb_channels > 2 ) + { + /* Check that the device supports this. */ + +#ifdef SNDCTL_DSP_GETCHANNELMASK + int i_chanmask; + if ( ioctl( p_sys->i_fd, SNDCTL_DSP_GETCHANNELMASK, + &i_chanmask ) == 0 ) + { + if ( !(i_chanmask & DSP_BIND_FRONT) ) + { + msg_Err( p_aout, "No front channels ! (%x)", + i_chanmask ); + close( p_sys->i_fd ); + free( p_sys ); + return VLC_EGENERIC; + } + + if ( !(i_chanmask & DSP_BIND_SURR) ) + { + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + i_nb_channels = 2; + } + + if ( p_aout->output.output.i_channels == + (AOUT_CHAN_3F2R | AOUT_CHAN_LFE) + && !(i_chanmask & DSP_BIND_CENTER_LFE) ) + { + p_aout->output.output.i_channels = AOUT_CHAN_2F2R; + i_nb_channels = 4; + } + } + else +#endif + { + /* The driver doesn't support this call, assume it is stereo. */ + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + i_nb_channels = 2; + } + } - if( ioctl( p_sys->i_fd, SNDCTL_DSP_STEREO, &b_stereo ) < 0 ) + /* Set the number of channels */ + if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) < 0 ) { msg_Err( p_aout, "cannot set number of audio channels (%i)", p_aout->output.output.i_channels ); + close( p_sys->i_fd ); + free( p_sys ); return VLC_EGENERIC; } - if ( b_stereo + 1 != p_aout->output.output.i_channels ) + if ( i_nb_channels != aout_FormatNbChannels( &p_aout->output.output ) ) { - msg_Warn( p_aout, "driver forced up/downmixing %li->%li", - p_aout->output.output.i_channels, - b_stereo + 1 ); - p_aout->output.output.i_channels = b_stereo + 1; + switch ( i_nb_channels ) + { + case 1: p_aout->output.output.i_channels = AOUT_CHAN_MONO; break; + case 2: p_aout->output.output.i_channels = AOUT_CHAN_STEREO; break; + case 4: p_aout->output.output.i_channels = AOUT_CHAN_2F2R; break; + default: + msg_Err( p_aout, "Unsupported downmixing (%d)", i_nb_channels ); + close( p_sys->i_fd ); + free( p_sys ); + return VLC_EGENERIC; + } } /* Set the output rate */ @@ -238,13 +324,13 @@ static int Open( vlc_object_t *p_this ) { msg_Err( p_aout, "cannot set audio output rate (%i)", p_aout->output.output.i_rate ); + close( p_sys->i_fd ); + free( p_sys ); return VLC_EGENERIC; } if( i_rate != p_aout->output.output.i_rate ) { - msg_Warn( p_aout, "driver forced resampling %li->%li", - p_aout->output.output.i_rate, i_rate ); p_aout->output.output.i_rate = i_rate; } } diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c index aa3cc920fd..35f7d74f75 100644 --- a/modules/audio_output/waveout.c +++ b/modules/audio_output/waveout.c @@ -2,7 +2,7 @@ * waveout.c : Windows waveOut plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: waveout.c,v 1.8 2002/10/11 10:08:06 gbazin Exp $ + * $Id: waveout.c,v 1.9 2002/10/20 12:23:47 massiot Exp $ * * Authors: Gildas Bazin * @@ -92,6 +92,7 @@ static int Open( vlc_object_t *p_this ) { aout_instance_t *p_aout = (aout_instance_t *)p_this; aout_buffer_t *p_buffer; + int i_nb_channels; /* Allocate structure */ p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) ); @@ -99,44 +100,43 @@ static int Open( vlc_object_t *p_this ) if( p_aout->output.p_sys == NULL ) { msg_Err( p_aout, "out of memory" ); - return 1; + return VLC_EGENERIC; } p_aout->output.pf_play = Play; aout_VolumeSoftInit( p_aout ); - /* FIXME */ - if ( p_aout->output.output.i_channels > 2 ) + i_nb_channels = aout_FormatNbChannels( &p_aout->output.output ); + if ( i_nb_channels > 2 ) { - msg_Warn( p_aout, "only two channels are supported at the moment" ); - /* Trigger downmixing */ - p_aout->output.output.i_channels = 2; + /* Waveout doesn't support more than two channels. */ + i_nb_channels = 2; + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; } /* We need to open the device with default values to be sure it is * available */ - if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, - p_aout->output.output.i_channels, + if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, i_nb_channels, p_aout->output.output.i_rate ) ) { msg_Err( p_aout, "cannot open waveout audio device with output " "rate (%i)", p_aout->output.output.i_rate ); - return 1; + return VLC_EGENERIC; - if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, - p_aout->output.output.i_channels, + if ( OpenWaveOut( p_aout, WAVE_FORMAT_PCM, i_nb_channels, 44100 ) ) { msg_Err( p_aout, "cannot open waveout audio device with output " "rate (44100)" ); - return 1; + return VLC_EGENERIC; } + p_aout->output.output.i_rate = 44100; } waveOutReset( p_aout->output.p_sys->h_waveout ); - /* calculate the frame size in bytes */ + /* Calculate the frame size in bytes */ p_aout->output.p_sys->i_buffer_size = FRAME_SIZE * sizeof(s16) * p_aout->output.p_sys->waveformat.nChannels; /* Allocate silence buffer */ @@ -194,11 +194,7 @@ static void Close( vlc_object_t *p_this ) /* Free silence buffer */ free( p_aout->output.p_sys->p_silence_buffer ); - if( p_aout->output.p_sys != NULL ) - { - free( p_aout->output.p_sys ); - p_aout->output.p_sys = NULL; - } + free( p_aout->output.p_sys ); } /***************************************************************************** diff --git a/modules/codec/mpeg_video/idct/idctaltivec.c b/modules/codec/mpeg_video/idct/idctaltivec.c index ed49f0de1e..4041d61a8b 100644 --- a/modules/codec/mpeg_video/idct/idctaltivec.c +++ b/modules/codec/mpeg_video/idct/idctaltivec.c @@ -2,9 +2,9 @@ * idctaltivec.c : AltiVec IDCT module ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: idctaltivec.c,v 1.1 2002/08/04 17:23:42 sam Exp $ + * $Id: idctaltivec.c,v 1.2 2002/10/20 12:23:47 massiot Exp $ * - * Authors: Christophe Massiot + * Authors: Michel Lespinasse * * 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 diff --git a/modules/codec/mpeg_video/synchro.c b/modules/codec/mpeg_video/synchro.c index 71e4e51f6a..402e6c488d 100644 --- a/modules/codec/mpeg_video/synchro.c +++ b/modules/codec/mpeg_video/synchro.c @@ -2,7 +2,7 @@ * vpar_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: synchro.c,v 1.2 2002/08/04 18:39:41 sam Exp $ + * $Id: synchro.c,v 1.3 2002/10/20 12:23:47 massiot Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -377,9 +377,9 @@ void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type, if( p_vpar->synchro.i_eta_p && p_vpar->synchro.i_eta_p != p_vpar->synchro.i_n_p ) { - msg_Warn( p_vpar->p_fifo, - "stream periodicity changed from P[%d] to P[%d]", - p_vpar->synchro.i_n_p, p_vpar->synchro.i_eta_p ); + msg_Dbg( p_vpar->p_fifo, + "stream periodicity changed from P[%d] to P[%d]", + p_vpar->synchro.i_n_p, p_vpar->synchro.i_eta_p ); p_vpar->synchro.i_n_p = p_vpar->synchro.i_eta_p; } p_vpar->synchro.i_eta_p = p_vpar->synchro.i_eta_b = 0; diff --git a/modules/demux/mpeg/system.c b/modules/demux/mpeg/system.c index 107094b15e..dd8f963f42 100644 --- a/modules/demux/mpeg/system.c +++ b/modules/demux/mpeg/system.c @@ -2,7 +2,7 @@ * system.c: helper module for TS, PS and PES management ***************************************************************************** * Copyright (C) 1998-2002 VideoLAN - * $Id: system.c,v 1.5 2002/10/03 21:45:16 massiot Exp $ + * $Id: system.c,v 1.6 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * Michel Lespinasse @@ -654,6 +654,7 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) p_es->i_cat = AUDIO_ES; break; case A52_AUDIO_ES: + case A52DVB_AUDIO_ES: p_es->i_fourcc = VLC_FOURCC('a','5','2','b'); p_es->i_cat = AUDIO_ES; break; diff --git a/modules/demux/mpeg/system.h b/modules/demux/mpeg/system.h index 11e152461e..d9f3af9ef4 100644 --- a/modules/demux/mpeg/system.h +++ b/modules/demux/mpeg/system.h @@ -2,7 +2,7 @@ * system.h: MPEG demultiplexing. ***************************************************************************** * Copyright (C) 1999-2002 VideoLAN - * $Id: system.h,v 1.2 2002/08/30 22:22:24 massiot Exp $ + * $Id: system.h,v 1.3 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -46,6 +46,7 @@ #define MPEG2_VIDEO_ES 0x02 #define MPEG1_AUDIO_ES 0x03 #define MPEG2_AUDIO_ES 0x04 +#define A52DVB_AUDIO_ES 0x06 #define A52_AUDIO_ES 0x81 /* These ones might violate the usage : */ #define DVD_SPU_ES 0x82 diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c index 83a541d397..ba1b59194e 100644 --- a/modules/demux/mpeg/ts.c +++ b/modules/demux/mpeg/ts.c @@ -2,7 +2,7 @@ * mpeg_ts.c : Transport Stream input module for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: ts.c,v 1.7 2002/10/12 21:31:56 gbazin Exp $ + * $Id: ts.c,v 1.8 2002/10/20 12:23:48 massiot Exp $ * * Authors: Henri Fallon * Johan Bilien @@ -638,6 +638,7 @@ static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es ) p_new_es->i_cat = AUDIO_ES; break; case A52_AUDIO_ES: + case A52DVB_AUDIO_ES: if ( !b_vls_compat ) p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' '); else @@ -903,6 +904,7 @@ void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt ) p_new_es->i_cat = AUDIO_ES; break; case A52_AUDIO_ES: + case A52DVB_AUDIO_ES: if ( !b_vls_compat ) p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' '); else @@ -994,6 +996,7 @@ void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt ) strcat( p_new_es->psz_desc, " (lpcm)" ); break; case A52_AUDIO_ES: + case A52DVB_AUDIO_ES: case A52B_AUDIO_ES: strcat( p_new_es->psz_desc, " (A52)" ); break; diff --git a/src/audio_output/common.c b/src/audio_output/common.c index 4043eb21df..e3d8afef79 100644 --- a/src/audio_output/common.c +++ b/src/audio_output/common.c @@ -2,7 +2,7 @@ * common.c : audio output management of common data structures ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: common.c,v 1.2 2002/09/30 21:32:33 massiot Exp $ + * $Id: common.c,v 1.3 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -166,6 +166,66 @@ void aout_FormatPrepare( audio_sample_format_t * p_format ) p_format->i_frame_length = 1; } +/***************************************************************************** + * FormatPrintChannels : print a channel in a human-readable form + *****************************************************************************/ +static const char * FormatPrintChannels( int i_channels ) +{ + switch ( i_channels ) + { + case AOUT_CHAN_CHANNEL: return "CHANNEL"; + case AOUT_CHAN_CHANNEL1: return "CHANNEL1"; + case AOUT_CHAN_CHANNEL2: return "CHANNEL2"; + case AOUT_CHAN_MONO: return "MONO"; + case AOUT_CHAN_STEREO: return "STEREO"; + case AOUT_CHAN_3F: return "3F"; + case AOUT_CHAN_2F1R: return "2F1R"; + case AOUT_CHAN_3F1R: return "3F1R"; + case AOUT_CHAN_2F2R: return "2F2R"; + case AOUT_CHAN_3F2R: return "3F2R"; + case AOUT_CHAN_DOLBY: return "DOLBY"; + case AOUT_CHAN_CHANNEL | AOUT_CHAN_LFE: return "CHANNEL|LFE"; + case AOUT_CHAN_CHANNEL1 | AOUT_CHAN_LFE: return "CHANNEL1|LFE"; + case AOUT_CHAN_CHANNEL2 | AOUT_CHAN_LFE: return "CHANNEL2|LFE"; + case AOUT_CHAN_MONO | AOUT_CHAN_LFE: return "MONO|LFE"; + case AOUT_CHAN_STEREO | AOUT_CHAN_LFE: return "STEREO|LFE"; + case AOUT_CHAN_3F | AOUT_CHAN_LFE: return "3F|LFE"; + case AOUT_CHAN_2F1R | AOUT_CHAN_LFE: return "2F1R|LFE"; + case AOUT_CHAN_3F1R | AOUT_CHAN_LFE: return "3F1R|LFE"; + case AOUT_CHAN_2F2R | AOUT_CHAN_LFE: return "2F2R|LFE"; + case AOUT_CHAN_3F2R | AOUT_CHAN_LFE: return "3F2R|LFE"; + case AOUT_CHAN_DOLBY | AOUT_CHAN_LFE: return "DOLBY|LFE"; + } + + return "ERROR"; +} + +/***************************************************************************** + * aout_FormatPrint : print a format in a human-readable form + *****************************************************************************/ +void aout_FormatPrint( aout_instance_t * p_aout, const char * psz_text, + audio_sample_format_t * p_format ) +{ + msg_Dbg( p_aout, "%s format='%4.4s' rate=%d channels=%s", psz_text, + (char *)&p_format->i_format, p_format->i_rate, + FormatPrintChannels( p_format->i_channels ) ); +} + +/***************************************************************************** + * aout_FormatsPrint : print two formats in a human-readable form + *****************************************************************************/ +void aout_FormatsPrint( aout_instance_t * p_aout, const char * psz_text, + audio_sample_format_t * p_format1, + audio_sample_format_t * p_format2 ) +{ + msg_Dbg( p_aout, "%s format='%4.4s'->'%4.4s' rate=%d->%d channels=%s->%s", + psz_text, + (char *)&p_format1->i_format, (char *)&p_format2->i_format, + p_format1->i_rate, p_format2->i_rate, + FormatPrintChannels( p_format1->i_channels ), + FormatPrintChannels( p_format2->i_channels ) ); +} + /* * FIFO management (internal) - please understand that solving race conditions diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c index 930fd8533e..382ca6a2f8 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.11 2002/09/30 21:32:33 massiot Exp $ + * $Id: filters.c,v 1.12 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -128,11 +128,7 @@ int aout_FiltersCreatePipeline( aout_instance_t * p_aout, return 0; } - msg_Dbg( p_aout, "filter(s) format=%4.4s->%4.4s rate=%d->%d channels=%d->%d", - (char *)&p_input_format->i_format, - (char *)&p_output_format->i_format, - p_input_format->i_rate, p_output_format->i_rate, - p_input_format->i_channels, p_output_format->i_channels ); + aout_FormatsPrint( p_aout, "filter(s)", p_input_format, p_output_format ); /* Try to find a filter to do the whole conversion. */ pp_filters[0] = FindFilter( p_aout, p_input_format, p_output_format ); diff --git a/src/audio_output/input.c b/src/audio_output/input.c index ac4ff722a6..6f6af6b9f7 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.16 2002/10/09 22:54:22 massiot Exp $ + * $Id: input.c,v 1.17 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -43,6 +43,8 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) { audio_sample_format_t intermediate_format; + aout_FormatPrint( p_aout, "input", &p_input->input ); + /* Prepare FIFO. */ aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate ); p_input->p_first_byte_to_mix = NULL; @@ -162,7 +164,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, * pauses the stream (or if the decoder is buggy, which cannot * happen :). */ msg_Warn( p_aout, "computed PTS is out of range (%lld), clearing out", - start_date ); + mdate() - start_date ); vlc_mutex_lock( &p_aout->input_fifos_lock ); aout_FifoSet( p_aout, &p_input->fifo, 0 ); vlc_mutex_unlock( &p_aout->input_fifos_lock ); diff --git a/src/audio_output/intf.c b/src/audio_output/intf.c index 17e59ba268..c5fcd43aa4 100644 --- a/src/audio_output/intf.c +++ b/src/audio_output/intf.c @@ -2,7 +2,7 @@ * intf.c : audio output API towards the interface modules ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: intf.c,v 1.4 2002/09/26 22:40:25 massiot Exp $ + * $Id: intf.c,v 1.5 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -355,3 +355,16 @@ int aout_Restart( aout_instance_t * p_aout ) return b_error; } +/***************************************************************************** + * aout_FindAndRestart : find the audio output instance and restart + *****************************************************************************/ +void aout_FindAndRestart( vlc_object_t * p_this ) +{ + aout_instance_t * p_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, + FIND_ANYWHERE ); + + if ( p_aout == NULL ) return; + + aout_Restart( p_aout ); + vlc_object_release( p_aout ); +} diff --git a/src/audio_output/mixer.c b/src/audio_output/mixer.c index 4e990045b9..8d183e8863 100644 --- a/src/audio_output/mixer.c +++ b/src/audio_output/mixer.c @@ -2,7 +2,7 @@ * mixer.c : audio output mixing operations ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: mixer.c,v 1.17 2002/09/28 13:05:16 massiot Exp $ + * $Id: mixer.c,v 1.18 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -136,6 +136,14 @@ static int MixBuffer( aout_instance_t * p_aout ) if ( p_input->b_error ) continue; p_buffer = p_fifo->p_first; + while ( p_buffer != NULL && p_buffer->start_date < mdate() ) + { + msg_Warn( p_aout, "input PTS is out of range (%lld), trashing", + mdate() - p_buffer->start_date ); + aout_BufferFree( aout_FifoPop( p_aout, p_fifo ) ); + p_buffer = p_fifo->p_first; + } + if ( p_buffer == NULL ) { break; diff --git a/src/audio_output/output.c b/src/audio_output/output.c index f7e6e03e69..058aa503d0 100644 --- a/src/audio_output/output.c +++ b/src/audio_output/output.c @@ -2,7 +2,7 @@ * output.c : internal management of output streams for the audio output ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: output.c,v 1.17 2002/10/03 18:56:09 sam Exp $ + * $Id: output.c,v 1.18 2002/10/20 12:23:48 massiot Exp $ * * Authors: Christophe Massiot * @@ -59,6 +59,12 @@ int aout_OutputNew( aout_instance_t * p_aout, = (p_aout->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) ? VLC_FOURCC('f','l','3','2') : VLC_FOURCC('f','i','3','2'); + + if ( p_aout->output.output.i_channels == AOUT_CHAN_DOLBY ) + { + /* Do not do Dolby surround unless the user requests it. */ + p_aout->output.output.i_channels = AOUT_CHAN_STEREO; + } } aout_FormatPrepare( &p_aout->output.output ); @@ -81,10 +87,7 @@ int aout_OutputNew( aout_instance_t * p_aout, vlc_mutex_unlock( &p_aout->output_fifo_lock ); - msg_Dbg( p_aout, "output format=%4.4s rate=%d channels=%d", - (char *)&p_aout->output.output.i_format, - p_aout->output.output.i_rate, - p_aout->output.output.i_channels ); + aout_FormatPrint( p_aout, "output", &p_aout->output.output ); /* Calculate the resulting mixer output format. */ memcpy( &p_aout->mixer.mixer, &p_aout->output.output, @@ -103,9 +106,7 @@ int aout_OutputNew( aout_instance_t * p_aout, p_aout->mixer.mixer.i_format = p_format->i_format; } - msg_Dbg( p_aout, "mixer format=%4.4s rate=%d channels=%d", - (char *)&p_aout->mixer.mixer.i_format, p_aout->mixer.mixer.i_rate, - p_aout->mixer.mixer.i_channels ); + aout_FormatPrint( p_aout, "mixer", &p_aout->output.output ); /* Create filters. */ if ( aout_FiltersCreatePipeline( p_aout, p_aout->output.pp_filters, -- 2.39.5