mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 09:49:14 +00:00
Bug 599089 - Remote Audio to parent process. r=kinetik a=blocking-fennec
--HG-- extra : rebase_source : 8552e45188f1e62a56d5e93b551ec9fb0d4faaca
This commit is contained in:
parent
99e3c36599
commit
56cee04483
@ -598,7 +598,7 @@ protected:
|
||||
nsCOMPtr<nsIContent> mSourceLoadCandidate;
|
||||
|
||||
// An audio stream for writing audio directly from JS.
|
||||
nsAutoPtr<nsAudioStream> mAudioStream;
|
||||
nsRefPtr<nsAudioStream> mAudioStream;
|
||||
|
||||
// PR_TRUE if MozAudioAvailable events can be safely dispatched, based on
|
||||
// a media and element same-origin check.
|
||||
|
@ -168,7 +168,7 @@ nsHTMLAudioElement::MozSetup(PRUint32 aChannels, PRUint32 aRate)
|
||||
mAudioStream->Shutdown();
|
||||
}
|
||||
|
||||
mAudioStream = new nsAudioStream();
|
||||
mAudioStream = nsAudioStream::AllocateStream();
|
||||
nsresult rv = mAudioStream->Init(aChannels, aRate,
|
||||
nsAudioStream::FORMAT_FLOAT32);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -98,6 +98,8 @@ endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
|
@ -35,6 +35,15 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/PAudioChild.h"
|
||||
#include "mozilla/dom/AudioChild.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
using namespace mozilla::dom;
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "prlog.h"
|
||||
@ -46,6 +55,7 @@ extern "C" {
|
||||
#include "sydneyaudio/sydney_audio.h"
|
||||
}
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define SA_PER_STREAM_VOLUME 1
|
||||
@ -57,21 +67,284 @@ using mozilla::TimeStamp;
|
||||
PRLogModuleInfo* gAudioStreamLog = nsnull;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
static nsIThread *gAudioPlaybackThread = nsnull;
|
||||
#endif
|
||||
|
||||
#define FAKE_BUFFER_SIZE 176400
|
||||
#define MILLISECONDS_PER_SECOND 1000
|
||||
|
||||
class nsAudioStreamLocal : public nsAudioStream
|
||||
{
|
||||
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);
|
||||
PRUint32 Available();
|
||||
void SetVolume(float aVolume);
|
||||
void Drain();
|
||||
void Pause();
|
||||
void Resume();
|
||||
PRInt64 GetPosition();
|
||||
PRInt64 GetSampleOffset();
|
||||
PRBool IsPaused();
|
||||
|
||||
private:
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
class nsAudioStreamRemote : public nsAudioStream
|
||||
{
|
||||
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);
|
||||
PRUint32 Available();
|
||||
void SetVolume(float aVolume);
|
||||
void Drain();
|
||||
void Pause();
|
||||
void Resume();
|
||||
PRInt64 GetPosition();
|
||||
PRInt64 GetSampleOffset();
|
||||
PRBool IsPaused();
|
||||
|
||||
AudioChild* mAudioChild;
|
||||
|
||||
SampleFormat mFormat;
|
||||
int mRate;
|
||||
int mChannels;
|
||||
// PR_TRUE if this audio stream is paused.
|
||||
PRPackedBool mPaused;
|
||||
|
||||
PRInt32 mBytesPerSample;
|
||||
|
||||
friend class AudioInitEvent;
|
||||
friend class AudioShutdownEvent;
|
||||
friend class AudioWriteEvent;
|
||||
friend class AudioSetVolumeEvent;
|
||||
friend class AudioPauseEvent;
|
||||
friend class AudioDrainEvent;
|
||||
friend class AudioGetSampleEvent;
|
||||
};
|
||||
|
||||
class AudioInitEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioInitEvent(nsAudioStreamRemote* owner)
|
||||
{
|
||||
mOwner = owner;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
ContentChild * cpc = ContentChild::GetSingleton();
|
||||
NS_ASSERTION(cpc, "Content Protocol is NULL!");
|
||||
mOwner->mAudioChild = static_cast<AudioChild*> (cpc->SendPAudioConstructor(mOwner->mChannels,
|
||||
mOwner->mRate,
|
||||
mOwner->mFormat));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
};
|
||||
|
||||
class AudioShutdownEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioShutdownEvent(nsAudioStreamRemote* owner)
|
||||
{
|
||||
mOwner = owner;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mOwner->mAudioChild) {
|
||||
PAudioChild::Send__delete__(mOwner->mAudioChild);
|
||||
mOwner->mAudioChild = nsnull;
|
||||
}
|
||||
mOwner = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
};
|
||||
|
||||
class AudioWriteEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioWriteEvent(nsAudioStreamRemote* owner,
|
||||
const void* aBuf,
|
||||
PRUint32 aNumberOfSamples,
|
||||
PRUint32 aBytesPerSample)
|
||||
{
|
||||
mOwner = owner;
|
||||
mBytesPerSample = aBytesPerSample;
|
||||
mBuffer.Assign((const char*)aBuf, aNumberOfSamples*aBytesPerSample);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (!mOwner->mAudioChild)
|
||||
return NS_OK;
|
||||
|
||||
mOwner->mAudioChild->SendWrite(mBuffer,
|
||||
mBuffer.Length() / mBytesPerSample);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
nsCString mBuffer;
|
||||
PRUint32 mBytesPerSample;
|
||||
};
|
||||
|
||||
class AudioSetVolumeEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioSetVolumeEvent(nsAudioStreamRemote* owner, float volume)
|
||||
{
|
||||
mOwner = owner;
|
||||
mVolume = volume;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (!mOwner->mAudioChild)
|
||||
return NS_OK;
|
||||
|
||||
mOwner->mAudioChild->SendSetVolume(mVolume);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
float mVolume;
|
||||
};
|
||||
|
||||
class AudioDrainEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioDrainEvent(nsAudioStreamRemote* owner)
|
||||
{
|
||||
mOwner = owner;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (!mOwner->mAudioChild)
|
||||
return NS_OK;
|
||||
|
||||
mOwner->mAudioChild->SendDrain();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
};
|
||||
|
||||
|
||||
class AudioPauseEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioPauseEvent(nsAudioStreamRemote* owner, PRBool pause)
|
||||
{
|
||||
mOwner = owner;
|
||||
mPause = pause;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (!mOwner->mAudioChild)
|
||||
return NS_OK;
|
||||
|
||||
if (mPause)
|
||||
mOwner->mAudioChild->SendPause();
|
||||
else
|
||||
mOwner->mAudioChild->SendResume();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsAudioStreamRemote> mOwner;
|
||||
PRBool mPause;
|
||||
};
|
||||
|
||||
|
||||
#endif // MOZ_IPC
|
||||
|
||||
|
||||
void nsAudioStream::InitLibrary()
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
gAudioStreamLog = PR_NewLogModule("nsAudioStream");
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
// We only need this thread in the main process.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
NS_NewThread(&gAudioPlaybackThread);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsAudioStream::ShutdownLibrary()
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
NS_IF_RELEASE(gAudioPlaybackThread);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsAudioStream::nsAudioStream() :
|
||||
|
||||
nsIThread *
|
||||
nsAudioStream::GetGlobalThread()
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
NS_IF_ADDREF(gAudioPlaybackThread);
|
||||
return gAudioPlaybackThread;
|
||||
#else
|
||||
return nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsAudioStream* nsAudioStream::AllocateStream()
|
||||
{
|
||||
nsAudioStream* result = nsnull;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
return new nsAudioStreamRemote();
|
||||
}
|
||||
#endif
|
||||
return new nsAudioStreamLocal();
|
||||
}
|
||||
|
||||
nsAudioStreamLocal::nsAudioStreamLocal() :
|
||||
mVolume(1.0),
|
||||
mAudioHandle(0),
|
||||
mRate(0),
|
||||
@ -82,16 +355,16 @@ nsAudioStream::nsAudioStream() :
|
||||
{
|
||||
}
|
||||
|
||||
nsAudioStream::~nsAudioStream()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
nsAudioStreamLocal::~nsAudioStreamLocal(){}
|
||||
|
||||
nsresult nsAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(nsAudioStreamLocal)
|
||||
|
||||
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,
|
||||
@ -100,7 +373,7 @@ nsresult nsAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat a
|
||||
aNumChannels) != SA_SUCCESS) {
|
||||
mAudioHandle = nsnull;
|
||||
mInError = PR_TRUE;
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_create_pcm error"));
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_create_pcm error"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -108,16 +381,17 @@ nsresult nsAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat a
|
||||
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
||||
mAudioHandle = nsnull;
|
||||
mInError = PR_TRUE;
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_open error"));
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_open error"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mInError = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAudioStream::Shutdown()
|
||||
void nsAudioStreamLocal::Shutdown()
|
||||
{
|
||||
if (!mAudioHandle)
|
||||
if (!mAudioHandle)
|
||||
return;
|
||||
|
||||
sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
|
||||
@ -125,7 +399,7 @@ void nsAudioStream::Shutdown()
|
||||
mInError = PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking)
|
||||
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");
|
||||
@ -199,7 +473,7 @@ nsresult nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlockin
|
||||
s_data.get(),
|
||||
count * sizeof(short)) != SA_SUCCESS)
|
||||
{
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_write error"));
|
||||
mInError = PR_TRUE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -207,7 +481,7 @@ nsresult nsAudioStream::Write(const void* aBuf, PRUint32 aCount, PRBool aBlockin
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 nsAudioStream::Available()
|
||||
PRUint32 nsAudioStreamLocal::Available()
|
||||
{
|
||||
// If the audio backend failed to open, lie and say we'll accept some
|
||||
// data.
|
||||
@ -221,12 +495,12 @@ PRUint32 nsAudioStream::Available()
|
||||
return s / sizeof(short);
|
||||
}
|
||||
|
||||
void nsAudioStream::SetVolume(float aVolume)
|
||||
void nsAudioStreamLocal::SetVolume(float 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, ("nsAudioStream: sa_stream_set_volume_abs error"));
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_set_volume_abs error"));
|
||||
mInError = PR_TRUE;
|
||||
}
|
||||
#else
|
||||
@ -234,7 +508,7 @@ void nsAudioStream::SetVolume(float aVolume)
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsAudioStream::Drain()
|
||||
void nsAudioStreamLocal::Drain()
|
||||
{
|
||||
if (mInError)
|
||||
return;
|
||||
@ -244,19 +518,19 @@ void nsAudioStream::Drain()
|
||||
if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
|
||||
mBufferOverflow.Elements(),
|
||||
mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS)
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
|
||||
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, ("nsAudioStream: sa_stream_drain error"));
|
||||
PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStreamLocal: sa_stream_drain error"));
|
||||
mInError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void nsAudioStream::Pause()
|
||||
void nsAudioStreamLocal::Pause()
|
||||
{
|
||||
if (mInError)
|
||||
return;
|
||||
@ -264,7 +538,7 @@ void nsAudioStream::Pause()
|
||||
sa_stream_pause(static_cast<sa_stream_t*>(mAudioHandle));
|
||||
}
|
||||
|
||||
void nsAudioStream::Resume()
|
||||
void nsAudioStreamLocal::Resume()
|
||||
{
|
||||
if (mInError)
|
||||
return;
|
||||
@ -272,17 +546,16 @@ void nsAudioStream::Resume()
|
||||
sa_stream_resume(static_cast<sa_stream_t*>(mAudioHandle));
|
||||
}
|
||||
|
||||
PRInt64 nsAudioStream::GetPosition()
|
||||
PRInt64 nsAudioStreamLocal::GetPosition()
|
||||
{
|
||||
PRInt64 sampleOffset = GetSampleOffset();
|
||||
if (sampleOffset >= 0) {
|
||||
return ((MILLISECONDS_PER_SECOND * sampleOffset) / mRate / mChannels);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRInt64 nsAudioStream::GetSampleOffset()
|
||||
PRInt64 nsAudioStreamLocal::GetSampleOffset()
|
||||
{
|
||||
if (mInError) {
|
||||
return -1;
|
||||
@ -300,3 +573,141 @@ PRInt64 nsAudioStream::GetSampleOffset()
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRBool nsAudioStreamLocal::IsPaused()
|
||||
{
|
||||
return mPaused;
|
||||
}
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
|
||||
nsAudioStreamRemote::nsAudioStreamRemote()
|
||||
: mAudioChild(NULL),
|
||||
mFormat(FORMAT_S16_LE),
|
||||
mRate(0),
|
||||
mChannels(0),
|
||||
mPaused(PR_FALSE),
|
||||
mBytesPerSample(1)
|
||||
{}
|
||||
|
||||
nsAudioStreamRemote::~nsAudioStreamRemote()
|
||||
{}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(nsAudioStreamRemote)
|
||||
|
||||
nsresult
|
||||
nsAudioStreamRemote::Init(PRInt32 aNumChannels,
|
||||
PRInt32 aRate,
|
||||
SampleFormat aFormat)
|
||||
{
|
||||
mRate = aRate;
|
||||
mChannels = aNumChannels;
|
||||
mFormat = aFormat;
|
||||
|
||||
switch (mFormat) {
|
||||
case FORMAT_U8: {
|
||||
mBytesPerSample = sizeof(PRUint8);
|
||||
break;
|
||||
}
|
||||
case FORMAT_S16_LE: {
|
||||
mBytesPerSample = sizeof(short);
|
||||
break;
|
||||
}
|
||||
case FORMAT_FLOAT32: {
|
||||
mBytesPerSample = sizeof(float);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = new AudioInitEvent(this);
|
||||
NS_DispatchToMainThread(event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsAudioStreamRemote::Shutdown()
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new AudioShutdownEvent(this);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAudioStreamRemote::Write(const void* aBuf,
|
||||
PRUint32 aCount,
|
||||
PRBool aBlocking)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(this,
|
||||
aBuf,
|
||||
aCount,
|
||||
mBytesPerSample);
|
||||
NS_DispatchToMainThread(event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAudioStreamRemote::Available()
|
||||
{
|
||||
return FAKE_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
nsAudioStreamRemote::SetVolume(float aVolume)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new AudioSetVolumeEvent(this, aVolume);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
nsAudioStreamRemote::Drain()
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new AudioDrainEvent(this);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
void
|
||||
nsAudioStreamRemote::Pause()
|
||||
{
|
||||
mPaused = PR_TRUE;
|
||||
nsCOMPtr<nsIRunnable> event = new AudioPauseEvent(this, PR_TRUE);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
nsAudioStreamRemote::Resume()
|
||||
{
|
||||
mPaused = PR_FALSE;
|
||||
nsCOMPtr<nsIRunnable> event = new AudioPauseEvent(this, PR_FALSE);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
PRInt64 nsAudioStreamRemote::GetPosition()
|
||||
{
|
||||
PRInt64 sampleOffset = GetSampleOffset();
|
||||
if (sampleOffset >= 0) {
|
||||
return ((MILLISECONDS_PER_SECOND * sampleOffset) / mRate / mChannels);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt64
|
||||
nsAudioStreamRemote::GetSampleOffset()
|
||||
{
|
||||
if(!mAudioChild)
|
||||
return 0;
|
||||
|
||||
PRInt64 offset = mAudioChild->GetLastKnownSampleOffset();
|
||||
if (offset == -1)
|
||||
return 0;
|
||||
|
||||
PRInt64 time = mAudioChild->GetLastKnownSampleOffsetTime();
|
||||
PRInt64 result = offset + (mRate * mChannels * (PR_IntervalNow() - time) / MILLISECONDS_PER_SECOND);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAudioStreamRemote::IsPaused()
|
||||
{
|
||||
return mPaused;
|
||||
}
|
||||
|
||||
#endif // MOZ_IPC
|
||||
|
@ -39,14 +39,13 @@
|
||||
#define nsAudioStream_h_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "prlog.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsIThread.h"
|
||||
|
||||
extern PRLogModuleInfo* gAudioStreamLog;
|
||||
|
||||
class nsAudioStream
|
||||
class nsAudioStream : public nsISupports
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
enum SampleFormat
|
||||
{
|
||||
FORMAT_U8,
|
||||
@ -62,16 +61,23 @@ class nsAudioStream
|
||||
// library after using it.
|
||||
static void ShutdownLibrary();
|
||||
|
||||
nsAudioStream();
|
||||
~nsAudioStream();
|
||||
// Thread, usually for MOZ_IPC handling, that is shared between audio streams.
|
||||
// This may return null in the child process
|
||||
static nsIThread *GetGlobalThread();
|
||||
|
||||
// AllocateStream will return either a local stream or a remoted stream
|
||||
// depending on where you call it from. If MOZ_IPC is enabled, and you
|
||||
// call this from a child process, you may recieve an implementation which
|
||||
// forwards to a compositing process.
|
||||
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).
|
||||
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
|
||||
virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) = 0;
|
||||
|
||||
// Closes the stream. All future use of the stream is an error.
|
||||
void Shutdown();
|
||||
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
|
||||
@ -79,54 +85,35 @@ class nsAudioStream
|
||||
// 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.
|
||||
nsresult Write(const void* aBuf, PRUint32 aCount, PRBool aBlocking);
|
||||
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.
|
||||
PRUint32 Available();
|
||||
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).
|
||||
void SetVolume(float aVolume);
|
||||
virtual void SetVolume(float aVolume) = 0;
|
||||
|
||||
// Block until buffered audio data has been consumed.
|
||||
void Drain();
|
||||
virtual void Drain() = 0;
|
||||
|
||||
// Pause audio playback
|
||||
void Pause();
|
||||
virtual void Pause() = 0;
|
||||
|
||||
// Resume audio playback
|
||||
void Resume();
|
||||
virtual void Resume() = 0;
|
||||
|
||||
// Return the position in milliseconds of the sample being played by the
|
||||
// audio hardware.
|
||||
PRInt64 GetPosition();
|
||||
virtual PRInt64 GetPosition() = 0;
|
||||
|
||||
// Return the position, measured in samples played since the start, by
|
||||
// the audio hardware.
|
||||
PRInt64 GetSampleOffset();
|
||||
virtual PRInt64 GetSampleOffset() = 0;
|
||||
|
||||
// Returns PR_TRUE when the audio stream is paused.
|
||||
PRBool IsPaused() { return mPaused; }
|
||||
|
||||
private:
|
||||
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;
|
||||
virtual PRBool IsPaused() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -161,6 +161,12 @@ nsBuiltinDecoderStateMachine::nsBuiltinDecoderStateMachine(nsBuiltinDecoder* aDe
|
||||
nsBuiltinDecoderStateMachine::~nsBuiltinDecoderStateMachine()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsBuiltinDecoderStateMachine);
|
||||
|
||||
if (mAudioStream) {
|
||||
MonitorAutoEnter mon(mDecoder->GetMonitor());
|
||||
mAudioStream->Shutdown();
|
||||
mAudioStream = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsBuiltinDecoderStateMachine::HasFutureAudio() const {
|
||||
@ -611,7 +617,7 @@ void nsBuiltinDecoderStateMachine::StartPlayback()
|
||||
} else {
|
||||
// No audiostream, create one.
|
||||
const nsVideoInfo& info = mReader->GetInfo();
|
||||
mAudioStream = new nsAudioStream();
|
||||
mAudioStream = nsAudioStream::AllocateStream();
|
||||
mAudioStream->Init(info.mAudioChannels,
|
||||
info.mAudioRate,
|
||||
MOZ_SOUND_DATA_FORMAT);
|
||||
|
@ -426,7 +426,7 @@ protected:
|
||||
// The audio stream resource. Used on the state machine, audio, and main
|
||||
// threads. You must hold the mAudioMonitor, and must NOT hold the decoder
|
||||
// monitor when using the audio stream!
|
||||
nsAutoPtr<nsAudioStream> mAudioStream;
|
||||
nsRefPtr<nsAudioStream> mAudioStream;
|
||||
|
||||
// The reader, don't call its methods with the decoder monitor held.
|
||||
// This is created in the play state machine's constructor, and destroyed
|
||||
|
@ -295,7 +295,7 @@ private:
|
||||
// Our audio stream. Created on demand when entering playback state. It
|
||||
// is destroyed when seeking begins and will not be reinitialized until
|
||||
// playback resumes, so it is possible for this to be null.
|
||||
nsAutoPtr<nsAudioStream> mAudioStream;
|
||||
nsRefPtr<nsAudioStream> mAudioStream;
|
||||
|
||||
// Maximum time to spend waiting for data during buffering.
|
||||
TimeDuration mBufferingWait;
|
||||
@ -906,7 +906,7 @@ nsWaveStateMachine::ChangeState(State aState)
|
||||
void
|
||||
nsWaveStateMachine::OpenAudioStream()
|
||||
{
|
||||
mAudioStream = new nsAudioStream();
|
||||
mAudioStream = nsAudioStream::AllocateStream();
|
||||
if (!mAudioStream) {
|
||||
LOG(PR_LOG_ERROR, ("Could not create audio stream"));
|
||||
} else {
|
||||
|
79
dom/ipc/AudioChild.cpp
Normal file
79
dom/ipc/AudioChild.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 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/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Audio IPC
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Doug Turner <dougt@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* 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 {
|
||||
|
||||
AudioChild::AudioChild()
|
||||
: mLastSampleOffset(-1),
|
||||
mLastSampleOffsetTime(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(AudioChild);
|
||||
}
|
||||
|
||||
AudioChild::~AudioChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(AudioChild);
|
||||
}
|
||||
|
||||
bool
|
||||
AudioChild::RecvSampleOffsetUpdate(const PRInt64& offset,
|
||||
const PRInt64& time)
|
||||
{
|
||||
mLastSampleOffset = offset;
|
||||
mLastSampleOffsetTime = time;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRInt64
|
||||
AudioChild::GetLastKnownSampleOffset()
|
||||
{
|
||||
return mLastSampleOffset;
|
||||
}
|
||||
|
||||
PRInt64
|
||||
AudioChild::GetLastKnownSampleOffsetTime()
|
||||
{
|
||||
return mLastSampleOffsetTime;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
64
dom/ipc/AudioChild.h
Normal file
64
dom/ipc/AudioChild.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 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/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Audio IPC
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Doug Turner <dougt@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_dom_AudioChild_h
|
||||
#define mozilla_dom_AudioChild_h
|
||||
|
||||
#include "mozilla/dom/PAudioChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioChild : public PAudioChild
|
||||
{
|
||||
public:
|
||||
AudioChild();
|
||||
virtual ~AudioChild();
|
||||
virtual bool RecvSampleOffsetUpdate(const PRInt64&, const PRInt64&);
|
||||
|
||||
PRInt64 GetLastKnownSampleOffset();
|
||||
PRInt64 GetLastKnownSampleOffsetTime();
|
||||
private:
|
||||
PRInt64 mLastSampleOffset, mLastSampleOffsetTime;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
160
dom/ipc/AudioParent.cpp
Normal file
160
dom/ipc/AudioParent.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 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/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Audio IPC
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Doug Turner <dougt@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/dom/AudioParent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
// C++ file contents
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioWriteEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AudioWriteEvent(nsAudioStream* owner, nsCString data, PRUint32 count)
|
||||
{
|
||||
mOwner = owner;
|
||||
mData = data;
|
||||
mCount = count;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mOwner->Write(mData.get(), mCount, true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsAudioStream> mOwner;
|
||||
nsCString mData;
|
||||
PRUint32 mCount;
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(AudioParent, nsITimerCallback)
|
||||
|
||||
nsresult
|
||||
AudioParent::Notify(nsITimer* timer)
|
||||
{
|
||||
if (!mStream) {
|
||||
timer->Cancel();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt64 offset = mStream->GetSampleOffset();
|
||||
SendSampleOffsetUpdate(offset, PR_IntervalNow());
|
||||
return NS_OK;
|
||||
}
|
||||
bool
|
||||
AudioParent::RecvWrite(
|
||||
const nsCString& data,
|
||||
const PRUint32& count)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(mStream, data, count);
|
||||
nsCOMPtr<nsIThread> thread = nsAudioStream::GetGlobalThread();
|
||||
thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioParent::RecvSetVolume(const float& aVolume)
|
||||
{
|
||||
if (mStream)
|
||||
mStream->SetVolume(aVolume);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioParent::RecvDrain()
|
||||
{
|
||||
if (mStream)
|
||||
mStream->Drain();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioParent::RecvPause()
|
||||
{
|
||||
if (mStream)
|
||||
mStream->Pause();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioParent::RecvResume()
|
||||
{
|
||||
if (mStream)
|
||||
mStream->Resume();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioParent::Recv__delete__()
|
||||
{
|
||||
if (mStream) {
|
||||
mStream->Shutdown();
|
||||
mStream = nsnull;
|
||||
}
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nsnull;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
AudioParent::AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat)
|
||||
{
|
||||
mStream = nsAudioStream::AllocateStream();
|
||||
if (mStream)
|
||||
mStream->Init(aNumChannels,
|
||||
aRate,
|
||||
(nsAudioStream::SampleFormat) aFormat);
|
||||
if (!mStream)
|
||||
return;
|
||||
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mTimer->InitWithCallback(this, 1000, nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
|
||||
AudioParent::~AudioParent()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
86
dom/ipc/AudioParent.h
Normal file
86
dom/ipc/AudioParent.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 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/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Audio IPC
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Doug Turner <dougt@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_dom_AudioParent_h
|
||||
#define mozilla_dom_AudioParent_h
|
||||
|
||||
#include "mozilla/dom/PAudioParent.h"
|
||||
#include "nsAudioStream.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class AudioParent : public PAudioParent, public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
virtual bool
|
||||
RecvWrite(
|
||||
const nsCString& data,
|
||||
const PRUint32& count);
|
||||
|
||||
virtual bool
|
||||
RecvSetVolume(const float& aVolume);
|
||||
|
||||
virtual bool
|
||||
RecvDrain();
|
||||
|
||||
virtual bool
|
||||
RecvPause();
|
||||
|
||||
virtual bool
|
||||
RecvResume();
|
||||
|
||||
virtual bool
|
||||
Recv__delete__();
|
||||
|
||||
AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
|
||||
virtual ~AudioParent();
|
||||
|
||||
nsRefPtr<nsAudioStream> mStream;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
};
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -47,6 +47,7 @@
|
||||
|
||||
#include "ContentChild.h"
|
||||
#include "TabChild.h"
|
||||
#include "AudioChild.h"
|
||||
|
||||
#include "mozilla/ipc/TestShellChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
@ -54,6 +55,8 @@
|
||||
#include "mozilla/jsipc/PContextWrapperChild.h"
|
||||
#include "mozilla/dom/ExternalHelperAppChild.h"
|
||||
|
||||
#include "nsAudioStream.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsIObserver.h"
|
||||
@ -287,6 +290,22 @@ ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PAudioChild*
|
||||
ContentChild::AllocPAudio(const PRInt32& numChannels,
|
||||
const PRInt32& rate,
|
||||
const PRInt32& format)
|
||||
{
|
||||
PAudioChild *child = new AudioChild();
|
||||
return child;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::DeallocPAudio(PAudioChild* doomed)
|
||||
{
|
||||
delete doomed;
|
||||
return true;
|
||||
}
|
||||
|
||||
PNeckoChild*
|
||||
ContentChild::AllocPNecko()
|
||||
{
|
||||
|
@ -83,6 +83,11 @@ public:
|
||||
virtual bool DeallocPTestShell(PTestShellChild*);
|
||||
virtual bool RecvPTestShellConstructor(PTestShellChild*);
|
||||
|
||||
virtual PAudioChild* AllocPAudio(const PRInt32&,
|
||||
const PRInt32&,
|
||||
const PRInt32&);
|
||||
virtual bool DeallocPAudio(PAudioChild*);
|
||||
|
||||
virtual PNeckoChild* AllocPNecko();
|
||||
virtual bool DeallocPNecko(PNeckoChild*);
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsConsoleMessage.h"
|
||||
#include "AudioParent.h"
|
||||
|
||||
#ifdef MOZ_PERMISSIONS
|
||||
#include "nsPermissionManager.h"
|
||||
@ -361,6 +362,24 @@ ContentParent::DeallocPTestShell(PTestShellParent* shell)
|
||||
delete shell;
|
||||
return true;
|
||||
}
|
||||
|
||||
PAudioParent*
|
||||
ContentParent::AllocPAudio(const PRInt32& numChannels,
|
||||
const PRInt32& rate,
|
||||
const PRInt32& format)
|
||||
{
|
||||
AudioParent *parent = new AudioParent(numChannels, rate, format);
|
||||
parent->AddRef();
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPAudio(PAudioParent* doomed)
|
||||
{
|
||||
AudioParent *parent = static_cast<AudioParent*>(doomed);
|
||||
NS_RELEASE(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
PNeckoParent*
|
||||
ContentParent::AllocPNecko()
|
||||
|
@ -117,6 +117,11 @@ private:
|
||||
virtual PTestShellParent* AllocPTestShell();
|
||||
virtual bool DeallocPTestShell(PTestShellParent* shell);
|
||||
|
||||
virtual PAudioParent* AllocPAudio(const PRInt32&,
|
||||
const PRInt32&,
|
||||
const PRInt32&);
|
||||
virtual bool DeallocPAudio(PAudioParent*);
|
||||
|
||||
virtual PNeckoParent* AllocPNecko();
|
||||
virtual bool DeallocPNecko(PNeckoParent* necko);
|
||||
|
||||
|
@ -52,6 +52,8 @@ EXPORTS = TabMessageUtils.h PCOMContentPermissionRequestChild.h
|
||||
EXPORTS_NAMESPACES = mozilla/dom
|
||||
|
||||
EXPORTS_mozilla/dom = \
|
||||
AudioChild.h \
|
||||
AudioParent.h \
|
||||
ContentChild.h \
|
||||
ContentParent.h \
|
||||
ContentProcess.h \
|
||||
@ -60,6 +62,8 @@ EXPORTS_mozilla/dom = \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
AudioChild.cpp \
|
||||
AudioParent.cpp \
|
||||
ContentProcess.cpp \
|
||||
ContentParent.cpp \
|
||||
ContentChild.cpp \
|
||||
|
70
dom/ipc/PAudio.ipdl
Normal file
70
dom/ipc/PAudio.ipdl
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 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/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Audio IPC
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Doug Turner <dougt@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
include protocol PContent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
sync protocol PAudio
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
|
||||
__delete__();
|
||||
|
||||
Write(nsCString data, PRUint32 count);
|
||||
|
||||
SetVolume(float aVolume);
|
||||
|
||||
sync Drain();
|
||||
|
||||
Pause();
|
||||
Resume();
|
||||
|
||||
child:
|
||||
|
||||
SampleOffsetUpdate(PRInt64 offset, PRInt64 time);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -36,6 +36,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
include protocol PAudio;
|
||||
include protocol PBrowser;
|
||||
include protocol PTestShell;
|
||||
include protocol PNecko;
|
||||
@ -61,6 +62,7 @@ namespace dom {
|
||||
|
||||
rpc protocol PContent
|
||||
{
|
||||
manages PAudio;
|
||||
manages PBrowser;
|
||||
manages PTestShell;
|
||||
manages PNecko;
|
||||
@ -92,6 +94,8 @@ child:
|
||||
parent:
|
||||
PNecko();
|
||||
|
||||
PAudio(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
|
||||
|
||||
// Services remoting
|
||||
|
||||
async StartVisitedQuery(URI uri);
|
||||
|
@ -35,6 +35,7 @@
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
IPDLSRCS = \
|
||||
PAudio.ipdl \
|
||||
PBrowser.ipdl \
|
||||
PContent.ipdl \
|
||||
PContentDialog.ipdl \
|
||||
|
Loading…
x
Reference in New Issue
Block a user