vlc | branch: master | Denis Charmet <t...@dinauz.org> | Sat May 10 15:50:09 2014 +0200| [6bb0368b1b46ca7814a039d547f744b56b295b57] | committer: Denis Charmet
Fix Directsound TimeGet Fix #11333 > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6bb0368b1b46ca7814a039d547f744b56b295b57 --- modules/audio_output/directsound.c | 54 +++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/modules/audio_output/directsound.c b/modules/audio_output/directsound.c index 5ded68f..ad183af 100644 --- a/modules/audio_output/directsound.c +++ b/modules/audio_output/directsound.c @@ -112,6 +112,8 @@ typedef struct aout_stream_sys vlc_fourcc_t format; size_t i_write; + size_t i_last_read; + int64_t i_data; bool b_playing; vlc_mutex_t lock; @@ -137,23 +139,39 @@ struct aout_sys_t HINSTANCE hdsound_dll; /*< handle of the opened dsound DLL */ }; +static HRESULT Flush( aout_stream_sys_t *sys, bool drain); static HRESULT TimeGet( aout_stream_sys_t *sys, mtime_t *delay ) { - DWORD read; + DWORD read, status; HRESULT hr; mtime_t size; + hr = IDirectSoundBuffer_GetStatus( sys->p_dsbuffer, &status ); + if(hr != DS_OK || !(status & DSBSTATUS_PLAYING)) + return 1; + hr = IDirectSoundBuffer_GetCurrentPosition( sys->p_dsbuffer, &read, NULL ); if( hr != DS_OK ) return hr; - read %= DS_BUF_SIZE; + size = read - sys->i_last_read; + + /* GetCurrentPosition cannot be trusted if the return doesn't change + * Just return an error */ + if( size == 0 ) + return 1; + else if( size < 0 ) + size += DS_BUF_SIZE; + + sys->i_data -= size; + sys->i_last_read = read; + + if( sys->i_data < 0 ) + /* underrun */ + Flush(sys, false); - size = (mtime_t)sys->i_write - (mtime_t) read; - if( size < 0 ) - size += DS_BUF_SIZE; + *delay = ( sys->i_data / sys->i_bytes_per_sample ) * CLOCK_FREQ / sys->i_rate; - *delay = ( size / sys->i_bytes_per_sample ) * CLOCK_FREQ / sys->i_rate; return DS_OK; } @@ -242,6 +260,7 @@ static HRESULT FillBuffer( vlc_object_t *obj, aout_stream_sys_t *p_sys, p_sys->i_write += towrite; p_sys->i_write %= DS_BUF_SIZE; + p_sys->i_data += towrite; vlc_mutex_unlock( &p_sys->lock ); return DS_OK; @@ -317,23 +336,30 @@ static void OutputPause( audio_output_t *aout, bool pause, mtime_t date ) (void) date; } -static HRESULT Flush( aout_stream_sys_t *sys ) +static HRESULT Flush( aout_stream_sys_t *sys, bool drain) { - return IDirectSoundBuffer_Stop( sys->p_dsbuffer ); + HRESULT ret = IDirectSoundBuffer_Stop( sys->p_dsbuffer ); + if( ret == DS_OK && !drain ) + { + vlc_mutex_lock(&sys->lock); + sys->i_data = 0; + sys->i_last_read = sys->i_write; + IDirectSoundBuffer_SetCurrentPosition( sys->p_dsbuffer, sys->i_write); + sys->b_playing = false; + vlc_mutex_unlock(&sys->lock); + } + return ret; } static HRESULT StreamFlush( aout_stream_t *s ) { - return Flush( s->sys ); + return Flush( s->sys, false ); } static void OutputFlush( audio_output_t *aout, bool drain ) { aout_stream_sys_t *sys = &aout->sys->s; - - Flush( sys ); - if( !drain ) - IDirectSoundBuffer_SetCurrentPosition( sys->p_dsbuffer, sys->i_write ); + Flush( sys, drain ); } /** @@ -759,6 +785,8 @@ static HRESULT Start( vlc_object_t *obj, aout_stream_sys_t *sys, } sys->b_playing = false; sys->i_write = 0; + sys->i_last_read = 0; + sys->i_data = 0; vlc_mutex_unlock( &sys->lock ); return DS_OK; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits