b=906966 limit ScriptProcessorNode input channel count through channelCount and channelCountMode r=ehsan
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 05 Sep 2013 07:44:37 +1200
changeset 145494 15a71c6cb0d3ab794fee0b4307ef108162e66f05
parent 145493 4d5107aea7080cbc0e7e4ac11e37da2f81caeffe
child 145495 0783c819410df43f5dd5caa6b1db64e3ad31f109
push id33296
push userktomlinson@mozilla.com
push dateWed, 04 Sep 2013 20:32:35 +0000
treeherdermozilla-inbound@15a71c6cb0d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs906966
milestone26.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
b=906966 limit ScriptProcessorNode input channel count through channelCount and channelCountMode r=ehsan
content/media/webaudio/ScriptProcessorNode.cpp
content/media/webaudio/ScriptProcessorNode.h
content/media/webaudio/test/test_scriptProcessorNodeChannelCount.html
--- a/content/media/webaudio/ScriptProcessorNode.cpp
+++ b/content/media/webaudio/ScriptProcessorNode.cpp
@@ -208,20 +208,21 @@ public:
                             AudioDestinationNode* aDestination,
                             uint32_t aBufferSize,
                             uint32_t aNumberOfInputChannels)
     : AudioNodeEngine(aNode)
     , mSharedBuffers(aNode->GetSharedBuffers())
     , mSource(nullptr)
     , mDestination(static_cast<AudioNodeStream*> (aDestination->Stream()))
     , mBufferSize(aBufferSize)
-    , mDefaultNumberOfInputChannels(aNumberOfInputChannels)
     , mInputWriteIndex(0)
     , mSeenNonSilenceInput(false)
   {
+    mInputChannels.SetLength(aNumberOfInputChannels);
+    AllocateInputBlock();
   }
 
   void SetSourceStream(AudioNodeStream* aSource)
   {
     mSource = aSource;
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
@@ -232,26 +233,25 @@ public:
     MutexAutoLock lock(NodeMutex());
 
     // If our node is dead, just output silence.
     if (!Node()) {
       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
       return;
     }
 
-    EnsureInputChannels(aInput.mChannelData.Length());
-
     // First, record our input buffer
     for (uint32_t i = 0; i < mInputChannels.Length(); ++i) {
       if (aInput.IsNull()) {
         PodZero(mInputChannels[i] + mInputWriteIndex,
                 aInput.GetDuration());
       } else {
         mSeenNonSilenceInput = true;
         MOZ_ASSERT(aInput.GetDuration() == WEBAUDIO_BLOCK_SIZE, "sanity check");
+        MOZ_ASSERT(aInput.mChannelData.Length() == mInputChannels.Length());
         AudioBlockCopyChannelWithScale(static_cast<const float*>(aInput.mChannelData[i]),
                                        aInput.mVolume,
                                        mInputChannels[i] + mInputWriteIndex);
       }
     }
     mInputWriteIndex += aInput.GetDuration();
 
     // Now, see if we have data to output
@@ -272,35 +272,16 @@ private:
   {
     for (unsigned i = 0; i < mInputChannels.Length(); ++i) {
       if (!mInputChannels[i]) {
         mInputChannels[i] = new float[mBufferSize];
       }
     }
   }
 
-  void EnsureInputChannels(uint32_t aNumberOfChannels)
-  {
-    if (aNumberOfChannels == 0) {
-      aNumberOfChannels = mDefaultNumberOfInputChannels;
-    }
-    if (mInputChannels.Length() == 0) {
-      mInputChannels.SetLength(aNumberOfChannels);
-      AllocateInputBlock();
-    } else if (aNumberOfChannels < mInputChannels.Length()) {
-      mInputChannels.SetLength(aNumberOfChannels);
-    } else if (aNumberOfChannels > mInputChannels.Length()) {
-      uint32_t oldLength = mInputChannels.Length();
-      mInputChannels.SetLength(aNumberOfChannels);
-      for (uint32_t i = oldLength; i < aNumberOfChannels; ++i) {
-        mInputChannels[i] = new float[mBufferSize];
-      }
-    }
-  }
-
   void SendBuffersToMainThread(AudioNodeStream* aStream)
   {
     MOZ_ASSERT(!NS_IsMainThread());
 
     // we now have a full input buffer ready to be sent to the main thread.
     TrackTicks playbackTick = mSource->GetCurrentPosition();
     // Add the duration of the current sample
     playbackTick += WEBAUDIO_BLOCK_SIZE;
@@ -406,17 +387,16 @@ private:
 
   friend class ScriptProcessorNode;
 
   SharedBuffers* mSharedBuffers;
   AudioNodeStream* mSource;
   AudioNodeStream* mDestination;
   InputChannels mInputChannels;
   const uint32_t mBufferSize;
-  const uint32_t mDefaultNumberOfInputChannels;
   // The write index into the current input buffer
   uint32_t mInputWriteIndex;
   bool mSeenNonSilenceInput;
 };
 
 ScriptProcessorNode::ScriptProcessorNode(AudioContext* aContext,
                                          uint32_t aBufferSize,
                                          uint32_t aNumberOfInputChannels,
--- a/content/media/webaudio/ScriptProcessorNode.h
+++ b/content/media/webaudio/ScriptProcessorNode.h
@@ -54,16 +54,31 @@ public:
   virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv) MOZ_OVERRIDE
   {
     AudioNode::Disconnect(aOutput, aRv);
     if (!aRv.Failed()) {
       mPlayingRef.Drop(this);
     }
   }
 
+  virtual void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) MOZ_OVERRIDE
+  {
+    if (aChannelCount != ChannelCount()) {
+      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    }
+    return;
+  }
+  virtual void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) MOZ_OVERRIDE
+  {
+    if (aMode != ChannelCountMode::Explicit) {
+      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    }
+    return;
+  }
+
   uint32_t BufferSize() const
   {
     return mBufferSize;
   }
 
   SharedBuffers* GetSharedBuffers() const
   {
     return mSharedBuffers;
--- a/content/media/webaudio/test/test_scriptProcessorNodeChannelCount.html
+++ b/content/media/webaudio/test/test_scriptProcessorNodeChannelCount.html
@@ -27,19 +27,24 @@ addLoadEvent(function() {
 
   var monoBuffer = context.createBuffer(1, 2048, context.sampleRate);
   for (var i = 0; i < 2048; ++i) {
     monoBuffer.getChannelData(0)[i] = 1;
   }
 
   var source = context.createBufferSource();
 
-  var sp = context.createScriptProcessor(2048);
-  sp.channelCount = 3;
+  var sp = context.createScriptProcessor(2048, 3);
+  expectException(function() { sp.channelCount = 2; },
+                  DOMException.NOT_SUPPORTED_ERR);
   sp.channelCountMode = "explicit";
+  expectException(function() { sp.channelCountMode = "max"; },
+                  DOMException.NOT_SUPPORTED_ERR);
+  expectException(function() { sp.channelCountMode = "clamped-max"; },
+                  DOMException.NOT_SUPPORTED_ERR);
   sp.channelInterpretation = "discrete";
   source.start(0);
   source.buffer = buffer;
   source.connect(sp);
   sp.connect(context.destination);
 
   var monoSource = context.createBufferSource();
   monoSource.buffer = monoBuffer;