Bug 1377370. P1 - let HLSDecoder override Load() so it can create an HLSResource directly without going through MediaResource::Create().
MozReview-Commit-ID: BL8bt2JtKfa
--- 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_ */