Bug 1208371 - Move ImageCapture to a MediaStreamTrackListener. r?roc draft
authorAndreas Pehrson <pehrsons@gmail.com>
Fri, 22 Jan 2016 12:29:54 +0800
changeset 342114 206354fbd858b7c1ab510a948a44d5ba4d806c69
parent 342113 a51dd8868a6d6fff642b18f240bdeba13aa353be
child 342115 1d84aea4dfc5986fe319a00e8b6dfdde58495151
push id13352
push userpehrsons@gmail.com
push dateFri, 18 Mar 2016 13:49:47 +0000
reviewersroc
bugs1208371
milestone47.0a1
Bug 1208371 - Move ImageCapture to a MediaStreamTrackListener. r?roc MozReview-Commit-ID: 10v7EZXu49a
dom/media/imagecapture/CaptureTask.cpp
dom/media/imagecapture/CaptureTask.h
dom/media/imagecapture/ImageCapture.cpp
--- a/dom/media/imagecapture/CaptureTask.cpp
+++ b/dom/media/imagecapture/CaptureTask.cpp
@@ -15,17 +15,17 @@
 
 namespace mozilla {
 
 nsresult
 CaptureTask::TaskComplete(already_AddRefed<dom::Blob> aBlob, nsresult aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  DetachStream();
+  DetachTrack();
 
   nsresult rv;
   RefPtr<dom::Blob> blob(aBlob);
 
   // We have to set the parent because the blob has been generated with a valid one.
   if (blob) {
     blob = dom::Blob::Create(mImageCapture->GetParentObject(), blob->Impl());
   }
@@ -44,68 +44,52 @@ CaptureTask::TaskComplete(already_AddRef
   // Ensure ImageCapture dereference on main thread here because the TakePhoto()
   // sequences stopped here.
   mImageCapture = nullptr;
 
   return rv;
 }
 
 void
-CaptureTask::AttachStream()
+CaptureTask::AttachTrack()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
-
   track->AddPrincipalChangeObserver(this);
-
-  RefPtr<DOMMediaStream> domStream = track->GetStream();
-  MOZ_RELEASE_ASSERT(domStream);
-  RefPtr<MediaStream> stream = domStream->GetPlaybackStream();
-  stream->AddListener(this);
+  track->AddListener(this);
 }
 
 void
-CaptureTask::DetachStream()
+CaptureTask::DetachTrack()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
-
   track->RemovePrincipalChangeObserver(this);
-
-  DOMMediaStream* domStream = track->GetStream();
-  MOZ_RELEASE_ASSERT(domStream);
-  RefPtr<MediaStream> stream = domStream->GetPlaybackStream();
-  stream->RemoveListener(this);
+  track->RemoveListener(this);
 }
 
 void
 CaptureTask::PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mPrincipalChanged = true;
 }
 
 void
-CaptureTask::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
-                                      StreamTime aTrackOffset,
-                                      uint32_t aTrackEvents,
-                                      const MediaSegment& aQueuedMedia,
-                                      MediaStream* aInputStream,
-                                      TrackID aInputTrackID)
+CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph,
+                                 StreamTime aTrackOffset,
+                                 const MediaSegment& aQueuedMedia)
 {
   if (mImageGrabbedOrTrackEnd) {
     return;
   }
 
-  if (aTrackEvents == MediaStreamListener::TRACK_EVENT_ENDED) {
-    PostTrackEndEvent();
-    return;
-  }
+  MOZ_ASSERT(aQueuedMedia.GetType() == MediaSegment::VIDEO);
 
   // Callback for encoding complete, it calls on main thread.
   class EncodeComplete : public dom::EncodeCompleteCallback
   {
   public:
     explicit EncodeComplete(CaptureTask* aTask) : mTask(aTask) {}
 
     nsresult ReceiveBlob(already_AddRefed<dom::Blob> aBlob) override
@@ -115,60 +99,57 @@ CaptureTask::NotifyQueuedTrackChanges(Me
       mTask = nullptr;
       return NS_OK;
     }
 
   protected:
     RefPtr<CaptureTask> mTask;
   };
 
-  if (aQueuedMedia.GetType() == MediaSegment::VIDEO && mTrackID == aID) {
-    VideoSegment* video =
-      const_cast<VideoSegment*> (static_cast<const VideoSegment*>(&aQueuedMedia));
-    VideoSegment::ChunkIterator iter(*video);
-    while (!iter.IsEnded()) {
-      VideoChunk chunk = *iter;
-      // Extract the first valid video frame.
-      VideoFrame frame;
-      if (!chunk.IsNull()) {
-        RefPtr<layers::Image> image;
-        if (chunk.mFrame.GetForceBlack()) {
-          // Create a black image.
-          image = VideoFrame::CreateBlackImage(chunk.mFrame.GetIntrinsicSize());
-        } else {
-          image = chunk.mFrame.GetImage();
-        }
-        MOZ_ASSERT(image);
-        mImageGrabbedOrTrackEnd = true;
+  VideoSegment* video =
+    const_cast<VideoSegment*> (static_cast<const VideoSegment*>(&aQueuedMedia));
+  VideoSegment::ChunkIterator iter(*video);
+  while (!iter.IsEnded()) {
+    VideoChunk chunk = *iter;
+    // Extract the first valid video frame.
+    VideoFrame frame;
+    if (!chunk.IsNull()) {
+      RefPtr<layers::Image> image;
+      if (chunk.mFrame.GetForceBlack()) {
+        // Create a black image.
+        image = VideoFrame::CreateBlackImage(chunk.mFrame.GetIntrinsicSize());
+      } else {
+        image = chunk.mFrame.GetImage();
+      }
+      MOZ_ASSERT(image);
+      mImageGrabbedOrTrackEnd = true;
 
-        // Encode image.
-        nsresult rv;
-        nsAutoString type(NS_LITERAL_STRING("image/jpeg"));
-        nsAutoString options;
-        rv = dom::ImageEncoder::ExtractDataFromLayersImageAsync(
-                                  type,
-                                  options,
-                                  false,
-                                  image,
-                                  new EncodeComplete(this));
-        if (NS_FAILED(rv)) {
-          PostTrackEndEvent();
-        }
-        return;
+      // Encode image.
+      nsresult rv;
+      nsAutoString type(NS_LITERAL_STRING("image/jpeg"));
+      nsAutoString options;
+      rv = dom::ImageEncoder::ExtractDataFromLayersImageAsync(
+                                type,
+                                options,
+                                false,
+                                image,
+                                new EncodeComplete(this));
+      if (NS_FAILED(rv)) {
+        PostTrackEndEvent();
       }
-      iter.Next();
+      return;
     }
+    iter.Next();
   }
 }
 
 void
-CaptureTask::NotifyEvent(MediaStreamGraph* aGraph, MediaStreamGraphEvent aEvent)
+CaptureTask::NotifyEnded()
 {
-  if (((aEvent == EVENT_FINISHED) || (aEvent == EVENT_REMOVED)) &&
-      !mImageGrabbedOrTrackEnd) {
+  if(!mImageGrabbedOrTrackEnd) {
     PostTrackEndEvent();
   }
 }
 
 void
 CaptureTask::PostTrackEndEvent()
 {
   mImageGrabbedOrTrackEnd = true;
--- a/dom/media/imagecapture/CaptureTask.h
+++ b/dom/media/imagecapture/CaptureTask.h
@@ -15,58 +15,54 @@ namespace mozilla {
 namespace dom {
 class Blob;
 class ImageCapture;
 class MediaStreamTrack;
 } // namespace dom
 
 /**
  * CaptureTask retrieves image from MediaStream and encodes the image to jpeg in
- * ImageEncoder. The whole procedures start at AttachStream(), it will add this
+ * ImageEncoder. The whole procedures start at AttachTrack(), it will add this
  * class into MediaStream and retrieves an image in MediaStreamGraph thread.
  * Once the image is retrieved, it will be sent to ImageEncoder and the encoded
  * blob will be sent out via encoder callback in main thread.
  *
  * CaptureTask holds a reference of ImageCapture to ensure ImageCapture won't be
  * released during the period of the capturing process described above.
  */
-class CaptureTask : public MediaStreamListener,
+class CaptureTask : public MediaStreamTrackListener,
                     public dom::PrincipalChangeObserver<dom::MediaStreamTrack>
 {
 public:
-  // MediaStreamListener methods.
-  void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
-                                StreamTime aTrackOffset,
-                                uint32_t aTrackEvents,
-                                const MediaSegment& aQueuedMedia,
-                                MediaStream* aInputStream,
-                                TrackID aInputTrackID) override;
+  // MediaStreamTrackListener methods.
+  void NotifyQueuedChanges(MediaStreamGraph* aGraph,
+                           StreamTime aTrackOffset,
+                           const MediaSegment& aQueuedMedia) override;
 
-  void NotifyEvent(MediaStreamGraph* aGraph,
-                   MediaStreamGraphEvent aEvent) override;
+  void NotifyEnded() override;
 
   // PrincipalChangeObserver<MediaStreamTrack> method.
   void PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) override;
 
   // CaptureTask methods.
 
   // It is called when aBlob is ready to post back to script in company with
   // aRv == NS_OK. If aRv is not NS_OK, it will post an error event to script.
   //
   // Note:
   //   this function should be called on main thread.
   nsresult TaskComplete(already_AddRefed<dom::Blob> aBlob, nsresult aRv);
 
-  // Add listeners into MediaStream and PrincipalChangeObserver.
+  // Add listeners into MediaStreamTrack and PrincipalChangeObserver.
   // It should be on main thread only.
-  void AttachStream();
+  void AttachTrack();
 
-  // Remove listeners from MediaStream and PrincipalChangeObserver.
+  // Remove listeners from MediaStreamTrack and PrincipalChangeObserver.
   // It should be on main thread only.
-  void DetachStream();
+  void DetachTrack();
 
   // CaptureTask should be created on main thread.
   CaptureTask(dom::ImageCapture* aImageCapture, TrackID aTrackID)
     : mImageCapture(aImageCapture)
     , mTrackID(aTrackID)
     , mImageGrabbedOrTrackEnd(false)
     , mPrincipalChanged(false) {}
 
--- a/dom/media/imagecapture/ImageCapture.cpp
+++ b/dom/media/imagecapture/ImageCapture.cpp
@@ -147,17 +147,17 @@ ImageCapture::TakePhoto(ErrorResult& aRe
   // support TakePhoto().
   if (rv == NS_ERROR_NOT_IMPLEMENTED) {
     IC_LOG("MediaEngine doesn't support TakePhoto(), it falls back to MediaStreamGraph.");
     RefPtr<CaptureTask> task =
       new CaptureTask(this, mVideoStreamTrack->GetTrackID());
 
     // It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold
     // the reference.
-    task->AttachStream();
+    task->AttachTrack();
   }
 }
 
 nsresult
 ImageCapture::PostBlobEvent(Blob* aBlob)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!CheckPrincipal()) {