Bug 1377370. P1 - let HLSDecoder override Load() so it can create an HLSResource directly without going through MediaResource::Create(). draft
authorJW Wang <jwwang@mozilla.com>
Fri, 30 Jun 2017 10:11:42 +0800
changeset 603209 e11932c681af0ef0e492c1727ba3316b1b16d6c0
parent 602503 d9f424aee6e41e2f3fae9c697d7f066ab352e4c0
child 603210 7814a37479c0c4a329fa519abff8a50caf34612d
push id66683
push userjwwang@mozilla.com
push dateMon, 03 Jul 2017 02:24:24 +0000
bugs1377370
milestone56.0a1
Bug 1377370. P1 - let HLSDecoder override Load() so it can create an HLSResource directly without going through MediaResource::Create(). MozReview-Commit-ID: BL8bt2JtKfa
dom/media/ChannelMediaDecoder.h
dom/media/MediaDecoder.h
dom/media/hls/HLSDecoder.cpp
dom/media/hls/HLSDecoder.h
--- a/dom/media/ChannelMediaDecoder.h
+++ b/dom/media/ChannelMediaDecoder.h
@@ -47,31 +47,32 @@ class ChannelMediaDecoder : public Media
 
     // The decoder to send notifications. Main-thread only.
     ChannelMediaDecoder* mDecoder = nullptr;
     nsCOMPtr<nsITimer> mTimer;
     bool mTimerArmed = false;
     const RefPtr<AbstractThread> mAbstractMainThread;
   };
 
+protected:
   RefPtr<ResourceCallback> mResourceCallback;
 
 public:
   explicit ChannelMediaDecoder(MediaDecoderInit& aInit);
 
   void Shutdown() override;
 
   // Create a new decoder of the same type as this one.
   // Subclasses must implement this.
   virtual ChannelMediaDecoder* Clone(MediaDecoderInit& aInit) = 0;
 
-  nsresult Load(nsIChannel* aChannel,
-                bool aIsPrivateBrowsing,
-                nsIStreamListener** aStreamListener);
-  nsresult Load(MediaResource* aOriginal);
+  virtual nsresult Load(nsIChannel* aChannel,
+                        bool aIsPrivateBrowsing,
+                        nsIStreamListener** aStreamListener);
+  virtual nsresult Load(MediaResource* aOriginal);
 
 private:
   nsresult OpenResource(nsIStreamListener** aStreamListener);
 };
 
 } // namespace mozilla
 
 #endif // ChannelMediaDecoder_h_
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -126,18 +126,17 @@ public:
   // Notified by the shutdown manager that XPCOM shutdown has begun.
   // The decoder should notify its owner to drop the reference to the decoder
   // to prevent further calls into the decoder.
   void NotifyXPCOMShutdown();
 
   // Called if the media file encounters a network error.
   void NetworkError();
 
-  // Get the current MediaResource being used. Its URI will be returned
-  // by currentSrc. Returns what was passed to Load(), if Load() has been called.
+  // Get the current MediaResource being used.
   // Note: The MediaResource is refcounted, but it outlives the MediaDecoder,
   // so it's OK to use the reference returned by this function without
   // refcounting, *unless* you need to store and use the reference after the
   // MediaDecoder has been destroyed. You might need to do this if you're
   // wrapping the MediaResource in some kind of byte stream interface to be
   // passed to a platform decoder.
   MediaResource* GetResource() const final override
   {
--- a/dom/media/hls/HLSDecoder.cpp
+++ b/dom/media/hls/HLSDecoder.cpp
@@ -9,16 +9,18 @@
 #include "DecoderTraits.h"
 #include "HLSDemuxer.h"
 #include "HLSResource.h"
 #include "HLSUtils.h"
 #include "MediaContainerType.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaFormatReader.h"
 #include "MediaPrefs.h"
+#include "MediaShutdownManager.h"
+#include "nsNetUtil.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine*
 HLSDecoder::CreateStateMachine()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -51,9 +53,43 @@ HLSDecoder::IsEnabled()
 
 bool
 HLSDecoder::IsSupportedType(const MediaContainerType& aContainerType)
 {
   return IsEnabled() &&
          DecoderTraits::IsHttpLiveStreamingType(aContainerType);
 }
 
+nsresult
+HLSDecoder::Load(nsIChannel* aChannel,
+                 bool aIsPrivateBrowsing,
+                 nsIStreamListener**)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!mResource);
+
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  mResource = new HLSResource(mResourceCallback, aChannel, uri);
+
+  rv = MediaShutdownManager::Instance().Register(this);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  SetStateMachine(CreateStateMachine());
+  NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE);
+
+  return InitializeStateMachine();
+}
+
+nsresult
+HLSDecoder::Load(MediaResource*)
+{
+  MOZ_CRASH("Clone is not supported");
+  return NS_ERROR_FAILURE;
+}
+
 } // namespace mozilla
--- a/dom/media/hls/HLSDecoder.h
+++ b/dom/media/hls/HLSDecoder.h
@@ -28,15 +28,20 @@ public:
   // Returns true if the HLS backend is pref'ed on.
   static bool IsEnabled();
 
   // Returns true if aContainerType is an HLS type that we think we can render
   // with the a platform decoder backend.
   // If provided, codecs are checked for support.
   static bool IsSupportedType(const MediaContainerType& aContainerType);
 
+  nsresult Load(nsIChannel* aChannel,
+                bool aIsPrivateBrowsing,
+                nsIStreamListener**) override;
+  nsresult Load(MediaResource*) override;
+
 private:
   RefPtr<MediaFormatReader> mReader;
 };
 
 } // namespace mozilla
 
 #endif /* HLSDecoder_h_ */