vlc_fourcc_t format;
size_t i_write;
+ size_t i_last_read;
+ int64_t i_data;
bool b_playing;
vlc_mutex_t lock;
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;
}
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;
(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 );
}
/**
}
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;