Commit 6bb0368b authored by Denis Charmet's avatar Denis Charmet

Fix Directsound TimeGet

Fix #11333
parent 435a44a8
...@@ -112,6 +112,8 @@ typedef struct aout_stream_sys ...@@ -112,6 +112,8 @@ typedef struct aout_stream_sys
vlc_fourcc_t format; vlc_fourcc_t format;
size_t i_write; size_t i_write;
size_t i_last_read;
int64_t i_data;
bool b_playing; bool b_playing;
vlc_mutex_t lock; vlc_mutex_t lock;
...@@ -137,23 +139,39 @@ struct aout_sys_t ...@@ -137,23 +139,39 @@ struct aout_sys_t
HINSTANCE hdsound_dll; /*< handle of the opened dsound DLL */ 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 ) static HRESULT TimeGet( aout_stream_sys_t *sys, mtime_t *delay )
{ {
DWORD read; DWORD read, status;
HRESULT hr; HRESULT hr;
mtime_t size; 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 ); hr = IDirectSoundBuffer_GetCurrentPosition( sys->p_dsbuffer, &read, NULL );
if( hr != DS_OK ) if( hr != DS_OK )
return hr; 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; *delay = ( sys->i_data / sys->i_bytes_per_sample ) * CLOCK_FREQ / sys->i_rate;
if( size < 0 )
size += DS_BUF_SIZE;
*delay = ( size / sys->i_bytes_per_sample ) * CLOCK_FREQ / sys->i_rate;
return DS_OK; return DS_OK;
} }
...@@ -242,6 +260,7 @@ static HRESULT FillBuffer( vlc_object_t *obj, aout_stream_sys_t *p_sys, ...@@ -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 += towrite;
p_sys->i_write %= DS_BUF_SIZE; p_sys->i_write %= DS_BUF_SIZE;
p_sys->i_data += towrite;
vlc_mutex_unlock( &p_sys->lock ); vlc_mutex_unlock( &p_sys->lock );
return DS_OK; return DS_OK;
...@@ -317,23 +336,30 @@ static void OutputPause( audio_output_t *aout, bool pause, mtime_t date ) ...@@ -317,23 +336,30 @@ static void OutputPause( audio_output_t *aout, bool pause, mtime_t date )
(void) 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 ) 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 ) static void OutputFlush( audio_output_t *aout, bool drain )
{ {
aout_stream_sys_t *sys = &aout->sys->s; aout_stream_sys_t *sys = &aout->sys->s;
Flush( sys, drain );
Flush( sys );
if( !drain )
IDirectSoundBuffer_SetCurrentPosition( sys->p_dsbuffer, sys->i_write );
} }
/** /**
...@@ -759,6 +785,8 @@ static HRESULT Start( vlc_object_t *obj, aout_stream_sys_t *sys, ...@@ -759,6 +785,8 @@ static HRESULT Start( vlc_object_t *obj, aout_stream_sys_t *sys,
} }
sys->b_playing = false; sys->b_playing = false;
sys->i_write = 0; sys->i_write = 0;
sys->i_last_read = 0;
sys->i_data = 0;
vlc_mutex_unlock( &sys->lock ); vlc_mutex_unlock( &sys->lock );
return DS_OK; return DS_OK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment