From 608aa7e45bae057672d3d0a66f76d459389d1c03 Mon Sep 17 00:00:00 2001 From: ctai Date: Tue, 31 May 2016 13:53:49 +0800 Subject: [PATCH] Bug 1201363 - MediaStreamVideoSink for ImageCapture case. r=jesup Make CaptureTask to inherite from MediaStreamVideoSink. The main change is to move the logic of |NotifyQueuedTrackChanges| to |SetCurrentFrames|. The original image capture is not modified for support multiple video MediaStreamTracks. The design still used the track id in owned media stream. The should be fixed in the following bug if we still want to support ImageCapture in multiple video tracks case. MozReview-Commit-ID: Od4tHoR8Ef --HG-- extra : transplant_source : %8D%848%99%1C%DFOz%40r%D5%F4%85%10%9A6%E1%A6%3Fs --- dom/media/imagecapture/CaptureTask.cpp | 54 ++++++++++++++++--------- dom/media/imagecapture/CaptureTask.h | 19 +++++---- dom/media/imagecapture/ImageCapture.cpp | 3 +- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/dom/media/imagecapture/CaptureTask.cpp b/dom/media/imagecapture/CaptureTask.cpp index 7dc1b3dd1a6c..e9ca87f4e66d 100644 --- a/dom/media/imagecapture/CaptureTask.cpp +++ b/dom/media/imagecapture/CaptureTask.cpp @@ -15,6 +15,32 @@ namespace mozilla { +class CaptureTask::MediaStreamEventListener : public MediaStreamTrackListener +{ +public: + MediaStreamEventListener(CaptureTask* aCaptureTask) + : mCaptureTask(aCaptureTask) {}; + + // MediaStreamListener methods. + void NotifyEnded() override + { + if(!mCaptureTask->mImageGrabbedOrTrackEnd) { + mCaptureTask->PostTrackEndEvent(); + } + } + +private: + CaptureTask* mCaptureTask; +}; + +CaptureTask::CaptureTask(dom::ImageCapture* aImageCapture) + : mImageCapture(aImageCapture) + , mEventListener(new MediaStreamEventListener(this)) + , mImageGrabbedOrTrackEnd(false) + , mPrincipalChanged(false) +{ +} + nsresult CaptureTask::TaskComplete(already_AddRefed aBlob, nsresult aRv) { @@ -55,7 +81,8 @@ CaptureTask::AttachTrack() dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack(); track->AddPrincipalChangeObserver(this); - track->AddListener(this); + track->AddListener(mEventListener.get()); + track->AddDirectListener(this); } void @@ -65,7 +92,8 @@ CaptureTask::DetachTrack() dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack(); track->RemovePrincipalChangeObserver(this); - track->RemoveListener(this); + track->RemoveListener(mEventListener.get()); + track->RemoveDirectListener(this); } void @@ -76,16 +104,12 @@ CaptureTask::PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) } void -CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph, - StreamTime aTrackOffset, - const MediaSegment& aQueuedMedia) +CaptureTask::SetCurrentFrames(const VideoSegment& aSegment) { if (mImageGrabbedOrTrackEnd) { return; } - MOZ_ASSERT(aQueuedMedia.GetType() == MediaSegment::VIDEO); - // Callback for encoding complete, it calls on main thread. class EncodeComplete : public dom::EncodeCompleteCallback { @@ -104,11 +128,13 @@ CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph, RefPtr mTask; }; - VideoSegment* video = - const_cast (static_cast(&aQueuedMedia)); - VideoSegment::ChunkIterator iter(*video); + VideoSegment::ConstChunkIterator iter(aSegment); + + + while (!iter.IsEnded()) { VideoChunk chunk = *iter; + // Extract the first valid video frame. VideoFrame frame; if (!chunk.IsNull()) { @@ -141,14 +167,6 @@ CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph, } } -void -CaptureTask::NotifyEnded() -{ - if(!mImageGrabbedOrTrackEnd) { - PostTrackEndEvent(); - } -} - void CaptureTask::PostTrackEndEvent() { diff --git a/dom/media/imagecapture/CaptureTask.h b/dom/media/imagecapture/CaptureTask.h index 7363ef7bdd9e..b898b7451e13 100644 --- a/dom/media/imagecapture/CaptureTask.h +++ b/dom/media/imagecapture/CaptureTask.h @@ -10,6 +10,7 @@ #include "MediaStreamGraph.h" #include "MediaStreamListener.h" #include "PrincipalChangeObserver.h" +#include "MediaStreamVideoSink.h" namespace mozilla { @@ -29,16 +30,15 @@ class MediaStreamTrack; * 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 MediaStreamTrackListener, +class CaptureTask : public MediaStreamVideoSink, public dom::PrincipalChangeObserver { public: - // MediaStreamTrackListener methods. - void NotifyQueuedChanges(MediaStreamGraph* aGraph, - StreamTime aTrackOffset, - const MediaSegment& aQueuedMedia) override; + class MediaStreamEventListener; - void NotifyEnded() override; + // MediaStreamVideoSink methods. + void SetCurrentFrames(const VideoSegment& aSegment) override; + void ClearFrames() override {} // PrincipalChangeObserver method. void PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) override; @@ -61,10 +61,7 @@ public: void DetachTrack(); // CaptureTask should be created on main thread. - explicit CaptureTask(dom::ImageCapture* aImageCapture) - : mImageCapture(aImageCapture) - , mImageGrabbedOrTrackEnd(false) - , mPrincipalChanged(false) {} + CaptureTask(dom::ImageCapture* aImageCapture); protected: virtual ~CaptureTask() {} @@ -78,6 +75,8 @@ protected: // event to script. RefPtr mImageCapture; + RefPtr mEventListener; + // True when an image is retrieved from MediaStreamGraph or MediaStreamGraph // sends a track finish, end, or removed event. bool mImageGrabbedOrTrackEnd; diff --git a/dom/media/imagecapture/ImageCapture.cpp b/dom/media/imagecapture/ImageCapture.cpp index 146e719b60c2..243fcbcc8941 100644 --- a/dom/media/imagecapture/ImageCapture.cpp +++ b/dom/media/imagecapture/ImageCapture.cpp @@ -147,8 +147,7 @@ ImageCapture::TakePhoto(ErrorResult& aResult) // support TakePhoto(). if (rv == NS_ERROR_NOT_IMPLEMENTED) { IC_LOG("MediaEngine doesn't support TakePhoto(), it falls back to MediaStreamGraph."); - RefPtr task = - new CaptureTask(this); + RefPtr task = new CaptureTask(this); // It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold // the reference.