[vlc-devel] [PATCH] Clean the played waveout frames in Play and Stop
Rémi Denis-Courmont
remi at remlab.net
Sat Dec 29 17:25:59 CET 2012
On Sat, 29 Dec 2012 16:38:50 +0100, Denis Charmet <typx at dinauz.org> wrote:
> @@ -409,12 +418,16 @@ static void Probe( audio_output_t * p_aout, const
> audio_sample_format_t *fmt
>
*****************************************************************************/
> static void Play( audio_output_t *p_aout, block_t *block )
> {
> - WAVEHDR * p_waveheader = (WAVEHDR *) malloc(sizeof(WAVEHDR));
> + struct lkwavehdr * p_waveheader =
> + (struct lkwavehdr *) malloc(sizeof(struct lkwavehdr));
> if(!p_waveheader)
> {
> msg_Err(p_aout, "Couldn't alloc WAVEHDR");
> return;
Memory leak.
> }
> +
> + p_waveheader->p_next = NULL;
> +
> if( block && p_aout->sys->chans_to_reorder )
> {
> aout_ChannelReorder( block->p_buffer, block->i_buffer,
> @@ -429,6 +442,8 @@ static void Play( audio_output_t *p_aout, block_t
> *block )
> msleep( block->i_length );
> }
>
> + WaveOutClean( p_aout->sys );
> +
> vlc_mutex_lock( &p_aout->sys->lock );
> p_aout->sys->i_frames++;
> p_aout->sys->i_played_length += block->i_length;
> @@ -466,6 +481,10 @@ static void Stop( audio_output_t *p_aout )
> }
> }
>
> + /* wait for the frames to be queued in cleaning list */
> + WaveOutFlush( p_aout, true );
> + WaveOutClean( p_aout->sys );
> +
> /* now we can Close the device */
> if( waveOutClose( p_sys->h_waveout ) != MMSYSERR_NOERROR )
> {
> @@ -639,15 +658,15 @@ static int OpenWaveOutPCM( audio_output_t *p_aout,
> uint32_t i_device_id,
> * PlayWaveOut: play a buffer through the WaveOut device
>
*****************************************************************************/
> static int PlayWaveOut( audio_output_t *p_aout, HWAVEOUT h_waveout,
> - WAVEHDR *p_waveheader, block_t *p_buffer, bool
> b_spdif)
> + struct lkwavehdr *p_waveheader, block_t
> *p_buffer, bool b_spdif)
> {
> MMRESULT result;
>
> /* Prepare the buffer */
> if( p_buffer != NULL )
> {
> - p_waveheader->lpData = (LPSTR)p_buffer->p_buffer;
> - p_waveheader->dwBufferLength = p_buffer->i_buffer;
> + p_waveheader->hdr.lpData = (LPSTR)p_buffer->p_buffer;
> + p_waveheader->hdr.dwBufferLength = p_buffer->i_buffer;
> /*
> copy the buffer to the silence buffer :) so in case we don't
> get the next buffer fast enough (I will repeat this one a
time
> @@ -672,14 +691,14 @@ static int PlayWaveOut( audio_output_t *p_aout,
> HWAVEOUT h_waveout,
> 0x00, p_aout->sys->i_buffer_size );
> }
> }
> - p_waveheader->lpData = (LPSTR)p_aout->sys->p_silence_buffer;
> - p_waveheader->dwBufferLength = p_aout->sys->i_buffer_size;
> + p_waveheader->hdr.lpData =
(LPSTR)p_aout->sys->p_silence_buffer;
> + p_waveheader->hdr.dwBufferLength = p_aout->sys->i_buffer_size;
> }
>
> - p_waveheader->dwUser = p_buffer ? (DWORD_PTR)p_buffer :
(DWORD_PTR)1;
> - p_waveheader->dwFlags = 0;
> + p_waveheader->hdr.dwUser = p_buffer ? (DWORD_PTR)p_buffer :
> (DWORD_PTR)1;
> + p_waveheader->hdr.dwFlags = 0;
>
> - result = waveOutPrepareHeader( h_waveout, p_waveheader,
> sizeof(WAVEHDR) );
> + result = waveOutPrepareHeader( h_waveout, &p_waveheader->hdr,
> sizeof(WAVEHDR) );
> if( result != MMSYSERR_NOERROR )
> {
> msg_Err( p_aout, "waveOutPrepareHeader failed" );
> @@ -687,7 +706,7 @@ static int PlayWaveOut( audio_output_t *p_aout,
> HWAVEOUT h_waveout,
> }
>
> /* Send the buffer to the waveOut queue */
> - result = waveOutWrite( h_waveout, p_waveheader, sizeof(WAVEHDR) );
> + result = waveOutWrite( h_waveout, &p_waveheader->hdr,
sizeof(WAVEHDR)
> );
> if( result != MMSYSERR_NOERROR )
> {
> msg_Err( p_aout, "waveOutWrite failed" );
> @@ -704,21 +723,38 @@ static void CALLBACK WaveOutCallback( HWAVEOUT
> h_waveout, UINT uMsg,
> DWORD_PTR _p_aout,
> DWORD_PTR dwParam1, DWORD_PTR
> dwParam2 )
> {
> - (void)dwParam2;
> + (void) h_waveout;
> + (void) dwParam2;
> audio_output_t *p_aout = (audio_output_t *)_p_aout;
> - WAVEHDR * p_waveheader = (WAVEHDR *) dwParam1;
> + struct lkwavehdr * p_waveheader = (struct lkwavehdr *) dwParam1;
>
> if( uMsg != WOM_DONE ) return;
>
> - WaveOutClearBuffer( h_waveout, p_waveheader );
> -
> - free(p_waveheader);
> vlc_mutex_lock( &p_aout->sys->lock );
> + p_waveheader->p_next = p_aout->sys->p_free_list;
> + p_aout->sys->p_free_list = p_waveheader;
> p_aout->sys->i_frames--;
> vlc_cond_broadcast( &p_aout->sys->cond );
> vlc_mutex_unlock( &p_aout->sys->lock );
> }
>
> +static void WaveOutClean( aout_sys_t * p_sys )
> +{
> + struct lkwavehdr * p_whdr = NULL;
> +
> + vlc_mutex_lock(&p_sys->lock);
> + while( p_sys->p_free_list )
> + {
> + p_whdr = p_sys->p_free_list;
> + p_sys->p_free_list = p_whdr->p_next;
> + vlc_mutex_unlock(&p_sys->lock);
> + WaveOutClearBuffer( p_sys->h_waveout, &p_whdr->hdr );
> + free(p_whdr);
> + vlc_mutex_lock(&p_sys->lock);
> + }
> + vlc_mutex_unlock(&p_sys->lock);
> +}
You don't need to reacquire the lock, just copy p_free_list to a local
variable and then set the former to NULL.
> +
> static void WaveOutClearBuffer( HWAVEOUT h_waveout, WAVEHDR
*p_waveheader
> )
> {
> block_t *p_buffer = (block_t *)(p_waveheader->dwUser);
> @@ -873,6 +909,7 @@ static void WaveOutFlush( audio_output_t *p_aout,
bool
> wait)
> static void WaveOutPause( audio_output_t * p_aout, bool pause, mtime_t
> date)
> {
> MMRESULT res;
> + (void) date;
> if(pause)
> {
> res = waveOutPause( p_aout->sys->h_waveout );
--
Rémi Denis-Courmont
Sent from my collocated server
More information about the vlc-devel
mailing list