directsoundsink: Check the return value of GetStatus() too to decide if there was an error

If GetStatus() fails, the status itself won't be very meaningful but we also
have to look at its return value. This fixes blocking pipelines when removing
sound devices or during other errors, where we wouldn't notice the error and
then wait forever.

https://bugzilla.gnome.org/show_bug.cgi?id=734098
This commit is contained in:
Thomas Roos 2015-12-11 11:23:13 +01:00 committed by Sebastian Dröge
parent e731fe4af5
commit 4d72fd9884

View file

@ -589,8 +589,8 @@ static gint
gst_directsound_sink_write (GstAudioSink * asink, gpointer data, guint length) gst_directsound_sink_write (GstAudioSink * asink, gpointer data, guint length)
{ {
GstDirectSoundSink *dsoundsink; GstDirectSoundSink *dsoundsink;
DWORD dwStatus; DWORD dwStatus = 0;
HRESULT hRes; HRESULT hRes, hRes2;
LPVOID pLockedBuffer1 = NULL, pLockedBuffer2 = NULL; LPVOID pLockedBuffer1 = NULL, pLockedBuffer2 = NULL;
DWORD dwSizeBuffer1, dwSizeBuffer2; DWORD dwSizeBuffer1, dwSizeBuffer2;
DWORD dwCurrentPlayCursor; DWORD dwCurrentPlayCursor;
@ -603,10 +603,10 @@ gst_directsound_sink_write (GstAudioSink * asink, gpointer data, guint length)
hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus); hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);
/* get current play cursor position */ /* get current play cursor position */
hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary, hRes2 = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
&dwCurrentPlayCursor, NULL); &dwCurrentPlayCursor, NULL);
if (SUCCEEDED (hRes) && (dwStatus & DSBSTATUS_PLAYING)) { if (SUCCEEDED (hRes) && SUCCEEDED (hRes2) && (dwStatus & DSBSTATUS_PLAYING)) {
DWORD dwFreeBufferSize; DWORD dwFreeBufferSize;
calculate_freesize: calculate_freesize:
@ -624,14 +624,19 @@ gst_directsound_sink_write (GstAudioSink * asink, gpointer data, guint length)
hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary, hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
&dwCurrentPlayCursor, NULL); &dwCurrentPlayCursor, NULL);
hRes = hRes2 =
IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus); IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);
if (SUCCEEDED (hRes) && (dwStatus & DSBSTATUS_PLAYING)) if (SUCCEEDED (hRes) && SUCCEEDED (hRes2)
&& (dwStatus & DSBSTATUS_PLAYING))
goto calculate_freesize; goto calculate_freesize;
else { else {
dsoundsink->first_buffer_after_reset = FALSE; dsoundsink->first_buffer_after_reset = FALSE;
GST_DSOUND_UNLOCK (dsoundsink); GST_DSOUND_UNLOCK (dsoundsink);
return 0; GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_WRITE,
("gst_directsound_sink_write: IDirectSoundBuffer_GetStatus %s, IDirectSoundBuffer_GetCurrentPosition: %s, dwStatus: %lu",
DXGetErrorString9 (hRes2), DXGetErrorString9 (hRes), dwStatus),
(NULL));
return -1;
} }
} }
} }
@ -690,7 +695,7 @@ gst_directsound_sink_delay (GstAudioSink * asink)
/* get current buffer status */ /* get current buffer status */
hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus); hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);
if (dwStatus & DSBSTATUS_PLAYING) { if (SUCCEEDED (hRes) && (dwStatus & DSBSTATUS_PLAYING)) {
/*evaluate the number of samples in queue in the circular buffer */ /*evaluate the number of samples in queue in the circular buffer */
hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary, hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
&dwCurrentPlayCursor, NULL); &dwCurrentPlayCursor, NULL);