gecko-dev/media/libsydneyaudio/bug564734-win32-drain.patch

150 строки
4.5 KiB
Diff

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
@@ -121,16 +121,17 @@ struct sa_stream {
};
/** Forward definitions of audio api specific functions */
int allocateBlocks(int size, int count, WAVEHDR** blocks);
int freeBlocks(WAVEHDR* blocks);
int openAudio(sa_stream_t *s);
int closeAudio(sa_stream_t * s);
+int writeBlock(sa_stream_t *s, WAVEHDR* current);
int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
int getSAErrorCode(int waveErrorCode);
void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg,
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
/** Normal way to open a PCM device */
int sa_stream_create_pcm(sa_stream_t **s,
@@ -320,20 +321,32 @@ int sa_stream_pause(sa_stream_t *s) {
status = waveOutPause(s->hWaveOut);
HANDLE_WAVE_ERROR(status, "resuming audio playback");
s->playing = 0;
return SA_SUCCESS;
}
+
/** Block until all audio has been played */
int sa_stream_drain(sa_stream_t *s) {
+ int status;
+ WAVEHDR* current;
+
ERROR_IF_NO_INIT(s);
-
+
+ current = &(s->waveBlocks[s->waveCurrentBlock]);
+ if (current->dwUser) {
+ /* We've got pending audio which hasn't been written, we must write it to
+ the hardware, else it will never be played. */
+ status = writeBlock(s, current);
+ HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+ }
+
if (!s->playing) {
return SA_ERROR_INVALID;
}
/* wait for all blocks to complete */
EnterCriticalSection(&(s->waveCriticalSection));
while(s->waveFreeBlockCount < BLOCK_COUNT) {
LeaveCriticalSection(&(s->waveCriticalSection));
@@ -502,16 +515,48 @@ int closeAudio(sa_stream_t * s) {
s->playing = 0;
DeleteCriticalSection(&(s->waveCriticalSection));
CloseHandle(s->callbackEvent);
return result;
}
+
+/**
+ * \brief - writes a WAVEHDR block of PCM audio samples to hardware.
+ * \param s - valid handle to opened sydney stream
+ * \param current - pointer to WAVEHDR storing audio samples to be played
+ * \return - completion status
+ */
+int writeBlock(sa_stream_t *s, WAVEHDR* current) {
+ int status;
+ ERROR_IF_NO_INIT(s);
+
+ current->dwBufferLength = current->dwUser;
+ /* write to audio device */
+ waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
+ status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
+ HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+
+ EnterCriticalSection(&(s->waveCriticalSection));
+ s->waveFreeBlockCount--;
+ LeaveCriticalSection(&(s->waveCriticalSection));
+
+ /*
+ * point to the next block
+ */
+ (s->waveCurrentBlock)++;
+ (s->waveCurrentBlock) %= BLOCK_COUNT;
+
+ s->playing = 1;
+
+ return SA_SUCCESS;
+}
+
/**
* \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
* \return - completion status
*/
int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {
@@ -536,40 +581,27 @@ int writeAudio(sa_stream_t *s, LPSTR dat
if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {
memcpy(current->lpData + current->dwUser, data, bytes);
current->dwUser += bytes;
break;
}
/* remain is even as BLOCK_SIZE and dwUser are even too */
- remain = BLOCK_SIZE - current->dwUser;
+ remain = BLOCK_SIZE - current->dwUser;
memcpy(current->lpData + current->dwUser, data, remain);
+ current->dwUser += remain;
bytes -= remain;
data += remain;
- current->dwBufferLength = BLOCK_SIZE;
- /* write to audio device */
- waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
- status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));
+
+ status = writeBlock(s, current);
HANDLE_WAVE_ERROR(status, "writing audio to audio device");
-
- EnterCriticalSection(&(s->waveCriticalSection));
- s->waveFreeBlockCount--;
- LeaveCriticalSection(&(s->waveCriticalSection));
-
- /*
- * point to the next block
- */
- (s->waveCurrentBlock)++;
- (s->waveCurrentBlock) %= BLOCK_COUNT;
current = &(s->waveBlocks[s->waveCurrentBlock]);
current->dwUser = 0;
-
- s->playing = 1;
}
return SA_SUCCESS;
}
/**
* \brief - audio callback function called when next WAVE header is played by audio device
*/
void CALLBACK waveOutProc(