Bug 620331 - Remote nsAudioStreamRemote::GetMinWriteSamples; r=kinetik
authorPaul ADENOT <paul@paul.cx>
Sun, 15 May 2011 12:53:55 +0200
changeset 69547 f937f55b4a7f8e80b997403ab49a8885408b23da
parent 69546 a466b57361d08afaca52c65ef113cca96d2a6fa0
child 69548 48c0f02f4614fe670a736f6eb8924a4c3c3e60e5
push id20009
push userMs2ger@gmail.com
push dateSun, 15 May 2011 13:28:32 +0000
treeherdermozilla-central@62b546e80604 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs620331
milestone6.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
Bug 620331 - Remote nsAudioStreamRemote::GetMinWriteSamples; r=kinetik
content/media/nsAudioStream.cpp
dom/ipc/AudioChild.cpp
dom/ipc/AudioChild.h
dom/ipc/AudioParent.cpp
dom/ipc/AudioParent.h
dom/ipc/PAudio.ipdl
--- 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