Bug 1250054. Part 1 - add new files and move StartTimeRendezvous from MediaDecoderStateMachine.h to MediaDecoderReaderWrapper.cpp. r=jya.
☠☠ backed out by 97001a5fbcb5 ☠ ☠
authorJW Wang <jwwang@mozilla.com>
Tue, 29 Mar 2016 14:48:11 +0800
changeset 290853 15058cd337313e26ee0cc699826dcbe7f448c977
parent 290852 ab6ca47677a8219cb08014f02fd41bc7dd83b9a4
child 290854 fe425b8cb8cbe0260d3ce1ff1746831f3b65ad02
push id30128
push userkwierso@gmail.com
push dateThu, 31 Mar 2016 20:04:34 +0000
treeherdermozilla-central@bccb11375f2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1250054
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1250054. Part 1 - add new files and move StartTimeRendezvous from MediaDecoderStateMachine.h to MediaDecoderReaderWrapper.cpp. r=jya.
dom/media/MediaDecoderReaderWrapper.cpp
dom/media/MediaDecoderReaderWrapper.h
dom/media/MediaDecoderStateMachine.h
dom/media/moz.build
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "mozilla/MozPromise.h"
+#include "MediaDecoderReaderWrapper.h"
+
+namespace mozilla {
+
+extern LazyLogModule gMediaDecoderLog;
+
+#undef LOG
+#define LOG(...) \
+  MOZ_LOG(gMediaDecoderLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
+
+// StartTimeRendezvous is a helper class that quarantines the first sample
+// until it gets a sample from both channels, such that we can be guaranteed
+// to know the start time by the time On{Audio,Video}Decoded is called on MDSM.
+class StartTimeRendezvous {
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StartTimeRendezvous);
+  typedef MediaDecoderReader::AudioDataPromise AudioDataPromise;
+  typedef MediaDecoderReader::VideoDataPromise VideoDataPromise;
+
+public:
+  StartTimeRendezvous(AbstractThread* aOwnerThread,
+                      bool aHasAudio,
+                      bool aHasVideo,
+                      bool aForceZeroStartTime)
+    : mOwnerThread(aOwnerThread)
+  {
+    if (aForceZeroStartTime) {
+      mAudioStartTime.emplace(0);
+      mVideoStartTime.emplace(0);
+      return;
+    }
+    if (!aHasAudio) {
+      mAudioStartTime.emplace(INT64_MAX);
+    }
+    if (!aHasVideo) {
+      mVideoStartTime.emplace(INT64_MAX);
+    }
+  }
+
+  void Destroy()
+  {
+    mAudioStartTime = Some(mAudioStartTime.refOr(INT64_MAX));
+    mVideoStartTime = Some(mVideoStartTime.refOr(INT64_MAX));
+    mHaveStartTimePromise.RejectIfExists(false, __func__);
+  }
+
+  RefPtr<HaveStartTimePromise> AwaitStartTime()
+  {
+    if (HaveStartTime()) {
+      return HaveStartTimePromise::CreateAndResolve(true, __func__);
+    }
+    return mHaveStartTimePromise.Ensure(__func__);
+  }
+
+  template<typename PromiseType>
+  struct PromiseSampleType {
+    typedef typename PromiseType::ResolveValueType::element_type Type;
+  };
+
+  template<typename PromiseType, MediaData::Type SampleType>
+  RefPtr<PromiseType>
+  ProcessFirstSample(typename PromiseSampleType<PromiseType>::Type* aData)
+  {
+    typedef typename PromiseSampleType<PromiseType>::Type DataType;
+    typedef typename PromiseType::Private PromisePrivate;
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+
+    MaybeSetChannelStartTime<SampleType>(aData->mTime);
+
+    RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
+    RefPtr<DataType> data = aData;
+    RefPtr<StartTimeRendezvous> self = this;
+    AwaitStartTime()->Then(
+      mOwnerThread, __func__,
+      [p, data, self] () {
+        MOZ_ASSERT(self->mOwnerThread->IsCurrentThreadIn());
+        p->Resolve(data, __func__);
+      },
+      [p] () {
+        p->Reject(MediaDecoderReader::CANCELED, __func__);
+      });
+
+    return p.forget();
+  }
+
+  template<MediaData::Type SampleType>
+  void FirstSampleRejected(MediaDecoderReader::NotDecodedReason aReason)
+  {
+    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+    if (aReason == MediaDecoderReader::DECODE_ERROR) {
+      mHaveStartTimePromise.RejectIfExists(false, __func__);
+    } else if (aReason == MediaDecoderReader::END_OF_STREAM) {
+      LOG("StartTimeRendezvous=%p SampleType(%d) Has no samples.",
+           this, SampleType);
+      MaybeSetChannelStartTime<SampleType>(INT64_MAX);
+    }
+  }
+
+  bool HaveStartTime() const
+  {
+    return mAudioStartTime.isSome() && mVideoStartTime.isSome();
+  }
+
+  int64_t StartTime() const
+  {
+    int64_t time = std::min(mAudioStartTime.ref(), mVideoStartTime.ref());
+    return time == INT64_MAX ? 0 : time;
+  }
+
+private:
+  ~StartTimeRendezvous() {}
+
+  template<MediaData::Type SampleType>
+  void MaybeSetChannelStartTime(int64_t aStartTime)
+  {
+    if (ChannelStartTime(SampleType).isSome()) {
+      // If we're initialized with aForceZeroStartTime=true, the channel start
+      // times are already set.
+      return;
+    }
+
+    LOG("StartTimeRendezvous=%p Setting SampleType(%d) start time to %lld",
+        this, SampleType, aStartTime);
+
+    ChannelStartTime(SampleType).emplace(aStartTime);
+    if (HaveStartTime()) {
+      mHaveStartTimePromise.ResolveIfExists(true, __func__);
+    }
+  }
+
+  Maybe<int64_t>& ChannelStartTime(MediaData::Type aType)
+  {
+    return aType == MediaData::AUDIO_DATA ? mAudioStartTime : mVideoStartTime;
+  }
+
+  MozPromiseHolder<HaveStartTimePromise> mHaveStartTimePromise;
+  RefPtr<AbstractThread> mOwnerThread;
+  Maybe<int64_t> mAudioStartTime;
+  Maybe<int64_t> mVideoStartTime;
+};
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef MediaDecoderReaderWrapper_h_
+#define MediaDecoderReaderWrapper_h_
+
+#include "mozilla/AbstractThread.h"
+#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
+
+#include "MediaDecoderReader.h"
+
+namespace mozilla {
+
+class StartTimeRendezvous;
+
+typedef MozPromise<bool, bool, /* isExclusive = */ false> HaveStartTimePromise;
+
+} // namespace mozilla
+
+#endif // MediaDecoderReaderWrapper_h_
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -689,143 +689,16 @@ private:
 
   // True if we've dispatched a task to run the state machine but the task has
   // yet to run.
   bool mDispatchedStateMachine;
 
   // Used to dispatch another round schedule with specific target time.
   DelayedScheduler mDelayedScheduler;
 
-  // StartTimeRendezvous is a helper class that quarantines the first sample
-  // until it gets a sample from both channels, such that we can be guaranteed
-  // to know the start time by the time On{Audio,Video}Decoded is called.
-  class StartTimeRendezvous {
-  public:
-    typedef MediaDecoderReader::AudioDataPromise AudioDataPromise;
-    typedef MediaDecoderReader::VideoDataPromise VideoDataPromise;
-    typedef MozPromise<bool, bool, /* isExclusive = */ false> HaveStartTimePromise;
-
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StartTimeRendezvous);
-    StartTimeRendezvous(AbstractThread* aOwnerThread, bool aHasAudio, bool aHasVideo,
-                        bool aForceZeroStartTime)
-      : mOwnerThread(aOwnerThread)
-    {
-      if (aForceZeroStartTime) {
-        mAudioStartTime.emplace(0);
-        mVideoStartTime.emplace(0);
-        return;
-      }
-
-      if (!aHasAudio) {
-        mAudioStartTime.emplace(INT64_MAX);
-      }
-
-      if (!aHasVideo) {
-        mVideoStartTime.emplace(INT64_MAX);
-      }
-    }
-
-    void Destroy()
-    {
-      mAudioStartTime = Some(mAudioStartTime.refOr(INT64_MAX));
-      mVideoStartTime = Some(mVideoStartTime.refOr(INT64_MAX));
-      mHaveStartTimePromise.RejectIfExists(false, __func__);
-    }
-
-    RefPtr<HaveStartTimePromise> AwaitStartTime()
-    {
-      if (HaveStartTime()) {
-        return HaveStartTimePromise::CreateAndResolve(true, __func__);
-      }
-      return mHaveStartTimePromise.Ensure(__func__);
-    }
-
-    template<typename PromiseType>
-    struct PromiseSampleType {
-      typedef typename PromiseType::ResolveValueType::element_type Type;
-    };
-
-    template<typename PromiseType, MediaData::Type SampleType>
-    RefPtr<PromiseType> ProcessFirstSample(typename PromiseSampleType<PromiseType>::Type* aData)
-    {
-      typedef typename PromiseSampleType<PromiseType>::Type DataType;
-      typedef typename PromiseType::Private PromisePrivate;
-      MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
-
-      MaybeSetChannelStartTime<SampleType>(aData->mTime);
-
-      RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
-      RefPtr<DataType> data = aData;
-      RefPtr<StartTimeRendezvous> self = this;
-      AwaitStartTime()->Then(mOwnerThread, __func__,
-                             [p, data, self] () -> void {
-                               MOZ_ASSERT(self->mOwnerThread->IsCurrentThreadIn());
-                               p->Resolve(data, __func__);
-                             },
-                             [p] () -> void { p->Reject(MediaDecoderReader::CANCELED, __func__); });
-
-      return p.forget();
-    }
-
-    template<MediaData::Type SampleType>
-    void FirstSampleRejected(MediaDecoderReader::NotDecodedReason aReason)
-    {
-      MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
-      if (aReason == MediaDecoderReader::DECODE_ERROR) {
-        mHaveStartTimePromise.RejectIfExists(false, __func__);
-      } else if (aReason == MediaDecoderReader::END_OF_STREAM) {
-        MOZ_LOG(gMediaDecoderLog, LogLevel::Debug,
-                ("StartTimeRendezvous=%p SampleType(%d) Has no samples.", this, SampleType));
-        MaybeSetChannelStartTime<SampleType>(INT64_MAX);
-      }
-    }
-
-    bool HaveStartTime() { return mAudioStartTime.isSome() && mVideoStartTime.isSome(); }
-    int64_t StartTime()
-    {
-      int64_t time = std::min(mAudioStartTime.ref(), mVideoStartTime.ref());
-      return time == INT64_MAX ? 0 : time;
-    }
-  private:
-    virtual ~StartTimeRendezvous() {}
-
-    template<MediaData::Type SampleType>
-    void MaybeSetChannelStartTime(int64_t aStartTime)
-    {
-      if (ChannelStartTime(SampleType).isSome()) {
-        // If we're initialized with aForceZeroStartTime=true, the channel start
-        // times are already set.
-        return;
-      }
-
-      MOZ_LOG(gMediaDecoderLog, LogLevel::Debug,
-              ("StartTimeRendezvous=%p Setting SampleType(%d) start time to %lld",
-               this, SampleType, aStartTime));
-
-      ChannelStartTime(SampleType).emplace(aStartTime);
-      if (HaveStartTime()) {
-        mHaveStartTimePromise.ResolveIfExists(true, __func__);
-      }
-    }
-
-    Maybe<int64_t>& ChannelStartTime(MediaData::Type aType)
-    {
-      return aType == MediaData::AUDIO_DATA ? mAudioStartTime : mVideoStartTime;
-    }
-
-    MozPromiseHolder<HaveStartTimePromise> mHaveStartTimePromise;
-    RefPtr<AbstractThread> mOwnerThread;
-    Maybe<int64_t> mAudioStartTime;
-    Maybe<int64_t> mVideoStartTime;
-  };
-  RefPtr<StartTimeRendezvous> mStartTimeRendezvous;
-
-  bool HaveStartTime() { return mStartTimeRendezvous && mStartTimeRendezvous->HaveStartTime(); }
-  int64_t StartTime() { return mStartTimeRendezvous->StartTime(); }
-
   // Queue of audio frames. This queue is threadsafe, and is accessed from
   // the audio, decoder, state machine, and main threads.
   MediaQueue<MediaData> mAudioQueue;
   // Queue of video frames. This queue is threadsafe, and is accessed from
   // the decoder, state machine, and main threads.
   MediaQueue<MediaData> mVideoQueue;
 
   // The decoder monitor must be obtained before modifying this state.
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -209,16 +209,17 @@ UNIFIED_SOURCES += [
     'FlushableTaskQueue.cpp',
     'GetUserMediaRequest.cpp',
     'GraphDriver.cpp',
     'Latency.cpp',
     'MediaCache.cpp',
     'MediaData.cpp',
     'MediaDecoder.cpp',
     'MediaDecoderReader.cpp',
+    'MediaDecoderReaderWrapper.cpp',
     'MediaDecoderStateMachine.cpp',
     'MediaDeviceInfo.cpp',
     'MediaDevices.cpp',
     'MediaFormatReader.cpp',
     'MediaManager.cpp',
     'MediaRecorder.cpp',
     'MediaResource.cpp',
     'MediaShutdownManager.cpp',