Bug 1380234. P1 - pass KnowsCompositor to MFR through MediaDecoderReaderInit. draft
authorJW Wang <jwwang@mozilla.com>
Wed, 12 Jul 2017 15:37:02 +0800
changeset 608707 f040d592211f19987fbde9bcf692cfc59426d78b
parent 608658 67cd1ee26f2661fa5efe3d952485ab3c89af4271
child 608708 9eb248ad193ebebfd9a9da5d62a0d384be7b7483
push id68379
push userjwwang@mozilla.com
push dateFri, 14 Jul 2017 02:37:00 +0000
bugs1380234
milestone56.0a1
Bug 1380234. P1 - pass KnowsCompositor to MFR through MediaDecoderReaderInit. MozReview-Commit-ID: 3krK3meG5jV
dom/media/DecoderTraits.cpp
dom/media/DecoderTraits.h
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/android/AndroidMediaReader.cpp
dom/media/android/AndroidMediaReader.h
dom/media/fmp4/MP4Decoder.cpp
dom/media/hls/HLSDecoder.cpp
dom/media/mediasource/MediaSourceDecoder.cpp
dom/media/ogg/OggDecoder.cpp
dom/media/webm/WebMDecoder.cpp
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -334,17 +334,17 @@ DecoderTraits::CreateDecoder(MediaDecode
 {
   MOZ_ASSERT(NS_IsMainThread());
   return InstantiateDecoder(aInit, aDiagnostics);
 }
 
 /* static */
 MediaDecoderReader*
 DecoderTraits::CreateReader(const MediaContainerType& aType,
-                            const MediaDecoderReaderInit& aInit)
+                            MediaDecoderReaderInit& aInit)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MediaDecoderReader* decoderReader = nullptr;
 
   if (!aInit.mDecoder) {
     return decoderReader;
   }
 
--- a/dom/media/DecoderTraits.h
+++ b/dom/media/DecoderTraits.h
@@ -47,17 +47,17 @@ public:
   // were unable to create the decoder.
   static already_AddRefed<ChannelMediaDecoder> CreateDecoder(
     MediaDecoderInit& aInit,
     DecoderDoctorDiagnostics* aDiagnostics);
 
   // Create a reader for thew given MIME type aType. Returns null
   // if we were unable to create the reader.
   static MediaDecoderReader* CreateReader(const MediaContainerType& aType,
-                                          const MediaDecoderReaderInit& aInit);
+                                          MediaDecoderReaderInit& aInit);
 
   // Returns true if MIME type aType is supported in video documents,
   // or false otherwise. Not all platforms support all MIME types, and
   // vice versa.
   static bool IsSupportedInVideoDocument(const nsACString& aType);
 
   // Convenience function that returns false if MOZ_FMP4 is not defined,
   // otherwise defers to MP4Decoder::IsSupportedType().
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -1053,29 +1053,33 @@ MediaDecoder::DurationChanged()
     GetOwner()->DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   }
 
   if (CurrentPosition() > TimeUnit::FromSeconds(mDuration)) {
     Seek(mDuration, SeekTarget::Accurate);
   }
 }
 
+already_AddRefed<KnowsCompositor>
+MediaDecoder::GetCompositor()
+{
+  MediaDecoderOwner* owner = GetOwner();
+  nsIDocument* ownerDoc = owner ? owner->GetDocument() : nullptr;
+  RefPtr<LayerManager> layerManager =
+    ownerDoc ? nsContentUtils::LayerManagerForDocument(ownerDoc) : nullptr;
+  RefPtr<KnowsCompositor> knows =
+    layerManager ? layerManager->AsShadowForwarder() : nullptr;
+  return knows.forget();
+}
+
 void
 MediaDecoder::NotifyCompositor()
 {
-  MediaDecoderOwner* owner = GetOwner();
-  NS_ENSURE_TRUE_VOID(owner);
-
-  nsIDocument* ownerDoc = owner->GetDocument();
-  NS_ENSURE_TRUE_VOID(ownerDoc);
-
-  RefPtr<LayerManager> layerManager =
-    nsContentUtils::LayerManagerForDocument(ownerDoc);
-  if (layerManager) {
-    RefPtr<KnowsCompositor> knowsCompositor = layerManager->AsShadowForwarder();
+  RefPtr<KnowsCompositor> knowsCompositor = GetCompositor();
+  if (knowsCompositor) {
     mCompositorUpdatedEvent.Notify(knowsCompositor);
   }
 }
 
 void
 MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
                                    Visibility aElementVisibility,
                                    bool aIsElementInTree)
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -507,16 +507,18 @@ protected:
   // This corresponds to the "current position" in HTML5.
   // We allow omx subclasses to substitute an alternative current position for
   // usage with the audio offload player.
   virtual media::TimeUnit CurrentPosition()
   {
     return mCurrentPosition.Ref();
   }
 
+  already_AddRefed<layers::KnowsCompositor> GetCompositor();
+
   // Official duration of the media resource as observed by script.
   double mDuration;
 
   /******
    * The following member variables can be accessed from any thread.
    ******/
 
   // Media data resource.
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -63,17 +63,17 @@ public:
     const AudioData* audioData = static_cast<const AudioData*>(aObject);
     mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
     return nullptr;
   }
 
   size_t mSize;
 };
 
-MediaDecoderReader::MediaDecoderReader(const MediaDecoderReaderInit& aInit)
+MediaDecoderReader::MediaDecoderReader(MediaDecoderReaderInit& aInit)
   : mAudioCompactor(mAudioQueue)
   , mDecoder(aInit.mDecoder)
   , mTaskQueue(new TaskQueue(
       GetMediaThreadPool(MediaThreadType::PLAYBACK),
       "MediaDecoderReader::mTaskQueue",
       /* aSupportsTailDispatch = */ true))
   , mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderReader::mBuffered (Canonical)")
   , mIgnoreAudioOutputFormat(false)
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -62,16 +62,17 @@ struct MetadataHolder
   UniquePtr<MetadataTags> mTags;
 };
 
 struct MOZ_STACK_CLASS MediaDecoderReaderInit
 {
   AbstractMediaDecoder* const mDecoder;
   MediaResource* mResource = nullptr;
   VideoFrameContainer* mVideoFrameContainer = nullptr;
+  already_AddRefed<layers::KnowsCompositor> mKnowsCompositor;
 
   explicit MediaDecoderReaderInit(AbstractMediaDecoder* aDecoder)
     : mDecoder(aDecoder)
   {
   }
 };
 
 // Encapsulates the decoding and reading of media data. Reading can either
@@ -105,17 +106,17 @@ public:
   // for multiple WaitForData consumers, feel free to flip the exclusivity here.
   using WaitForDataPromise =
     MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
 
   // The caller must ensure that Shutdown() is called before aDecoder is
   // destroyed.
-  explicit MediaDecoderReader(const MediaDecoderReaderInit& aInit);
+  explicit MediaDecoderReader(MediaDecoderReaderInit& aInit);
 
   // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
   // on failure.
   nsresult Init();
 
   // Called by MDSM in dormant state to release resources allocated by this
   // reader. The reader can resume decoding by calling Seek() to a specific
   // position.
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -4,31 +4,30 @@
  * 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 "MediaFormatReader.h"
 
 #include "AutoTaskQueue.h"
 #include "Layers.h"
 #include "MediaData.h"
+#include "MediaDecoderOwner.h"
 #include "MediaInfo.h"
 #include "MediaResource.h"
 #include "VideoFrameContainer.h"
 #include "VideoUtils.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/CDMProxy.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/SizePrintfMacros.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/layers/ShadowLayers.h"
 #include "nsContentUtils.h"
 #include "nsPrintfCString.h"
 #include "nsSize.h"
 
 #include <algorithm>
 #include <queue>
 
 using namespace mozilla::media;
@@ -1089,28 +1088,29 @@ MediaFormatReader::DemuxerProxy::NotifyD
     }
     if (data->mVideoDemuxer) {
       data->mVideoDemuxer->UpdateBuffered();
     }
     return NotifyDataArrivedPromise::CreateAndResolve(true, __func__);
   });
 }
 
-MediaFormatReader::MediaFormatReader(const MediaDecoderReaderInit& aInit,
+MediaFormatReader::MediaFormatReader(MediaDecoderReaderInit& aInit,
                                      MediaDataDemuxer* aDemuxer)
   : MediaDecoderReader(aInit)
   , mAudio(this, MediaData::AUDIO_DATA,
            MediaPrefs::MaxAudioDecodeError())
   , mVideo(this, MediaData::VIDEO_DATA,
            MediaPrefs::MaxVideoDecodeError())
   , mDemuxer(new DemuxerProxy(aDemuxer))
   , mDemuxerInitDone(false)
   , mPendingNotifyDataArrived(false)
   , mLastReportedNumDecodedFrames(0)
   , mPreviousDecodedKeyframeTime_us(sNoPreviousDecodedKeyframe)
+  , mKnowsCompositor(aInit.mKnowsCompositor)
   , mInitDone(false)
   , mTrackDemuxersMayBlock(false)
   , mSeekScheduled(false)
   , mVideoFrameContainer(aInit.mVideoFrameContainer)
   , mDecoderFactory(new DecoderFactory(this))
   , mShutdownPromisePool(new ShutdownPromisePool())
 {
   MOZ_ASSERT(aDemuxer);
@@ -1209,48 +1209,21 @@ MediaFormatReader::TearDownDecoders()
 
   mDecoderFactory = nullptr;
   mPlatform = nullptr;
   mVideoFrameContainer = nullptr;
 
   return MediaDecoderReader::Shutdown();
 }
 
-void
-MediaFormatReader::InitLayersBackendType()
-{
-  // Extract the layer manager backend type so that platform decoders
-  // can determine whether it's worthwhile using hardware accelerated
-  // video decoding.
-  if (!mDecoder) {
-    return;
-  }
-  MediaDecoderOwner* owner = mDecoder->GetOwner();
-  if (!owner) {
-    NS_WARNING("MediaFormatReader without a decoder owner, can't get HWAccel");
-    return;
-  }
-
-  dom::HTMLMediaElement* element = owner->GetMediaElement();
-  NS_ENSURE_TRUE_VOID(element);
-
-  RefPtr<LayerManager> layerManager =
-    nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
-  NS_ENSURE_TRUE_VOID(layerManager);
-
-  mKnowsCompositor = layerManager->AsShadowForwarder();
-}
-
 nsresult
 MediaFormatReader::InitInternal()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
 
-  InitLayersBackendType();
-
   mAudio.mTaskQueue = new TaskQueue(
     GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
     "MFR::mAudio::mTaskQueue");
 
   mVideo.mTaskQueue = new TaskQueue(
     GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
     "MFR::mVideo::mTaskQueue");
 
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -24,17 +24,17 @@ namespace mozilla {
 class CDMProxy;
 
 class MediaFormatReader final : public MediaDecoderReader
 {
   typedef TrackInfo::TrackType TrackType;
   typedef MozPromise<bool, MediaResult, /* IsExclusive = */ true> NotifyDataArrivedPromise;
 
 public:
-  MediaFormatReader(const MediaDecoderReaderInit& aInit, MediaDataDemuxer* aDemuxer);
+  MediaFormatReader(MediaDecoderReaderInit& aInit, MediaDataDemuxer* aDemuxer);
 
   virtual ~MediaFormatReader();
 
   size_t SizeOfVideoQueueInFrames() override;
   size_t SizeOfAudioQueueInFrames() override;
 
   RefPtr<VideoDataPromise>
   RequestVideoData(const media::TimeUnit& aTimeThreshold) override;
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -21,17 +21,17 @@ namespace mozilla {
 
 using namespace mozilla::gfx;
 using namespace mozilla::media;
 
 typedef mozilla::layers::Image Image;
 typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
 
 AndroidMediaReader::AndroidMediaReader(const MediaContainerType& aContainerType,
-                                       const MediaDecoderReaderInit& aInit) :
+                                       MediaDecoderReaderInit& aInit) :
   MediaDecoderReader(aInit),
   mType(aContainerType),
   mPlugin(nullptr),
   mHasAudio(false),
   mHasVideo(false),
   mVideoSeekTimeUs(-1),
   mAudioSeekTimeUs(-1)
 {
--- a/dom/media/android/AndroidMediaReader.h
+++ b/dom/media/android/AndroidMediaReader.h
@@ -33,17 +33,17 @@ class AndroidMediaReader : public MediaD
   nsIntSize mInitialFrame;
   int64_t mVideoSeekTimeUs;
   int64_t mAudioSeekTimeUs;
   RefPtr<VideoData> mLastVideoFrame;
   MozPromiseHolder<MediaDecoderReader::SeekPromise> mSeekPromise;
   MozPromiseRequestHolder<MediaDecoderReader::VideoDataPromise> mSeekRequest;
 public:
   AndroidMediaReader(const MediaContainerType& aContainerType,
-                     const MediaDecoderReaderInit& aInit);
+                     MediaDecoderReaderInit& aInit);
 
   nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
                                                    TrackInfo::kVideoTrack)) override;
 
   bool DecodeAudioData() override;
   bool DecodeVideoFrame(bool& aKeyframeSkip,
                         const media::TimeUnit& aTimeThreshold) override;
 
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -29,16 +29,17 @@ MP4Decoder::MP4Decoder(MediaDecoderInit&
   : ChannelMediaDecoder(aInit)
 {
 }
 
 MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
 {
   MediaDecoderReaderInit init(this);
   init.mVideoFrameContainer = GetVideoFrameContainer();
+  init.mKnowsCompositor = GetCompositor();
   mReader = new MediaFormatReader(init, new MP4Demuxer(mResource));
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 static bool
 IsWhitelistedH264Codec(const nsAString& aCodec)
 {
   int16_t profile = 0, level = 0;
--- a/dom/media/hls/HLSDecoder.cpp
+++ b/dom/media/hls/HLSDecoder.cpp
@@ -25,16 +25,17 @@ HLSDecoder::CreateStateMachine()
   MOZ_ASSERT(NS_IsMainThread());
 
   MediaResource* resource = GetResource();
   MOZ_ASSERT(resource);
   auto resourceWrapper = static_cast<HLSResource*>(resource)->GetResourceWrapper();
   MOZ_ASSERT(resourceWrapper);
   MediaDecoderReaderInit init(this);
   init.mVideoFrameContainer = GetVideoFrameContainer();
+  init.mKnowsCompositor = GetCompositor();
   mReader =
     new MediaFormatReader(init, new HLSDemuxer(resourceWrapper->GetPlayerId()));
 
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 ChannelMediaDecoder*
 HLSDecoder::Clone(MediaDecoderInit& aInit)
--- a/dom/media/mediasource/MediaSourceDecoder.cpp
+++ b/dom/media/mediasource/MediaSourceDecoder.cpp
@@ -36,16 +36,17 @@ MediaSourceDecoder::MediaSourceDecoder(M
 
 MediaDecoderStateMachine*
 MediaSourceDecoder::CreateStateMachine()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mDemuxer = new MediaSourceDemuxer(AbstractMainThread());
   MediaDecoderReaderInit init(this);
   init.mVideoFrameContainer = GetVideoFrameContainer();
+  init.mKnowsCompositor = GetCompositor();
   mReader = new MediaFormatReader(init, mDemuxer);
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 nsresult
 MediaSourceDecoder::Load(nsIPrincipal* aPrincipal)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/ogg/OggDecoder.cpp
+++ b/dom/media/ogg/OggDecoder.cpp
@@ -13,16 +13,17 @@
 
 namespace mozilla {
 
 MediaDecoderStateMachine* OggDecoder::CreateStateMachine()
 {
   RefPtr<OggDemuxer> demuxer = new OggDemuxer(mResource);
   MediaDecoderReaderInit init(this);
   init.mVideoFrameContainer = GetVideoFrameContainer();
+  init.mKnowsCompositor = GetCompositor();
   mReader = new MediaFormatReader(init, demuxer);
   demuxer->SetChainingEvents(&mReader->TimedMetadataProducer(),
                              &mReader->MediaNotSeekableProducer());
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 /* static */
 bool
--- a/dom/media/webm/WebMDecoder.cpp
+++ b/dom/media/webm/WebMDecoder.cpp
@@ -15,16 +15,17 @@
 #include "VideoUtils.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine* WebMDecoder::CreateStateMachine()
 {
   MediaDecoderReaderInit init(this);
   init.mVideoFrameContainer = GetVideoFrameContainer();
+  init.mKnowsCompositor = GetCompositor();
   mReader = new MediaFormatReader(init, new WebMDemuxer(mResource));
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 /* static */
 bool
 WebMDecoder::IsSupportedType(const MediaContainerType& aContainerType)
 {