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 : amend_source : a3318f6fd3d9104c2f84a8ed5e79cf68f304308c
This commit is contained in:
ctai 2016-05-31 13:53:49 +08:00
parent a3cc6128d3
commit 3d269ad415
3 changed files with 46 additions and 30 deletions

View File

@ -15,6 +15,32 @@
namespace mozilla { namespace mozilla {
class CaptureTask::MediaStreamEventListener : public MediaStreamTrackListener
{
public:
explicit 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 nsresult
CaptureTask::TaskComplete(already_AddRefed<dom::Blob> aBlob, nsresult aRv) CaptureTask::TaskComplete(already_AddRefed<dom::Blob> aBlob, nsresult aRv)
{ {
@ -55,7 +81,8 @@ CaptureTask::AttachTrack()
dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack(); dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
track->AddPrincipalChangeObserver(this); track->AddPrincipalChangeObserver(this);
track->AddListener(this); track->AddListener(mEventListener.get());
track->AddDirectListener(this);
} }
void void
@ -65,7 +92,8 @@ CaptureTask::DetachTrack()
dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack(); dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
track->RemovePrincipalChangeObserver(this); track->RemovePrincipalChangeObserver(this);
track->RemoveListener(this); track->RemoveListener(mEventListener.get());
track->RemoveDirectListener(this);
} }
void void
@ -76,16 +104,12 @@ CaptureTask::PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack)
} }
void void
CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph, CaptureTask::SetCurrentFrames(const VideoSegment& aSegment)
StreamTime aTrackOffset,
const MediaSegment& aQueuedMedia)
{ {
if (mImageGrabbedOrTrackEnd) { if (mImageGrabbedOrTrackEnd) {
return; return;
} }
MOZ_ASSERT(aQueuedMedia.GetType() == MediaSegment::VIDEO);
// Callback for encoding complete, it calls on main thread. // Callback for encoding complete, it calls on main thread.
class EncodeComplete : public dom::EncodeCompleteCallback class EncodeComplete : public dom::EncodeCompleteCallback
{ {
@ -104,11 +128,13 @@ CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph,
RefPtr<CaptureTask> mTask; RefPtr<CaptureTask> mTask;
}; };
VideoSegment* video = VideoSegment::ConstChunkIterator iter(aSegment);
const_cast<VideoSegment*> (static_cast<const VideoSegment*>(&aQueuedMedia));
VideoSegment::ChunkIterator iter(*video);
while (!iter.IsEnded()) { while (!iter.IsEnded()) {
VideoChunk chunk = *iter; VideoChunk chunk = *iter;
// Extract the first valid video frame. // Extract the first valid video frame.
VideoFrame frame; VideoFrame frame;
if (!chunk.IsNull()) { if (!chunk.IsNull()) {
@ -141,14 +167,6 @@ CaptureTask::NotifyQueuedChanges(MediaStreamGraph* aGraph,
} }
} }
void
CaptureTask::NotifyEnded()
{
if(!mImageGrabbedOrTrackEnd) {
PostTrackEndEvent();
}
}
void void
CaptureTask::PostTrackEndEvent() CaptureTask::PostTrackEndEvent()
{ {

View File

@ -10,6 +10,7 @@
#include "MediaStreamGraph.h" #include "MediaStreamGraph.h"
#include "MediaStreamListener.h" #include "MediaStreamListener.h"
#include "PrincipalChangeObserver.h" #include "PrincipalChangeObserver.h"
#include "MediaStreamVideoSink.h"
namespace mozilla { namespace mozilla {
@ -29,16 +30,15 @@ class MediaStreamTrack;
* CaptureTask holds a reference of ImageCapture to ensure ImageCapture won't be * CaptureTask holds a reference of ImageCapture to ensure ImageCapture won't be
* released during the period of the capturing process described above. * released during the period of the capturing process described above.
*/ */
class CaptureTask : public MediaStreamTrackListener, class CaptureTask : public MediaStreamVideoSink,
public dom::PrincipalChangeObserver<dom::MediaStreamTrack> public dom::PrincipalChangeObserver<dom::MediaStreamTrack>
{ {
public: public:
// MediaStreamTrackListener methods. class MediaStreamEventListener;
void NotifyQueuedChanges(MediaStreamGraph* aGraph,
StreamTime aTrackOffset,
const MediaSegment& aQueuedMedia) override;
void NotifyEnded() override; // MediaStreamVideoSink methods.
void SetCurrentFrames(const VideoSegment& aSegment) override;
void ClearFrames() override {}
// PrincipalChangeObserver<MediaStreamTrack> method. // PrincipalChangeObserver<MediaStreamTrack> method.
void PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) override; void PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) override;
@ -61,10 +61,7 @@ public:
void DetachTrack(); void DetachTrack();
// CaptureTask should be created on main thread. // CaptureTask should be created on main thread.
explicit CaptureTask(dom::ImageCapture* aImageCapture) explicit CaptureTask(dom::ImageCapture* aImageCapture);
: mImageCapture(aImageCapture)
, mImageGrabbedOrTrackEnd(false)
, mPrincipalChanged(false) {}
protected: protected:
virtual ~CaptureTask() {} virtual ~CaptureTask() {}
@ -78,6 +75,8 @@ protected:
// event to script. // event to script.
RefPtr<dom::ImageCapture> mImageCapture; RefPtr<dom::ImageCapture> mImageCapture;
RefPtr<MediaStreamEventListener> mEventListener;
// True when an image is retrieved from MediaStreamGraph or MediaStreamGraph // True when an image is retrieved from MediaStreamGraph or MediaStreamGraph
// sends a track finish, end, or removed event. // sends a track finish, end, or removed event.
bool mImageGrabbedOrTrackEnd; bool mImageGrabbedOrTrackEnd;

View File

@ -147,8 +147,7 @@ ImageCapture::TakePhoto(ErrorResult& aResult)
// support TakePhoto(). // support TakePhoto().
if (rv == NS_ERROR_NOT_IMPLEMENTED) { if (rv == NS_ERROR_NOT_IMPLEMENTED) {
IC_LOG("MediaEngine doesn't support TakePhoto(), it falls back to MediaStreamGraph."); IC_LOG("MediaEngine doesn't support TakePhoto(), it falls back to MediaStreamGraph.");
RefPtr<CaptureTask> task = RefPtr<CaptureTask> task = new CaptureTask(this);
new CaptureTask(this);
// It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold // It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold
// the reference. // the reference.