☠☠ backed out by 484a69f1e530 ☠ ☠ | |
author | Paul ADENOT <paul@paul.cx> |
Fri, 10 Jun 2011 15:54:06 +0200 | |
changeset 70873 | 3206cfacc0e630eb6fa26d7503fb3ffafe46777e |
parent 70872 | bf46495e80aeda5c898a81ae771ab55c61276f1e |
child 70874 | 484a69f1e53068cbbcc7b313f68cbb08b9376124 |
push id | 20435 |
push user | eakhgari@mozilla.com |
push date | Fri, 10 Jun 2011 20:08:22 +0000 |
treeherder | mozilla-central@28217403cd02 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kinetik |
bugs | 612799 |
milestone | 7.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/media/nsAudioStream.cpp +++ b/content/media/nsAudioStream.cpp @@ -84,20 +84,20 @@ class nsAudioStreamLocal : public nsAudi { public: NS_DECL_ISUPPORTS ~nsAudioStreamLocal(); nsAudioStreamLocal(); nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat); - void Shutdown(); + nsresult Shutdown(); nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking); PRUint32 Available(); - void SetVolume(double aVolume); + nsresult SetVolume(double aVolume); nsresult Drain(); void Pause(); void Resume(); PRInt64 GetPosition(); PRInt64 GetSampleOffset(); PRBool IsPaused(); PRInt32 GetMinWriteSamples(); @@ -128,20 +128,20 @@ class nsAudioStreamRemote : public nsAud { public: NS_DECL_ISUPPORTS nsAudioStreamRemote(); ~nsAudioStreamRemote(); nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat); - void Shutdown(); + nsresult Shutdown(); nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking); PRUint32 Available(); - void SetVolume(double aVolume); + nsresult SetVolume(double aVolume); nsresult Drain(); void Pause(); void Resume(); PRInt64 GetPosition(); PRInt64 GetSampleOffset(); PRBool IsPaused(); PRInt32 GetMinWriteSamples(); @@ -405,17 +405,18 @@ nsAudioStreamLocal::nsAudioStreamLocal() nsAudioStreamLocal::~nsAudioStreamLocal() { Shutdown(); } NS_IMPL_THREADSAFE_ISUPPORTS0(nsAudioStreamLocal) -nsresult nsAudioStreamLocal::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) +nsresult +nsAudioStreamLocal::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) { mRate = aRate; mChannels = aNumChannels; mFormat = aFormat; if (sa_stream_create_pcm(reinterpret_cast<sa_stream_t**>(&mAudioHandle), NULL, SA_MODE_WRONLY, @@ -435,24 +436,31 @@ nsresult nsAudioStreamLocal::Init(PRInt3 PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_open error")); return NS_ERROR_FAILURE; } mInError = PR_FALSE; return NS_OK; } -void nsAudioStreamLocal::Shutdown() +nsresult +nsAudioStreamLocal::Shutdown() { if (!mAudioHandle) - return; + return NS_ERROR_FAILURE; - sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle)); + if (sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle))); + { + PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_destroy error")); + mInError = true; + return NS_ERROR_FAILURE; + } mAudioHandle = nsnull; mInError = PR_TRUE; + return NS_OK; } nsresult nsAudioStreamLocal::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking) { 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"); @@ -542,27 +550,30 @@ PRUint32 nsAudioStreamLocal::Available() size_t s = 0; if (sa_stream_get_write_size(static_cast<sa_stream_t*>(mAudioHandle), &s) != SA_SUCCESS) return 0; return s / sizeof(short); } -void nsAudioStreamLocal::SetVolume(double aVolume) +nsresult +nsAudioStreamLocal::SetVolume(double aVolume) { NS_ASSERTION(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume"); #if defined(SA_PER_STREAM_VOLUME) if (sa_stream_set_volume_abs(static_cast<sa_stream_t*>(mAudioHandle), aVolume) != SA_SUCCESS) { PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_set_volume_abs error")); mInError = PR_TRUE; + return NS_ERROR_FAILURE; } #else mVolume = aVolume; #endif + return NS_OK; } nsresult nsAudioStreamLocal::Drain() { NS_ASSERTION(!mPaused, "Don't drain audio when paused, it won't finish!"); if (mInError) return NS_ERROR_FAILURE; @@ -687,32 +698,33 @@ nsAudioStreamRemote::Init(PRInt32 aNumCh } } nsCOMPtr<nsIRunnable> event = new AudioInitEvent(this); NS_DispatchToMainThread(event, NS_DISPATCH_SYNC); return NS_OK; } -void +nsresult nsAudioStreamRemote::Shutdown() { if (!mAudioChild) - return; + return NS_ERROR_FAILURE; nsCOMPtr<nsIRunnable> event = new AudioShutdownEvent(mAudioChild); NS_DispatchToMainThread(event); mAudioChild = nsnull; + return NS_OK; } nsresult nsAudioStreamRemote::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking) { - if (!mAudioChild) + if (!mAudioChild || mAudioChild->IsInError()) return NS_ERROR_FAILURE; nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(mAudioChild, aBuf, aCount, mBytesPerSample); NS_DispatchToMainThread(event); return NS_OK; } @@ -730,48 +742,49 @@ PRInt32 nsAudioStreamRemote::GetMinWrite nsCOMPtr<nsIRunnable> event = new AudioMinWriteSampleEvent(mAudioChild); NS_DispatchToMainThread(event); return mAudioChild->WaitForMinWriteSample(); } void nsAudioStreamRemote::SetVolume(double aVolume) { - if (!mAudioChild) - return; + if (!mAudioChild || mAudioChild->IsInError()) + return NS_ERROR_FAILURE; nsCOMPtr<nsIRunnable> event = new AudioSetVolumeEvent(mAudioChild, aVolume); NS_DispatchToMainThread(event); + return NS_OK; } nsresult nsAudioStreamRemote::Drain() { if (!mAudioChild) return NS_ERROR_FAILURE; nsCOMPtr<nsIRunnable> event = new AudioDrainEvent(mAudioChild); NS_DispatchToMainThread(event); return mAudioChild->WaitForDrain(); } void nsAudioStreamRemote::Pause() { + if (!mAudioChild || mAudioChild->IsInError()) + return; mPaused = PR_TRUE; - if (!mAudioChild) - return; nsCOMPtr<nsIRunnable> event = new AudioPauseEvent(mAudioChild, PR_TRUE); NS_DispatchToMainThread(event); } void nsAudioStreamRemote::Resume() { + if (!mAudioChild || mAudioChild->IsInError()) + return; mPaused = PR_FALSE; - if (!mAudioChild) - return; nsCOMPtr<nsIRunnable> event = new AudioPauseEvent(mAudioChild, PR_FALSE); NS_DispatchToMainThread(event); } PRInt64 nsAudioStreamRemote::GetPosition() { PRInt64 sampleOffset = GetSampleOffset(); if (sampleOffset >= 0) {
--- a/content/media/nsAudioStream.h +++ b/content/media/nsAudioStream.h @@ -74,33 +74,33 @@ public: static nsAudioStream* AllocateStream(); // Initialize the audio stream. aNumChannels is the number of audio channels // (1 for mono, 2 for stereo, etc) and aRate is the frequency of the sound // samples (22050, 44100, etc). virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) = 0; // Closes the stream. All future use of the stream is an error. - virtual void Shutdown() = 0; + virtual nsresult 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; // 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; + virtual nsresult SetVolume(double aVolume) = 0; // Block until buffered audio data has been consumed. virtual nsresult Drain() = 0; // Pause audio playback virtual void Pause() = 0; // Resume audio playback
--- a/dom/ipc/AudioChild.cpp +++ b/dom/ipc/AudioChild.cpp @@ -82,16 +82,23 @@ AudioChild::RecvDrainDone(const nsresult if (status == NS_OK) mDrained = PR_TRUE; mAudioReentrantMonitor.NotifyAll(); return true; } +bool +AudioChild::RecvEnteringErrorState() +{ + mInError = PR_TRUE; + return true; +} + PRInt32 AudioChild::WaitForMinWriteSample() { ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor); // -2 : initial value while (mMinWriteSample == -2 && mIPCOpen) mAudioReentrantMonitor.Wait(); return mMinWriteSample;
--- a/dom/ipc/AudioChild.h +++ b/dom/ipc/AudioChild.h @@ -50,32 +50,35 @@ class AudioChild : public PAudioChild { public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); AudioChild(); virtual ~AudioChild(); virtual bool RecvSampleOffsetUpdate(const PRInt64&, const PRInt64&); + virtual bool RecvEnteringErrorState(); virtual bool RecvDrainDone(const nsresult& status); virtual PRInt32 WaitForMinWriteSample(); virtual bool RecvMinWriteSampleDone(const PRInt32& sampleCount); virtual nsresult WaitForDrain(); virtual void ActorDestroy(ActorDestroyReason); PRInt64 GetLastKnownSampleOffset(); PRInt64 GetLastKnownSampleOffsetTime(); PRBool IsIPCOpen() { return mIPCOpen; }; + PRBool IsInError() { return mInError; }; private: nsAutoRefCnt mRefCnt; NS_DECL_OWNINGTHREAD PRInt64 mLastSampleOffset, mLastSampleOffsetTime; PRInt32 mMinWriteSample; mozilla::ReentrantMonitor mAudioReentrantMonitor; PRPackedBool mIPCOpen; PRPackedBool mDrained; + PRPackedBool mInError; }; } // namespace dom } // namespace mozilla #endif
--- a/dom/ipc/AudioParent.cpp +++ b/dom/ipc/AudioParent.cpp @@ -43,31 +43,34 @@ // C++ file contents namespace mozilla { namespace dom { class AudioWriteEvent : public nsRunnable { public: - AudioWriteEvent(nsAudioStream* owner, nsCString data, PRUint32 count) + AudioWriteEvent(AudioParent* parent, nsAudioStream* owner, nsCString data, PRUint32 count) { + mParent = parent; mOwner = owner; mData = data; mCount = count; } NS_IMETHOD Run() { - mOwner->Write(mData.get(), mCount, true); + if (mOwner->Write(mData.get(), mCount, true) != NS_OK) + mParent->EnteringErrorState(); return NS_OK; } private: nsRefPtr<nsAudioStream> mOwner; + nsRefPtr<AudioParent> mParent; nsCString mData; PRUint32 mCount; }; class AudioPauseEvent : public nsRunnable { public: AudioPauseEvent(nsAudioStream* owner, PRBool aPause) @@ -211,17 +214,17 @@ AudioParent::Notify(nsITimer* timer) bool AudioParent::RecvWrite( const nsCString& data, const PRUint32& count) { if (!mStream) return false; - nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(mStream, data, count); + nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(this, mStream, data, count); nsCOMPtr<nsIThread> thread = mStream->GetThread(); thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); return true; } bool AudioParent::RecvSetVolume(const float& aVolume) { @@ -278,16 +281,23 @@ AudioParent::RecvResume() bool AudioParent::RecvShutdown() { Shutdown(); unused << PAudioParent::Send__delete__(this); return true; } +void +AudioParent::EnteringErrorState() +{ + if (mIPCOpen) + PAudioParent::SendEnteringErrorState(); +} + bool AudioParent::SendMinWriteSampleDone(PRInt32 minSamples) { if (mIPCOpen) return PAudioParent::SendMinWriteSampleDone(minSamples); return true; } @@ -304,16 +314,17 @@ AudioParent::AudioParent(PRInt32 aNumCha { mStream = nsAudioStream::AllocateStream(); NS_ASSERTION(mStream, "AudioStream allocation failed."); if (NS_FAILED(mStream->Init(aNumChannels, aRate, (nsAudioStream::SampleFormat) aFormat))) { NS_WARNING("AudioStream initialization failed."); mStream = nsnull; + EnteringErrorState(); return; } mTimer = do_CreateInstance("@mozilla.org/timer;1"); mTimer->InitWithCallback(this, 1000, nsITimer::TYPE_REPEATING_SLACK); } AudioParent::~AudioParent()
--- a/dom/ipc/AudioParent.h +++ b/dom/ipc/AudioParent.h @@ -81,16 +81,18 @@ class AudioParent : public PAudioParent, virtual bool SendDrainDone(nsresult status); AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat); virtual ~AudioParent(); virtual void ActorDestroy(ActorDestroyReason); + void EnteringErrorState(); + nsRefPtr<nsAudioStream> mStream; nsCOMPtr<nsITimer> mTimer; private: void Shutdown(); PRPackedBool mIPCOpen; };