mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
cbff465051
- Bug 1167420 - Handle fallible AppendElement call in netwerk/base/Dashboard.cpp. r=valentin (a485b8990) - Bug 968520 - Add mozilla::fallible to FallibleTArray::AppendElement calls. r=froydnj (12a529a0e) - Bug 1172584 - Avoid coping FallibleTArray in SendRequestRunnable constructor. r=dragana (c3a4a4253) - Bug 948466: Rename gfxPangoFonts to gfxFontconfigFonts. r=nical (43eed1f5f) - Bug 968520 - Add mozilla::fallible to more FallibleTArray calls. r=froydnj (339968a1d) - Bug 1166544 - Assume successful InsertElementAt calls in DOMSVG*List::MaybeInsertNullInAnimValListAt. r=dholbert (cf687dad7) - Bug 968520 - Add mozilla::fallible to FallibleTArray::InsertElementAt calls. r=froydnj (cc5c68ff2) - Bug 968520 - Add mozilla::fallible to more FallibleTArray::InsertElementsAt calls. r=froydnj (66df1d034) - Bug 1165735 - Make ThreadSharedFloatArrayBufferList::mContents infallible. r=roc (eda2839db) - Bug 1166544 - Use ReplaceElementAt instead of Clear and InsertElementAt in SVGMotionSMILType::Add. r=dholbert (474887a8c) - Bug 1167418 - Check AppendElement call in MediaQueryList. r=heycam (b6ed6d153) - Bug 1167418 - Use nsTArray instead of FallibleTArray in MediaQueryList. r=heycam (c9e3816d0) - Bug 1167418 - Follow-up: Fix bustage (5015e91ce) - Bug 1174220 - Part 1: Remove capacity constructor of MediaLargeByteBuffer. r=jya (66819d3e4) - Bug 1179282 - Use nsTArray::Assign instead of the assignment operator in dom/svg/. r=dholbert (cb3d43c19) - Bug 968520 - Add nsTArray::Assign. r=froydnj (e5eccf354) - Bug 1182277, don't leak when using nsAutoTArray inside nsTArray, r=nfroyd (bba32394c) - Bug 1143575. Avoid including Android's GraphicBuffer.h from LayersTypes.h. r=nical (99e4e2816) - Bug 1143575. Avoid use of COMPARE macro which can clash with Android headers. r=bent (99cfc74c4) - Bug 1143575. Add RefBase #include to stagefright stubs. r=cpearce (f9e327600) - Bug 1143575. test_HaveMetadataUnbufferedSeek should not wait for canplay since preload='metadata' elements may not fire canplay. r=cpearce (f1b0eee27) - Bug 1143575. Make GL context current before cleaning up programs. r=nical (d7b05b2bd) - partial Bug 1143575. Android's screenshotting code should invalidate the LayrManagerComposite to ensure composition will actually happen. r=nical (58fb296ab) - Bug 1143575. Remove unused Image::IsSentToCompositor tracking. r=nical (808d0b3f0) - Bug 1143575. Remove unused CompositionNotifySink. r=nical (98a332305) - Bug 1143575. Remove unused VideoFrameContainer::Reset. r=nical (e292bc722) - Bug 1143575. Rename mAsyncTransactionTrackeres to mAsyncTransactionTrackers. r=nical (df71ebf4f) - Bug 1143575. Remove unused ImageContainer::ResetPaintCount. r=nical (a92c5bf6e) - Bug 1143575. Remove unused VideoFrameContainer::ClearCurrentFrame aResetSize parameter. r=nical (5d3c9b83a) - Bug 1143575. Remove unused ReturnReleaseFence. r=nical (9d6ea92b5) - Bug 1143575. LayerManagerComposite can't get END_NO_COMPOSITE. r=mattwoodrow (0c5c364b5) - Bug 1143575. Remove unused AttachAsyncCompositable overload. r=nical (5fd3d4f6d) - Bug 1143575. Rename ImageBridgeChild's AutoRemoteTextures to AutoRemoveTexturesFromImageBridge to avoid clashes with later work. r=nical (34d67fcc0) - Bug 1143575. Fix some code formatting. r=nical (1d7f30f60) - Bug 1143575. Move mLayer from ImageClientBridge up into its superclass ImageClient. r=nical (40c902a36) - Bug 1127336 - Label HW-decoded frames with correct origin. - r=vlad (fd1580bcd) - Bug 1167504 - Part 1: Remove BindableName - Framebuffer. r=jgilbert (b3133eee6) - Bug 1167504 - Part 2: Remove BindableName - Renderbuffer. r=jgilbert (155a7e796) - Bug 1167504 - Part 3: Remove BindableName - Sampler. r=jgilbert (8c5c68960) - Bug 1167504 - Part 4: Remove BindableName - Texture. r=jgilbert (28077db04) - Bug 1167504 - Part 5: Remove BindableName - Transform Feedback. r=jgilbert (4fd839598) - Bug 1170454: Fix up instance type for VAOs. r=smaug,r=jgilbert (cc62d993a) - Bug 1167504 - Part 6: Remove BindableName - Vertex Array. r=jgilbert (1d54d5bc1) - Bug 1048724 - Implement GetBufferSubData. r=jgilbert, r=smaug (06570aa84) - Bug 1167504 - Part 7: Remove BindableName - Buffer. r=jgilbert (b2ddf3fc6)
398 lines
13 KiB
C++
398 lines
13 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#ifndef MOZILLA_AUDIONODEENGINE_H_
|
|
#define MOZILLA_AUDIONODEENGINE_H_
|
|
|
|
#include "AudioSegment.h"
|
|
#include "mozilla/dom/AudioNode.h"
|
|
#include "mozilla/MemoryReporting.h"
|
|
#include "mozilla/Mutex.h"
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
struct ThreeDPoint;
|
|
class AudioParamTimeline;
|
|
class DelayNodeEngine;
|
|
} // namespace dom
|
|
|
|
class AudioNodeStream;
|
|
|
|
/**
|
|
* This class holds onto a set of immutable channel buffers. The storage
|
|
* for the buffers must be malloced, but the buffer pointers and the malloc
|
|
* pointers can be different (e.g. if the buffers are contained inside
|
|
* some malloced object).
|
|
*/
|
|
class ThreadSharedFloatArrayBufferList final : public ThreadSharedObject
|
|
{
|
|
public:
|
|
/**
|
|
* Construct with null data.
|
|
*/
|
|
explicit ThreadSharedFloatArrayBufferList(uint32_t aCount)
|
|
{
|
|
mContents.SetLength(aCount);
|
|
}
|
|
|
|
struct Storage final
|
|
{
|
|
Storage() :
|
|
mDataToFree(nullptr),
|
|
mFree(nullptr),
|
|
mSampleData(nullptr)
|
|
{}
|
|
~Storage() {
|
|
if (mFree) {
|
|
mFree(mDataToFree);
|
|
} else { MOZ_ASSERT(!mDataToFree); }
|
|
}
|
|
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
// NB: mSampleData might not be owned, if it is it just points to
|
|
// mDataToFree.
|
|
return aMallocSizeOf(mDataToFree);
|
|
}
|
|
void* mDataToFree;
|
|
void (*mFree)(void*);
|
|
const float* mSampleData;
|
|
};
|
|
|
|
/**
|
|
* This can be called on any thread.
|
|
*/
|
|
uint32_t GetChannels() const { return mContents.Length(); }
|
|
/**
|
|
* This can be called on any thread.
|
|
*/
|
|
const float* GetData(uint32_t aIndex) const { return mContents[aIndex].mSampleData; }
|
|
|
|
/**
|
|
* Call this only during initialization, before the object is handed to
|
|
* any other thread.
|
|
*/
|
|
void SetData(uint32_t aIndex, void* aDataToFree, void (*aFreeFunc)(void*), const float* aData)
|
|
{
|
|
Storage* s = &mContents[aIndex];
|
|
if (s->mFree) {
|
|
s->mFree(s->mDataToFree);
|
|
} else {
|
|
MOZ_ASSERT(!s->mDataToFree);
|
|
}
|
|
|
|
s->mDataToFree = aDataToFree;
|
|
s->mFree = aFreeFunc;
|
|
s->mSampleData = aData;
|
|
}
|
|
|
|
/**
|
|
* Put this object into an error state where there are no channels.
|
|
*/
|
|
void Clear() { mContents.Clear(); }
|
|
|
|
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override
|
|
{
|
|
size_t amount = ThreadSharedObject::SizeOfExcludingThis(aMallocSizeOf);
|
|
amount += mContents.SizeOfExcludingThis(aMallocSizeOf);
|
|
for (size_t i = 0; i < mContents.Length(); i++) {
|
|
amount += mContents[i].SizeOfExcludingThis(aMallocSizeOf);
|
|
}
|
|
|
|
return amount;
|
|
}
|
|
|
|
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
|
|
{
|
|
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
|
}
|
|
|
|
private:
|
|
nsAutoTArray<Storage, 2> mContents;
|
|
};
|
|
|
|
/**
|
|
* Allocates an AudioChunk with fresh buffers of WEBAUDIO_BLOCK_SIZE float samples.
|
|
* AudioChunk::mChannelData's entries can be cast to float* for writing.
|
|
*/
|
|
void AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk);
|
|
|
|
/**
|
|
* aChunk must have been allocated by AllocateAudioBlock.
|
|
*/
|
|
void WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength);
|
|
|
|
/**
|
|
* Copy with scale. aScale == 1.0f should be optimized.
|
|
*/
|
|
void AudioBufferCopyWithScale(const float* aInput,
|
|
float aScale,
|
|
float* aOutput,
|
|
uint32_t aSize);
|
|
|
|
/**
|
|
* Pointwise multiply-add operation. aScale == 1.0f should be optimized.
|
|
*/
|
|
void AudioBufferAddWithScale(const float* aInput,
|
|
float aScale,
|
|
float* aOutput,
|
|
uint32_t aSize);
|
|
|
|
/**
|
|
* Pointwise multiply-add operation. aScale == 1.0f should be optimized.
|
|
*/
|
|
void AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
float aScale,
|
|
float aOutput[WEBAUDIO_BLOCK_SIZE]);
|
|
|
|
/**
|
|
* Pointwise copy-scaled operation. aScale == 1.0f should be optimized.
|
|
*
|
|
* Buffer size is implicitly assumed to be WEBAUDIO_BLOCK_SIZE.
|
|
*/
|
|
void AudioBlockCopyChannelWithScale(const float* aInput,
|
|
float aScale,
|
|
float* aOutput);
|
|
|
|
/**
|
|
* Vector copy-scaled operation.
|
|
*/
|
|
void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
const float aScale[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutput[WEBAUDIO_BLOCK_SIZE]);
|
|
|
|
/**
|
|
* Vector complex multiplication on arbitrary sized buffers.
|
|
*/
|
|
void BufferComplexMultiply(const float* aInput,
|
|
const float* aScale,
|
|
float* aOutput,
|
|
uint32_t aSize);
|
|
|
|
/**
|
|
* Vector maximum element magnitude ( max(abs(aInput)) ).
|
|
*/
|
|
float AudioBufferPeakValue(const float* aInput, uint32_t aSize);
|
|
|
|
/**
|
|
* In place gain. aScale == 1.0f should be optimized.
|
|
*/
|
|
void AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
|
|
float aScale);
|
|
|
|
/**
|
|
* In place gain. aScale == 1.0f should be optimized.
|
|
*/
|
|
void AudioBufferInPlaceScale(float* aBlock,
|
|
float aScale,
|
|
uint32_t aSize);
|
|
|
|
/**
|
|
* Upmix a mono input to a stereo output, scaling the two output channels by two
|
|
* different gain value.
|
|
* This algorithm is specified in the WebAudio spec.
|
|
*/
|
|
void
|
|
AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainL, float aGainR,
|
|
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
|
|
void
|
|
AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainL[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainR[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
/**
|
|
* Pan a stereo source according to right and left gain, and the position
|
|
* (whether the listener is on the left of the source or not).
|
|
* This algorithm is specified in the WebAudio spec.
|
|
*/
|
|
void
|
|
AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainL, float aGainR, bool aIsOnTheLeft,
|
|
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
void
|
|
AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|
const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainL[WEBAUDIO_BLOCK_SIZE],
|
|
float aGainR[WEBAUDIO_BLOCK_SIZE],
|
|
bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
|
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
|
|
|
/**
|
|
* Return the sum of squares of all of the samples in the input.
|
|
*/
|
|
float
|
|
AudioBufferSumOfSquares(const float* aInput, uint32_t aLength);
|
|
|
|
/**
|
|
* All methods of this class and its subclasses are called on the
|
|
* MediaStreamGraph thread.
|
|
*/
|
|
class AudioNodeEngine
|
|
{
|
|
public:
|
|
// This should be compatible with AudioNodeStream::OutputChunks.
|
|
typedef nsAutoTArray<AudioChunk, 1> OutputChunks;
|
|
|
|
explicit AudioNodeEngine(dom::AudioNode* aNode)
|
|
: mNode(aNode)
|
|
, mInputCount(aNode ? aNode->NumberOfInputs() : 1)
|
|
, mOutputCount(aNode ? aNode->NumberOfOutputs() : 0)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_COUNT_CTOR(AudioNodeEngine);
|
|
}
|
|
virtual ~AudioNodeEngine()
|
|
{
|
|
MOZ_ASSERT(!mNode, "The node reference must be already cleared");
|
|
MOZ_COUNT_DTOR(AudioNodeEngine);
|
|
}
|
|
|
|
virtual dom::DelayNodeEngine* AsDelayNodeEngine() { return nullptr; }
|
|
|
|
virtual void SetStreamTimeParameter(uint32_t aIndex, StreamTime aParam)
|
|
{
|
|
NS_ERROR("Invalid SetStreamTimeParameter index");
|
|
}
|
|
virtual void SetDoubleParameter(uint32_t aIndex, double aParam)
|
|
{
|
|
NS_ERROR("Invalid SetDoubleParameter index");
|
|
}
|
|
virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam)
|
|
{
|
|
NS_ERROR("Invalid SetInt32Parameter index");
|
|
}
|
|
virtual void SetTimelineParameter(uint32_t aIndex,
|
|
const dom::AudioParamTimeline& aValue,
|
|
TrackRate aSampleRate)
|
|
{
|
|
NS_ERROR("Invalid SetTimelineParameter index");
|
|
}
|
|
virtual void SetThreeDPointParameter(uint32_t aIndex,
|
|
const dom::ThreeDPoint& aValue)
|
|
{
|
|
NS_ERROR("Invalid SetThreeDPointParameter index");
|
|
}
|
|
virtual void SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList> aBuffer)
|
|
{
|
|
NS_ERROR("SetBuffer called on engine that doesn't support it");
|
|
}
|
|
// This consumes the contents of aData. aData will be emptied after this returns.
|
|
virtual void SetRawArrayData(nsTArray<float>& aData)
|
|
{
|
|
NS_ERROR("SetRawArrayData called on an engine that doesn't support it");
|
|
}
|
|
|
|
/**
|
|
* Produce the next block of audio samples, given input samples aInput
|
|
* (the mixed data for input 0).
|
|
* aInput is guaranteed to have float sample format (if it has samples at all)
|
|
* and to have been resampled to the sampling rate for the stream, and to have
|
|
* exactly WEBAUDIO_BLOCK_SIZE samples.
|
|
* *aFinished is set to false by the caller. If the callee sets it to true,
|
|
* we'll finish the stream and not call this again.
|
|
*/
|
|
virtual void ProcessBlock(AudioNodeStream* aStream,
|
|
const AudioChunk& aInput,
|
|
AudioChunk* aOutput,
|
|
bool* aFinished)
|
|
{
|
|
MOZ_ASSERT(mInputCount <= 1 && mOutputCount <= 1);
|
|
*aOutput = aInput;
|
|
}
|
|
/**
|
|
* Produce the next block of audio samples, before input is provided.
|
|
* ProcessBlock() will be called later, and it then should not change
|
|
* aOutput. This is used only for DelayNodeEngine in a feedback loop.
|
|
*/
|
|
virtual void ProduceBlockBeforeInput(AudioChunk* aOutput)
|
|
{
|
|
NS_NOTREACHED("ProduceBlockBeforeInput called on wrong engine\n");
|
|
}
|
|
|
|
/**
|
|
* Produce the next block of audio samples, given input samples in the aInput
|
|
* array. There is one input sample per active port in aInput, in order.
|
|
* This is the multi-input/output version of ProcessBlock. Only one kind
|
|
* of ProcessBlock is called on each node, depending on whether the
|
|
* number of inputs and outputs are both 1 or not.
|
|
*
|
|
* aInput is always guaranteed to not contain more input AudioChunks than the
|
|
* maximum number of inputs for the node. It is the responsibility of the
|
|
* overrides of this function to make sure they will only add a maximum number
|
|
* of AudioChunks to aOutput as advertized by the AudioNode implementation.
|
|
* An engine may choose to produce fewer inputs than advertizes by the
|
|
* corresponding AudioNode, in which case it will be interpreted as a channel
|
|
* of silence.
|
|
*/
|
|
virtual void ProcessBlocksOnPorts(AudioNodeStream* aStream,
|
|
const OutputChunks& aInput,
|
|
OutputChunks& aOutput,
|
|
bool* aFinished)
|
|
{
|
|
MOZ_ASSERT(mInputCount > 1 || mOutputCount > 1);
|
|
// Only produce one output port, and drop all other input ports.
|
|
aOutput[0] = aInput[0];
|
|
}
|
|
|
|
bool HasNode() const
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
return !!mNode;
|
|
}
|
|
|
|
dom::AudioNode* NodeMainThread() const
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
return mNode;
|
|
}
|
|
|
|
void ClearNode()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(mNode != nullptr);
|
|
mNode = nullptr;
|
|
}
|
|
|
|
uint16_t InputCount() const { return mInputCount; }
|
|
uint16_t OutputCount() const { return mOutputCount; }
|
|
|
|
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
// NB: |mNode| is tracked separately so it is excluded here.
|
|
return 0;
|
|
}
|
|
|
|
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
|
}
|
|
|
|
void SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
|
AudioNodeSizes& aUsage) const
|
|
{
|
|
aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf);
|
|
if (HasNode()) {
|
|
aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf);
|
|
aUsage.mNodeType = mNode->NodeType();
|
|
}
|
|
}
|
|
|
|
private:
|
|
dom::AudioNode* mNode;
|
|
const uint16_t mInputCount;
|
|
const uint16_t mOutputCount;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif /* MOZILLA_AUDIONODEENGINE_H_ */
|