Bug 1116384 - Keep media element alive from attached MediaSource. r=roc, a=sledru
authorKarl Tomlinson <karlt+@karlt.net>
Mon, 29 Dec 2014 16:18:41 +1300
changeset 234659 c1d21f6b75bf7dd6eaa92a677d9b9601bf236258
parent 234658 4414b41c79f7d316707e506b7da9450514d0dc48
child 234660 dc435d732d916442b310046817a3c4f8de8670dd
push id7451
push userryanvm@gmail.com
push dateThu, 08 Jan 2015 15:14:57 +0000
treeherdermozilla-aurora@bd53ccf7ce3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs1116384
milestone36.0a2
Bug 1116384 - Keep media element alive from attached MediaSource. r=roc, a=sledru
dom/media/mediasource/MediaSource.cpp
dom/media/mediasource/MediaSource.h
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -307,19 +307,22 @@ MediaSource::IsTypeSupported(const Globa
 }
 
 bool
 MediaSource::Attach(MediaSourceDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MSE_DEBUG("MediaSource(%p)::Attach(aDecoder=%p) owner=%p", this, aDecoder, aDecoder->GetOwner());
   MOZ_ASSERT(aDecoder);
+  MOZ_ASSERT(aDecoder->GetOwner());
   if (mReadyState != MediaSourceReadyState::Closed) {
     return false;
   }
+  MOZ_ASSERT(!mMediaElement);
+  mMediaElement = aDecoder->GetOwner()->GetMediaElement();
   MOZ_ASSERT(!mDecoder);
   mDecoder = aDecoder;
   mDecoder->AttachMediaSource(this);
   SetReadyState(MediaSourceReadyState::Open);
   return true;
 }
 
 void
@@ -330,16 +333,17 @@ MediaSource::Detach()
             this, mDecoder.get(), mDecoder ? mDecoder->GetOwner() : nullptr);
   if (!mDecoder) {
     MOZ_ASSERT(mReadyState == MediaSourceReadyState::Closed);
     MOZ_ASSERT(mActiveSourceBuffers->IsEmpty() && mSourceBuffers->IsEmpty());
     return;
   }
   mDecoder->DetachMediaSource();
   mDecoder = nullptr;
+  mMediaElement = nullptr;
   mFirstSourceBufferInitialized = false;
   SetReadyState(MediaSourceReadyState::Closed);
   if (mActiveSourceBuffers) {
     mActiveSourceBuffers->Clear();
   }
   if (mSourceBuffers) {
     mSourceBuffers->Clear();
   }
@@ -482,16 +486,17 @@ MediaSource::GetParentObject() const
 
 JSObject*
 MediaSource::WrapObject(JSContext* aCx)
 {
   return MediaSourceBinding::Wrap(aCx, this);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaSource, DOMEventTargetHelper,
+                                   mMediaElement,
                                    mSourceBuffers, mActiveSourceBuffers)
 
 NS_IMPL_ADDREF_INHERITED(MediaSource, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MediaSource, DOMEventTargetHelper)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaSource)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::MediaSource)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
--- a/dom/media/mediasource/MediaSource.h
+++ b/dom/media/mediasource/MediaSource.h
@@ -123,16 +123,19 @@ private:
   void DurationChange(double aOldDuration, double aNewDuration);
 
   void InitializationEvent();
 
   nsRefPtr<SourceBufferList> mSourceBuffers;
   nsRefPtr<SourceBufferList> mActiveSourceBuffers;
 
   nsRefPtr<MediaSourceDecoder> mDecoder;
+  // Ensures the media element remains alive to dispatch progress and
+  // durationchanged events.
+  nsRefPtr<HTMLMediaElement> mMediaElement;
 
   nsRefPtr<nsIPrincipal> mPrincipal;
 
   MediaSourceReadyState mReadyState;
 
   bool mFirstSourceBufferInitialized;
 };