Bug 1156708: Part2. Add pref to toggle new code. r=kentuckyfriedtakahe
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 18 May 2015 15:41:22 +1000
changeset 275075 e043b13f0ef0f061c24bd1c4b8577f261c607543
parent 275074 0cb2a615df60102a479c5f17b0060aad0935451e
child 275076 ae61b05d266c05f84f5cc38d509394e54e7f6427
push idunknown
push userunknown
push dateunknown
reviewerskentuckyfriedtakahe
bugs1156708
milestone41.0a1
Bug 1156708: Part2. Add pref to toggle new code. r=kentuckyfriedtakahe media.format-reader.mp4=true: Will enable the new format decoder for mp4 media.mediasource.format-reader.mp4=true: Will enable new format decoder for mp4 within MSE.
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/fmp4/MP4Decoder.cpp
dom/media/mediasource/MediaSourceReader.cpp
modules/libpref/init/all.js
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -331,17 +331,16 @@ MediaFormatReader::OnDemuxerInitDone(nsr
 
   int64_t duration = std::max(videoDuration, audioDuration);
   if (duration != -1) {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mDecoder->SetMediaDuration(duration);
   }
 
   mSeekable = mDemuxer->IsSeekable();
-  mInitDone = true;
 
   // Create demuxer object for main thread.
   mMainThreadDemuxer = mDemuxer->Clone();
   if (!mMainThreadDemuxer) {
     mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
     NS_WARNING("Unable to clone current MediaDataDemuxer");
     return;
   }
@@ -351,16 +350,18 @@ MediaFormatReader::OnDemuxerInitDone(nsr
     MOZ_ASSERT(mVideoTrackDemuxer);
   }
   if (audioActive) {
     mAudioTrackDemuxer =
       mMainThreadDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
     MOZ_ASSERT(mAudioTrackDemuxer);
   }
 
+  mInitDone = true;
+
   if (!IsWaitingOnCDMResource() && !EnsureDecodersSetup()) {
     mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
   } else {
     nsRefPtr<MetadataHolder> metadata = new MetadataHolder();
     metadata->mInfo = mInfo;
     metadata->mTags = nullptr;
     mMetadataPromise.Resolve(metadata, __func__);
   }
@@ -1271,29 +1272,21 @@ void MediaFormatReader::ReleaseMediaReso
     container->ClearCurrentFrame();
   }
   if (mVideo.mDecoder) {
     mVideo.mDecoder->Shutdown();
     mVideo.mDecoder = nullptr;
   }
 }
 
-void MediaFormatReader::NotifyResourcesStatusChanged()
-{
-  if (mDecoder) {
-    mDecoder->NotifyWaitingForResourcesStatusChanged();
-  }
-}
-
 void
 MediaFormatReader::SetIdle()
 {
   if (mSharedDecoderManager && mVideo.mDecoder) {
     mSharedDecoderManager->SetIdle(mVideo.mDecoder);
-    NotifyResourcesStatusChanged();
   }
 }
 
 void
 MediaFormatReader::SetSharedDecoderManager(SharedDecoderManager* aManager)
 {
 #if !defined(MOZ_WIDGET_ANDROID)
   mSharedDecoderManager = aManager;
@@ -1332,16 +1325,17 @@ void
 MediaFormatReader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mInitDone) {
     return;
   }
 
+  MOZ_ASSERT(mMainThreadDemuxer);
   mMainThreadDemuxer->NotifyDataArrived(aLength, aOffset);
 
   // Queue a task to notify our main demuxer.
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArgs<int32_t, uint64_t>(
       this, &MediaFormatReader::NotifyDemuxer,
       aLength, aOffset);
   GetTaskQueue()->Dispatch(task);
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -133,17 +133,16 @@ private:
   // functions.
   void Output(TrackType aType, MediaData* aSample);
   void InputExhausted(TrackType aTrack);
   void Error(TrackType aTrack);
   void Flush(TrackType aTrack);
   void DrainComplete(TrackType aTrack);
   bool IsSupportedAudioMimeType(const nsACString& aMimeType);
   bool IsSupportedVideoMimeType(const nsACString& aMimeType);
-  void NotifyResourcesStatusChanged();
 
   bool ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
 
   size_t SizeOfQueue(TrackType aTrack);
 
   nsRefPtr<MediaDataDemuxer> mDemuxer;
   nsRefPtr<PlatformDecoderModule> mPlatform;
 
@@ -161,19 +160,16 @@ private:
       mReader->InputExhausted(mType);
     }
     virtual void Error() override {
       mReader->Error(mType);
     }
     virtual void DrainComplete() override {
       mReader->DrainComplete(mType);
     }
-    virtual void NotifyResourcesStatusChanged() override {
-      mReader->NotifyResourcesStatusChanged();
-    }
     virtual void ReleaseMediaResources() override {
       mReader->ReleaseMediaResources();
     }
     virtual bool OnReaderTaskQueue() override {
       return mReader->OnTaskQueue();
     }
 
   private:
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -2,16 +2,18 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 "MP4Decoder.h"
 #include "MP4Reader.h"
 #include "MediaDecoderStateMachine.h"
+#include "MediaFormatReader.h"
+#include "MP4Demuxer.h"
 #include "mozilla/Preferences.h"
 #include "nsCharSeparatedTokenizer.h"
 #ifdef MOZ_EME
 #include "mozilla/CDMProxy.h"
 #endif
 #include "prlog.h"
 
 #ifdef XP_WIN
@@ -29,17 +31,23 @@
 #include "AndroidBridge.h"
 #endif
 #include "mozilla/layers/LayersTypes.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
 {
-  return new MediaDecoderStateMachine(this, new MP4Reader(this));
+  bool useFormatDecoder =
+    Preferences::GetBool("media.format-reader.mp4", false);
+  nsRefPtr<MediaDecoderReader> reader = useFormatDecoder ?
+    static_cast<MediaDecoderReader*>(new MediaFormatReader(this, new MP4Demuxer(GetResource()))) :
+    static_cast<MediaDecoderReader*>(new MP4Reader(this));
+
+  return new MediaDecoderStateMachine(this, reader);
 }
 
 #ifdef MOZ_EME
 nsresult
 MP4Decoder::SetCDMProxy(CDMProxy* aProxy)
 {
   nsresult rv = MediaDecoder::SetCDMProxy(aProxy);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -5,25 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "MediaSourceReader.h"
 
 #include <cmath>
 #include "prlog.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "DecoderTraits.h"
 #include "MediaDecoderOwner.h"
+#include "MediaFormatReader.h"
 #include "MediaSourceDecoder.h"
 #include "MediaSourceUtils.h"
 #include "SourceBufferDecoder.h"
 #include "TrackBuffer.h"
 #include "nsPrintfCString.h"
 
 #ifdef MOZ_FMP4
 #include "SharedDecoderManager.h"
 #include "MP4Decoder.h"
+#include "MP4Demuxer.h"
 #include "MP4Reader.h"
 #endif
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
 #define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 #define MSE_DEBUGV(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
@@ -683,17 +685,22 @@ CreateReaderForType(const nsACString& aT
 #ifdef MOZ_FMP4
   // The MP4Reader that supports fragmented MP4 and uses
   // PlatformDecoderModules is hidden behind prefs for regular video
   // elements, but we always want to use it for MSE, so instantiate it
   // directly here.
   if ((aType.LowerCaseEqualsLiteral("video/mp4") ||
        aType.LowerCaseEqualsLiteral("audio/mp4")) &&
       MP4Decoder::IsEnabled() && aDecoder) {
-    return new MP4Reader(aDecoder);
+    bool useFormatDecoder =
+      Preferences::GetBool("media.mediasource.format-reader.mp4", false);
+    MediaDecoderReader* reader = useFormatDecoder ?
+      static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource()))) :
+      static_cast<MediaDecoderReader*>(new MP4Reader(aDecoder));
+    return reader;
   }
 #endif
   return DecoderTraits::CreateReader(aType, aDecoder);
 }
 
 already_AddRefed<SourceBufferDecoder>
 MediaSourceReader::CreateSubDecoder(const nsACString& aType, int64_t aTimestampOffset)
 {
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -448,16 +448,21 @@ pref("media.mediasource.enabled", false)
 pref("media.mediasource.whitelist", true);
 #else
 pref("media.mediasource.whitelist", false);
 #endif // RELEASE_BUILD
 
 pref("media.mediasource.mp4.enabled", true);
 pref("media.mediasource.webm.enabled", false);
 
+// Enable new MediaFormatReader architecture for mp4 in MSE
+pref("media.mediasource.format-reader.mp4", false);
+// Enable new MediaFormatReader architecture for plain mp4.
+pref("media.format-reader.mp4", false);
+
 #ifdef MOZ_WEBSPEECH
 pref("media.webspeech.recognition.enable", false);
 pref("media.webspeech.synth.enabled", false);
 #endif
 #ifdef MOZ_WEBM_ENCODER
 pref("media.encoder.webm.enabled", true);
 #endif
 #ifdef MOZ_OMX_ENCODER