Bug 1440195 Add a random context seed for AudioContext and MediaStream r?baku draft
authorTom Ritter <tom@mozilla.com>
Thu, 01 Mar 2018 11:00:12 -0600
changeset 767472 8535014c39560943dc3018fffac3b30f90d99d94
parent 767471 9f69e3802148b0af56b99c68ce91ecc8f3003496
child 767473 fa1dfc0632d20a776c287c8ff707600a2aa5de82
push id102611
push userbmo:tom@mozilla.com
push dateWed, 14 Mar 2018 17:48:37 +0000
reviewersbaku
bugs1440195
milestone60.0a1
Bug 1440195 Add a random context seed for AudioContext and MediaStream r?baku MozReview-Commit-ID: sHpVCgd8Fs
dom/media/DOMMediaStream.cpp
dom/media/DOMMediaStream.h
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -567,18 +567,22 @@ DOMMediaStream::Constructor(const Global
 }
 
 double
 DOMMediaStream::CurrentTime()
 {
   if (!mPlaybackStream) {
     return 0.0;
   }
+  // The value of a MediaStream's CurrentTime will always advance forward; it will never
+  // reset (even if one rewinds a video.) Therefore we can use a single Random Seed
+  // initialized at the same time as the object.
   return nsRFPService::ReduceTimePrecisionAsSecs(mPlaybackStream->
-    StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime));
+    StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime),
+    GetRandomTimelineSeed());
 }
 
 already_AddRefed<Promise>
 DOMMediaStream::CountUnderlyingStreams(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -11,16 +11,17 @@
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "StreamTracks.h"
 #include "nsIDOMWindow.h"
 #include "nsIPrincipal.h"
 #include "MediaTrackConstraints.h"
 #include "mozilla/DOMEventTargetHelper.h"
+#include "mozilla/RelativeTimeline.h"
 #include "PrincipalChangeObserver.h"
 
 // X11 has a #define for CurrentTime. Unbelievable :-(.
 // See dom/media/webaudio/AudioContext.h for more fun!
 #ifdef CurrentTime
 #undef CurrentTime
 #endif
 
@@ -197,17 +198,18 @@ protected:
  * DOMStream A'   \    \
  *           Input \    \ Owned          Playback
  *                  \    -> t1 ------------> t1     <- MediaStreamTrack Y'
  *                   \                                 (pointing to t1 in A')
  *                    ----> t2 ------------> t2     <- MediaStreamTrack Z'
  *                                                     (pointing to t2 in A')
  */
 class DOMMediaStream : public DOMEventTargetHelper,
-                       public dom::PrincipalChangeObserver<dom::MediaStreamTrack>
+                       public dom::PrincipalChangeObserver<dom::MediaStreamTrack>,
+                       public RelativeTimeline
 {
   friend class DOMLocalMediaStream;
   friend class dom::MediaStreamTrack;
   typedef dom::MediaStreamTrack MediaStreamTrack;
   typedef dom::AudioStreamTrack AudioStreamTrack;
   typedef dom::VideoStreamTrack VideoStreamTrack;
   typedef dom::MediaStreamTrackSource MediaStreamTrackSource;
   typedef dom::AudioTrack AudioTrack;
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -645,21 +645,25 @@ AudioContext::DestinationStream() const
 {
   if (Destination()) {
     return Destination()->Stream();
   }
   return nullptr;
 }
 
 double
-AudioContext::CurrentTime() const
+AudioContext::CurrentTime()
 {
   MediaStream* stream = Destination()->Stream();
+  // The value of a MediaStream's CurrentTime will always advance forward; it will never
+  // reset (even if one rewinds a video.) Therefore we can use a single Random Seed
+  // initialized at the same time as the object.
   return nsRFPService::ReduceTimePrecisionAsSecs(
-    stream->StreamTimeToSeconds(stream->GetCurrentTime()));
+    stream->StreamTimeToSeconds(stream->GetCurrentTime()),
+    GetRandomTimelineSeed());
 }
 
 void AudioContext::DisconnectFromOwner()
 {
   mIsDisconnecting = true;
   Shutdown();
   DOMEventTargetHelper::DisconnectFromOwner();
 }
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -8,16 +8,17 @@
 #define AudioContext_h_
 
 #include "mozilla/dom/OfflineAudioContextBinding.h"
 #include "MediaBufferDecoder.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/TypedArray.h"
+#include "mozilla/RelativeTimeline.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsHashKeys.h"
 #include "nsTHashtable.h"
 #include "js/TypeDecls.h"
 #include "nsIMemoryReporter.h"
 
@@ -112,17 +113,18 @@ private:
   void* mPromise;
   RefPtr<AudioNodeStream> mAudioNodeStream;
   AudioContextState mNewState;
 };
 
 enum class AudioContextOperation { Suspend, Resume, Close };
 
 class AudioContext final : public DOMEventTargetHelper,
-                           public nsIMemoryReporter
+                           public nsIMemoryReporter,
+                           public RelativeTimeline
 {
   AudioContext(nsPIDOMWindowInner* aParentWindow,
                bool aIsOffline,
                uint32_t aNumberOfChannels = 0,
                uint32_t aLength = 0,
                float aSampleRate = 0.0f);
   ~AudioContext();
 
@@ -176,17 +178,17 @@ public:
 
   float SampleRate() const
   {
     return mSampleRate;
   }
 
   bool ShouldSuspendNewStream() const { return mSuspendCalled; }
 
-  double CurrentTime() const;
+  double CurrentTime();
 
   AudioListener* Listener();
 
   AudioContextState State() const { return mAudioContextState; }
   bool IsRunning() const;
 
   // Those three methods return a promise to content, that is resolved when an
   // (possibly long) operation is completed on the MSG (and possibly other)