Bug 1383628. P5 - move CanClone() from MediaResource to BaseMediaResource. draft
authorJW Wang <jwwang@mozilla.com>
Fri, 04 Aug 2017 15:29:55 +0800
changeset 642343 63e8767275aaf989fdedf8eb577e895d97953355
parent 642342 0adc20143b54947770fc8f5f0c54e83423c510d6
child 642344 e798a152f933606b960da43467d1c47a2f5aa05f
push id72707
push userjwwang@mozilla.com
push dateTue, 08 Aug 2017 02:32:36 +0000
bugs1383628
milestone57.0a1
Bug 1383628. P5 - move CanClone() from MediaResource to BaseMediaResource. 1. we move clone related methods to BaseMediaResource which is the only cloneable sub-class of MediaResource. 2. add CanClone() to ChannelMediaDecoder to reduce the dependency on MediaResource for HTMLMediaElement. MediaResource should be internal details to MediaDecoder. MozReview-Commit-ID: Hl2nAiuyTO0
dom/html/HTMLMediaElement.cpp
dom/media/ChannelMediaDecoder.cpp
dom/media/ChannelMediaDecoder.h
dom/media/MediaResource.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3739,19 +3739,21 @@ HTMLMediaElement::LookupMediaElementURIT
   }
   for (uint32_t i = 0; i < entry->mElements.Length(); ++i) {
     HTMLMediaElement* elem = entry->mElements[i];
     bool equal;
     // Look for elements that have the same principal and CORS mode.
     // Ditto for anything else that could cause us to send different headers.
     if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal &&
         elem->mCORSMode == mCORSMode) {
-      NS_ASSERTION(elem->mDecoder && elem->mDecoder->GetResource(), "Decoder gone");
-      MediaResource* resource = elem->mDecoder->GetResource();
-      if (resource->CanClone()) {
+      // See SetupDecoder() below. We only add a element to the table when
+      // mDecoder is a ChannelMediaDecoder.
+      auto decoder = static_cast<ChannelMediaDecoder*>(elem->mDecoder.get());
+      NS_ASSERTION(decoder, "Decoder gone");
+      if (decoder->CanClone()) {
         return elem;
       }
     }
   }
   return nullptr;
 }
 
 class HTMLMediaElement::ShutdownObserver : public nsIObserver {
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -150,16 +150,23 @@ ChannelMediaDecoder::ResourceCallback::N
 
 ChannelMediaDecoder::ChannelMediaDecoder(MediaDecoderInit& aInit)
   : MediaDecoder(aInit)
   , mResourceCallback(new ResourceCallback(aInit.mOwner->AbstractMainThread()))
 {
   mResourceCallback->Connect(this);
 }
 
+bool
+ChannelMediaDecoder::CanClone()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  return mResource && mResource->CanClone();
+}
+
 already_AddRefed<ChannelMediaDecoder>
 ChannelMediaDecoder::Clone(MediaDecoderInit& aInit)
 {
   if (!mResource) {
     return nullptr;
   }
   RefPtr<ChannelMediaDecoder> decoder = CloneImpl(aInit);
   if (!decoder) {
--- a/dom/media/ChannelMediaDecoder.h
+++ b/dom/media/ChannelMediaDecoder.h
@@ -61,16 +61,18 @@ public:
   explicit ChannelMediaDecoder(MediaDecoderInit& aInit);
 
   MediaDecoderStateMachine* CreateStateMachine() override;
 
   MediaResource* GetResource() const override final;
 
   void Shutdown() override;
 
+  bool CanClone();
+
   // Create a new decoder of the same type as this one.
   already_AddRefed<ChannelMediaDecoder> Clone(MediaDecoderInit& aInit);
 
   nsresult Load(nsIChannel* aChannel,
                 bool aIsPrivateBrowsing,
                 nsIStreamListener** aStreamListener);
 
 private:
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -169,22 +169,16 @@ public:
   // since we don't expect to resume again any time soon. Otherwise we
   // may resume again soon so resources should be held for a little
   // while.
   virtual void Suspend(bool aCloseImmediately) = 0;
   // Resume any downloads that have been suspended.
   virtual void Resume() = 0;
   // Get the current principal for the channel
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
-  // If this returns false, then we shouldn't try to clone this MediaResource
-  // because its underlying resources are not suitable for reuse (e.g.
-  // because the underlying connection has been lost, or this resource
-  // just can't be safely cloned). If this returns true, CloneData could
-  // still fail. If this returns false, CloneData should not be called.
-  virtual bool CanClone() { return false; }
 
   // These methods are called off the main thread.
   // The mode is initially MODE_PLAYBACK.
   virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0;
   // This is the client's estimate of the playback rate assuming
   // the media plays continuously. The cache can't guess this itself
   // because it doesn't know when the decoder was paused, buffering, etc.
   virtual void SetPlaybackRate(uint32_t aBytesPerSecond) = 0;
@@ -326,16 +320,23 @@ public:
    * Create a resource, reading data from the channel. Call on main thread only.
    * The caller must follow up by calling resource->Open().
    */
   static already_AddRefed<BaseMediaResource> Create(
     MediaResourceCallback* aCallback,
     nsIChannel* aChannel,
     bool aIsPrivateBrowsing);
 
+  // If this returns false, then we shouldn't try to clone this MediaResource
+  // because its underlying resources are not suitable for reuse (e.g.
+  // because the underlying connection has been lost, or this resource
+  // just can't be safely cloned). If this returns true, CloneData could
+  // still fail. If this returns false, CloneData should not be called.
+  virtual bool CanClone() { return false; }
+
   // Create a new stream of the same type that refers to the same URI
   // with a new channel. Any cached data associated with the original
   // stream should be accessible in the new stream too.
   virtual already_AddRefed<BaseMediaResource> CloneData(
     MediaResourceCallback* aCallback)
   {
     return nullptr;
   }