[Mplayerxp-cvslog] SF.net SVN: mplayerxp:[187] mplayerxp
Brought to you by:
olov
From: <nic...@us...> - 2012-10-21 09:46:22
|
Revision: 187 http://mplayerxp.svn.sourceforge.net/mplayerxp/?rev=187&view=rev Author: nickols_k Date: 2012-10-21 09:46:13 +0000 (Sun, 21 Oct 2012) Log Message: ----------- make libao2 re-enterable Modified Paths: -------------- mplayerxp/cfg-mplayer.h mplayerxp/dec_ahead.c mplayerxp/libao2/ao_alsa9.c mplayerxp/libao2/ao_arts.c mplayerxp/libao2/ao_esd.c mplayerxp/libao2/ao_jack.c mplayerxp/libao2/ao_nas.c mplayerxp/libao2/ao_null.c mplayerxp/libao2/ao_openal.c mplayerxp/libao2/ao_oss.c mplayerxp/libao2/ao_sdl.c mplayerxp/libao2/ao_wav.c mplayerxp/libao2/audio_out.c mplayerxp/libao2/audio_out.h mplayerxp/libao2/audio_out_internal.h mplayerxp/mixer.c mplayerxp/mplayer.c mplayerxp/postproc/af.c mplayerxp/postproc/af_ao2.c Modified: mplayerxp/cfg-mplayer.h =================================================================== --- mplayerxp/cfg-mplayer.h 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/cfg-mplayer.h 2012-10-21 09:46:13 UTC (rev 187) @@ -271,7 +271,6 @@ #ifdef USE_FAKE_MONO {"stereo", &fakemono, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL, "selects type of MP2/MP3 stereo output"}, #endif - {"bs", &ao_data.buffersize, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL, "specifies sound card audio buffer size in bytes. Default: measuring"}, {NULL, NULL, 0, 0, 0, 0, NULL,NULL}, }; Modified: mplayerxp/dec_ahead.c =================================================================== --- mplayerxp/dec_ahead.c 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/dec_ahead.c 2012-10-21 09:46:13 UTC (rev 187) @@ -770,6 +770,7 @@ #define NOTHING_PLAYED (-1.0) #define XP_MIN_TIMESLICE 0.010 /* under Linux on x86 min time_slice = 10 ms */ +extern ao_data_t* ao_data; any_t* audio_play_routine( any_t* arg ) { int xp_id; @@ -778,7 +779,7 @@ struct timespec timeout; float d; int retval; - const float MAX_AUDIO_TIME = (float)ao_get_space() / sh_audio->af_bps + ao_get_delay(); + const float MAX_AUDIO_TIME = (float)ao_get_space(ao_data) / sh_audio->af_bps + ao_get_delay(ao_data); float min_audio_time = MAX_AUDIO_TIME; float min_audio, max_audio; int samples, collect_samples; @@ -861,7 +862,7 @@ } LOCK_AUDIO_PLAY(); - d = ao_get_delay() - min_audio_time; + d = ao_get_delay(ao_data) - min_audio_time; if( !xp_core.in_lseek && d > 0 ) { gettimeofday(&now,NULL); audio_play_timeout.tv_nsec = now.tv_usec * 1000 + d*1000000000l; Modified: mplayerxp/libao2/ao_alsa9.c =================================================================== --- mplayerxp/libao2/ao_alsa9.c 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/libao2/ao_alsa9.c 2012-10-21 09:46:13 UTC (rev 187) @@ -39,19 +39,15 @@ LIBAO_EXTERN(alsa) -typedef struct alsa_pric_s { +typedef struct priv_s { snd_pcm_t* handler; snd_pcm_format_t format; snd_pcm_hw_params_t*hwparams; snd_pcm_sw_params_t*swparams; size_t bytes_per_sample; - int ao_mmap; - int ao_noblock; int first; -}alsa_priv_t; +}priv_t; -static alsa_priv_t alsa = { NULL, 0, NULL, NULL, 0, 0, 0, 1 }; - #define ALSA_DEVICE_SIZE 48 #define BUFFERTIME // else SET_CHUNK_SIZE @@ -123,21 +119,22 @@ } /* to set/get/query special features/parameters */ -static int __FASTCALL__ control(int cmd, long arg) +static int __FASTCALL__ control(ao_data_t* ao,int cmd, long arg) { + priv_t*priv=ao->priv; int rval; switch(cmd) { case AOCONTROL_QUERY_FORMAT: rval=fmt2alsa(arg); - return snd_pcm_hw_params_test_format(alsa.handler, alsa.hwparams,rval)==0? + return snd_pcm_hw_params_test_format(priv->handler, priv->hwparams,rval)==0? CONTROL_TRUE:CONTROL_FALSE; case AOCONTROL_QUERY_CHANNELS: rval=arg; - return snd_pcm_hw_params_test_channels(alsa.handler, alsa.hwparams,rval)==0? + return snd_pcm_hw_params_test_channels(priv->handler, priv->hwparams,rval)==0? CONTROL_TRUE:CONTROL_FALSE; case AOCONTROL_QUERY_RATE: rval=arg; - return snd_pcm_hw_params_test_rate(alsa.handler, alsa.hwparams,rval,0)==0? + return snd_pcm_hw_params_test_rate(priv->handler, priv->hwparams,rval,0)==0? CONTROL_TRUE:CONTROL_FALSE; case AOCONTROL_GET_VOLUME: case AOCONTROL_SET_VOLUME: @@ -157,7 +154,7 @@ long get_vol, set_vol; float calc_vol, diff, f_multi; - if(ao_data.format == AFMT_AC3) return CONTROL_TRUE; + if(ao->format == AFMT_AC3) return CONTROL_TRUE; //allocate simple id snd_mixer_selem_id_alloca(&sid); @@ -297,17 +294,18 @@ snd_pcm_info_free(alsa_info); } - +static int ao_mmap; +static int ao_noblock; static mrl_config_t alsaconf[]={ - { "mmap", &alsa.ao_mmap, MRL_TYPE_BOOL, 0, 1 }, - { "noblock", &alsa.ao_noblock, MRL_TYPE_BOOL, 0, 1 }, + { "mmap", &ao_mmap, MRL_TYPE_BOOL, 0, 1 }, + { "noblock", &ao_noblock, MRL_TYPE_BOOL, 0, 1 }, { NULL, NULL, 0, 0, 0 } }; /* open & setup audio device return: 1=success 0=fail */ -static int __FASTCALL__ init(unsigned flags) +static int __FASTCALL__ init(ao_data_t* ao,unsigned flags) { int err; int cards = -1; @@ -317,8 +315,11 @@ char *alsa_port=NULL; char alsa_device[ALSA_DEVICE_SIZE]; UNUSED(flags); + ao->priv=malloc(sizeof(priv_t)); + priv_t*priv=ao->priv; + priv->first=1; - alsa.handler = NULL; + priv->handler = NULL; alsa_device[0]='\0'; MSG_V("alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); @@ -350,7 +351,7 @@ } if (alsa_device[0] == '\0') { - int tmp_device, tmp_subdevice, err; + int tmp_device, tmp_subdevice; if ((err = snd_pcm_info_malloc(&alsa_info)) < 0) { MSG_ERR("alsa-init: memory allocation error: %s\n", snd_strerror(err)); @@ -377,7 +378,7 @@ MSG_WARN("alsa-init: Testing & bugs are welcome. Found %d cards, use: %s\n",cards+1,alsa_device); //setting modes for block or nonblock-mode int open_mode,block_mode; - if (alsa.ao_noblock) { + if (ao_noblock) { open_mode = SND_PCM_NONBLOCK; block_mode = 1; str_block_mode = "nonblock-mode"; @@ -387,12 +388,12 @@ str_block_mode = "block-mode"; } - if (!alsa.handler) { + if (!priv->handler) { //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC - if ((err = snd_pcm_open(&alsa.handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0) { - if (alsa.ao_noblock) { + if ((err = snd_pcm_open(&priv->handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0) { + if (ao_noblock) { MSG_ERR("alsa-init: open in nonblock-mode failed, trying to open in block-mode\n"); - if ((err = snd_pcm_open(&alsa.handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { + if ((err = snd_pcm_open(&priv->handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { MSG_ERR("alsa-init: playback open error: %s\n", snd_strerror(err)); alsa_device[0]='\0'; return 0; @@ -407,44 +408,45 @@ } } alsa_device[0]='\0'; - if ((err = snd_pcm_nonblock(alsa.handler, block_mode)) < 0) { + if ((err = snd_pcm_nonblock(priv->handler, block_mode)) < 0) { MSG_ERR("alsa-init: error set block-mode %s\n", snd_strerror(err)); } else MSG_V("alsa-init: pcm opend in %s\n", str_block_mode); - snd_pcm_hw_params_malloc(&alsa.hwparams); - snd_pcm_sw_params_malloc(&alsa.swparams); + snd_pcm_hw_params_malloc(&priv->hwparams); + snd_pcm_sw_params_malloc(&priv->swparams); // setting hw-parameters - if ((err = snd_pcm_hw_params_any(alsa.handler, alsa.hwparams)) < 0) + if ((err = snd_pcm_hw_params_any(priv->handler, priv->hwparams)) < 0) { MSG_ERR("alsa-init: unable to get initial parameters: %s\n", snd_strerror(err)); return 0; } MSG_DBG2("snd_pcm_hw_params_any()\n"); - if (alsa.ao_mmap) { + if (ao_mmap) { snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); snd_pcm_access_mask_none(mask); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); - err = snd_pcm_hw_params_set_access_mask(alsa.handler, alsa.hwparams, mask); + err = snd_pcm_hw_params_set_access_mask(priv->handler, priv->hwparams, mask); MSG_ERR("alsa-init: mmap set\n"); } else { - err = snd_pcm_hw_params_set_access(alsa.handler, alsa.hwparams,SND_PCM_ACCESS_RW_INTERLEAVED); + err = snd_pcm_hw_params_set_access(priv->handler, priv->hwparams,SND_PCM_ACCESS_RW_INTERLEAVED); MSG_DBG2("snd_pcm_hw_params_set_access(SND_PCM_ACCESS_RW_INTERLEAVED)\n"); } if (err < 0) { MSG_ERR("alsa-init: unable to set access type: %s\n", snd_strerror(err)); return 0; } - } // end switch alsa.handler (spdif) + } // end switch priv->handler (spdif) return 1; } // end init -static int __FASTCALL__ configure(unsigned rate_hz,unsigned channels,unsigned format) +static int __FASTCALL__ configure(ao_data_t* ao,unsigned rate_hz,unsigned channels,unsigned format) { + priv_t*priv=ao->priv; int err,i; size_t chunk_size=0,chunk_bytes,bits_per_sample,bits_per_frame; snd_pcm_uframes_t dummy; @@ -452,21 +454,21 @@ MSG_V("alsa-conf: requested format: %d Hz, %d channels, %s\n", rate_hz, channels, ao_format_name(format)); - ao_data.samplerate = rate_hz; - ao_data.bps = channels * rate_hz; - ao_data.format = format; - ao_data.channels = channels; - ao_data.outburst = OUTBURST; - //ao_data.buffersize = MAX_OUTBURST; // was 16384 + ao->samplerate = rate_hz; + ao->bps = channels * rate_hz; + ao->format = format; + ao->channels = channels; + ao->outburst = OUTBURST; + //ao->buffersize = MAX_OUTBURST; // was 16384 - alsa.format=fmt2alsa(format); + priv->format=fmt2alsa(format); - switch(alsa.format) { + switch(priv->format) { case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_U16_LE: case SND_PCM_FORMAT_S16_BE: case SND_PCM_FORMAT_U16_BE: - ao_data.bps *= 2; + ao->bps *= 2; break; case SND_PCM_FORMAT_S32_LE: case SND_PCM_FORMAT_S32_BE: @@ -474,13 +476,13 @@ case SND_PCM_FORMAT_U32_BE: case SND_PCM_FORMAT_FLOAT_BE: case SND_PCM_FORMAT_FLOAT_LE: - ao_data.bps *= 4; + ao->bps *= 4; break; case SND_PCM_FORMAT_S24_LE: case SND_PCM_FORMAT_S24_BE: case SND_PCM_FORMAT_U24_LE: case SND_PCM_FORMAT_U24_BE: - ao_data.bps *= 3; + ao->bps *= 3; break; case -1: MSG_ERR("alsa-conf: invalid format (%s) requested - output disabled\n", @@ -489,44 +491,44 @@ default: break; } - alsa.bytes_per_sample = ao_data.bps / ao_data.samplerate; + priv->bytes_per_sample = ao->bps / ao->samplerate; - if ((err = snd_pcm_hw_params_set_format(alsa.handler, alsa.hwparams, - alsa.format)) < 0) { + if ((err = snd_pcm_hw_params_set_format(priv->handler, priv->hwparams, + priv->format)) < 0) { MSG_ERR("alsa-conf: unable to set format(%s): %s\n", - snd_pcm_format_name(alsa.format), + snd_pcm_format_name(priv->format), snd_strerror(err)); MSG_HINT("Please try one of: "); for(i=0;i<SND_PCM_FORMAT_LAST;i++) - if (!(snd_pcm_hw_params_test_format(alsa.handler, alsa.hwparams, i))) + if (!(snd_pcm_hw_params_test_format(priv->handler, priv->hwparams, i))) MSG_HINT("%s ",snd_pcm_format_name(i)); MSG_HINT("\n"); return 0; } - MSG_DBG2("snd_pcm_hw_params_set_format(%i)\n",alsa.format); + MSG_DBG2("snd_pcm_hw_params_set_format(%i)\n",priv->format); - if ((err = snd_pcm_hw_params_set_rate_near(alsa.handler, alsa.hwparams, &ao_data.samplerate, 0)) < 0) { + if ((err = snd_pcm_hw_params_set_rate_near(priv->handler, priv->hwparams, &ao->samplerate, 0)) < 0) { MSG_ERR("alsa-conf: unable to set samplerate %u: %s\n", - ao_data.samplerate, + ao->samplerate, snd_strerror(err)); return 0; } - MSG_DBG2("snd_pcm_hw_params_set_rate_near(%i)\n",ao_data.samplerate); + MSG_DBG2("snd_pcm_hw_params_set_rate_near(%i)\n",ao->samplerate); - if ((err = snd_pcm_hw_params_set_channels(alsa.handler, alsa.hwparams, - ao_data.channels)) < 0) { + if ((err = snd_pcm_hw_params_set_channels(priv->handler, priv->hwparams, + ao->channels)) < 0) { MSG_ERR("alsa-conf: unable to set %u channels: %s\n", - ao_data.channels, + ao->channels, snd_strerror(err)); return 0; } - MSG_DBG2("snd_pcm_hw_params_set_channels(%i)\n",ao_data.channels); + MSG_DBG2("snd_pcm_hw_params_set_channels(%i)\n",ao->channels); #ifdef BUFFERTIME { int dir; unsigned period_time,alsa_buffer_time = 500000; /* buffer time in us */ - if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa.handler, alsa.hwparams, &alsa_buffer_time, &dir)) < 0) { + if ((err = snd_pcm_hw_params_set_buffer_time_near(priv->handler, priv->hwparams, &alsa_buffer_time, &dir)) < 0) { MSG_ERR("alsa-init: unable to set buffer time near: %s\n", snd_strerror(err)); return 0; @@ -534,8 +536,8 @@ MSG_DBG2("snd_pcm_hw_set_buffer_time_near(%i)\n",alsa_buffer_time); period_time = alsa_buffer_time/4; - if ((err = snd_pcm_hw_params_set_period_time_near(alsa.handler, alsa.hwparams, &period_time, &dir)) < 0) { - /* original: alsa_buffer_time/ao_data.bps */ + if ((err = snd_pcm_hw_params_set_period_time_near(priv->handler, priv->hwparams, &period_time, &dir)) < 0) { + /* original: alsa_buffer_time/ao->bps */ MSG_ERR("alsa-init: unable to set period time: %s\n", snd_strerror(err)); return 0; @@ -548,14 +550,14 @@ int dir=0; unsigned period_time=100000; /* period time in us */ snd_pcm_uframes_t size; - if ((err = snd_pcm_hw_params_set_period_time_near(alsa.handler, alsa.hwparams, &period_time, &dir)) < 0) { + if ((err = snd_pcm_hw_params_set_period_time_near(priv->handler, priv->hwparams, &period_time, &dir)) < 0) { MSG_ERR("alsa-init: unable to set period_time: %s\n", snd_strerror(err)); return 0; } MSG_DBG2("snd_pcm_hw_set_period_time(%i)\n",period_time); //get chunksize - if ((err = snd_pcm_hw_params_get_period_size(alsa.hwparams, &size, &dir)) < 0) { + if ((err = snd_pcm_hw_params_get_period_size(priv->hwparams, &size, &dir)) < 0) { MSG_ERR("alsa-init: unable to get period_size: %s\n", snd_strerror(err)); return 0; } @@ -564,15 +566,15 @@ } #endif // gets buffersize for control - if ((err = snd_pcm_hw_params_get_buffer_size(alsa.hwparams,&dummy)) < 0) { + if ((err = snd_pcm_hw_params_get_buffer_size(priv->hwparams,&dummy)) < 0) { MSG_ERR("alsa-conf: unable to get buffersize: %s\n", snd_strerror(err)); return 0; } else { - ao_data.buffersize = dummy * alsa.bytes_per_sample; - MSG_V("alsa-conf: got buffersize=%i\n", ao_data.buffersize); + ao->buffersize = dummy * priv->bytes_per_sample; + MSG_V("alsa-conf: got buffersize=%i\n", ao->buffersize); } MSG_DBG2("snd_pcm_hw_params_get_buffer_size(%i)\n",dummy); - bits_per_sample = snd_pcm_format_physical_width(alsa.format); + bits_per_sample = snd_pcm_format_physical_width(priv->format); MSG_DBG2("%i=snd_pcm_hw_format_pohysical_width()\n",bits_per_sample); bits_per_frame = bits_per_sample * channels; chunk_bytes = chunk_size * bits_per_frame / 8; @@ -580,78 +582,84 @@ MSG_V("alsa-conf: bits per sample (bps)=%i, bits per frame (bpf)=%i, chunk_bytes=%i\n",bits_per_sample,bits_per_frame,chunk_bytes); /* finally install hardware parameters */ - if ((err = snd_pcm_hw_params(alsa.handler, alsa.hwparams)) < 0) { + if ((err = snd_pcm_hw_params(priv->handler, priv->hwparams)) < 0) { MSG_ERR("alsa-conf: unable to set hw-parameters: %s\n", snd_strerror(err)); return 0; } MSG_DBG2("snd_pcm_hw_params()\n"); // setting sw-params (only avail-min) if noblocking mode was choosed - if (alsa.ao_noblock) { - if ((err = snd_pcm_sw_params_current(alsa.handler, alsa.swparams)) < 0) { + if (ao_noblock) { + if ((err = snd_pcm_sw_params_current(priv->handler, priv->swparams)) < 0) { MSG_ERR("alsa-conf: unable to get parameters: %s\n",snd_strerror(err)); return 0; } //set min available frames to consider pcm ready (4) //increased for nonblock-mode should be set dynamically later - if ((err = snd_pcm_sw_params_set_avail_min(alsa.handler, alsa.swparams, 4)) < 0) { + if ((err = snd_pcm_sw_params_set_avail_min(priv->handler, priv->swparams, 4)) < 0) { MSG_ERR("alsa-conf: unable to set avail_min %s\n",snd_strerror(err)); return 0; } - if ((err = snd_pcm_sw_params(alsa.handler, alsa.swparams)) < 0) { + if ((err = snd_pcm_sw_params(priv->handler, priv->swparams)) < 0) { MSG_ERR("alsa-conf: unable to install sw-params\n"); return 0; } }//end swparams - if ((err = snd_pcm_prepare(alsa.handler)) < 0) { + if ((err = snd_pcm_prepare(priv->handler)) < 0) { MSG_ERR("alsa-conf: pcm prepare error: %s\n", snd_strerror(err)); return 0; } // end setting hw-params MSG_V("alsa-conf: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", - ao_data.samplerate, ao_data.channels, alsa.bytes_per_sample, ao_data.buffersize, - snd_pcm_format_description(alsa.format)); + ao->samplerate, ao->channels, priv->bytes_per_sample, ao->buffersize, + snd_pcm_format_description(priv->format)); return 1; } // end configure /* close audio device */ -static void uninit(void) +static void uninit(ao_data_t* ao) { int err; - if(!alsa.handler) { + priv_t*priv=ao->priv; + if(!priv->handler) { MSG_ERR("alsa-uninit: no handler defined!\n"); + free(priv); return; } - if (!alsa.ao_noblock) { - if ((err = snd_pcm_drain(alsa.handler)) < 0) { + if (!ao_noblock) { + if ((err = snd_pcm_drain(priv->handler)) < 0) { MSG_ERR("alsa-uninit: pcm drain error: %s\n", snd_strerror(err)); + free(priv); return; } } - if ((err = snd_pcm_close(alsa.handler)) < 0) { + if ((err = snd_pcm_close(priv->handler)) < 0) { MSG_ERR("alsa-uninit: pcm close error: %s\n", snd_strerror(err)); + free(priv); return; } else { - alsa.handler = NULL; + priv->handler = NULL; MSG_V("alsa-uninit: pcm closed\n"); } - snd_pcm_hw_params_free(alsa.hwparams); - snd_pcm_sw_params_free(alsa.swparams); + snd_pcm_hw_params_free(priv->hwparams); + snd_pcm_sw_params_free(priv->swparams); + free(priv); } -static void audio_pause(void) +static void audio_pause(ao_data_t* ao) { + priv_t*priv=ao->priv; int err; - if (!alsa.ao_noblock) { + if (!ao_noblock) { //drain causes error in nonblock-mode! - if ((err = snd_pcm_drain(alsa.handler)) < 0) { + if ((err = snd_pcm_drain(priv->handler)) < 0) { MSG_ERR("alsa-pause: pcm drain error: %s\n", snd_strerror(err)); return; } @@ -661,26 +669,28 @@ } } -static void audio_resume(void) +static void audio_resume(ao_data_t* ao) { + priv_t*priv=ao->priv; int err; - if ((err = snd_pcm_prepare(alsa.handler)) < 0) { + if ((err = snd_pcm_prepare(priv->handler)) < 0) { MSG_ERR("alsa-resume: pcm prepare error: %s\n", snd_strerror(err)); return; } } /* stop playing and empty buffers (for seeking/pause) */ -static void reset(void) +static void reset(ao_data_t* ao) { + priv_t*priv=ao->priv; int err; - if ((err = snd_pcm_drop(alsa.handler)) < 0) { + if ((err = snd_pcm_drop(priv->handler)) < 0) { MSG_ERR("alsa-reset: pcm drop error: %s\n", snd_strerror(err)); return; } - if ((err = snd_pcm_prepare(alsa.handler)) < 0) { + if ((err = snd_pcm_prepare(priv->handler)) < 0) { MSG_ERR("alsa-reset: pcm prepare error: %s\n", snd_strerror(err)); return; } @@ -714,14 +724,15 @@ #endif /* I/O error handler */ -static int __FASTCALL__ xrun(const char *str_mode) +static int __FASTCALL__ xrun(ao_data_t* ao,const char *str_mode) { + priv_t*priv=ao->priv; int err; snd_pcm_status_t *status; snd_pcm_status_alloca(&status); - if ((err = snd_pcm_status(alsa.handler, status))<0) { + if ((err = snd_pcm_status(priv->handler, status))<0) { MSG_ERR("status error: %s", snd_strerror(err)); return 0; } @@ -736,7 +747,7 @@ diff.tv_sec * 1000 + diff.tv_usec / 1000.0); } - if ((err = snd_pcm_prepare(alsa.handler))<0) { + if ((err = snd_pcm_prepare(priv->handler))<0) { MSG_ERR("xrun: prepare error: %s", snd_strerror(err)); return 0; } @@ -744,16 +755,16 @@ return 1; /* ok, data should be accepted again */ } -static unsigned __FASTCALL__ play_normal(any_t* data, unsigned len); -static unsigned __FASTCALL__ play_mmap(any_t* data, unsigned len); +static unsigned __FASTCALL__ play_normal(ao_data_t* ao,any_t* data, unsigned len); +static unsigned __FASTCALL__ play_mmap(ao_data_t* ao,any_t* data, unsigned len); -static unsigned __FASTCALL__ play(any_t* data, unsigned len, unsigned flags) +static unsigned __FASTCALL__ play(ao_data_t* ao,any_t* data, unsigned len, unsigned flags) { unsigned result; UNUSED(flags); - MSG_DBG2("[ao_alsa] %s playing %i bytes\n",alsa.ao_mmap?"mmap":"normal",len); - if (alsa.ao_mmap) result = play_mmap(data, len); - else result = play_normal(data, len); + MSG_DBG2("[ao_alsa] %s playing %i bytes\n",priv->ao_mmap?"mmap":"normal",len); + if (ao_mmap) result = play_mmap(ao,data, len); + else result = play_normal(ao,data, len); return result; } @@ -764,35 +775,36 @@ thanxs for marius <ma...@ro...> for giving us the light ;) */ -static unsigned __FASTCALL__ play_normal(any_t* data, unsigned len) +static unsigned __FASTCALL__ play_normal(ao_data_t* ao,any_t* data, unsigned len) { - //alsa.bytes_per_sample is always 4 for 2 chn S16_LE - unsigned num_frames = len / alsa.bytes_per_sample; + priv_t*priv=ao->priv; + //priv->bytes_per_sample is always 4 for 2 chn S16_LE + unsigned num_frames = len / priv->bytes_per_sample; char *output_samples = (char *)data; snd_pcm_sframes_t res = 0; //fprintf(stderr,"alsa-play: frames=%i, len=%i\n",num_frames,len); - if (!alsa.handler) { + if (!priv->handler) { MSG_ERR("alsa-play: device configuration error"); return 0; } while (num_frames > 0) { - res = snd_pcm_writei(alsa.handler, (any_t*)output_samples, num_frames); + res = snd_pcm_writei(priv->handler, (any_t*)output_samples, num_frames); if (res == -EAGAIN) { - snd_pcm_wait(alsa.handler, 1000); + snd_pcm_wait(priv->handler, 1000); } else if (res == -EPIPE) { /* underrun */ - if (xrun("play") <= 0) { + if (xrun(ao,"play") <= 0) { MSG_ERR("alsa-play: xrun reset error"); return 0; } } else if (res == -ESTRPIPE) { /* suspend */ MSG_WARN("alsa-play: pcm in suspend mode. trying to resume\n"); - while ((res = snd_pcm_resume(alsa.handler)) == -EAGAIN) sleep(1); + while ((res = snd_pcm_resume(priv->handler)) == -EAGAIN) sleep(1); } else if (res < 0) { MSG_ERR("alsa-play: unknown status, trying to reset soundcard\n"); - if ((res = snd_pcm_prepare(alsa.handler)) < 0) { + if ((res = snd_pcm_prepare(priv->handler)) < 0) { MSG_ERR("alsa-play: snd prepare error"); return 0; break; @@ -800,8 +812,8 @@ } if (res > 0) { - /* output_samples += ao_data.channels * res; */ - output_samples += res * alsa.bytes_per_sample; + /* output_samples += ao->channels * res; */ + output_samples += res * priv->bytes_per_sample; num_frames -= res; } } //end while @@ -817,8 +829,9 @@ * 'An overview of the ALSA API' http://people.debian.org/~joshua/x66.html * and some help by Paul Davis <pb...@op...> */ -static unsigned __FASTCALL__ play_mmap(any_t* data, unsigned len) +static unsigned __FASTCALL__ play_mmap(ao_data_t* ao,any_t* data, unsigned len) { + priv_t*priv=ao->priv; snd_pcm_sframes_t commitres, frames_available; snd_pcm_uframes_t frames_transmit, size, offset; const snd_pcm_channel_area_t *area; @@ -829,75 +842,75 @@ struct pollfd *ufds; int count; - count = snd_pcm_poll_descriptors_count (alsa.handler); + count = snd_pcm_poll_descriptors_count (priv->handler); ufds = malloc(sizeof(struct pollfd) * count); - snd_pcm_poll_descriptors(alsa.handler, ufds, count); + snd_pcm_poll_descriptors(priv->handler, ufds, count); //first wait_for_poll - if (err = (wait_for_poll(alsa.handler, ufds, count) < 0)) { - if (snd_pcm_state(alsa.handler) == SND_PCM_STATE_XRUN || - snd_pcm_state(alsa.handler) == SND_PCM_STATE_SUSPENDED) { + if (err = (wait_for_poll(priv->handler, ufds, count) < 0)) { + if (snd_pcm_state(priv->handler) == SND_PCM_STATE_XRUN || + snd_pcm_state(priv->handler) == SND_PCM_STATE_SUSPENDED) { xrun("play"); } } #endif - outbuffer = alloca(ao_data.buffersize); + outbuffer = alloca(ao->buffersize); //don't trust get_space() ;) - frames_available = snd_pcm_avail_update(alsa.handler) * alsa.bytes_per_sample; - if (frames_available < 0) xrun("play"); + frames_available = snd_pcm_avail_update(priv->handler) * priv->bytes_per_sample; + if (frames_available < 0) xrun(ao,"play"); if (frames_available < 4) { - if (alsa.first) { - alsa.first = 0; - snd_pcm_start(alsa.handler); + if (priv->first) { + priv->first = 0; + snd_pcm_start(priv->handler); } else { //FIXME should break and return 0? - snd_pcm_wait(alsa.handler, -1); - alsa.first = 1; + snd_pcm_wait(priv->handler, -1); + priv->first = 1; } } /* len is simply the available bufferspace got by get_space() - * but real avail_buffer in frames is ab/alsa.bytes_per_sample */ - size = len / alsa.bytes_per_sample; + * but real avail_buffer in frames is ab/priv->bytes_per_sample */ + size = len / priv->bytes_per_sample; //if (verbose) - //printf("len: %i size %i, f_avail %i, bps %i ...\n", len, size, frames_available, alsa.bytes_per_sample); + //printf("len: %i size %i, f_avail %i, bps %i ...\n", len, size, frames_available, priv->bytes_per_sample); frames_transmit = size; /* prepare areas and set sw-pointers * frames_transmit returns the real available buffer-size * sometimes != frames_available cause of ringbuffer 'emulation' */ - snd_pcm_mmap_begin(alsa.handler, &area, &offset, &frames_transmit); + snd_pcm_mmap_begin(priv->handler, &area, &offset, &frames_transmit); /* this is specific to interleaved streams (or non-interleaved * streams with only one channel) */ outbuffer = ((char *) area->addr + (area->first + area->step * offset) / 8); //8 //write data - memcpy(outbuffer, data, (frames_transmit * alsa.bytes_per_sample)); - commitres = snd_pcm_mmap_commit(alsa.handler, offset, frames_transmit); + memcpy(outbuffer, data, (frames_transmit * priv->bytes_per_sample)); + commitres = snd_pcm_mmap_commit(priv->handler, offset, frames_transmit); if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames_transmit) { - if (snd_pcm_state(alsa.handler) == SND_PCM_STATE_XRUN || - snd_pcm_state(alsa.handler) == SND_PCM_STATE_SUSPENDED) { - xrun("play"); + if (snd_pcm_state(priv->handler) == SND_PCM_STATE_XRUN || + snd_pcm_state(priv->handler) == SND_PCM_STATE_SUSPENDED) { + xrun(ao,"play"); } } //if (verbose) //printf("mmap ft: %i, cres: %i\n", frames_transmit, commitres); - /* err = snd_pcm_area_copy(&area, offset, &data, offset, len, alsa.format); */ + /* err = snd_pcm_area_copy(&area, offset, &data, offset, len, priv->format); */ /* if (err < 0) { */ /* printf("area-copy-error\n"); */ /* return 0; */ /* } */ //calculate written frames! - result = commitres * alsa.bytes_per_sample; + result = commitres * priv->bytes_per_sample; /* if (verbose) { */ @@ -926,8 +939,9 @@ GET_SPACE_UNDEFINED }space_status; /* how many byes are free in the buffer */ -static unsigned get_space(void) +static unsigned get_space(ao_data_t* ao) { + priv_t*priv=ao->priv; snd_pcm_status_t *status; int ret,st; space_status e_status=GET_SPACE_UNDEFINED; @@ -939,7 +953,7 @@ return 0; } - if ((ret = snd_pcm_status(alsa.handler, status)) < 0) { + if ((ret = snd_pcm_status(priv->handler, status)) < 0) { MSG_ERR("alsa-space: cannot get pcm status: %s\n", snd_strerror(ret)); return 0; } @@ -950,15 +964,15 @@ case SND_PCM_STATE_PREPARED: if (e_status!=GET_SPACE_OPEN) { e_status = GET_SPACE_PREPARED; - alsa.first = 1; - ret = snd_pcm_status_get_avail(status) * alsa.bytes_per_sample; + priv->first = 1; + ret = snd_pcm_status_get_avail(status) * priv->bytes_per_sample; if (ret == 0) //ugly workaround for hang in mmap-mode ret = 10; break; } case SND_PCM_STATE_RUNNING: - ret = snd_pcm_status_get_avail(status) * alsa.bytes_per_sample; - //avail_frames = snd_pcm_avail_update(alsa.handler) * alsa.bytes_per_sample; + ret = snd_pcm_status_get_avail(status) * priv->bytes_per_sample; + //avail_frames = snd_pcm_avail_update(priv->handler) * priv->bytes_per_sample; if (e_status!=GET_SPACE_OPEN && e_status!=GET_SPACE_PREPARED) e_status = GET_SPACE_RUNNING; break; @@ -968,16 +982,16 @@ ret = 0; break; case SND_PCM_STATE_XRUN: - xrun("space"); + xrun(ao,"space"); e_status = GET_SPACE_XRUN; - alsa.first = 1; + priv->first = 1; ret = 0; break; default: e_status = GET_SPACE_UNDEFINED; - ret = snd_pcm_status_get_avail(status) * alsa.bytes_per_sample; + ret = snd_pcm_status_get_avail(status) * priv->bytes_per_sample; if (ret <= 0) { - xrun("space"); + xrun(ao,"space"); } } @@ -994,9 +1008,10 @@ } /* delay in seconds between first and last sample in buffer */ -static float get_delay(void) +static float get_delay(ao_data_t* ao) { - if (alsa.handler) { + priv_t*priv=ao->priv; + if (priv->handler) { snd_pcm_status_t *status; int r; float ret; @@ -1006,7 +1021,7 @@ return 0; } - if ((ret = snd_pcm_status(alsa.handler, status)) < 0) { + if ((ret = snd_pcm_status(priv->handler, status)) < 0) { MSG_ERR("alsa-delay: cannot get pcm status: %s\n", snd_strerror(ret)); return 0; } @@ -1016,7 +1031,7 @@ case SND_PCM_STATE_PREPARED: case SND_PCM_STATE_RUNNING: r=snd_pcm_status_get_delay(status); - ret = (float)r/(float)ao_data.samplerate; + ret = (float)r/(float)ao->samplerate; break; default: ret = 0; Modified: mplayerxp/libao2/ao_arts.c =================================================================== --- mplayerxp/libao2/ao_arts.c 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/libao2/ao_arts.c 2012-10-21 09:46:13 UTC (rev 187) @@ -34,7 +34,6 @@ #define ARTS_PACKETS 10 /* Number of audio packets */ #define ARTS_PACKET_SIZE_LOG2 11 /* Log2 of audio packet size */ -static arts_stream_t stream; static const ao_info_t info = { @@ -46,16 +45,18 @@ LIBAO_EXTERN(arts) -static int control(int cmd, long arg) +static int control(ao_data_t* ao,int cmd, long arg) { + UNUSED(ao); UNUSED(cmd); UNUSED(arg); return CONTROL_UNKNOWN; } -static int init(unsigned flags) +static int init(ao_data_t* ao,unsigned flags) { int err; + UNUSED(ao); UNUSED(flags); if( (err=arts_init()) ) { @@ -67,8 +68,9 @@ return 1; } -static int __FASTCALL__ configure(unsigned rate,unsigned channels,unsigned format) +static int __FASTCALL__ configure(ao_data_t* ao,unsigned rate,unsigned channels,unsigned format) { + arts_stream_t stream; unsigned frag_spec,samplesize; /* * arts supports 8bit unsigned and 16bit signed sample formats @@ -106,12 +108,13 @@ break; } - ao_data.format = format; - ao_data.channels = channels; - ao_data.samplerate = rate; - ao_data.bps = rate*channels*samplesize; + ao->format = format; + ao->channels = channels; + ao->samplerate = rate; + ao->bps = rate*channels*samplesize; stream=arts_play_stream(rate, samplesize*8, channels, "MPlayerXP"); + ao->priv=stream; if(stream == NULL) { MSG_ERR("[aRts] Can't open stream\n"); @@ -124,43 +127,47 @@ arts_stream_set(stream, ARTS_P_BLOCKING, 1); frag_spec = ARTS_PACKET_SIZE_LOG2 | ARTS_PACKETS << 16; arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec); - ao_data.buffersize = arts_stream_get(stream, ARTS_P_BUFFER_SIZE); + ao->buffersize = arts_stream_get(stream, ARTS_P_BUFFER_SIZE); MSG_INFO("[aRts] Stream opened\n"); - MSG_V("[aRts] buffersize=%u\n",ao_data.buffersize); + MSG_V("[aRts] buffersize=%u\n",ao->buffersize); MSG_V("[aRts] buffersize=%u\n", arts_stream_get(stream, ARTS_P_PACKET_SIZE)); return 1; } -static void uninit(void) +static void uninit(ao_data_t* ao) { - arts_close_stream(stream); - arts_free(); + arts_stream_t stream=ao->priv; + arts_close_stream(stream); + arts_free(); } -static unsigned play(any_t* data,unsigned len,unsigned flags) +static unsigned play(ao_data_t* ao,any_t* data,unsigned len,unsigned flags) { + arts_stream_t stream=ao->priv; UNUSED(flags); return arts_write(stream, data, len); } -static void audio_pause(void) +static void audio_pause(ao_data_t* ao) { + UNUSED(ao); } -static void audio_resume(void) { } +static void audio_resume(ao_data_t* ao) { UNUSED(ao); } +static void reset(ao_data_t* ao) { UNUSED(ao); } -static void reset(void) { } - -static unsigned get_space(void) +static unsigned get_space(ao_data_t* ao) { - return arts_stream_get(stream, ARTS_P_BUFFER_SPACE); + arts_stream_t stream=ao->priv; + return arts_stream_get(stream, ARTS_P_BUFFER_SPACE); } -static float get_delay(void) +static float get_delay(ao_data_t* ao) { - return ((float) (ao_data.buffersize - arts_stream_get(stream, - ARTS_P_BUFFER_SPACE))) / ((float) ao_data.bps); + arts_stream_t stream=ao->priv; + return ((float) (ao->buffersize - arts_stream_get(stream, + ARTS_P_BUFFER_SPACE))) / ((float) ao->bps); } Modified: mplayerxp/libao2/ao_esd.c =================================================================== --- mplayerxp/libao2/ao_esd.c 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/libao2/ao_esd.c 2012-10-21 09:46:13 UTC (rev 187) @@ -36,6 +36,7 @@ #include <sys/time.h> #include <sys/socket.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> @@ -77,7 +78,7 @@ LIBAO_EXTERN(esd) -typedef struct esd_priv_s { +typedef struct priv_s { int fd; int play_fd; esd_server_info_t* svinfo; @@ -86,16 +87,14 @@ unsigned long samples_written; struct timeval play_start; float audio_delay; -}esd_priv_t; +}priv_t; -static esd_priv_t esd = { -1, -1, NULL, 0, 0, 0, { 0, 0 }, 0 }; - - /* * to set/get/query special features/parameters */ -static int control(int cmd, long arg) +static int control(ao_data_t* ao,int cmd, long arg) { + priv_t*priv=ao->priv; esd_player_info_t *esd_pi; esd_info_t *esd_i; time_t now; @@ -111,7 +110,7 @@ } dprintf("esd: get vol\n"); - if ((esd_i = esd_get_all_info(esd.fd)) == NULL) + if ((esd_i = esd_get_all_info(priv->fd)) == NULL) return CONTROL_ERROR; for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) @@ -132,7 +131,7 @@ case AOCONTROL_SET_VOLUME: dprintf("esd: set vol\n"); - if ((esd_i = esd_get_all_info(esd.fd)) == NULL) + if ((esd_i = esd_get_all_info(priv->fd)) == NULL) return CONTROL_ERROR; for (esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) @@ -141,7 +140,7 @@ if (esd_pi != NULL) { ao_control_vol_t *vol = (ao_control_vol_t *)arg; - esd_set_stream_pan(esd.fd, esd_pi->source_id, + esd_set_stream_pan(priv->fd, esd_pi->source_id, vol->left * ESD_VOLUME_BASE / 100, vol->right * ESD_VOLUME_BASE / 100); @@ -161,13 +160,16 @@ * open & setup audio device * return: 1=success 0=fail */ -static int init(unsigned flags) +static int init(ao_data_t* ao,unsigned flags) { + ao->priv=malloc(sizeof(priv_t)); + priv_t*priv=ao->priv; + priv->fd=priv->play_fd=-1; char *server = ao_subdevice; /* NULL for localhost */ UNUSED(flags); - if (esd.fd < 0) { - esd.fd = esd_open_sound(server); - if (esd.fd < 0) { + if (priv->fd < 0) { + priv->fd = esd_open_sound(server); + if (priv->fd < 0) { MSG_ERR("ESD: Can't open sound: %s\n", strerror(errno)); return 0; } @@ -175,8 +177,9 @@ return 1; } -static int configure(unsigned rate_hz,unsigned channels,unsigned format) +static int configure(ao_data_t* ao,unsigned rate_hz,unsigned channels,unsigned format) { + priv_t*priv=ao->priv; char *server = ao_subdevice; /* NULL for localhost */ esd_format_t esd_fmt; int bytes_per_sample; @@ -185,7 +188,7 @@ struct timeval proto_start, proto_end; /* get server info, and measure network latency */ gettimeofday(&proto_start, NULL); - esd.svinfo = esd_get_server_info(esd.fd); + priv->svinfo = esd_get_server_info(priv->fd); if(server) { gettimeofday(&proto_end, NULL); lag_net = (proto_end.tv_sec - proto_start.tv_sec) + @@ -195,9 +198,9 @@ lag_net = 0.0; /* no network lag */ /* - if (esd.svinfo) { + if (priv->svinfo) { mp_msg(MSGT_AO, MSGL_INFO, "AO: [esd] server info:\n"); - esd_print_server_info(esd.svinfo); + esd_print_server_info(priv->svinfo); } */ esd_fmt = ESD_STREAM | ESD_PLAY; @@ -206,20 +209,20 @@ /* let the esd daemon convert sample rate */ #else /* let mplayer's audio filter convert the sample rate */ - if (esd.svinfo != NULL) - rate_hz = esd.svinfo->rate; + if (priv->svinfo != NULL) + rate_hz = priv->svinfo->rate; #endif - ao_data.samplerate = rate_hz; + ao->samplerate = rate_hz; /* EsounD can play mono or stereo */ switch (channels) { case 1: esd_fmt |= ESD_MONO; - ao_data.channels = bytes_per_sample = 1; + ao->channels = bytes_per_sample = 1; break; default: esd_fmt |= ESD_STEREO; - ao_data.channels = bytes_per_sample = 2; + ao->channels = bytes_per_sample = 2; break; } @@ -228,63 +231,63 @@ case AFMT_S8: case AFMT_U8: esd_fmt |= ESD_BITS8; - ao_data.format = AFMT_U8; + ao->format = AFMT_U8; break; default: esd_fmt |= ESD_BITS16; - ao_data.format = AFMT_S16_NE; + ao->format = AFMT_S16_NE; bytes_per_sample *= 2; break; } - /* modify esd.audio_delay depending on esd.latency + /* modify priv->audio_delay depending on priv->latency * latency is number of samples @ 44.1khz stereo 16 bit * adjust according to rate_hz & bytes_per_sample */ #ifdef CONFIG_ESD_LATENCY - esd.latency = esd_get_latency(esd.fd); + priv->latency = esd_get_latency(priv->fd); #else - esd.latency = ((channels == 1 ? 2 : 1) * ESD_DEFAULT_RATE * + priv->latency = ((channels == 1 ? 2 : 1) * ESD_DEFAULT_RATE * (ESD_BUF_SIZE + 64 * (4.0f / bytes_per_sample)) ) / rate_hz; - esd.latency += ESD_BUF_SIZE * 2; + priv->latency += ESD_BUF_SIZE * 2; #endif - if(esd.latency > 0) { - lag_serv = (esd.latency * 4.0f) / (bytes_per_sample * rate_hz); + if(priv->latency > 0) { + lag_serv = (priv->latency * 4.0f) / (bytes_per_sample * rate_hz); lag_seconds = lag_net + lag_serv; - esd.audio_delay += lag_seconds; + priv->audio_delay += lag_seconds; MSG_INFO("ESD: LatencyInfo: %f %f %f\n",lag_serv, lag_net, lag_seconds); } - esd.play_fd = esd_play_stream_fallback(esd_fmt, rate_hz, + priv->play_fd = esd_play_stream_fallback(esd_fmt, rate_hz, server, ESD_CLIENT_NAME); - if (esd.play_fd < 0) { + if (priv->play_fd < 0) { MSG_ERR("ESD: Can't open play stream: %s\n", strerror(errno)); return 0; } /* enable non-blocking i/o on the socket connection to the esd server */ - if ((fl = fcntl(esd.play_fd, F_GETFL)) >= 0) - fcntl(esd.play_fd, F_SETFL, O_NDELAY|fl); + if ((fl = fcntl(priv->play_fd, F_GETFL)) >= 0) + fcntl(priv->play_fd, F_SETFL, O_NDELAY|fl); #if ESD_DEBUG { int sbuf, rbuf, len; len = sizeof(sbuf); - getsockopt(esd.play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len); + getsockopt(priv->play_fd, SOL_SOCKET, SO_SNDBUF, &sbuf, &len); len = sizeof(rbuf); - getsockopt(esd.play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len); + getsockopt(priv->play_fd, SOL_SOCKET, SO_RCVBUF, &rbuf, &len); dprintf("esd: send/receive socket buffer space %d/%d bytes\n", sbuf, rbuf); } #endif - ao_data.bps = bytes_per_sample * rate_hz; - ao_data.outburst = ao_data.bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE; + ao->bps = bytes_per_sample * rate_hz; + ao->outburst = ao->bps > 100000 ? 4*ESD_BUF_SIZE : 2*ESD_BUF_SIZE; - esd.play_start.tv_sec = 0; - esd.samples_written = 0; - esd.bytes_per_sample = bytes_per_sample; + priv->play_start.tv_sec = 0; + priv->samples_written = 0; + priv->bytes_per_sample = bytes_per_sample; return 1; } @@ -293,22 +296,24 @@ /* * close audio device */ -static void uninit(void) +static void uninit(ao_data_t* ao) { - if (esd.play_fd >= 0) { - esd_close(esd.play_fd); - esd.play_fd = -1; + priv_t*priv=ao->priv; + if (priv->play_fd >= 0) { + esd_close(priv->play_fd); + priv->play_fd = -1; } - if (esd.svinfo) { - esd_free_server_info(esd.svinfo); - esd.svinfo = NULL; + if (priv->svinfo) { + esd_free_server_info(priv->svinfo); + priv->svinfo = NULL; } - if (esd.fd >= 0) { - esd_close(esd.fd); - esd.fd = -1; + if (priv->fd >= 0) { + esd_close(priv->fd); + priv->fd = -1; } + free(priv); } @@ -317,8 +322,9 @@ * it should round it down to outburst*n * return: number of bytes played */ -static unsigned play(any_t* data, unsigned len, unsigned flags) +static unsigned play(ao_data_t* ao,any_t* data, unsigned len, unsigned flags) { + priv_t*priv=ao->priv; unsigned offs; unsigned nwritten; int nsamples; @@ -329,14 +335,14 @@ #define SINGLE_WRITE 0 #if SINGLE_WRITE - nwritten = write(esd.play_fd, data, len); + nwritten = write(priv->play_fd, data, len); #else for (offs = 0, nwritten=0; offs + ESD_BUF_SIZE <= len; offs += ESD_BUF_SIZE) { /* * note: we're writing to a non-blocking socket here. * A partial write means, that the socket buffer is full. */ - n = write(esd.play_fd, (char*)data + offs, ESD_BUF_SIZE); + n = write(priv->play_fd, (char*)data + offs, ESD_BUF_SIZE); if ( n < 0 ) { if ( errno != EAGAIN ) { dprintf("esd play: write failed: %s\n", strerror(errno)); @@ -351,14 +357,14 @@ #endif if (nwritten > 0) { - if (!esd.play_start.tv_sec) - gettimeofday(&esd.play_start, NULL); - nsamples = nwritten / esd.bytes_per_sample; - esd.samples_written += nsamples; + if (!priv->play_start.tv_sec) + gettimeofday(&priv->play_start, NULL); + nsamples = nwritten / priv->bytes_per_sample; + priv->samples_written += nsamples; - dprintf("esd play: %d %lu\n", nsamples, esd.samples_written); + dprintf("esd play: %d %lu\n", nsamples, priv->samples_written); } else { - dprintf("esd play: blocked / %lu\n", esd.samples_written); + dprintf("esd play: blocked / %lu\n", priv->samples_written); } return nwritten; @@ -368,41 +374,46 @@ /* * stop playing, keep buffers (for pause) */ -static void audio_pause(void) +static void audio_pause(ao_data_t* ao) { /* - * not possible with esd. the esd daemom will continue playing + * not possible with priv-> the esd daemom will continue playing * buffered data (not more than ESD_MAX_DELAY seconds of samples) */ + UNUSED(ao); } /* * resume playing, after audio_pause() */ -static void audio_resume(void) +static void audio_resume(ao_data_t* ao) { + priv_t*priv=ao->priv; /* - * not possible with esd. + * not possible with priv-> * * Let's hope the pause was long enough that the esd ran out of * buffered data; we restart our time based delay computation * for an audio resume. */ - esd.play_start.tv_sec = 0; - esd.samples_written = 0; + priv->play_start.tv_sec = 0; + priv->samples_written = 0; } /* * stop playing and empty buffers (for seeking/pause) */ -static void reset(void) +static void reset(ao_data_t* ao) { #ifdef __svr4__ + priv_t*priv=ao->priv; /* throw away data buffered in the esd connection */ - if (ioctl(esd.play_fd, I_FLUSH, FLUSHW)) + if (ioctl(priv->play_fd, I_FLUSH, FLUSHW)) perror("I_FLUSH"); +#else + UNUSED(ao); #endif } @@ -410,8 +421,9 @@ /* * return: how many bytes can be played without blocking */ -static unsigned get_space(void) +static unsigned get_space(ao_data_t* ao) { + priv_t*priv=ao->priv; struct timeval tmout; fd_set wfds; float current_delay; @@ -424,24 +436,24 @@ * device, and the consequence is a huge slow down for things like * esd_get_all_info(). */ - if ((current_delay = get_delay()) >= ESD_MAX_DELAY) { + if ((current_delay = get_delay(ao)) >= ESD_MAX_DELAY) { dprintf("esd get_space: too much data buffered\n"); return 0; } FD_ZERO(&wfds); - FD_SET(esd.play_fd, &wfds); + FD_SET(priv->play_fd, &wfds); tmout.tv_sec = 0; tmout.tv_usec = 0; - if (select(esd.play_fd + 1, NULL, &wfds, NULL, &tmout) != 1) + if (select(priv->play_fd + 1, NULL, &wfds, NULL, &tmout) != 1) return 0; - if (!FD_ISSET(esd.play_fd, &wfds)) + if (!FD_ISSET(priv->play_fd, &wfds)) return 0; /* try to fill 50% of the remaining "free" buffer space */ - space = (ESD_MAX_DELAY - current_delay) * ao_data.bps * 0.5f; + space = (ESD_MAX_DELAY - current_delay) * ao->bps * 0.5f; /* round up to next multiple of ESD_BUF_SIZE */ space = (space + ESD_BUF_SIZE-1) / ESD_BUF_SIZE * ESD_BUF_SIZE; @@ -454,26 +466,27 @@ /* * return: delay in seconds between first and last sample in buffer */ -static float get_delay(void) +static float get_delay(ao_data_t* ao) { + priv_t*priv=ao->priv; struct timeval now; double buffered_samples_time; double play_time; - if (!esd.play_start.tv_sec) + if (!priv->play_start.tv_sec) return 0; - buffered_samples_time = (float)esd.samples_written / ao_data.samplerate; + buffered_samples_time = (float)priv->samples_written / ao->samplerate; gettimeofday(&now, NULL); - play_time = now.tv_sec - esd.play_start.tv_sec; - play_time += (now.tv_usec - esd.play_start.tv_usec) / 1000000.; + play_time = now.tv_sec - priv->play_start.tv_sec; + play_time += (now.tv_usec - priv->play_start.tv_usec) / 1000000.; /* dprintf("esd delay: %f %f\n", play_time, buffered_samples_time); */ if (play_time > buffered_samples_time) { dprintf("esd: underflow\n"); - esd.play_start.tv_sec = 0; - esd.samples_written = 0; + priv->play_start.tv_sec = 0; + priv->samples_written = 0; return 0; } Modified: mplayerxp/libao2/ao_jack.c =================================================================== --- mplayerxp/libao2/ao_jack.c 2012-10-20 13:48:57 UTC (rev 186) +++ mplayerxp/libao2/ao_jack.c 2012-10-21 09:46:13 UTC (rev 187) @@ -50,44 +50,43 @@ //! maximum number of channels supported, avoids lots of mallocs #define MAX_CHANS 6 -typedef struct jack_priv_s { +typedef struct priv_s { jack_port_t * ports[MAX_CHANS]; unsigned num_ports; ///< Number of used ports == number of channels jack_client_t * client; float latency; int estimate; -}jack_priv_t; + volatile int paused; ///< set if paused + volatile int underrun; ///< signals if an priv->underrun occured -static jack_priv_t jack; + volatile float callback_interval; + volatile float callback_time; -static volatile int paused = 0; ///< set if paused -static volatile int underrun = 0; ///< signals if an underrun occured + CBFifoBuffer * buffer; //! buffer for audio data +}priv_t; -static volatile float callback_interval = 0; -static volatile float callback_time = 0; //! size of one chunk, if this is too small MPlayer will start to "stutter" //! after a short time of playback #define CHUNK_SIZE (16 * 1024) -//! number of "virtual" chunks the buffer consists of +//! number of "virtual" chunks the priv->buffer consists of #define NUM_CHUNKS 8 #define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE) -//! buffer for audio data -static CBFifoBuffer *buffer; /** - * \brief insert len bytes into buffer + * \brief insert len bytes into priv->buffer * \param data data to insert * \param len length of data - * \return number of bytes inserted into buffer + * \return number of bytes inserted into priv->buffer * - * If there is not enough room, the buffer is filled up + * If there is not enough room, the priv->buffer is filled up */ -static int write_buffer(unsigned char* data, int len) { - int free = cb_fifo_space(buffer); - if (len > free) len = free; - return cb_fifo_generic_write(buffer, data, len, NULL); +static int write_buffer(ao_data_t* ao,unsigned char* data, int len) { + priv_t*priv=ao->priv; + int _free = cb_fifo_space(priv->buffer); + if (len > _free) len = _free; + return cb_fifo_generic_write(priv->buffer, data, len, NULL); } static void silence(float **bufs, int cnt, int num_bufs); @@ -99,8 +98,8 @@ int pos; }; -static void deinterleave(any_t*info, any_t*src, int len) { - struct deinterleave *di = info; +static void deinterleave(any_t*_info, any_t*src, int len) { + struct deinterleave *di = _info; float *s = src; int i; len /= sizeof(float); @@ -114,42 +113,44 @@ } /** - * \brief read data from buffer and splitting it into channels - * \param bufs num_bufs float buffers, each will contain the data of one channel + * \brief read data from priv->buffer and splitting it into channels + * \param bufs num_bufs float priv->buffers, each will contain the data of one channel * \param cnt number of samples to read per channel * \param num_bufs number of channels to split the data into * \return number of samples read per channel, equals cnt unless there was too - * little data in the buffer + * little data in the priv->buffer * - * Assumes the data in the buffer is of type float, the number of bytes + * Assumes the data in the priv->buffer is of type float, the number of bytes * read is res * num_bufs * sizeof(float), where res is the return value. - * If there is not enough data in the buffer remaining parts will be filled + * If there is not enough data in the priv->buffer remaining parts will be filled * with silence. */ -static unsigned read_buffer(float **bufs, unsigned cnt, unsigned num_bufs) { +static unsigned read_buffer(ao_data_t* ao,float **bufs, unsigned cnt, unsigned num_bufs) { + priv_t*priv=ao->priv; struct deinterleave di = {bufs, num_bufs, 0, 0}; - unsigned buffered = cb_fifo_size(buffer); + unsigned buffered = cb_fifo_size(priv->buffer); if (cnt * sizeof(float) * num_bufs > buffered) { silence(bufs, cnt, num_bufs); cnt = buffered / sizeof(float) / num_bufs; } - cb_fifo_generic_read(buffer, &di, cnt * num_bufs * sizeof(float), deinterleave); + cb_fifo_generic_read(priv->buffer, &di, cnt * num_bufs * sizeof(float), deinterleave); return cnt; } -// end ring buffer stuff +// end ring priv->buffer stuff -static int control(int cmd, long arg) { +static int control(ao_data_t* ao,int cmd, long arg) { + UNUSED(ao); UNUSED(cmd); UNUSED(arg); return CONTROL_UNKNOWN; } /** - * \brief fill the buffers with silence - * \param bufs num_bufs float buffers, each will contain the data of one channel - * \param cnt number of samples in each buffer - * \param num_bufs number of buffers + * \brief fill the priv->buffers with silence + * \param bufs num_bufs float priv->buffers, each will contain the data of one channel + * \param cnt number of samples in each priv->buffer + * \param num_bufs number of priv->buffers */ static void silence(float **bufs, int cnt, int num_bufs) { int i; @@ -159,31 +160,31 @@ /** * \brief JACK Callback function - * \param nframes number of frames to fill into buffers + * \param nframes number of frames to fill into priv->buffers * \param arg unused * \return currently always 0 * - * Write silence into buffers if paused or an underrun occured + * Write silence into priv->buffers if priv->paused or an priv->underrun occured */ -static int outputaudio(jack_nframes_t nframes, any_t*arg) { +static int outputaudio(jack_nframes_t nframes, any_t* ao) { + priv_t*priv=((ao_data_t*)ao)->priv; float *bufs[MAX_CHANS]; unsigned i; - UNUSED(arg); - for (i = 0; i < jack.num_ports; i++) - bufs[i] = jack_port_get_buffer(jack.ports[i], nframes); - if (paused || underrun) - silence(bufs, nframes, jack.num_ports); + for (i = 0; i < priv->num_ports; i++) + bufs[i] = jack_port_get_buffer(priv->ports[i], nframes); + if (priv->paused || priv->underrun) + silence(bufs, nframes, priv->num_ports); else - if (read_buffer(bufs, nframes, jack.num_ports) < nframes) - underrun = 1; - if (jack.estimate) { + if (read_buffer(ao,bufs, nframes, priv->num_ports) < nframes) + priv->underrun = 1; + if (priv->estimate) { float now = (float)GetTimer() / 1000000.0; - float diff = callback_time + callback_interval - now; + float diff = priv->callback_time + priv->callback_interval - now; if ((diff > -0.002) && (diff < 0.002)) - callback_time += callback_interval; + priv->callback_time += priv->callback_interval; else - callback_time = now; - callback_interval = (float)nframes / (float)ao_data.samplerate; + priv->callback_time = now; + priv->callback_interval = (float)nframes / (float)((ao_data_t*)ao)->samplerate; } return 0; } @@ -197,22 +198,29 @@ MSG_FATAL( "\n-ao jack commandline help:\n" "Example: mplayer -ao jack:port=myout\n" - " connects MPlayer to the jack jack.ports named myout\n" + " connects MPlayer to the jack priv->ports named myout\n" "\nOptions:\n" " port=<port name>\n" - " Connects to the given jack.ports instead of the default physical ones\n" + " Connects to the given priv->ports instead of the default physical ones\n" " name=<client name>\n" - " jack.client name to pass to JACK\n" - " jack.estimate\n" - " jack.estimates the amount of data in buffers (experimental)\n" + " priv->client name to pass to JACK\n" + " priv->estimate\n" + " priv->estimates the amount of data in priv->buffers (experimental)\n" " autostart\n" " Automatically start JACK server if necessary\n" ); } #endif -static int init(unsigned flags) { UNUSED(flags); return 1; } +static int init(ao_data_t* ao,unsigned flags) { + ao->priv=malloc(sizeof(priv_t)); + priv_t*priv=ao->priv; + memset(priv,0,sizeof(priv_t)); + UNUSED(flags); + return 1; +} -static int configure(unsigned rate,unsigned channels,unsigned format) { +static int configure(ao_data_t* ao,unsigned rate,unsigned channels,unsigned format) { + priv_t*priv=ao->priv; const char **matching_ports = NULL; char *port_name = NULL; char *client_name = NULL; @@ -221,7 +229,7 @@ const opt_t subopts[] = { {"port", OPT_ARG_MSTRZ, &port_name, NULL}, {"name", OPT_ARG_MSTRZ, &client_name, NULL}, - {"jack.estimate", OPT_ARG_BOOL, &jack.estimate, NULL}, + {"priv->estimate", OPT_ARG_BOOL, &priv->estimate, NULL}, {"autostart", OPT_ARG_BOOL, &autostart, NULL}, {NULL} }; @@ -229,7 +237,7 @@ jack_options_t open_options = JackUseExactName; int port_flags = JackPortIsInput; unsigned i; - jack.estimate = 1; + priv->estimate = 1; UNUSED(format); /* if (subopt_parse(ao_subdevice, subopts) != 0) { @@ -247,58 +255,58 @@ } if (!autostart) open_options |= JackNoStartServer; - jack.client = jack_client_open(client_name, open_options, NULL); - if (!jack.client) { + priv->client = jack_client_open(client_name, open_options, NULL); + if (!priv->client) { MSG_FATAL("[JACK] cannot open server\n"); goto err_out; } - buffer = cb_fifo_alloc(BUFFSIZE); - jack_set_process_callback(jack.client, outputaudio, 0); + priv->buffer = cb_fifo_alloc(BUFFSIZE); + jack_set_process_callback(priv->client, outputaudio, ao); - // list matching jack.ports + // list matching priv->ports if (!port_name) port_flags |= JackPortIsPhysical; - matching_ports = jack_get_ports(jack.client, ao_subdevice, NULL, port_flags); + matching_ports = jack_get_ports(priv->client, ao_subdevice, NULL, port_flags); if (!matching_ports || !matching_ports[0]) { - MSG_FATAL("[JACK] no physical jack.ports available\n"); + MSG_FATAL("[JACK] no physical priv->ports available\n"); goto err_out; } i = 1; while (matching_ports[i]) i++; if (channels > i) channels = i; - jack.num_ports = channels; + priv->num_ports = channels; - // create out output jack.ports - for (i = 0; i < jack.num_ports; i++) { + // create out output priv->ports + for (i = 0; i < priv->num_ports; i++) { char pname[30]; snprintf(pname, 30, "out_%d", i); - jack.ports[i] = jack_port_register(jack.client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - if (!jack.ports[i]) { - MSG_FATAL("[JACK] not enough jack.ports available\n"); + priv->ports[i] = jack_port_register(priv->client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + if (!priv->ports[i]) { + MSG_FATAL("[JACK] not enough priv->ports available\n"); goto err_out; } } - if (jack_activate(jack.client)) { + if (jack_activate(priv->client)) { MSG_FATAL("[JACK] activate failed\n"); goto err_out; } - for (i = 0; i < jack.num_ports; i++) { - if (jack_connect(jack.client, jack_port_name(jack.ports[i]), matching_ports[i])) { + for (i = 0; i < priv->num_ports; i++) { + if (jack_connect(priv->client, jack_port_name(priv->ports[i]), matching_ports[i])) { MSG_FATAL( "[JACK] connecting failed\n"); goto err_out; } } - rate = jack_get_sample_rate(jack.client); - jack.latency = (float)(jack_port_get_total_latency(jack.client, jack.ports[0]) + - jack_get_buffer_size(jack.client)) / (float)rate; - callback_interval = 0; + rate = jack_get_sample_rate(priv->client); + priv->latency = (float)(jack_port_get_total_latency(priv->client, priv->ports[0]) + + jack_get_buffer_size(priv->client)) / (float)rate; + priv->callback_interval = 0; - ao_data.channels = channels; - ao_data.samplerate = rate; - ao_data.format = AFMT_FLOAT32; - ao_data.bps = channels * rate * sizeof(float); - ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS; - ao_data.outburst = CHUNK_SIZE; + ao->channels = channels; + ao->samplerate = rate; + ao->format = AFMT_FLOAT32; + ao->bps = channels * rate * sizeof(float); + ao->buffersize = CHUNK_SIZE * NUM_CHUNKS; + ao->outburst = CHUNK_SIZE; free(matching_ports); free(port_name); free(client_name); @@ -308,67 +316,75 @@ free(matching_ports); free(port_name); free(client_name); - if (jack.client) - jack_client_close(jack.client); - cb_fifo_free(buffer); - buffer = NULL; + if (priv->client) + jack_client_close(priv->client); + cb_fifo_free(priv->buffer); + priv->buffer = NULL; return 0; } // close audio device -static void uninit(void) { - // HACK, make sure jack doesn't loop-output dirty buffers - reset(); +static void uninit(ao_data_t* ao) { + priv_t*priv=ao->priv; + // HACK, make sure jack doesn't loop-output dirty priv->buffers + reset(ao); usec_sleep(100 * 1000); - jack_client_close(jack.client); - cb_fifo_free(buffer); - buffer = NULL; + jack_client_close(priv->client); + cb_fifo_free(priv->buffer); + priv->buffer = NULL; + free(priv); } /** - * \brief stop playing and empty buffers (for seeking/pause) + * \brief stop playing and empty priv->buffers (for seeking/pause) */ -static void reset(void) { - paused = 1; - cb_fifo_reset(buffer); - paused = 0; +static void reset(ao_data_t* ao) { + priv_t*priv=ao->priv; + priv->paused = 1; + cb_fifo_reset(priv->buffer); + priv->paused = 0; } /** - * \brief stop playing, keep buffers (for pause) + * \brief stop playing, keep priv->buffers (for pause) */ -static void audio_pause(void) { - paused = 1; +static void audio_pause(ao_data_t* ao) { ... [truncated message content] |