X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Foss.c;h=ba9befc42b08084f462b9a63ee86c71b9d3ce09a;hb=5a13b475ceef886157d0d87decab17a3b0e354f8;hp=9c348b83e58c13f70e9c90f3ca6b1c3a4e50d910;hpb=f22f4ef52e0bf8f7a6c7354881c455b08fb3a85f;p=vlc diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c index 9c348b83e5..ba9befc42b 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.39 2002/12/18 14:17:09 sam Exp $ + * $Id: oss.c,v 1.52 2003/02/20 01:52:45 sigmunau Exp $ * * Authors: Michel Kaempf * Samuel Hocevar @@ -12,7 +12,7 @@ * 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 @@ -53,6 +53,20 @@ # include #endif +/* Patches for ignorant OSS versions */ +#ifndef AFMT_AC3 +# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */ +#endif + +#ifndef AFMT_S16_NE +# ifdef WORDS_BIGENDIAN +# define AFMT_S16_NE AFMT_S16_BE +# else +# define AFMT_S16_NE AFMT_S16_LE +# endif +#endif + + /***************************************************************************** * aout_sys_t: OSS audio output method descriptor ***************************************************************************** @@ -85,17 +99,24 @@ static mtime_t BufferDuration( aout_instance_t * p_aout ); /***************************************************************************** * Module descriptor *****************************************************************************/ -#define BUGGY_TEXT N_("Try to work around buggy OSS drivers") +#define BUGGY_TEXT N_("try to work around buggy OSS drivers") #define BUGGY_LONGTEXT N_( \ "Some buggy OSS drivers just don't like when their internal buffers " \ "are completely filled (the sound gets heavily hashed). If you have one " \ "of these drivers, then you need to enable this option." ) +#define SPDIF_TEXT N_("try to use S/PDIF output") +#define SPDIF_LONGTEXT N_( \ + "Sometimes we attempt to use the S/PDIF output, even if nothing is " \ + "connected to it. Un-checking this option disables this behaviour, " \ + "and permanently selects analog PCM output." ) + vlc_module_begin(); - add_category_hint( N_("OSS"), NULL ); + add_category_hint( N_("OSS"), NULL, VLC_FALSE ); add_file( "dspdev", "/dev/dsp", aout_FindAndRestart, - N_("OSS dsp device"), NULL ); - add_bool( "oss-buggy", 0, NULL, BUGGY_TEXT, BUGGY_LONGTEXT ); + N_("OSS dsp device"), NULL, VLC_FALSE ); + add_bool( "oss-buggy", 0, NULL, BUGGY_TEXT, BUGGY_LONGTEXT, VLC_TRUE ); + add_bool( "spdif", 1, NULL, SPDIF_TEXT, SPDIF_LONGTEXT, VLC_FALSE ); set_description( _("Linux OSS /dev/dsp module") ); set_capability( "audio output", 100 ); add_shortcut( "oss" ); @@ -120,14 +141,15 @@ static void Probe( aout_instance_t * p_aout ) return; } - if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) + if ( config_GetInt( p_aout, "spdif" ) + && AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { i_format = AFMT_AC3; if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) >= 0 && i_format == AFMT_AC3 ) { - val.psz_string = N_("S/PDIF"); + val.psz_string = N_("A/52 over S/PDIF"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val ); } } @@ -199,15 +221,20 @@ static void Probe( aout_instance_t * p_aout ) /* Test for mono. */ i_nb_channels = 1; - if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) >= 0 + if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) >= 0 && i_nb_channels == 1 ) { val.psz_string = N_("Mono"); - var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val ); + var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val ); + if ( p_aout->output.output.i_physical_channels == AOUT_CHAN_CENTER ) + { + var_Set( p_aout, "audio-device", val ); + } } - val.b_bool = VLC_TRUE; - var_Set( p_aout, "intf-change", val ); + + var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, + NULL ); } /***************************************************************************** @@ -240,8 +267,7 @@ static int Open( vlc_object_t *p_this ) } /* Open the sound device */ - p_sys->i_fd = open( psz_device, O_WRONLY ); - free( psz_device ); + p_sys->i_fd = open( psz_device, O_WRONLY | O_NDELAY ); if( p_sys->i_fd < 0 ) { msg_Err( p_aout, "cannot open audio device (%s)", psz_device ); @@ -249,6 +275,12 @@ static int Open( vlc_object_t *p_this ) return VLC_EGENERIC; } + /* if the opening was ok, put the device back in blocking mode */ + fcntl( p_sys->i_fd, F_SETFL, + fcntl( p_sys->i_fd, F_GETFL ) &~ FNDELAY ); + + free( psz_device ); + p_aout->output.pf_play = Play; if ( var_Type( p_aout, "audio-device" ) == 0 ) @@ -263,7 +295,7 @@ static int Open( vlc_object_t *p_this ) return VLC_EGENERIC; } - if ( !strcmp( val.psz_string, N_("S/PDIF") ) ) + if ( !strcmp( val.psz_string, N_("A/52 over S/PDIF") ) ) { p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); } @@ -282,19 +314,31 @@ static int Open( vlc_object_t *p_this ) = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT; } - else if ( !strcmp( val.psz_string, "Stereo" ) ) + else if ( !strcmp( val.psz_string, N_("Stereo") ) ) { p_aout->output.output.i_format = AOUT_FMT_S16_NE; p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } - else if ( !strcmp( val.psz_string, "Mono" ) ) + else if ( !strcmp( val.psz_string, N_("Mono") ) ) { p_aout->output.output.i_format = AOUT_FMT_S16_NE; p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER; } + else + { + /* This should not happen ! */ + msg_Err( p_aout, "internal: can't find audio-device (%s)", + val.psz_string ); + free( p_sys ); + free( val.psz_string ); + return VLC_EGENERIC; + } free( val.psz_string ); + val.b_bool = VLC_TRUE; + var_Set( p_aout, "intf-change", val ); + /* Reset the DSP device */ if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 ) { @@ -575,7 +619,7 @@ static int OSSThread( aout_instance_t * p_aout ) msleep( delay / 2 ); } } - + while( !p_aout->b_die && ! ( p_buffer = aout_OutputNextBuffer( p_aout, next_date, VLC_TRUE ) ) ) {