Bug 837034. Part 2: Convert DOMMediaStream to use WebIDL. r=peterv,jesup
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 15 Feb 2013 21:04:11 +1300
changeset 122018 2512bb04bbe034ab02db20580b7a589e8cc7f3f9
parent 122017 c34f0e0628adebb282dfcb06000305032558eb6b
child 122019 70c60db1a326ae595a156b229d45f0b3ff1ec78d
push id24314
push userryanvm@gmail.com
push dateFri, 15 Feb 2013 14:39:46 +0000
treeherdermozilla-central@326c5e4868fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv, jesup
bugs837034
milestone21.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 837034. Part 2: Convert DOMMediaStream to use WebIDL. r=peterv,jesup
content/html/content/src/nsHTMLMediaElement.cpp
content/media/DOMMediaStream.cpp
content/media/DOMMediaStream.h
dom/base/URL.cpp
dom/base/URL.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/camera/CameraControlImpl.cpp
dom/camera/DOMCameraControl.h
dom/camera/DOMCameraManager.h
dom/camera/DOMCameraPreview.cpp
dom/camera/DOMCameraPreview.h
dom/media/MediaManager.cpp
dom/media/nsIDOMMediaStream.idl
dom/webidl/LocalMediaStream.webidl
dom/webidl/MediaStream.webidl
dom/webidl/MediaStreamList.webidl
dom/webidl/URL.webidl
dom/webidl/WebIDL.mk
dom/workers/URL.cpp
dom/workers/URL.h
media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
media/webrtc/signaling/src/peerconnection/MediaStreamList.cpp
media/webrtc/signaling/src/peerconnection/MediaStreamList.h
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/test/FakeMediaStreams.h
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -1598,18 +1598,23 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMut
   DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
 
   return NS_OK;
 }
 
 already_AddRefed<DOMMediaStream>
 nsHTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
 {
+  nsIDOMWindow* window = OwnerDoc()->GetInnerWindow();
+  if (!window) {
+    return nullptr;
+  }
+
   OutputMediaStream* out = mOutputStreams.AppendElement();
-  out->mStream = DOMMediaStream::CreateTrackUnionStream();
+  out->mStream = DOMMediaStream::CreateTrackUnionStream(window);
   nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
   out->mStream->CombineWithPrincipal(principal);
   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.
@@ -1621,22 +1626,28 @@ nsHTMLMediaElement::CaptureStreamInterna
   }
   nsRefPtr<DOMMediaStream> result = out->mStream;
   return result.forget();
 }
 
 NS_IMETHODIMP nsHTMLMediaElement::MozCaptureStream(nsIDOMMediaStream** aStream)
 {
   *aStream = CaptureStreamInternal(false).get();
+  if (!*aStream) {
+    return NS_ERROR_FAILURE;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream** aStream)
 {
   *aStream = CaptureStreamInternal(true).get();
+  if (!*aStream) {
+    return NS_ERROR_FAILURE;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLMediaElement::GetMozAudioCaptured(bool *aCaptured)
 {
   *aCaptured = mAudioCaptured;
   return NS_OK;
 }
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -1,117 +1,134 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* 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/. */
 
 #include "DOMMediaStream.h"
 #include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/MediaStreamBinding.h"
+#include "mozilla/dom/LocalMediaStreamBinding.h"
+#include "MediaStreamGraph.h"
 
 using namespace mozilla;
 
-DOMCI_DATA(MediaStream, DOMMediaStream)
-
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMMediaStream)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MediaStream)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMMediaStream)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMMediaStream)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMMediaStream)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMMediaStream)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-// LocalMediaStream currently is the same C++ class as MediaStream;
-// they may eventually split
-DOMCI_DATA(LocalMediaStream, DOMLocalMediaStream)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMMediaStream, mWindow)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMLocalMediaStream)
   NS_INTERFACE_MAP_ENTRY(nsIDOMLocalMediaStream)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMMediaStream, DOMMediaStream)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMLocalMediaStream)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(LocalMediaStream)
-NS_INTERFACE_MAP_END
+NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMLocalMediaStream)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMLocalMediaStream)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMLocalMediaStream)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMLocalMediaStream)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
+NS_IMPL_ADDREF_INHERITED(DOMLocalMediaStream, DOMMediaStream)
+NS_IMPL_RELEASE_INHERITED(DOMLocalMediaStream, DOMMediaStream)
+NS_IMPL_CYCLE_COLLECTION_INHERITED_0(DOMLocalMediaStream, DOMMediaStream)
 
 DOMMediaStream::~DOMMediaStream()
 {
   if (mStream) {
     mStream->Destroy();
   }
 }
 
-NS_IMETHODIMP
-DOMMediaStream::GetCurrentTime(double *aCurrentTime)
+JSObject*
+DOMMediaStream::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+{
+  return dom::MediaStreamBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+double
+DOMMediaStream::CurrentTime()
+{
+  return mStream ? MediaTimeToSeconds(mStream->GetCurrentTime()) : 0.0;
+}
+
+bool
+DOMMediaStream::IsFinished()
+{
+  return !mStream || mStream->IsFinished();
+}
+
+void
+DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
 {
-  *aCurrentTime = mStream ? MediaTimeToSeconds(mStream->GetCurrentTime()) : 0.0;
-  return NS_OK;
+  mWindow = aWindow;
+  SetHintContents(aHintContents);
+  MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
+  mStream = gm->CreateSourceStream(this);
+}
+
+void
+DOMMediaStream::InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+{
+  mWindow = aWindow;
+  SetHintContents(aHintContents);
+  MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
+  mStream = gm->CreateTrackUnionStream(this);
+}
+
+already_AddRefed<DOMMediaStream>
+DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+{
+  nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
+  stream->InitSourceStream(aWindow, aHintContents);
+  return stream.forget();
+}
+
+already_AddRefed<DOMMediaStream>
+DOMMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+{
+  nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
+  stream->InitTrackUnionStream(aWindow, aHintContents);
+  return stream.forget();
+}
+
+bool
+DOMMediaStream::CombineWithPrincipal(nsIPrincipal* aPrincipal)
+{
+  return nsContentUtils::CombineResourcePrincipals(&mPrincipal, aPrincipal);
 }
 
 DOMLocalMediaStream::~DOMLocalMediaStream()
 {
   if (mStream) {
     // Make sure Listeners of this stream know it's going away
     Stop();
   }
 }
 
-NS_IMETHODIMP
+JSObject*
+DOMLocalMediaStream::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+{
+  return dom::LocalMediaStreamBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+void
 DOMLocalMediaStream::Stop()
 {
   if (mStream && mStream->AsSourceStream()) {
     mStream->AsSourceStream()->EndAllTrackAndFinish();
   }
-  return NS_OK;
 }
 
-already_AddRefed<DOMMediaStream>
-DOMMediaStream::CreateSourceStream(uint32_t aHintContents)
+already_AddRefed<DOMLocalMediaStream>
+DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
 {
-  nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
-  stream->InitSourceStream(aHintContents);
+  nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
+  stream->InitSourceStream(aWindow, aHintContents);
   return stream.forget();
 }
 
 already_AddRefed<DOMLocalMediaStream>
-DOMLocalMediaStream::CreateSourceStream(uint32_t aHintContents)
+DOMLocalMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
 {
   nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
-  stream->InitSourceStream(aHintContents);
-  return stream.forget();
-}
-
-already_AddRefed<DOMMediaStream>
-DOMMediaStream::CreateTrackUnionStream(uint32_t aHintContents)
-{
-  nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
-  stream->InitTrackUnionStream(aHintContents);
+  stream->InitTrackUnionStream(aWindow, aHintContents);
   return stream.forget();
 }
-
-already_AddRefed<DOMLocalMediaStream>
-DOMLocalMediaStream::CreateTrackUnionStream(uint32_t aHintContents)
-{
-  nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
-  stream->InitTrackUnionStream(aHintContents);
-  return stream.forget();
-}
-
-bool
-DOMMediaStream::CombineWithPrincipal(nsIPrincipal* aPrincipal)
-{
-  return nsContentUtils::CombineResourcePrincipals(&mPrincipal, aPrincipal);
-}
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -2,49 +2,65 @@
 /* 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 NSDOMMEDIASTREAM_H_
 #define NSDOMMEDIASTREAM_H_
 
 #include "nsIDOMMediaStream.h"
-#include "MediaStreamGraph.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIPrincipal.h"
+#include "nsWrapperCache.h"
+#include "nsIDOMWindow.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
 #endif
+// X11 has a #define for CurrentTime. Unbelievable :-(.
+#ifdef CurrentTime
+#undef CurrentTime
+#endif
 
 namespace mozilla {
 
+class MediaStream;
+
 /**
  * DOM wrapper for MediaStreams.
  */
-class DOMMediaStream : public nsIDOMMediaStream
+class DOMMediaStream : public nsIDOMMediaStream,
+                       public nsWrapperCache
 {
   friend class DOMLocalMediaStream;
 
 public:
-  DOMMediaStream() : mStream(nullptr), mHintContents(0) {}
+  DOMMediaStream() : mStream(nullptr), mHintContents(0)
+  {
+    SetIsDOMBinding();
+  }
   virtual ~DOMMediaStream();
 
-  NS_DECL_CYCLE_COLLECTION_CLASS(DOMMediaStream)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMMediaStream)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
-  NS_DECL_NSIDOMMEDIASTREAM
+  nsIDOMWindow* GetParentObject() const
+  {
+    return mWindow;
+  }
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
 
+  double CurrentTime();
   MediaStream* GetStream() { return mStream; }
-  bool IsFinished() { return !mStream || mStream->IsFinished(); }
+  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; }
 
   /**
    * Indicate that data will be contributed to this stream from origin aPrincipal.
@@ -52,45 +68,40 @@ public:
    * of this stream can only be accessed by principals that subsume aPrincipal.
    * Returns true if the stream's principal changed.
    */
   bool CombineWithPrincipal(nsIPrincipal* aPrincipal);
 
   /**
    * Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream.
    */
-  static already_AddRefed<DOMMediaStream> CreateSourceStream(uint32_t aHintContents);
+  static already_AddRefed<DOMMediaStream>
+  CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
 
   // Hints to tell the SDP generator about whether this
   // MediaStream probably has audio and/or video
   enum {
     HINT_CONTENTS_AUDIO = 0x00000001U,
     HINT_CONTENTS_VIDEO = 0x00000002U
   };
   uint32_t GetHintContents() const { return mHintContents; }
   void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; }
 
   /**
    * Create an nsDOMMediaStream whose underlying stream is a TrackUnionStream.
    */
-  static already_AddRefed<DOMMediaStream> CreateTrackUnionStream(uint32_t aHintContents = 0);
+  static already_AddRefed<DOMMediaStream>
+  CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
 
 protected:
-  void InitSourceStream(uint32_t aHintContents)
-  {
-    SetHintContents(aHintContents);
-    MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
-    mStream = gm->CreateSourceStream(this);
-  }
-  void InitTrackUnionStream(uint32_t aHintContents)
-  {
-    SetHintContents(aHintContents);
-    MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
-    mStream = gm->CreateTrackUnionStream(this);
-  }
+  void InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
+  void InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
+
+  // We need this to track our parent object.
+  nsCOMPtr<nsIDOMWindow> mWindow;
 
   // MediaStream is owned by the graph, but we tell it when to die, and it won't
   // die until we let it.
   MediaStream* mStream;
   // 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;
 
@@ -103,26 +114,29 @@ class DOMLocalMediaStream : public DOMMe
                             public nsIDOMLocalMediaStream
 {
 public:
   DOMLocalMediaStream() {}
   virtual ~DOMLocalMediaStream();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMLocalMediaStream, DOMMediaStream)
-  NS_DECL_NSIDOMLOCALMEDIASTREAM
 
-  NS_FORWARD_NSIDOMMEDIASTREAM(DOMMediaStream::)
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
+
+  virtual void Stop();
 
   /**
    * Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
    */
-  static already_AddRefed<DOMLocalMediaStream> CreateSourceStream(uint32_t aHintContents);
+  static already_AddRefed<DOMLocalMediaStream>
+  CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
 
   /**
    * Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
    */
-  static already_AddRefed<DOMLocalMediaStream> CreateTrackUnionStream(uint32_t aHintContents = 0);
+  static already_AddRefed<DOMLocalMediaStream>
+  CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
 };
 
 }
 
 #endif /* NSDOMMEDIASTREAM_H_ */
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #include "URL.h"
 
 #include "nsGlobalWindow.h"
 #include "nsIDOMFile.h"
-#include "nsIDOMMediaStream.h"
+#include "DOMMediaStream.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
 #include "nsContentUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 
 namespace mozilla {
 namespace dom {
 
@@ -23,22 +23,22 @@ URL::CreateObjectURL(const GlobalObject&
                      ErrorResult& aError)
 {
   CreateObjectURLInternal(aGlobal.Get(), aBlob,
                           NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult,
                           aError);
 }
 
 void
-URL::CreateObjectURL(const GlobalObject& aGlobal, nsIDOMMediaStream* aStream,
+URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
                      const mozilla::dom::objectURLOptions& aOptions,
                      nsString& aResult,
                      ErrorResult& aError)
 {
-  CreateObjectURLInternal(aGlobal.Get(), aStream,
+  CreateObjectURLInternal(aGlobal.Get(), &aStream,
                           NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME), aOptions,
                           aResult, aError);
 }
 
 void
 URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
                              const nsACString& aScheme,
                              const mozilla::dom::objectURLOptions& aOptions,
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -4,31 +4,33 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef URL_h___
 #define URL_h___
 
 #include "nscore.h"
 #include "mozilla/dom/URLBinding.h"
 
 class nsIDOMBlob;
-class nsIDOMMediaStream;
 
 namespace mozilla {
+
+class DOMMediaStream;
+
 namespace dom {
 
 class URL MOZ_FINAL
 {
 public:
   // WebIDL methods
   static void CreateObjectURL(const GlobalObject& aGlobal, nsIDOMBlob* aBlob,
                               const objectURLOptions& aOptions,
                               nsString& aResult,
                               ErrorResult& aError);
   static void CreateObjectURL(const GlobalObject& aGlobal,
-                              nsIDOMMediaStream* aStream,
+                              DOMMediaStream& aStream,
                               const mozilla::dom::objectURLOptions& aOptions,
                               nsString& aResult,
                               mozilla::ErrorResult& aError);
   static void RevokeObjectURL(const GlobalObject& aGlobal,
                               const nsAString& aURL);
 
 private:
   static void CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -259,19 +259,16 @@
 #include "nsIDOMHTMLTitleElement.h"
 #include "nsIDOMHTMLUListElement.h"
 #include "nsIDOMHTMLUnknownElement.h"
 #include "nsIDOMMediaError.h"
 #include "nsIDOMTimeRanges.h"
 #include "nsIDOMHTMLSourceElement.h"
 #include "nsIDOMHTMLVideoElement.h"
 #include "nsIDOMHTMLAudioElement.h"
-#if defined (MOZ_MEDIA)
-#include "nsIDOMMediaStream.h"
-#endif
 #include "nsIDOMProgressEvent.h"
 #include "nsIDOMCSSCharsetRule.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSSupportsRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
@@ -1257,20 +1254,16 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(HTMLSourceElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MediaError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLAudioElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(TimeRanges, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MediaStream, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(LocalMediaStream, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
   // DOM Traversal NodeIterator class
   NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // data transfer for drag and drop
   NS_DEFINE_CLASSINFO_DATA(DataTransfer, nsDOMGenericSH,
@@ -3325,24 +3318,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(HTMLAudioElement, nsIDOMHTMLAudioElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLAudioElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(TimeRanges, nsIDOMTimeRanges)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMTimeRanges)
   DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(MediaStream, nsIDOMMediaStream)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMediaStream)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(LocalMediaStream, nsIDOMLocalMediaStream)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocalMediaStream)
-  DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN(DataTransfer, nsIDOMDataTransfer)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataTransfer)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(NotifyPaintEvent, nsIDOMNotifyPaintEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNotifyPaintEvent)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -318,20 +318,16 @@ DOMCI_CLASS(CSSFontFaceRule)
 
 #if defined(MOZ_MEDIA)
 // WhatWG Video Element
 DOMCI_CLASS(HTMLVideoElement)
 DOMCI_CLASS(HTMLSourceElement)
 DOMCI_CLASS(MediaError)
 DOMCI_CLASS(HTMLAudioElement)
 DOMCI_CLASS(TimeRanges)
-
-// Media streams
-DOMCI_CLASS(MediaStream)
-DOMCI_CLASS(LocalMediaStream)
 #endif
 
 // DOM Traversal NodeIterator class
 DOMCI_CLASS(NodeIterator)
 
 DOMCI_CLASS(DataTransfer)
 
 DOMCI_CLASS(NotifyPaintEvent)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -601,24 +601,30 @@ DOMInterfaces = {
     'register': False
 },
 
 'MediaError': {
     'hasInstanceInterface': 'nsIDOMMediaError',
 },
 
 'MediaStream': [{
-    'nativeType': 'nsIDOMMediaStream',
+    'headerFile': 'DOMMediaStream.h',
+    'nativeType': 'mozilla::DOMMediaStream'
 },
 {
     'nativeType': 'JSObject',
     'workers': True,
     'skipGen': True
 }],
 
+'LocalMediaStream': {
+    'headerFile': 'DOMMediaStream.h',
+    'nativeType': 'mozilla::DOMLocalMediaStream'
+},
+
 'MediaStreamList': {
     'headerFile': 'MediaStreamList.h',
     'wrapperCache': False,
     'nativeOwnership': 'owned',
     'resultNotAddRefed': [ '__indexedGetter' ],
     'binaryNames': { '__indexedGetter': 'IndexedGetter' }
 },
 
--- a/dom/camera/CameraControlImpl.cpp
+++ b/dom/camera/CameraControlImpl.cpp
@@ -2,16 +2,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 "base/basictypes.h"
 #include "DOMCameraPreview.h"
 #include "CameraRecorderProfiles.h"
 #include "CameraControlImpl.h"
 #include "CameraCommon.h"
+#include "nsGlobalWindow.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::idl;
 
 CameraControlImpl::CameraControlImpl(uint32_t aCameraId, nsIThread* aCameraThread, uint64_t aWindowId)
   : mCameraId(aCameraId)
   , mCameraThread(aCameraThread)
@@ -415,14 +416,17 @@ GetPreviewStreamResult::Run()
   /**
    * The camera preview stream object is DOM-facing, and as such
    * must be a cycle-collection participant created on the main
    * thread.
    */
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsICameraPreviewStreamCallback> onSuccess = mOnSuccessCb.get();
-  if (onSuccess && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
-    nsCOMPtr<nsIDOMMediaStream> stream = new DOMCameraPreview(mCameraControl, mWidth, mHeight, mWindowId, mFramesPerSecond);
+  nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
+  if (onSuccess && nsDOMCameraManager::IsWindowStillActive(mWindowId) && window) {
+    nsCOMPtr<nsIDOMMediaStream> stream =
+      new DOMCameraPreview(window, mCameraControl, mWidth, mHeight,
+	                         mFramesPerSecond);
     onSuccess->HandleEvent(stream);
   }
   return NS_OK;
 }
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -21,17 +21,19 @@ namespace mozilla {
 // Main camera control.
 class nsDOMCameraControl : public nsICameraControl
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMCameraControl)
   NS_DECL_NSICAMERACONTROL
 
-  nsDOMCameraControl(uint32_t aCameraId, nsIThread* aCameraThread, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId);
+  nsDOMCameraControl(uint32_t aCameraId, nsIThread* aCameraThread,
+                     nsICameraGetCameraCallback* onSuccess,
+                     nsICameraErrorCallback* onError, uint64_t aWindowId);
   nsresult Result(nsresult aResult, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId);
 
   void Shutdown();
 
 protected:
   virtual ~nsDOMCameraControl();
 
 private:
--- a/dom/camera/DOMCameraManager.h
+++ b/dom/camera/DOMCameraManager.h
@@ -47,17 +47,17 @@ public:
   void OnNavigation(uint64_t aWindowId);
 
 protected:
   void XpComShutdown();
   void Shutdown(uint64_t aWindowId);
   ~nsDOMCameraManager();
 
 private:
-  nsDOMCameraManager();
+  nsDOMCameraManager() MOZ_DELETE;
   nsDOMCameraManager(uint64_t aWindowId);
   nsDOMCameraManager(const nsDOMCameraManager&) MOZ_DELETE;
   nsDOMCameraManager& operator=(const nsDOMCameraManager&) MOZ_DELETE;
 
 protected:
   uint64_t mWindowId;
   nsCOMPtr<nsIThread> mCameraThread;
   /**
--- a/dom/camera/DOMCameraPreview.cpp
+++ b/dom/camera/DOMCameraPreview.cpp
@@ -135,42 +135,44 @@ public:
     }
   }
 
 protected:
   // Raw pointer; if we exist, 'mDOMPreview' exists as well
   DOMCameraPreview* mDOMPreview;
 };
 
-DOMCameraPreview::DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint64_t aWindowId, uint32_t aFrameRate)
+DOMCameraPreview::DOMCameraPreview(nsGlobalWindow* aWindow,
+                                   ICameraControl* aCameraControl,
+                                   uint32_t aWidth, uint32_t aHeight,
+                                   uint32_t aFrameRate)
   : DOMMediaStream()
   , mState(STOPPED)
   , mWidth(aWidth)
   , mHeight(aHeight)
   , mFramesPerSecond(aFrameRate)
   , mFrameCount(0)
   , mCameraControl(aCameraControl)
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p : mWidth=%d, mHeight=%d, mFramesPerSecond=%d\n", __func__, __LINE__, this, mWidth, mHeight, mFramesPerSecond);
 
   mImageContainer = LayerManager::CreateImageContainer();
   MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
   mStream = gm->CreateSourceStream(this);
+  mWindow = aWindow;
   mInput = GetStream()->AsSourceStream();
 
   mListener = new DOMCameraPreviewListener(this);
   mInput->AddListener(mListener);
 
   mInput->AddTrack(TRACK_VIDEO, mFramesPerSecond, 0, new VideoSegment());
   mInput->AdvanceKnownTracksTime(MEDIA_TIME_MAX);
 
-  nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
-     (nsGlobalWindow::GetInnerWindowWithId(aWindowId));
-  if (window && window->GetExtantDoc()) {
-    this->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
+  if (aWindow->GetExtantDoc()) {
+    CombineWithPrincipal(aWindow->GetExtantDoc()->NodePrincipal());
   }
 }
 
 DOMCameraPreview::~DOMCameraPreview()
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p, mListener=%p\n", __func__, __LINE__, this, mListener);
   mInput->RemoveListener(mListener);
 }
--- a/dom/camera/DOMCameraPreview.h
+++ b/dom/camera/DOMCameraPreview.h
@@ -7,39 +7,40 @@
 
 #include "nsCycleCollectionParticipant.h"
 #include "MediaStreamGraph.h"
 #include "StreamBuffer.h"
 #include "ICameraControl.h"
 #include "DOMMediaStream.h"
 #include "CameraCommon.h"
 
+class nsGlobalWindow;
+
 namespace mozilla {
 
 typedef void (*FrameBuilder)(mozilla::layers::Image* aImage, void* aBuffer, uint32_t aWidth, uint32_t aHeight);
 
 /**
  * DOMCameraPreview is only exposed to the DOM as an nsDOMMediaStream,
- * which is a cycle-collection participant already.
+ * which is a cycle-collection participant already, and we don't
+ * add any traceable fields here, so we don't need to declare any
+ * more cycle-collection goop.
  */
 class DOMCameraPreview : public DOMMediaStream
 {
 protected:
   enum { TRACK_VIDEO = 1 };
 
 public:
-  DOMCameraPreview(ICameraControl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint64_t aWindowId, uint32_t aFramesPerSecond = 30);
+  DOMCameraPreview(nsGlobalWindow* aWindow, ICameraControl* aCameraControl,
+                   uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond = 30);
+
   bool ReceiveFrame(void* aBuffer, ImageFormat aFormat, mozilla::FrameBuilder aBuilder);
   bool HaveEnoughBuffered();
 
-  NS_IMETHODIMP
-  GetCurrentTime(double* aCurrentTime) {
-    return DOMMediaStream::GetCurrentTime(aCurrentTime);
-  }
-
   void Start();   // called by the MediaStreamListener to start preview
   void Started(); // called by the CameraControl when preview is started
   void StopPreview(); // called by the MediaStreamListener to stop preview
   void Stopped(bool aForced = false);
                   // called by the CameraControl when preview is stopped
   void Error();   // something went wrong, NS_RELEASE needed
 
   void SetStateStarted();
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -256,41 +256,40 @@ MediaDevice::GetSource()
 /**
  * A subclass that we only use to stash internal pointers to MediaStreamGraph objects
  * that need to be cleaned up.
  */
 class nsDOMUserMediaStream : public DOMLocalMediaStream
 {
 public:
   static already_AddRefed<nsDOMUserMediaStream>
-  CreateTrackUnionStream(uint32_t aHintContents)
+  CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
   {
     nsRefPtr<nsDOMUserMediaStream> stream = new nsDOMUserMediaStream();
-    stream->InitTrackUnionStream(aHintContents);
+    stream->InitTrackUnionStream(aWindow, aHintContents);
     return stream.forget();
   }
 
   virtual ~nsDOMUserMediaStream()
   {
     Stop();
 
     if (mPort) {
       mPort->Destroy();
     }
     if (mSourceStream) {
       mSourceStream->Destroy();
     }
   }
 
-  NS_IMETHODIMP Stop()
+  virtual void Stop()
   {
     if (mSourceStream) {
       mSourceStream->EndAllTrackAndFinish();
     }
-    return NS_OK;
   }
 
   // The actual MediaStream is a TrackUnionStream. But these resources need to be
   // explicitly destroyed too.
   nsRefPtr<SourceMediaStream> mSourceStream;
   nsRefPtr<MediaInputPort> mPort;
 };
 
@@ -327,31 +326,33 @@ public:
     , mManager(MediaManager::GetInstance()) {}
 
   ~GetUserMediaStreamRunnable() {}
 
   NS_IMETHOD
   Run()
   {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
+    nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
+      (nsGlobalWindow::GetInnerWindowWithId(mWindowID));
 
     // We're on main-thread, and the windowlist can only
     // be invalidated from the main-thread (see OnNavigation)
     StreamListeners* listeners = mManager->GetWindowListeners(mWindowID);
-    if (!listeners) {
+    if (!listeners || !window || !window->GetExtantDoc()) {
       // This window is no longer live.  mListener has already been removed
       return NS_OK;
     }
 
     // Create a media stream.
     uint32_t hints = (mAudioSource ? DOMMediaStream::HINT_CONTENTS_AUDIO : 0);
     hints |= (mVideoSource ? DOMMediaStream::HINT_CONTENTS_VIDEO : 0);
 
     nsRefPtr<nsDOMUserMediaStream> trackunion =
-      nsDOMUserMediaStream::CreateTrackUnionStream(hints);
+      nsDOMUserMediaStream::CreateTrackUnionStream(window, hints);
     if (!trackunion) {
       nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
       LOG(("Returning error for getUserMedia() - no stream"));
       error->OnError(NS_LITERAL_STRING("NO_STREAM"));
       return NS_OK;
     }
 
     MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
@@ -359,21 +360,17 @@ public:
 
     // connect the source stream to the track union stream to avoid us blocking
     trackunion->GetStream()->AsProcessedStream()->SetAutofinish(true);
     nsRefPtr<MediaInputPort> port = trackunion->GetStream()->AsProcessedStream()->
       AllocateInputPort(stream, MediaInputPort::FLAG_BLOCK_OUTPUT);
     trackunion->mSourceStream = stream;
     trackunion->mPort = port.forget();
 
-    nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
-      (nsGlobalWindow::GetInnerWindowWithId(mWindowID));
-    if (window && window->GetExtantDoc()) {
-      trackunion->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
-    }
+    trackunion->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
 
     // The listener was added at the begining in an inactive state.
     // Activate our listener. We'll call Start() on the source when get a callback
     // that the MediaStream has started consuming. The listener is freed
     // when the page is invalidated (on navigation or close).
     mListener->Activate(stream.forget(), mAudioSource, mVideoSource);
 
     // Dispatch to the media thread to ask it to start the sources,
--- a/dom/media/nsIDOMMediaStream.idl
+++ b/dom/media/nsIDOMMediaStream.idl
@@ -7,20 +7,21 @@
 
 // undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
 %{C++
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 %}
 
-[scriptable, builtinclass, uuid(f37c2871-4cb7-4672-bb28-c2d601f7cc9e)]
+[scriptable, builtinclass, uuid(3ef760bb-ff19-4dbb-b552-af27ab84b9b8)]
 interface nsIDOMMediaStream : nsISupports
 {
-  readonly attribute double currentTime;
+  /* Placeholder interface only; will be removed after further WebIDL conversion.
+     Do not add anything here. */
 };
 
-[scriptable, builtinclass, uuid(210a16e3-2a38-4ae9-b0f6-0fb5a8252814)]
+[scriptable, builtinclass, uuid(dd37150a-9823-4605-ac4c-3516629a8aaf)]
 interface nsIDOMLocalMediaStream : nsIDOMMediaStream
 {
-  void stop();
+  /* Placeholder interface only; will be removed after further WebIDL conversion.
+     Do not add anything here. */
 };
-
new file mode 100644
--- /dev/null
+++ b/dom/webidl/LocalMediaStream.webidl
@@ -0,0 +1,15 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origins of this IDL file are
+ * http://dev.w3.org/2011/webrtc/editor/getusermedia.html
+ *
+ * Copyright  2012 W3C (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface LocalMediaStream : MediaStream {
+    void stop();
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MediaStream.webidl
@@ -0,0 +1,25 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origins of this IDL file are
+ * http://dev.w3.org/2011/webrtc/editor/getusermedia.html
+ *
+ * Copyright � 2012 W3C� (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface MediaStream : EventTarget {
+    // readonly attribute DOMString    id;
+    // sequence<MediaStreamTrack> getAudioTracks ();
+    // sequence<MediaStreamTrack> getVideoTracks ();
+    // MediaStreamTrack           getTrackById (DOMString trackId);
+    // void                       addTrack (MediaStreamTrack track);
+    // void                       removeTrack (MediaStreamTrack track);
+    //         attribute boolean      ended;
+    //         attribute EventHandler onended;
+    //         attribute EventHandler onaddtrack;
+    //         attribute EventHandler onremovetrack;
+	readonly attribute double currentTime;
+};
--- a/dom/webidl/MediaStreamList.webidl
+++ b/dom/webidl/MediaStreamList.webidl
@@ -1,13 +1,11 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
 
-interface MediaStream;
-
 [NoInterfaceObject]
 interface MediaStreamList {
   getter MediaStream? (unsigned long index);
   readonly attribute unsigned long length;
 };
--- a/dom/webidl/URL.webidl
+++ b/dom/webidl/URL.webidl
@@ -6,18 +6,16 @@
  * The origins of this IDL file are
  * http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking
  * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-interface MediaStream;
- 
 interface URL {
   [Throws]
   static DOMString? createObjectURL(Blob blob, optional objectURLOptions options);
   [Throws]
   static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
   static void revokeObjectURL(DOMString url);
 };
 
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -102,17 +102,19 @@ webidl_files = \
   HTMLTableColElement.webidl \
   HTMLTableElement.webidl \
   HTMLTableRowElement.webidl \
   HTMLTableSectionElement.webidl \
   HTMLTitleElement.webidl \
   HTMLUListElement.webidl \
   ImageData.webidl \
   LinkStyle.webidl \
+  LocalMediaStream.webidl \
   Location.webidl \
+  MediaStream.webidl \
   MutationObserver.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeList.webidl \
   PaintRequest.webidl \
   PaintRequestList.webidl \
   PannerNode.webidl \
   Performance.webidl \
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -215,16 +215,25 @@ URL::CreateObjectURL(const WorkerGlobalO
 
   if (!runnable->Dispatch(cx)) {
     JS_ReportPendingException(cx);
   }
 }
 
 // static
 void
+URL::CreateObjectURL(const WorkerGlobalObject& aGlobal, JSObject& aBlob,
+                     const mozilla::dom::objectURLOptionsWorkers& aOptions,
+                     nsString& aResult, mozilla::ErrorResult& aRv)
+{
+  return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv);
+}
+
+// static
+void
 URL::RevokeObjectURL(const WorkerGlobalObject& aGlobal, const nsAString& aUrl)
 {
   JSContext* cx = aGlobal.GetContext();
   WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
 
   nsRefPtr<RevokeURLRunnable> runnable =
     new RevokeURLRunnable(workerPrivate, aUrl);
 
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -17,14 +17,19 @@ class URL : public EventTarget
 {
 public: // Methods for WebIDL
   static void
   CreateObjectURL(const WorkerGlobalObject& aGlobal,
                   JSObject* aArg, const objectURLOptionsWorkers& aOptions,
                   nsString& aResult, ErrorResult& aRv);
 
   static void
+  CreateObjectURL(const WorkerGlobalObject& aGlobal,
+                  JSObject& aArg, const objectURLOptionsWorkers& aOptions,
+                  nsString& aResult, ErrorResult& aRv);
+
+  static void
   RevokeObjectURL(const WorkerGlobalObject& aGlobal, const nsAString& aUrl);
 };
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_url_h__ */
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
@@ -8,16 +8,17 @@
 #define mediapipeline_h__
 
 #include "sigslot.h"
 
 #ifdef USE_FAKE_MEDIA_STREAMS
 #include "FakeMediaStreams.h"
 #else
 #include "DOMMediaStream.h"
+#include "MediaStreamGraph.h"
 #endif
 #include "MediaConduitInterface.h"
 #include "AudioSegment.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "SrtpFlow.h"
 #include "databuffer.h"
 #include "runnable_utils.h"
 #include "transportflow.h"
--- a/media/webrtc/signaling/src/peerconnection/MediaStreamList.cpp
+++ b/media/webrtc/signaling/src/peerconnection/MediaStreamList.cpp
@@ -45,29 +45,29 @@ MediaStreamList::WrapObject(JSContext* c
   }
   return obj;
 #else
   return nullptr;
 #endif
 }
 
 template<class T>
-static nsIDOMMediaStream*
+static DOMMediaStream*
 GetStreamFromInfo(T* info, bool& found)
 {
   if (!info) {
     found = false;
     return nullptr;
   }
 
   found = true;
   return info->GetMediaStream();
 }
 
-nsIDOMMediaStream*
+DOMMediaStream*
 MediaStreamList::IndexedGetter(uint32_t index, bool& found)
 {
   if (mType == Local) {
     return GetStreamFromInfo(mPeerConnection->media()->
       GetLocalStream(index), found);
   }
 
   return GetStreamFromInfo(mPeerConnection->media()->
--- a/media/webrtc/signaling/src/peerconnection/MediaStreamList.h
+++ b/media/webrtc/signaling/src/peerconnection/MediaStreamList.h
@@ -6,17 +6,22 @@
 #define MediaStreamList_h__
 
 #include "mozilla/ErrorResult.h"
 #include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
 #include "jspubtd.h"
 #include "mozilla/dom/NonRefcountedDOMObject.h"
 
-class nsIDOMMediaStream;
+#ifdef USE_FAKE_MEDIA_STREAMS
+#include "FakeMediaStreams.h"
+#else
+#include "DOMMediaStream.h"
+#endif
+
 namespace sipcc {
 class PeerConnectionImpl;
 } // namespace sipcc
 
 namespace mozilla {
 namespace dom {
 
 class MediaStreamList : public NonRefcountedDOMObject
@@ -27,17 +32,17 @@ public:
     Remote
   };
 
   MediaStreamList(sipcc::PeerConnectionImpl* peerConnection, StreamType type);
   ~MediaStreamList();
 
   JSObject* WrapObject(JSContext* cx, ErrorResult& error);
 
-  nsIDOMMediaStream* IndexedGetter(uint32_t index, bool& found);
+  DOMMediaStream* IndexedGetter(uint32_t index, bool& found);
   uint32_t Length();
 
 private:
   nsRefPtr<sipcc::PeerConnectionImpl> mPeerConnection;
   StreamType mType;
 };
 
 } // namespace dom
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -275,21 +275,23 @@ PeerConnectionImpl::~PeerConnectionImpl(
   nsCOMPtr<nsIThread> mainThread;
   NS_GetMainThread(getter_AddRefs(mainThread));
   NS_ProxyRelease(mainThread, mPCObserver);
   */
 }
 
 // One level of indirection so we can use WrapRunnable in CreateMediaStream.
 nsresult
-PeerConnectionImpl::MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
+PeerConnectionImpl::MakeMediaStream(nsIDOMWindow* aWindow,
+                                    uint32_t aHint, nsIDOMMediaStream** aRetval)
 {
   MOZ_ASSERT(aRetval);
 
-  nsRefPtr<DOMMediaStream> stream = DOMMediaStream::CreateSourceStream(aHint);
+  nsRefPtr<DOMMediaStream> stream =
+    DOMMediaStream::CreateSourceStream(aWindow, aHint);
   NS_ADDREF(*aRetval = stream);
 
   CSFLogDebugS(logTag, "Created media stream " << static_cast<void*>(stream)
     << " inner: " << static_cast<void*>(stream->GetStream()));
 
   return NS_OK;
 }
 
@@ -301,17 +303,17 @@ PeerConnectionImpl::CreateRemoteSourceSt
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
 
   nsIDOMMediaStream* stream;
 
   // We need to pass a dummy hint here because FakeMediaStream currently
   // needs to actually propagate a hint for local streams.
   // TODO(ekr@rtfm.com): Clean up when we have explicit track lists.
   // See bug 834835.
-  nsresult res = MakeMediaStream(0, &stream);
+  nsresult res = MakeMediaStream(mWindow, 0, &stream);
   if (NS_FAILED(res)) {
     return res;
   }
 
   DOMMediaStream* comstream = static_cast<DOMMediaStream*>(stream);
   static_cast<mozilla::SourceMediaStream*>(comstream->GetStream())->SetPullEnabled(true);
 
   nsRefPtr<RemoteSourceStreamInfo> remote;
@@ -584,20 +586,20 @@ PeerConnectionImpl::CreateFakeMediaStrea
   // Hack to allow you to mute the stream
   if (aHint & MEDIA_STREAM_MUTE) {
     mute = true;
     aHint &= ~MEDIA_STREAM_MUTE;
   }
 
   nsresult res;
   if (!mThread || NS_IsMainThread()) {
-    res = MakeMediaStream(aHint, aRetval);
+    res = MakeMediaStream(mWindow, aHint, aRetval);
   } else {
     mThread->Dispatch(WrapRunnableNMRet(
-        &PeerConnectionImpl::MakeMediaStream, aHint, aRetval, &res
+        &PeerConnectionImpl::MakeMediaStream, mWindow, aHint, aRetval, &res
     ), NS_DISPATCH_SYNC);
   }
 
   if (NS_FAILED(res)) {
     return res;
   }
 
   if (!mute) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -139,17 +139,18 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_IPEERCONNECTION
 
   static PeerConnectionImpl* CreatePeerConnection();
   static nsresult ConvertRTCConfiguration(const JS::Value& aSrc,
     RTCConfiguration *aDst, JSContext* aCx);
   static nsresult ConvertConstraints(
     const JS::Value& aConstraints, MediaConstraints* aObj, JSContext* aCx);
-  static nsresult MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aStream);
+  static nsresult MakeMediaStream(nsIDOMWindow* aWindow,
+                                  uint32_t aHint, nsIDOMMediaStream** aStream);
 
   Role GetRole() const {
     PC_AUTO_ENTER_API_CALL_NO_CHECK();
     return mRole;
   }
 
   nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo);
 
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -18,16 +18,18 @@
 #include "AudioSegment.h"
 #include "MediaSegment.h"
 #include "StreamBuffer.h"
 #include "nsTArray.h"
 #include "nsIRunnable.h"
 #include "nsISupportsImpl.h"
 #include "nsIDOMMediaStream.h"
 
+class nsIDOMWindow;
+
 namespace mozilla {
    class MediaStreamGraph;
    class MediaSegment;
 };
 
 class Fake_SourceMediaStream;
 
 class Fake_MediaStreamListener
@@ -181,21 +183,20 @@ public:
   Fake_DOMMediaStream(Fake_MediaStream *stream) :
       mMediaStream(stream) {}
 
   virtual ~Fake_DOMMediaStream() {
     // Note: memory leak
     mMediaStream->Stop();
   }
 
+  NS_DECL_ISUPPORTS
 
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMMEDIASTREAM
-
-  static already_AddRefed<Fake_DOMMediaStream> CreateSourceStream(uint32_t aHintContents) {
+  static already_AddRefed<Fake_DOMMediaStream>
+  CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents) {
     Fake_SourceMediaStream *source = new Fake_SourceMediaStream();
 
     Fake_DOMMediaStream *ds = new Fake_DOMMediaStream(source);
     ds->SetHintContents(aHintContents);
     ds->AddRef();
 
     return ds;
   }