Bug 495794 - Fix crash when destroying audio stream that failed to open cleanly. r=chris.double

This commit is contained in:
Matthew Gregan 2009-07-02 16:38:26 +12:00
parent a33943492e
commit 3c8596b473
7 changed files with 148 additions and 23 deletions

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html class="reftest-wait">
<body>
<audio src="495794-1.ogg" autoplay onended="document.documentElement.className=undefined"></audio>
</body>
</html>

Binary file not shown.

View File

@ -1,2 +1,3 @@
load 468763-1.html
load 474744-1.html
load 495794-1.html

View File

@ -12,3 +12,6 @@ with pausing and resuming audio streams.
include-CoreServices.patch is applied to include CoreServices headers
on Mac OS X. Fixes a build failure on Mac OS X 10.6. b=492072
bug495794_closeAudio.patch fixes a crash when destroying the sa_stream_t after
a failed attempt to open the stream.

View File

@ -0,0 +1,105 @@
diff --git a/media/libsydneyaudio/src/sydney_audio_waveapi.c b/media/libsydneyaudio/src/sydney_audio_waveapi.c
--- a/media/libsydneyaudio/src/sydney_audio_waveapi.c
+++ b/media/libsydneyaudio/src/sydney_audio_waveapi.c
@@ -416,29 +416,34 @@ int openAudio(sa_stream_t *s) {
wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
supported = waveOutOpen(NULL, WAVE_MAPPER, &wfx, (DWORD_PTR)0, (DWORD_PTR)0,
WAVE_FORMAT_QUERY);
if (supported == MMSYSERR_NOERROR) { // audio device opened sucessfully
status = waveOutOpen((LPHWAVEOUT)&(s->hWaveOut), WAVE_MAPPER, &wfx,
(DWORD_PTR)waveOutProc, (DWORD_PTR)s, CALLBACK_FUNCTION);
- HANDLE_WAVE_ERROR(status, "opening audio device for playback");
- printf("Audio device sucessfully opened\n");
+ if (status != MMSYSERR_NOERROR) {
+ freeBlocks(s->waveBlocks);
+ s->waveBlocks = NULL;
+ HANDLE_WAVE_ERROR(status, "opening audio device for playback");
+ }
}
else if (supported == WAVERR_BADFORMAT) {
- printf("Requested format not supported...\n");
- // clean up the memory
- freeBlocks(s->waveBlocks);
+ printf("Requested format not supported.\n");
+ // clean up the memory
+ freeBlocks(s->waveBlocks);
+ s->waveBlocks = NULL;
return SA_ERROR_NOT_SUPPORTED;
}
else {
- printf("Error opening default audio device. Exiting...\n");
- // clean up the memory
- freeBlocks(s->waveBlocks);
+ printf("Error opening default audio device.\n");
+ // clean up the memory
+ freeBlocks(s->waveBlocks);
+ s->waveBlocks = NULL;
return SA_ERROR_SYSTEM;
}
// create notification for data written to a device
s->callbackEvent = CreateEvent(0, FALSE, FALSE, 0);
// initialise critical section for operations on waveFreeBlockCound variable
InitializeCriticalSection(&(s->waveCriticalSection));
return SA_SUCCESS;
@@ -454,40 +459,43 @@ int closeAudio(sa_stream_t * s) {
result = SA_SUCCESS;
// reseting audio device and flushing buffers
status = waveOutReset(s->hWaveOut);
if (status != MMSYSERR_NOERROR) {
result = getSAErrorCode(status);
}
- /* wait for all blocks to complete */
- while(s->waveFreeBlockCount < BLOCK_COUNT) {
- Sleep(10);
+ if (s->waveBlocks) {
+ /* wait for all blocks to complete */
+ while(s->waveFreeBlockCount < BLOCK_COUNT) {
+ Sleep(10);
+ }
+
+ /* unprepare any blocks that are still prepared */
+ for(i = 0; i < s->waveFreeBlockCount; i++) {
+ if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
+ status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
+ if (status != MMSYSERR_NOERROR) {
+ result = getSAErrorCode(status);
+ }
+ }
+ }
+
+ freeBlocks(s->waveBlocks);
+ s->waveBlocks = NULL;
}
- /* unprepare any blocks that are still prepared */
- for(i = 0; i < s->waveFreeBlockCount; i++) {
- if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
- status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
- if (status != MMSYSERR_NOERROR) {
- result = getSAErrorCode(status);
- }
- }
- }
-
- freeBlocks(s->waveBlocks);
status = waveOutClose(s->hWaveOut);
if (status != MMSYSERR_NOERROR) {
result = getSAErrorCode(status);
}
DeleteCriticalSection(&(s->waveCriticalSection));
CloseHandle(s->callbackEvent);
- printf("[audio] audio resources cleanup completed\n");
return result;
}
/**
* \brief - writes PCM audio samples to audio device
* \param s - valid handle to opened sydney stream
* \param data - pointer to memory storing audio samples to be played
* \param nsamples - number of samples in the memory pointed by previous parameter

View File

@ -421,19 +421,24 @@ int openAudio(sa_stream_t *s) {
if (supported == MMSYSERR_NOERROR) { // audio device opened sucessfully
status = waveOutOpen((LPHWAVEOUT)&(s->hWaveOut), WAVE_MAPPER, &wfx,
(DWORD_PTR)waveOutProc, (DWORD_PTR)s, CALLBACK_FUNCTION);
HANDLE_WAVE_ERROR(status, "opening audio device for playback");
printf("Audio device sucessfully opened\n");
if (status != MMSYSERR_NOERROR) {
freeBlocks(s->waveBlocks);
s->waveBlocks = NULL;
HANDLE_WAVE_ERROR(status, "opening audio device for playback");
}
}
else if (supported == WAVERR_BADFORMAT) {
printf("Requested format not supported...\n");
// clean up the memory
freeBlocks(s->waveBlocks);
printf("Requested format not supported.\n");
// clean up the memory
freeBlocks(s->waveBlocks);
s->waveBlocks = NULL;
return SA_ERROR_NOT_SUPPORTED;
}
else {
printf("Error opening default audio device. Exiting...\n");
// clean up the memory
freeBlocks(s->waveBlocks);
printf("Error opening default audio device.\n");
// clean up the memory
freeBlocks(s->waveBlocks);
s->waveBlocks = NULL;
return SA_ERROR_SYSTEM;
}
// create notification for data written to a device
@ -459,22 +464,26 @@ int closeAudio(sa_stream_t * s) {
result = getSAErrorCode(status);
}
/* wait for all blocks to complete */
while(s->waveFreeBlockCount < BLOCK_COUNT) {
Sleep(10);
if (s->waveBlocks) {
/* wait for all blocks to complete */
while(s->waveFreeBlockCount < BLOCK_COUNT) {
Sleep(10);
}
/* unprepare any blocks that are still prepared */
for(i = 0; i < s->waveFreeBlockCount; i++) {
if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
if (status != MMSYSERR_NOERROR) {
result = getSAErrorCode(status);
}
}
}
freeBlocks(s->waveBlocks);
s->waveBlocks = NULL;
}
/* unprepare any blocks that are still prepared */
for(i = 0; i < s->waveFreeBlockCount; i++) {
if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
if (status != MMSYSERR_NOERROR) {
result = getSAErrorCode(status);
}
}
}
freeBlocks(s->waveBlocks);
status = waveOutClose(s->hWaveOut);
if (status != MMSYSERR_NOERROR) {
result = getSAErrorCode(status);
@ -482,7 +491,6 @@ int closeAudio(sa_stream_t * s) {
DeleteCriticalSection(&(s->waveCriticalSection));
CloseHandle(s->callbackEvent);
printf("[audio] audio resources cleanup completed\n");
return result;
}

View File

@ -7,3 +7,4 @@ cp $1/src/*.c src/
cp $1/AUTHORS ./AUTHORS
patch -p4 <pause-resume.patch
patch -p4 <include-CoreServices.patch
patch -p3 <bug495794_closeAudio.patch