Bug 937718 - Output frames to the MediaElementAudioSourceNode when an <audio> has labeled the resource has CORS-cross-origin. r=roc
authorPaul Adenot <paul@paul.cx>
Wed, 17 Dec 2014 18:03:34 +0100
changeset 247840 0c9f97ebf7ead3d855b24f3e7d213eaf74f2c3df
parent 247839 c4ea7a2518fc05082dd81b0542b1d088f92f7046
child 247841 bcbc64d97fbf4eb28a8c7511f46a9186c4920c60
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs937718
milestone37.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 937718 - Output frames to the MediaElementAudioSourceNode when an <audio> has labeled the resource has CORS-cross-origin. r=roc
dom/html/HTMLMediaElement.cpp
dom/media/DOMMediaStream.cpp
dom/media/DOMMediaStream.h
dom/media/webaudio/MediaStreamAudioSourceNode.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1823,16 +1823,17 @@ HTMLMediaElement::CaptureStreamInternal(
         hints = DOMMediaStream::HINT_CONTENTS_AUDIO;
       }
     }
 #endif
   }
   out->mStream = DOMMediaStream::CreateTrackUnionStream(window, hints);
   nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
   out->mStream->CombineWithPrincipal(principal);
+  out->mStream->SetCORSMode(mCORSMode);
   out->mFinishWhenEnded = aFinishWhenEnded;
 
   mAudioCaptured = true;
   // Block the output stream initially.
   // Decoders are responsible for removing the block while they are playing
   // back into the output stream.
   out->mStream->GetStream()->ChangeExplicitBlockerCount(1);
   if (mDecoder) {
@@ -2654,26 +2655,26 @@ nsresult HTMLMediaElement::FinishDecoder
   mDecoder->SetAudioCaptured(mAudioCaptured);
   mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
   mDecoder->SetPreservesPitch(mPreservesPitch);
   mDecoder->SetPlaybackRate(mPlaybackRate);
   if (mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
     mDecoder->SetMinimizePrerollUntilPlaybackStarts();
   }
 
-  // Update decoder principal before we start decoding, since it
-  // can affect how we feed data to MediaStreams
-  NotifyDecoderPrincipalChanged();
-
   for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
     OutputMediaStream* ms = &mOutputStreams[i];
     aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
         ms->mFinishWhenEnded);
   }
 
+  // Update decoder principal before we start decoding, since it
+  // can affect how we feed data to MediaStreams
+  NotifyDecoderPrincipalChanged();
+
   nsresult rv = aDecoder->Load(aListener, aCloneDonor);
   if (NS_FAILED(rv)) {
     mDecoder = nullptr;
     LOG(PR_LOG_DEBUG, ("%p Failed to load for decoder %p", this, aDecoder));
     return rv;
   }
 
 #ifdef MOZ_EME
@@ -3506,20 +3507,22 @@ already_AddRefed<nsIPrincipal> HTMLMedia
 
 void HTMLMediaElement::NotifyDecoderPrincipalChanged()
 {
   nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
 
   bool subsumes;
   mDecoder->UpdateSameOriginStatus(
     !principal ||
-    (NS_SUCCEEDED(NodePrincipal()->Subsumes(principal, &subsumes)) && subsumes));
+    (NS_SUCCEEDED(NodePrincipal()->Subsumes(principal, &subsumes)) && subsumes) ||
+    mCORSMode != CORS_NONE);
 
   for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
     OutputMediaStream* ms = &mOutputStreams[i];
+    ms->mStream->SetCORSMode(mCORSMode);
     ms->mStream->CombineWithPrincipal(principal);
   }
 #ifdef MOZ_EME
   if (mMediaKeys && NS_FAILED(mMediaKeys->CheckPrincipals())) {
     mMediaKeys->Shutdown();
   }
 #endif
 }
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -139,17 +139,17 @@ NS_IMPL_ADDREF_INHERITED(DOMAudioNodeMed
 NS_IMPL_RELEASE_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream)
 NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
 
 DOMMediaStream::DOMMediaStream()
   : mLogicalStreamStartTime(0),
     mStream(nullptr), mHintContents(0), mTrackTypesAvailable(0),
-    mNotifiedOfMediaStreamGraphShutdown(false)
+    mNotifiedOfMediaStreamGraphShutdown(false), mCORSMode(CORS_NONE)
 {
 }
 
 DOMMediaStream::~DOMMediaStream()
 {
   Destroy();
 }
 
@@ -296,16 +296,30 @@ DOMMediaStream::CombineWithPrincipal(nsI
 void
 DOMMediaStream::SetPrincipal(nsIPrincipal* aPrincipal)
 {
   mPrincipal = aPrincipal;
   NotifyPrincipalChanged();
 }
 
 void
+DOMMediaStream::SetCORSMode(CORSMode aCORSMode)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  mCORSMode = aCORSMode;
+}
+
+CORSMode
+DOMMediaStream::GetCORSMode()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  return mCORSMode;
+}
+
+void
 DOMMediaStream::NotifyPrincipalChanged()
 {
   for (uint32_t i = 0; i < mPrincipalChangeObservers.Length(); ++i) {
     mPrincipalChangeObservers[i]->PrincipalChanged(this);
   }
 }
 
 
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -8,16 +8,17 @@
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "StreamBuffer.h"
 #include "nsIDOMWindow.h"
 #include "nsIPrincipal.h"
 #include "mozilla/PeerIdentity.h"
 #include "mozilla/DOMEventTargetHelper.h"
+#include "mozilla/CORSMode.h"
 
 class nsXPCClassInfo;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
 // currentTime getter.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
@@ -120,16 +121,18 @@ public:
   virtual DOMLocalMediaStream* AsDOMLocalMediaStream() { return nullptr; }
 
   bool IsFinished();
   /**
    * Returns a principal indicating who may access this stream. The stream contents
    * can only be accessed by principals subsuming this principal.
    */
   nsIPrincipal* GetPrincipal() { return mPrincipal; }
+  mozilla::CORSMode GetCORSMode();
+  void SetCORSMode(mozilla::CORSMode aCORSMode);
 
   /**
    * These are used in WebRTC.  A peerIdentity constrained MediaStream cannot be sent
    * across the network to anything other than a peer with the provided identity.
    * If this is set, then mPrincipal should be an instance of nsNullPrincipal.
    */
   PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; }
   void SetPeerIdentity(PeerIdentity* aPeerIdentity)
@@ -308,16 +311,17 @@ private:
 
   // Principal identifying who may access the contents of this stream.
   // If null, this stream can be used by anyone because it has no content yet.
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsTArray<PrincipalChangeObserver*> mPrincipalChangeObservers;
   // this is used in gUM and WebRTC to identify peers that this stream
   // is allowed to be sent to
   nsAutoPtr<PeerIdentity> mPeerIdentity;
+  CORSMode mCORSMode;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(DOMMediaStream,
                               NS_DOMMEDIASTREAM_IID)
 
 #define NS_DOMLOCALMEDIASTREAM_IID \
 { 0xb1437260, 0xec61, 0x4dfa, \
   { 0x92, 0x54, 0x04, 0x44, 0xe2, 0xb5, 0x94, 0x9c } }
--- a/dom/media/webaudio/MediaStreamAudioSourceNode.cpp
+++ b/dom/media/webaudio/MediaStreamAudioSourceNode.cpp
@@ -4,16 +4,17 @@
  * 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/. */
 
 #include "MediaStreamAudioSourceNode.h"
 #include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeExternalInputStream.h"
 #include "nsIDocument.h"
+#include "mozilla/CORSMode.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MediaStreamAudioSourceNode)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaStreamAudioSourceNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mInputStream)
@@ -65,32 +66,33 @@ MediaStreamAudioSourceNode::~MediaStream
  * media that they are not authorized to receive.
  *
  * One solution is to block the altered content, call this method, then dispatch
  * another change request to the MediaStreamGraph thread that allows the content
  * under the new principal to flow.  This might be unnecessary if the principal
  * change is changing to be the document principal.
  */
 void
-MediaStreamAudioSourceNode::PrincipalChanged(DOMMediaStream* ms)
+MediaStreamAudioSourceNode::PrincipalChanged(DOMMediaStream* aDOMMediaStream)
 {
   bool subsumes = false;
   nsPIDOMWindow* parent = Context()->GetParentObject();
   if (parent) {
     nsIDocument* doc = parent->GetExtantDoc();
     if (doc) {
       nsIPrincipal* docPrincipal = doc->NodePrincipal();
       nsIPrincipal* streamPrincipal = mInputStream->GetPrincipal();
       if (NS_FAILED(docPrincipal->Subsumes(streamPrincipal, &subsumes))) {
         subsumes = false;
       }
     }
   }
   auto stream = static_cast<AudioNodeExternalInputStream*>(mStream.get());
-  stream->SetInt32Parameter(MediaStreamAudioSourceNodeEngine::ENABLE, subsumes);
+  stream->SetInt32Parameter(MediaStreamAudioSourceNodeEngine::ENABLE,
+                            subsumes || aDOMMediaStream->GetCORSMode() != CORS_NONE);
 }
 
 size_t
 MediaStreamAudioSourceNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // Future:
   // - mInputStream
   size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);