author | Paul ADENOT <paul@paul.cx> |
Sun, 15 May 2011 12:53:55 +0200 | |
changeset 69547 | f937f55b4a7f8e80b997403ab49a8885408b23da |
parent 69546 | a466b57361d08afaca52c65ef113cca96d2a6fa0 |
child 69548 | 48c0f02f4614fe670a736f6eb8924a4c3c3e60e5 |
push id | 20009 |
push user | Ms2ger@gmail.com |
push date | Sun, 15 May 2011 13:28:32 +0000 |
treeherder | mozilla-central@62b546e80604 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kinetik |
bugs | 620331 |
milestone | 6.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 @@ -221,16 +221,37 @@ class AudioSetVolumeEvent : public nsRun mAudioChild->SendSetVolume(mVolume); return NS_OK; } nsRefPtr<AudioChild> mAudioChild; double mVolume; }; + +class AudioMinWriteSampleEvent : public nsRunnable +{ + public: + AudioMinWriteSampleEvent(AudioChild* aChild) + { + mAudioChild = aChild; + } + + NS_IMETHOD Run() + { + if (!mAudioChild->IsIPCOpen()) + return NS_OK; + + mAudioChild->SendMinWriteSample(); + return NS_OK; + } + + nsRefPtr<AudioChild> mAudioChild; +}; + class AudioDrainEvent : public nsRunnable { public: AudioDrainEvent(AudioChild* aChild) { mAudioChild = aChild; } @@ -665,19 +686,21 @@ nsAudioStreamRemote::Write(const void* a PRUint32 nsAudioStreamRemote::Available() { return FAKE_BUFFER_SIZE; } PRInt32 nsAudioStreamRemote::GetMinWriteSamples() { - /** TODO: Implement this function for remoting. We could potentially remote - to a backend which has a start threshold... */ - return 1; + if (!mAudioChild) + return -1; + nsCOMPtr<nsIRunnable> event = new AudioMinWriteSampleEvent(mAudioChild); + NS_DispatchToMainThread(event); + return mAudioChild->WaitForMinWriteSample(); } void nsAudioStreamRemote::SetVolume(double aVolume) { if (!mAudioChild) return; nsCOMPtr<nsIRunnable> event = new AudioSetVolumeEvent(mAudioChild, aVolume);
--- a/dom/ipc/AudioChild.cpp +++ b/dom/ipc/AudioChild.cpp @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set sw=4 ts=8 et tw=80 : */ +/* vim: set sw=2 ts=2 et tw=80 : */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * @@ -36,23 +36,23 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "mozilla/dom/AudioChild.h" namespace mozilla { namespace dom { - NS_IMPL_THREADSAFE_ADDREF(AudioChild); NS_IMPL_THREADSAFE_RELEASE(AudioChild); AudioChild::AudioChild() : mLastSampleOffset(-1), mLastSampleOffsetTime(0), + mMinWriteSample(-2),// Initial value, -2, error on -1 mAudioReentrantMonitor("AudioChild.mReentrantMonitor"), mIPCOpen(PR_TRUE), mDrained(PR_FALSE) { MOZ_COUNT_CTOR(AudioChild); } AudioChild::~AudioChild() @@ -79,16 +79,35 @@ bool AudioChild::RecvDrainDone() { ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor); mDrained = PR_TRUE; mAudioReentrantMonitor.NotifyAll(); return true; } +PRInt32 +AudioChild::WaitForMinWriteSample() +{ + ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor); + // -2 : initial value + while (mMinWriteSample == -2 && mIPCOpen) + mAudioReentrantMonitor.Wait(); + return mMinWriteSample; +} + +bool +AudioChild::RecvMinWriteSampleDone(const PRInt32& minSamples) +{ + ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor); + mMinWriteSample = minSamples; + mAudioReentrantMonitor.NotifyAll(); + return true; +} + void AudioChild::WaitForDrain() { ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor); while (!mDrained && mIPCOpen) { mAudioReentrantMonitor.Wait(); } }
--- a/dom/ipc/AudioChild.h +++ b/dom/ipc/AudioChild.h @@ -51,27 +51,30 @@ 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 RecvDrainDone(); + virtual PRInt32 WaitForMinWriteSample(); + virtual bool RecvMinWriteSampleDone(const PRInt32& sampleCount); virtual void WaitForDrain(); virtual void ActorDestroy(ActorDestroyReason); - + PRInt64 GetLastKnownSampleOffset(); PRInt64 GetLastKnownSampleOffsetTime(); PRBool IsIPCOpen() { return mIPCOpen; }; private: nsAutoRefCnt mRefCnt; NS_DECL_OWNINGTHREAD PRInt64 mLastSampleOffset, mLastSampleOffsetTime; + PRInt32 mMinWriteSample; mozilla::ReentrantMonitor mAudioReentrantMonitor; PRPackedBool mIPCOpen; PRPackedBool mDrained; }; } // namespace dom } // namespace mozilla
--- a/dom/ipc/AudioParent.cpp +++ b/dom/ipc/AudioParent.cpp @@ -103,16 +103,59 @@ class AudioStreamShutdownEvent : public mOwner->Shutdown(); return NS_OK; } private: nsRefPtr<nsAudioStream> mOwner; }; + +class AudioMinWriteSampleDone : public nsRunnable +{ + public: + AudioMinWriteSampleDone(AudioParent* owner, PRInt32 minSamples) + { + mOwner = owner; + mMinSamples = minSamples; + } + + NS_IMETHOD Run() + { + mOwner->SendMinWriteSampleDone(mMinSamples); + return NS_OK; + } + + private: + nsRefPtr<AudioParent> mOwner; + PRInt32 mMinSamples; +}; + +class AudioMinWriteSampleEvent : public nsRunnable +{ + public: + AudioMinWriteSampleEvent(AudioParent* parent, nsAudioStream* owner) + { + mParent = parent; + mOwner = owner; + } + + NS_IMETHOD Run() + { + PRInt32 minSamples = mOwner->GetMinWriteSamples(); + nsCOMPtr<nsIRunnable> event = new AudioMinWriteSampleDone(mParent, minSamples); + NS_DispatchToMainThread(event); + return NS_OK; + } + + private: + nsRefPtr<nsAudioStream> mOwner; + nsRefPtr<AudioParent> mParent; +}; + class AudioDrainDoneEvent : public nsRunnable { public: AudioDrainDoneEvent(AudioParent* owner) { mOwner = owner; } @@ -182,16 +225,27 @@ AudioParent::RecvSetVolume(const float& { if (!mStream) return false; mStream->SetVolume(aVolume); return true; } bool +AudioParent::RecvMinWriteSample() +{ + if (!mStream) + return false; + nsCOMPtr<nsIRunnable> event = new AudioMinWriteSampleEvent(this, mStream); + nsCOMPtr<nsIThread> thread = mStream->GetThread(); + thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); + return true; +} + +bool AudioParent::RecvDrain() { if (!mStream) return false; nsCOMPtr<nsIRunnable> event = new AudioDrainEvent(this, mStream); nsCOMPtr<nsIThread> thread = mStream->GetThread(); thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); return true; @@ -223,16 +277,24 @@ bool AudioParent::RecvShutdown() { Shutdown(); unused << PAudioParent::Send__delete__(this); return true; } bool +AudioParent::SendMinWriteSampleDone(PRInt32 minSamples) +{ + if (mIPCOpen) + return PAudioParent::SendMinWriteSampleDone(minSamples); + return true; +} + +bool AudioParent::SendDrainDone() { if (mIPCOpen) return PAudioParent::SendDrainDone(); return true; } AudioParent::AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat)
--- a/dom/ipc/AudioParent.h +++ b/dom/ipc/AudioParent.h @@ -57,28 +57,34 @@ class AudioParent : public PAudioParent, RecvWrite( const nsCString& data, const PRUint32& count); virtual bool RecvSetVolume(const float& aVolume); virtual bool + RecvMinWriteSample(); + + virtual bool RecvDrain(); virtual bool RecvPause(); virtual bool RecvResume(); virtual bool RecvShutdown(); virtual bool + SendMinWriteSampleDone(PRInt32 minSamples); + + virtual bool SendDrainDone(); AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat); virtual ~AudioParent(); virtual void ActorDestroy(ActorDestroyReason); nsRefPtr<nsAudioStream> mStream; nsCOMPtr<nsITimer> mTimer;
--- a/dom/ipc/PAudio.ipdl +++ b/dom/ipc/PAudio.ipdl @@ -47,25 +47,27 @@ protocol PAudio manager PContent; parent: Write(nsCString data, PRUint32 count); SetVolume(float aVolume); + MinWriteSample(); Drain(); Pause(); Resume(); Shutdown(); child: __delete__(); SampleOffsetUpdate(PRInt64 offset, PRInt64 time); + MinWriteSampleDone(PRInt32 sampleCount); DrainDone(); }; } // namespace dom } // namespace mozilla