Bug 1124139 - Don't use mPlaybackStream for CameraPreview. r=jesup, a=jocheng
authorAndreas Pehrson <pehrson@comoyo.com>
Thu, 22 Jan 2015 09:27:24 +0100
changeset 238498 f16c01430eeaa87b1639255594d756d0cdb112be
parent 238497 ebe9798dea2c18383058975ef033581aebc2ff57
child 238499 36a0330867e0ab1fa15b35e24899eb0571edd01d
push id651
push userryanvm@gmail.com
push dateThu, 28 May 2015 02:39:47 +0000
treeherdermozilla-b2g37_v2_2@a644263a8225 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, jocheng
bugs1124139
milestone37.0
Bug 1124139 - Don't use mPlaybackStream for CameraPreview. r=jesup, a=jocheng
dom/camera/CameraPreviewMediaStream.h
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/media/MediaStreamGraph.h
--- a/dom/camera/CameraPreviewMediaStream.h
+++ b/dom/camera/CameraPreviewMediaStream.h
@@ -37,16 +37,17 @@ protected:
  */
 class CameraPreviewMediaStream : public MediaStream
 {
   typedef mozilla::layers::Image Image;
 
 public:
   explicit CameraPreviewMediaStream(DOMMediaStream* aWrapper);
 
+  virtual CameraPreviewMediaStream* AsCameraPreviewStream() MOZ_OVERRIDE { return this; };
   virtual void AddAudioOutput(void* aKey) MOZ_OVERRIDE;
   virtual void SetAudioOutputVolume(void* aKey, float aVolume) MOZ_OVERRIDE;
   virtual void RemoveAudioOutput(void* aKey) MOZ_OVERRIDE;
   virtual void AddVideoOutput(VideoFrameContainer* aContainer) MOZ_OVERRIDE;
   virtual void RemoveVideoOutput(VideoFrameContainer* aContainer) MOZ_OVERRIDE;
   virtual void ChangeExplicitBlockerCount(int32_t aDelta) MOZ_OVERRIDE;
   virtual void AddListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
   virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3006,29 +3006,32 @@ void HTMLMediaElement::SetupSrcMediaStre
 
   mSrcStream = aStream;
 
   nsIDOMWindow* window = OwnerDoc()->GetInnerWindow();
   if (!window) {
     return;
   }
 
-  // Now that we have access to |mSrcStream| we can pipe it to our shadow
-  // version |mPlaybackStream|. If two media elements are playing the
-  // same realtime DOMMediaStream, this allows them to pause playback
-  // independently of each other.
-  mPlaybackStream = DOMMediaStream::CreateTrackUnionStream(window);
-  mPlaybackStreamInputPort = mPlaybackStream->GetStream()->AsProcessedStream()->
-    AllocateInputPort(mSrcStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
-
-  nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
-  mPlaybackStream->CombineWithPrincipal(principal);
-
-  // Let |mSrcStream| decide when the stream has finished.
-  GetSrcMediaStream()->AsProcessedStream()->SetAutofinish(true);
+  // XXX Remove this if with CameraPreviewMediaStream per bug 1124630.
+  if (!mSrcStream->GetStream()->AsCameraPreviewStream()) {
+    // Now that we have access to |mSrcStream| we can pipe it to our shadow
+    // version |mPlaybackStream|. If two media elements are playing the
+    // same realtime DOMMediaStream, this allows them to pause playback
+    // independently of each other.
+    mPlaybackStream = DOMMediaStream::CreateTrackUnionStream(window);
+    mPlaybackStreamInputPort = mPlaybackStream->GetStream()->AsProcessedStream()->
+      AllocateInputPort(mSrcStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
+
+    nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
+    mPlaybackStream->CombineWithPrincipal(principal);
+
+    // Let |mSrcStream| decide when the stream has finished.
+    GetSrcMediaStream()->AsProcessedStream()->SetAutofinish(true);
+  }
 
   nsRefPtr<MediaStream> stream = mSrcStream->GetStream();
   if (stream) {
     stream->SetAudioChannelType(mAudioChannel);
   }
 
   // XXX if we ever support capturing the output of a media element which is
   // playing a stream, we'll need to add a CombineWithPrincipal call here.
@@ -3074,17 +3077,19 @@ void HTMLMediaElement::EndSrcMediaStream
   if (stream) {
     stream->RemoveListener(mMediaStreamListener);
   }
   if (mSrcStream->GetStream()) {
     mSrcStream->GetStream()->RemoveListener(mMediaStreamSizeListener);
   }
   mSrcStream->DisconnectTrackListListeners(AudioTracks(), VideoTracks());
 
-  mPlaybackStreamInputPort->Destroy();
+  if (mPlaybackStreamInputPort) {
+    mPlaybackStreamInputPort->Destroy();
+  }
 
   // Kill its reference to this element
   mMediaStreamListener->Forget();
   mMediaStreamListener = nullptr;
   mMediaStreamSizeListener->Forget();
   mMediaStreamSizeListener = nullptr;
   if (stream) {
     stream->RemoveAudioOutput(this);
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -335,17 +335,21 @@ public:
    * be fired if we've not fired a timeupdate event (for any reason) in the
    * last 250ms, as required by the spec when the current time is periodically
    * increasing during playback.
    */
   virtual void FireTimeUpdate(bool aPeriodic) MOZ_FINAL MOZ_OVERRIDE;
 
   MediaStream* GetSrcMediaStream() const
   {
-    NS_ASSERTION(mPlaybackStream, "Don't call this when not playing a stream");
+    NS_ASSERTION(mSrcStream, "Don't call this when not playing a stream");
+    if (!mPlaybackStream) {
+      // XXX Remove this check with CameraPreviewMediaStream per bug 1124630.
+      return mSrcStream->GetStream();
+    }
     return mPlaybackStream->GetStream();
   }
 
   // WebIDL
 
   MediaError* GetError() const
   {
     return mError;
--- a/dom/media/MediaStreamGraph.h
+++ b/dom/media/MediaStreamGraph.h
@@ -235,16 +235,17 @@ struct AudioNodeSizes
 class MediaStreamGraphImpl;
 class SourceMediaStream;
 class ProcessedMediaStream;
 class MediaInputPort;
 class AudioNodeEngine;
 class AudioNodeExternalInputStream;
 class AudioNodeStream;
 struct AudioChunk;
+class CameraPreviewMediaStream;
 
 /**
  * A stream of synchronized audio and video data. All (not blocked) streams
  * progress at the same rate --- "real time". Streams cannot seek. The only
  * operation readers can perform on a stream is to read the next data.
  *
  * Consumers of a stream can be reading from it at different offsets, but that
  * should only happen due to the order in which consumers are being run.
@@ -413,16 +414,17 @@ public:
 
   friend class MediaStreamGraphImpl;
   friend class MediaInputPort;
   friend class AudioNodeExternalInputStream;
 
   virtual SourceMediaStream* AsSourceStream() { return nullptr; }
   virtual ProcessedMediaStream* AsProcessedStream() { return nullptr; }
   virtual AudioNodeStream* AsAudioNodeStream() { return nullptr; }
+  virtual CameraPreviewMediaStream* AsCameraPreviewStream() { return nullptr; }
 
   // media graph thread only
   void Init();
   // These Impl methods perform the core functionality of the control methods
   // above, on the media graph thread.
   /**
    * Stop all stream activity and disconnect it from all inputs and outputs.
    * This must be idempotent.