author | Matthew Gregan <kinetik@flim.org> |
Mon, 08 Aug 2011 12:51:04 +1200 | |
changeset 76484 | c54c3b67c10288c7ef0013a6cb17340cb9fe20cd |
parent 76483 | 4789623b77f2e792c0d348f25598f361736ba168 |
child 76485 | 5a4ca4d59be491a1d8d68ee9ad9c40243682885b |
push id | 340 |
push user | clegnitto@mozilla.com |
push date | Tue, 08 Nov 2011 22:56:33 +0000 |
treeherder | mozilla-beta@f745dc151615 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | doublec |
bugs | 623444 |
milestone | 9.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/html/content/src/nsHTMLAudioElement.cpp +++ b/content/html/content/src/nsHTMLAudioElement.cpp @@ -221,17 +221,17 @@ nsHTMLAudioElement::MozWriteAudio(const // on number of channels. if (dataLength % mChannels != 0) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } // Don't write more than can be written without blocking. PRUint32 writeLen = NS_MIN(mAudioStream->Available(), dataLength); - nsresult rv = mAudioStream->Write(JS_GetTypedArrayData(tsrc), writeLen, PR_TRUE); + nsresult rv = mAudioStream->Write(JS_GetTypedArrayData(tsrc), writeLen); if (NS_FAILED(rv)) { return rv; } // Return the actual amount written. *aRetVal = writeLen; return rv; }
--- a/content/media/nsAudioStream.cpp +++ b/content/media/nsAudioStream.cpp @@ -85,17 +85,17 @@ class nsAudioStreamLocal : public nsAudi public: NS_DECL_ISUPPORTS ~nsAudioStreamLocal(); nsAudioStreamLocal(); nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat); void Shutdown(); - nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking); + nsresult Write(const void* aBuf, PRUint32 aCount); PRUint32 Available(); void SetVolume(double aVolume); void Drain(); void Pause(); void Resume(); PRInt64 GetPosition(); PRInt64 GetSampleOffset(); PRBool IsPaused(); @@ -105,22 +105,16 @@ class nsAudioStreamLocal : public nsAudi double mVolume; void* mAudioHandle; int mRate; int mChannels; SampleFormat mFormat; - // When a Write() request is made, and the number of samples - // requested to be written exceeds the buffer size of the audio - // backend, the remaining samples are stored in this variable. They - // will be written on the next Write() request. - nsTArray<short> mBufferOverflow; - // PR_TRUE if this audio stream is paused. PRPackedBool mPaused; // PR_TRUE if this stream has encountered an error. PRPackedBool mInError; }; @@ -129,17 +123,17 @@ class nsAudioStreamRemote : public nsAud public: NS_DECL_ISUPPORTS nsAudioStreamRemote(); ~nsAudioStreamRemote(); nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat); void Shutdown(); - nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking); + nsresult Write(const void* aBuf, PRUint32 aCount); PRUint32 Available(); void SetVolume(double aVolume); void Drain(); void Pause(); void Resume(); PRInt64 GetPosition(); PRInt64 GetSampleOffset(); PRBool IsPaused(); @@ -447,90 +441,71 @@ void nsAudioStreamLocal::Shutdown() if (!mAudioHandle) return; sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle)); mAudioHandle = nsnull; mInError = PR_TRUE; } -nsresult nsAudioStreamLocal::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking) +nsresult nsAudioStreamLocal::Write(const void* aBuf, PRUint32 aCount) { NS_ABORT_IF_FALSE(aCount % mChannels == 0, "Buffer size must be divisible by channel count"); NS_ASSERTION(!mPaused, "Don't write audio when paused, you'll block"); if (mInError) return NS_ERROR_FAILURE; - PRUint32 offset = mBufferOverflow.Length(); - PRUint32 count = aCount + offset; - - nsAutoArrayPtr<short> s_data(new short[count]); + nsAutoArrayPtr<short> s_data(new short[aCount]); if (s_data) { - for (PRUint32 i=0; i < offset; ++i) { - s_data[i] = mBufferOverflow.ElementAt(i); - } - mBufferOverflow.Clear(); - double scaled_volume = GetVolumeScale() * mVolume; switch (mFormat) { case FORMAT_U8: { const PRUint8* buf = static_cast<const PRUint8*>(aBuf); PRInt32 volume = PRInt32((1 << 16) * scaled_volume); for (PRUint32 i = 0; i < aCount; ++i) { - s_data[i + offset] = short(((PRInt32(buf[i]) - 128) * volume) >> 8); + s_data[i] = short(((PRInt32(buf[i]) - 128) * volume) >> 8); } break; } case FORMAT_S16_LE: { const short* buf = static_cast<const short*>(aBuf); PRInt32 volume = PRInt32((1 << 16) * scaled_volume); for (PRUint32 i = 0; i < aCount; ++i) { short s = buf[i]; #if defined(IS_BIG_ENDIAN) s = ((s & 0x00ff) << 8) | ((s & 0xff00) >> 8); #endif - s_data[i + offset] = short((PRInt32(s) * volume) >> 16); + s_data[i] = short((PRInt32(s) * volume) >> 16); } break; } case FORMAT_FLOAT32: { const float* buf = static_cast<const float*>(aBuf); for (PRUint32 i = 0; i < aCount; ++i) { float scaled_value = floorf(0.5 + 32768 * buf[i] * scaled_volume); if (buf[i] < 0.0) { - s_data[i + offset] = (scaled_value < -32768.0) ? + s_data[i] = (scaled_value < -32768.0) ? -32768 : short(scaled_value); } else { - s_data[i+offset] = (scaled_value > 32767.0) ? + s_data[i] = (scaled_value > 32767.0) ? 32767 : short(scaled_value); } } break; } } - if (!aBlocking) { - // We're running in non-blocking mode, crop the data to the amount - // which is available in the audio buffer, and save the rest for - // subsequent calls. - PRUint32 available = Available(); - if (available < count) { - mBufferOverflow.AppendElements(s_data.get() + available, (count - available)); - count = available; - } - } - if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle), s_data.get(), - count * sizeof(short)) != SA_SUCCESS) + aCount * sizeof(short)) != SA_SUCCESS) { PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_write error")); mInError = PR_TRUE; return NS_ERROR_FAILURE; } } return NS_OK; } @@ -564,26 +539,16 @@ void nsAudioStreamLocal::SetVolume(doubl void nsAudioStreamLocal::Drain() { NS_ASSERTION(!mPaused, "Don't drain audio when paused, it won't finish!"); if (mInError) return; - // Write any remaining unwritten sound data in the overflow buffer - if (!mBufferOverflow.IsEmpty()) { - if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle), - mBufferOverflow.Elements(), - mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS) - PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_write error")); - mInError = PR_TRUE; - return; - } - int r = sa_stream_drain(static_cast<sa_stream_t*>(mAudioHandle)); if (r != SA_SUCCESS && r != SA_ERROR_INVALID) { PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_drain error")); mInError = PR_TRUE; } } void nsAudioStreamLocal::Pause() @@ -698,19 +663,17 @@ nsAudioStreamRemote::Shutdown() if (!mAudioChild) return; nsCOMPtr<nsIRunnable> event = new AudioShutdownEvent(mAudioChild); NS_DispatchToMainThread(event); mAudioChild = nsnull; } nsresult -nsAudioStreamRemote::Write(const void* aBuf, - PRUint32 aCount, - PRBool aBlocking) +nsAudioStreamRemote::Write(const void* aBuf, PRUint32 aCount) { if (!mAudioChild) return NS_ERROR_FAILURE; nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(mAudioChild, aBuf, aCount, mBytesPerSample); NS_DispatchToMainThread(event);
--- a/content/media/nsAudioStream.h +++ b/content/media/nsAudioStream.h @@ -80,21 +80,20 @@ public: virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) = 0; // Closes the stream. All future use of the stream is an error. // Unsafe to call with the decoder monitor held. virtual void Shutdown() = 0; // Write sound data to the audio hardware. aBuf is an array of samples in // the format specified by mFormat of length aCount. aCount should be - // evenly divisible by the number of channels in this audio stream. - // When aBlocking is PR_TRUE, we'll block until the write has completed, - // otherwise we'll buffer any data we can't write immediately, and write - // it in a later call. - virtual nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking) = 0; + // evenly divisible by the number of channels in this audio stream. If + // aCount is larger than the result of Available(), the write will block + // until sufficient buffer space is available. + virtual nsresult Write(const void* aBuf, PRUint32 aCount) = 0; // Return the number of sound samples that can be written to the audio device // without blocking. virtual PRUint32 Available() = 0; // Set the current volume of the audio playback. This is a value from // 0 (meaning muted) to 1 (meaning full volume). virtual void SetVolume(double aVolume) = 0;
--- a/content/media/nsBuiltinDecoderStateMachine.cpp +++ b/content/media/nsBuiltinDecoderStateMachine.cpp @@ -724,17 +724,17 @@ PRUint32 nsBuiltinDecoderStateMachine::P { NS_ASSERTION(OnAudioThread(), "Only call on audio thread."); NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused"); PRUint32 maxSamples = SILENCE_BYTES_CHUNK / aChannels; PRUint32 samples = NS_MIN(aSamples, maxSamples); PRUint32 numValues = samples * aChannels; nsAutoArrayPtr<SoundDataValue> buf(new SoundDataValue[numValues]); memset(buf.get(), 0, sizeof(SoundDataValue) * numValues); - mAudioStream->Write(buf, numValues, PR_TRUE); + mAudioStream->Write(buf, numValues); // Dispatch events to the DOM for the audio just written. mEventManager.QueueWrittenAudioData(buf.get(), numValues, (aSampleOffset + samples) * aChannels); return samples; } PRUint32 nsBuiltinDecoderStateMachine::PlayFromAudioQueue(PRUint64 aSampleOffset, PRUint32 aChannels) @@ -755,18 +755,17 @@ PRUint32 nsBuiltinDecoderStateMachine::P // monitor and acquired the audio monitor. Rather than acquire both // monitors, the audio stream also maintains whether its paused or not. // This prevents us from doing a blocking write while holding the audio // monitor while paused; we would block, and the state machine won't be // able to acquire the audio monitor in order to resume or destroy the // audio stream. if (!mAudioStream->IsPaused()) { mAudioStream->Write(sound->mAudioData, - sound->AudioDataLength(), - PR_TRUE); + sound->AudioDataLength()); offset = sound->mOffset; samples = sound->mSamples; // Dispatch events to the DOM for the audio just written. mEventManager.QueueWrittenAudioData(sound->mAudioData.get(), sound->AudioDataLength(), (aSampleOffset + samples) * aChannels);
--- a/dom/ipc/AudioParent.cpp +++ b/dom/ipc/AudioParent.cpp @@ -52,17 +52,17 @@ class AudioWriteEvent : public nsRunnabl { mOwner = owner; mData = data; mCount = count; } NS_IMETHOD Run() { - mOwner->Write(mData.get(), mCount, true); + mOwner->Write(mData.get(), mCount); return NS_OK; } private: nsRefPtr<nsAudioStream> mOwner; nsCString mData; PRUint32 mCount; };