зеркало из https://github.com/mozilla/gecko-dev.git
Bug 589071 - Avoid shutting down nsAudioStream when another thread may be using it. r=doublec a=roc
This commit is contained in:
Родитель
5e71ea141c
Коммит
1088a92d61
|
@ -76,7 +76,8 @@ nsAudioStream::nsAudioStream() :
|
||||||
mRate(0),
|
mRate(0),
|
||||||
mChannels(0),
|
mChannels(0),
|
||||||
mFormat(FORMAT_S16_LE),
|
mFormat(FORMAT_S16_LE),
|
||||||
mPaused(PR_FALSE)
|
mPaused(PR_FALSE),
|
||||||
|
mInError(PR_FALSE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +98,7 @@ void nsAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aForm
|
||||||
aRate,
|
aRate,
|
||||||
aNumChannels) != SA_SUCCESS) {
|
aNumChannels) != SA_SUCCESS) {
|
||||||
mAudioHandle = nsnull;
|
mAudioHandle = nsnull;
|
||||||
|
mInError = PR_TRUE;
|
||||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_create_pcm error"));
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_create_pcm error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -104,9 +106,11 @@ void nsAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aForm
|
||||||
if (sa_stream_open(static_cast<sa_stream_t*>(mAudioHandle)) != SA_SUCCESS) {
|
if (sa_stream_open(static_cast<sa_stream_t*>(mAudioHandle)) != SA_SUCCESS) {
|
||||||
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
||||||
mAudioHandle = nsnull;
|
mAudioHandle = nsnull;
|
||||||
|
mInError = PR_TRUE;
|
||||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_open error"));
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_open error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mInError = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAudioStream::Shutdown()
|
void nsAudioStream::Shutdown()
|
||||||
|
@ -116,6 +120,7 @@ void nsAudioStream::Shutdown()
|
||||||
|
|
||||||
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
||||||
mAudioHandle = nsnull;
|
mAudioHandle = nsnull;
|
||||||
|
mInError = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking)
|
void nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking)
|
||||||
|
@ -124,12 +129,12 @@ void nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking)
|
||||||
"Buffer size must be divisible by channel count");
|
"Buffer size must be divisible by channel count");
|
||||||
NS_ASSERTION(!mPaused, "Don't write audio when paused, you'll block");
|
NS_ASSERTION(!mPaused, "Don't write audio when paused, you'll block");
|
||||||
|
|
||||||
|
if (mInError)
|
||||||
|
return;
|
||||||
|
|
||||||
PRUint32 offset = mBufferOverflow.Length();
|
PRUint32 offset = mBufferOverflow.Length();
|
||||||
PRUint32 count = aCount + offset;
|
PRUint32 count = aCount + offset;
|
||||||
|
|
||||||
if (!mAudioHandle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsAutoArrayPtr<short> s_data(new short[count]);
|
nsAutoArrayPtr<short> s_data(new short[count]);
|
||||||
|
|
||||||
if (s_data) {
|
if (s_data) {
|
||||||
|
@ -193,7 +198,7 @@ void nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking)
|
||||||
count * sizeof(short)) != SA_SUCCESS)
|
count * sizeof(short)) != SA_SUCCESS)
|
||||||
{
|
{
|
||||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
|
||||||
Shutdown();
|
mInError = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +207,7 @@ PRUint32 nsAudioStream::Available()
|
||||||
{
|
{
|
||||||
// If the audio backend failed to open, lie and say we'll accept some
|
// If the audio backend failed to open, lie and say we'll accept some
|
||||||
// data.
|
// data.
|
||||||
if (!mAudioHandle)
|
if (mInError)
|
||||||
return FAKE_BUFFER_SIZE;
|
return FAKE_BUFFER_SIZE;
|
||||||
|
|
||||||
size_t s = 0;
|
size_t s = 0;
|
||||||
|
@ -218,7 +223,7 @@ void nsAudioStream::SetVolume(float aVolume)
|
||||||
#if defined(SA_PER_STREAM_VOLUME)
|
#if defined(SA_PER_STREAM_VOLUME)
|
||||||
if (sa_stream_set_volume_abs(static_cast<sa_stream_t*>(mAudioHandle), aVolume) != SA_SUCCESS) {
|
if (sa_stream_set_volume_abs(static_cast<sa_stream_t*>(mAudioHandle), aVolume) != SA_SUCCESS) {
|
||||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_set_volume_abs error"));
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_set_volume_abs error"));
|
||||||
Shutdown();
|
mInError = PR_TRUE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mVolume = aVolume;
|
mVolume = aVolume;
|
||||||
|
@ -227,7 +232,7 @@ void nsAudioStream::SetVolume(float aVolume)
|
||||||
|
|
||||||
void nsAudioStream::Drain()
|
void nsAudioStream::Drain()
|
||||||
{
|
{
|
||||||
if (!mAudioHandle)
|
if (mInError)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Write any remaining unwritten sound data in the overflow buffer
|
// Write any remaining unwritten sound data in the overflow buffer
|
||||||
|
@ -235,19 +240,21 @@ void nsAudioStream::Drain()
|
||||||
if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
|
if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
|
||||||
mBufferOverflow.Elements(),
|
mBufferOverflow.Elements(),
|
||||||
mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS)
|
mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS)
|
||||||
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
|
||||||
|
mInError = PR_TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = sa_stream_drain(static_cast<sa_stream_t*>(mAudioHandle));
|
int r = sa_stream_drain(static_cast<sa_stream_t*>(mAudioHandle));
|
||||||
if (r != SA_SUCCESS && r != SA_ERROR_INVALID) {
|
if (r != SA_SUCCESS && r != SA_ERROR_INVALID) {
|
||||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_drain error"));
|
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_drain error"));
|
||||||
Shutdown();
|
mInError = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAudioStream::Pause()
|
void nsAudioStream::Pause()
|
||||||
{
|
{
|
||||||
if (!mAudioHandle)
|
if (mInError)
|
||||||
return;
|
return;
|
||||||
mPaused = PR_TRUE;
|
mPaused = PR_TRUE;
|
||||||
sa_stream_pause(static_cast<sa_stream_t*>(mAudioHandle));
|
sa_stream_pause(static_cast<sa_stream_t*>(mAudioHandle));
|
||||||
|
@ -255,7 +262,7 @@ void nsAudioStream::Pause()
|
||||||
|
|
||||||
void nsAudioStream::Resume()
|
void nsAudioStream::Resume()
|
||||||
{
|
{
|
||||||
if (!mAudioHandle)
|
if (mInError)
|
||||||
return;
|
return;
|
||||||
mPaused = PR_FALSE;
|
mPaused = PR_FALSE;
|
||||||
sa_stream_resume(static_cast<sa_stream_t*>(mAudioHandle));
|
sa_stream_resume(static_cast<sa_stream_t*>(mAudioHandle));
|
||||||
|
@ -263,7 +270,7 @@ void nsAudioStream::Resume()
|
||||||
|
|
||||||
PRInt64 nsAudioStream::GetPosition()
|
PRInt64 nsAudioStream::GetPosition()
|
||||||
{
|
{
|
||||||
if (!mAudioHandle)
|
if (mInError)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sa_position_t positionType = SA_POSITION_WRITE_SOFTWARE;
|
sa_position_t positionType = SA_POSITION_WRITE_SOFTWARE;
|
||||||
|
|
|
@ -121,5 +121,8 @@ class nsAudioStream
|
||||||
|
|
||||||
// PR_TRUE if this audio stream is paused.
|
// PR_TRUE if this audio stream is paused.
|
||||||
PRPackedBool mPaused;
|
PRPackedBool mPaused;
|
||||||
|
|
||||||
|
// PR_TRUE if this stream has encountered an error.
|
||||||
|
PRPackedBool mInError;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче