diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h index 44bfe1ddf9f0..f405e5bff496 100644 --- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -189,7 +189,7 @@ public: nsresult DispatchAsyncEvent(const nsAString& aName); nsresult DispatchAudioAvailableEvent(float* aFrameBuffer, PRUint32 aFrameBufferLength, - PRUint64 aTime); + float aTime); // Dispatch events that were raised while in the bfcache nsresult DispatchPendingMediaEvents(); @@ -296,7 +296,7 @@ public: * Called when data has been written to the underlying audio stream. */ void NotifyAudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, - PRUint64 aTime); + float aTime); /** * Called in order to check whether some node (this window, its document, diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index 1ccc3eccf6a4..1a7e3ccbc2bd 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -121,8 +121,6 @@ static PRLogModuleInfo* gMediaElementEventsLog; #include "nsIChannelPolicy.h" #include "nsChannelPolicy.h" -#define MS_PER_SECOND 1000 - using namespace mozilla::layers; // Under certain conditions there may be no-one holding references to @@ -693,7 +691,7 @@ void nsHTMLMediaElement::NotifyLoadError() void nsHTMLMediaElement::NotifyAudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, - PRUint64 aTime) + float aTime) { // Auto manage the memory for the frame buffer, so that if we add an early // return-on-error here in future, we won't forget to release the memory. @@ -2218,7 +2216,7 @@ ImageContainer* nsHTMLMediaElement::GetImageContainer() nsresult nsHTMLMediaElement::DispatchAudioAvailableEvent(float* aFrameBuffer, PRUint32 aFrameBufferLength, - PRUint64 aTime) + float aTime) { // Auto manage the memory for the frame buffer. If we fail and return // an error, this ensures we free the memory in the frame buffer. Otherwise @@ -2238,7 +2236,7 @@ nsresult nsHTMLMediaElement::DispatchAudioAvailableEvent(float* aFrameBuffer, rv = audioavailableEvent->InitAudioAvailableEvent(NS_LITERAL_STRING("MozAudioAvailable"), PR_TRUE, PR_TRUE, frameBuffer.forget(), aFrameBufferLength, - (float)aTime / MS_PER_SECOND, mAllowAudioData); + aTime, mAllowAudioData); NS_ENSURE_SUCCESS(rv, rv); PRBool dummy; diff --git a/content/media/nsAudioAvailableEventManager.cpp b/content/media/nsAudioAvailableEventManager.cpp index 6a33a36e7a86..c830847b00d4 100644 --- a/content/media/nsAudioAvailableEventManager.cpp +++ b/content/media/nsAudioAvailableEventManager.cpp @@ -40,7 +40,7 @@ #include "nsTArray.h" #include "nsAudioAvailableEventManager.h" -#define MILLISECONDS_PER_SECOND 1000 +#define MILLISECONDS_PER_SECOND 1000.0f #define MAX_PENDING_EVENTS 100 using namespace mozilla; @@ -52,7 +52,7 @@ private: nsAutoArrayPtr mFrameBuffer; public: nsAudioAvailableEventRunner(nsBuiltinDecoder* aDecoder, float* aFrameBuffer, - PRUint32 aFrameBufferLength, PRUint64 aTime) : + PRUint32 aFrameBufferLength, float aTime) : mDecoder(aDecoder), mFrameBuffer(aFrameBuffer), mFrameBufferLength(aFrameBufferLength), @@ -72,7 +72,9 @@ public: } const PRUint32 mFrameBufferLength; - const PRUint64 mTime; + + // Start time of the buffer data (in seconds). + const float mTime; }; @@ -104,7 +106,7 @@ void nsAudioAvailableEventManager::DispatchPendingEvents(PRUint64 aCurrentTime) while (mPendingEvents.Length() > 0) { nsAudioAvailableEventRunner* e = (nsAudioAvailableEventRunner*)mPendingEvents[0].get(); - if (e->mTime > aCurrentTime) { + if (e->mTime * MILLISECONDS_PER_SECOND > aCurrentTime) { break; } nsCOMPtr event = mPendingEvents[0]; @@ -137,11 +139,11 @@ void nsAudioAvailableEventManager::QueueWrittenAudioData(float* aAudioData, // Group audio samples into optimal size for event dispatch, and queue. while (signalBufferTail <= audioDataLength) { - PRUint64 time = 0; + float time = 0.0; // Guard against unsigned number overflow during first frame time calculation. if (aEndTimeSampleOffset > mSignalBufferPosition + audioDataLength) { - time = MILLISECONDS_PER_SECOND * (aEndTimeSampleOffset - - mSignalBufferPosition - audioDataLength) / mSamplesPerSecond; + time = (aEndTimeSampleOffset - mSignalBufferPosition - audioDataLength) / + mSamplesPerSecond; } // Fill the signalBuffer. @@ -219,9 +221,11 @@ void nsAudioAvailableEventManager::Drain(PRUint64 aEndTime) (mSignalBufferLength - mSignalBufferPosition) * sizeof(float)); // Force this last event to go now. + float time = (aEndTime / MILLISECONDS_PER_SECOND) - + (mSignalBufferPosition / mSamplesPerSecond); nsCOMPtr lastEvent = new nsAudioAvailableEventRunner(mDecoder, mSignalBuffer.forget(), - mSignalBufferLength, aEndTime); + mSignalBufferLength, time); NS_DispatchToMainThread(lastEvent, NS_DISPATCH_NORMAL); mSignalBufferPosition = 0; diff --git a/content/media/nsAudioAvailableEventManager.h b/content/media/nsAudioAvailableEventManager.h index 3db94b7dc26b..dd7c2101d948 100644 --- a/content/media/nsAudioAvailableEventManager.h +++ b/content/media/nsAudioAvailableEventManager.h @@ -82,7 +82,7 @@ private: nsBuiltinDecoder* mDecoder; // The number of samples per second. - PRUint64 mSamplesPerSecond; + float mSamplesPerSecond; // A buffer for audio data to be dispatched in DOM events. nsAutoArrayPtr mSignalBuffer; diff --git a/content/media/nsBuiltinDecoder.cpp b/content/media/nsBuiltinDecoder.cpp index b44af6a7f572..b4a3a7d01759 100644 --- a/content/media/nsBuiltinDecoder.cpp +++ b/content/media/nsBuiltinDecoder.cpp @@ -310,7 +310,7 @@ already_AddRefed nsBuiltinDecoder::GetCurrentPrincipal() void nsBuiltinDecoder::AudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, - PRUint64 aTime) + float aTime) { // Auto manage the frame buffer's memory. If we return due to an error // here, this ensures we free the memory. Otherwise, we pass off ownership diff --git a/content/media/nsBuiltinDecoder.h b/content/media/nsBuiltinDecoder.h index 7cb00ae6eee2..4bad12dee1ee 100644 --- a/content/media/nsBuiltinDecoder.h +++ b/content/media/nsBuiltinDecoder.h @@ -413,7 +413,7 @@ class nsBuiltinDecoder : public nsMediaDecoder // state machine. void Stop(); - void AudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, PRUint64 aTime); + void AudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, float aTime); // Called by the state machine to notify the decoder that the duration // has changed. diff --git a/content/media/nsBuiltinDecoderStateMachine.cpp b/content/media/nsBuiltinDecoderStateMachine.cpp index 53d4f3acfee1..9c1f2c48b111 100644 --- a/content/media/nsBuiltinDecoderStateMachine.cpp +++ b/content/media/nsBuiltinDecoderStateMachine.cpp @@ -437,7 +437,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop() // time. missingSamples = NS_MIN(static_cast(PR_UINT32_MAX), missingSamples); audioDuration += PlaySilence(static_cast(missingSamples), - channels, sampleTime); + channels, playedSamples); } else { audioDuration += PlayFromAudioQueue(sampleTime, channels); } diff --git a/content/media/test/test_a4_tone.html b/content/media/test/test_a4_tone.html index ca927a762109..d745f48939ee 100644 --- a/content/media/test/test_a4_tone.html +++ b/content/media/test/test_a4_tone.html @@ -178,7 +178,7 @@ function audioAvailable(event) { spectrumMaxs.push({ value: maxValue, index: maxIndex, time: (currentSampleOffset / testFileSampleRate) }); if( (typeof event.time !== "number") || - (Math.abs(event.time - currentSampleOffset / testFileSampleRate) > 0.01) ) { + (Math.abs(event.time - currentSampleOffset / testFileSampleRate) >= 0.001) ) { isTimePropertyValid = false; }