Bug 1388604 - move SetReadMode() from MediaResource to BaseMediaResource. draft
authorJW Wang <jwwang@mozilla.com>
Wed, 09 Aug 2017 11:06:29 +0800
changeset 643698 0b08d3e627fcfc0f1dc3d868229a6bf1632d1e86
parent 643697 04f9815babac29554779e550ee52e82d3b4f2dc6
child 643699 78aab6fc4d85cd3fed5a0802809c1284fa4174ca
push id73191
push userjwwang@mozilla.com
push dateThu, 10 Aug 2017 02:32:58 +0000
bugs1388604
milestone57.0a1
Bug 1388604 - move SetReadMode() from MediaResource to BaseMediaResource. It would be less accurate to call SetReadMode(MediaCacheStream::MODE_PLAYBACK) in ChannelMediaDecoder::MetadataLoaded() instead of DecodeMetadataState::OnMetadataRead() because MDSM might have started decoding by the time 'metadata loaded' event arrives in the main thread. However this little inaccuracy should be fine since it only affects a small amount of data concerning the eviction algorithm. MozReview-Commit-ID: JoQMGr5Fvge
dom/media/BufferMediaResource.h
dom/media/ChannelMediaDecoder.cpp
dom/media/ChannelMediaDecoder.h
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaResource.h
dom/media/gtest/MockMediaResource.h
dom/media/hls/HLSResource.h
dom/media/mediasource/MediaSourceResource.h
dom/media/mediasource/SourceBufferResource.h
--- a/dom/media/BufferMediaResource.h
+++ b/dom/media/BufferMediaResource.h
@@ -38,18 +38,16 @@ protected:
 private:
   // Get the current principal for the channel
   already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
   {
     nsCOMPtr<nsIPrincipal> principal = mPrincipal;
     return principal.forget();
   }
   // These methods are called off the main thread.
-  // The mode is initially MODE_PLAYBACK.
-  void SetReadMode(MediaCacheStream::ReadMode aMode) override {}
   nsresult ReadAt(int64_t aOffset, char* aBuffer,
                   uint32_t aCount, uint32_t* aBytes) override
   {
     if (aOffset < 0 || aOffset > mLength) {
       return NS_ERROR_FAILURE;
     }
     *aBytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
     memcpy(aBuffer, mBuffer + aOffset, *aBytes);
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -249,16 +249,19 @@ ChannelMediaDecoder::Load(nsIChannel* aC
   nsresult rv = MediaShutdownManager::Instance().Register(this);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = OpenResource(aStreamListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Set mode to METADATA since we are about to read metadata.
+  mResource->SetReadMode(MediaCacheStream::MODE_METADATA);
+
   SetStateMachine(CreateStateMachine());
   NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE);
 
   return InitializeStateMachine();
 }
 
 nsresult
 ChannelMediaDecoder::Load(BaseMediaResource* aOriginal)
@@ -496,12 +499,23 @@ void
 ChannelMediaDecoder::Resume()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mResource) {
     mResource->Resume();
   }
 }
 
+void
+ChannelMediaDecoder::MetadataLoaded(
+  UniquePtr<MediaInfo> aInfo,
+  UniquePtr<MetadataTags> aTags,
+  MediaDecoderEventVisibility aEventVisibility)
+{
+  MediaDecoder::MetadataLoaded(Move(aInfo), Move(aTags), aEventVisibility);
+  // Set mode to PLAYBACK after reading metadata.
+  mResource->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
+}
+
 } // namespace mozilla
 
 // avoid redefined macro in unified build
 #undef LOG
--- a/dom/media/ChannelMediaDecoder.h
+++ b/dom/media/ChannelMediaDecoder.h
@@ -52,16 +52,20 @@ class ChannelMediaDecoder : public Media
     bool mTimerArmed = false;
     const RefPtr<AbstractThread> mAbstractMainThread;
   };
 
 protected:
   void OnPlaybackEvent(MediaEventType aEvent) override;
   void DurationChanged() override;
   void DownloadProgressed() override;
+  void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
+                      UniquePtr<MetadataTags> aTags,
+                      MediaDecoderEventVisibility aEventVisibility) override;
+
   RefPtr<ResourceCallback> mResourceCallback;
   RefPtr<BaseMediaResource> mResource;
 
 public:
   explicit ChannelMediaDecoder(MediaDecoderInit& aInit);
 
   MediaDecoderStateMachine* CreateStateMachine() override;
 
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -451,16 +451,22 @@ protected:
 
     // We Invoke DurationChanged explicitly, rather than using a watcher, so
     // that it takes effect immediately, rather than at the end of the current task.
     DurationChanged();
   }
 
   virtual void OnPlaybackEvent(MediaEventType aEvent);
 
+  // Called when the metadata from the media file has been loaded by the
+  // state machine. Call on the main thread only.
+  virtual void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
+                              UniquePtr<MetadataTags> aTags,
+                              MediaDecoderEventVisibility aEventVisibility);
+
   /******
    * The following members should be accessed with the decoder lock held.
    ******/
 
   // The logical playback position of the media resource in units of
   // seconds. This corresponds to the "official position" in HTML5. Note that
   // we need to store this as a double, rather than an int64_t (like
   // mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo|
@@ -491,22 +497,16 @@ protected:
   // the next frame is available.
   // An arbitrary value of 250ms is used.
   static constexpr auto DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED =
     media::TimeUnit::FromMicroseconds(250000);
 
 private:
   nsCString GetDebugInfo();
 
-  // Called when the metadata from the media file has been loaded by the
-  // state machine. Call on the main thread only.
-  void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
-                      UniquePtr<MetadataTags> aTags,
-                      MediaDecoderEventVisibility aEventVisibility);
-
   // Called when the owner's activity changed.
   void NotifyCompositor();
 
   void OnPlaybackErrorEvent(const MediaResult& aError);
 
   void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent);
 
   void OnMediaNotSeekable()
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -336,19 +336,16 @@ public:
   explicit DecodeMetadataState(Master* aPtr) : StateObject(aPtr) { }
 
   void Enter()
   {
     MOZ_ASSERT(!mMaster->mVideoDecodeSuspended);
     MOZ_ASSERT(!mMetadataRequest.Exists());
     SLOG("Dispatching AsyncReadMetadata");
 
-    // Set mode to METADATA since we are about to read metadata.
-    Resource()->SetReadMode(MediaCacheStream::MODE_METADATA);
-
     // We disconnect mMetadataRequest in Exit() so it is fine to capture
     // a raw pointer here.
     Reader()->ReadMetadata()
       ->Then(OwnerThread(), __func__,
         [this] (MetadataHolder&& aMetadata) {
           OnMetadataRead(Move(aMetadata));
         },
         [this] (const MediaResult& aError) {
@@ -2219,19 +2216,16 @@ StateObject::SetSeekingState(SeekJob&& a
 }
 
 void
 MediaDecoderStateMachine::
 DecodeMetadataState::OnMetadataRead(MetadataHolder&& aMetadata)
 {
   mMetadataRequest.Complete();
 
-  // Set mode to PLAYBACK after reading metadata.
-  Resource()->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
-
   mMaster->mInfo.emplace(*aMetadata.mInfo);
   mMaster->mMediaSeekable = Info().mMediaSeekable;
   mMaster->mMediaSeekableOnlyInBufferedRanges =
     Info().mMediaSeekableOnlyInBufferedRanges;
 
   if (Info().mMetadataDuration.isSome()) {
     mMaster->mDuration = Info().mMetadataDuration;
   } else if (Info().mUnadjustedMetadataEndTime.isSome()) {
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -159,18 +159,16 @@ public:
   // released on a non main thread, but the destructor will always run on
   // the main thread.
   NS_DECL_THREADSAFE_ISUPPORTS
 
   // Get the current principal for the channel
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
 
   // These methods are called off the main thread.
-  // The mode is initially MODE_PLAYBACK.
-  virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0;
   // Read up to aCount bytes from the stream. The read starts at
   // aOffset in the stream, seeking to that location initially if
   // it is not the current stream offset. The remaining arguments,
   // results and requirements are the same as per the Read method.
   virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
                           uint32_t aCount, uint32_t* aBytes) = 0;
   // Indicate whether caching data in advance of reads is worth it.
   // E.g. Caching lockless and memory-based MediaResource subclasses would be a
@@ -320,16 +318,19 @@ 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;
 
+  // The mode is initially MODE_PLAYBACK.
+  virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0;
+
   /**
    * Open the stream. This creates a stream listener and returns it in
    * aStreamListener; this listener needs to be notified of incoming data.
    */
   virtual nsresult Open(nsIStreamListener** aStreamListener) = 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.
--- a/dom/media/gtest/MockMediaResource.h
+++ b/dom/media/gtest/MockMediaResource.h
@@ -15,17 +15,16 @@ namespace mozilla
 class MockMediaResource : public MediaResource
 {
 public:
   explicit MockMediaResource(const char* aFileName);
   already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
   {
     return nullptr;
   }
-  void SetReadMode(MediaCacheStream::ReadMode aMode) override {}
   nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount,
                   uint32_t* aBytes) override;
   // Data stored in file, caching recommended.
   bool ShouldCacheReads() override { return true; }
   int64_t Tell() override { return 0; }
   void Pin() override {}
   void Unpin() override {}
   int64_t GetLength() override;
--- a/dom/media/hls/HLSResource.h
+++ b/dom/media/hls/HLSResource.h
@@ -43,17 +43,16 @@ private:
 
 class HLSResource final : public MediaResource
 {
 public:
   HLSResource(HLSDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI);
   ~HLSResource();
   void Suspend();
   void Resume();
-  void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
   nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
   bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; }
   int64_t Tell() override { UNIMPLEMENTED(); return -1; }
   void Pin() override { UNIMPLEMENTED(); }
   void Unpin() override { UNIMPLEMENTED(); }
   int64_t GetLength() override { UNIMPLEMENTED(); return -1; }
   int64_t GetNextCachedData(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
   int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
--- a/dom/media/mediasource/MediaSourceResource.h
+++ b/dom/media/mediasource/MediaSourceResource.h
@@ -27,17 +27,16 @@ class MediaSourceResource final : public
 {
 public:
   explicit MediaSourceResource(nsIPrincipal* aPrincipal = nullptr)
     : mPrincipal(aPrincipal)
     , mMonitor("MediaSourceResource")
     , mEnded(false)
     {}
 
-  void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
   nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
   bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; }
   int64_t Tell() override { UNIMPLEMENTED(); return -1; }
   void Pin() override { UNIMPLEMENTED(); }
   void Unpin() override { UNIMPLEMENTED(); }
   int64_t GetLength() override { UNIMPLEMENTED(); return -1; }
   int64_t GetNextCachedData(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
   int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -40,20 +40,16 @@ class SourceBufferResource final : publi
 public:
   SourceBufferResource();
   nsresult Close();
   already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
   {
     UNIMPLEMENTED();
     return nullptr;
   }
-  void SetReadMode(MediaCacheStream::ReadMode aMode) override
-  {
-    UNIMPLEMENTED();
-  }
   nsresult ReadAt(int64_t aOffset,
                   char* aBuffer,
                   uint32_t aCount,
                   uint32_t* aBytes) override;
   // Memory-based and no locks, caching discouraged.
   bool ShouldCacheReads() override { return false; }
   int64_t Tell() override { return mOffset; }
   void Pin() override { UNIMPLEMENTED(); }