[vlc-commits] Fix Directsound TimeGet
Denis Charmet
git at videolan.org
Sat May 10 15:54:22 CEST 2014
vlc | branch: master | Denis Charmet <typx at 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;
More information about the vlc-commits
mailing list