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 {
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
CaptureTask::TaskComplete(already_AddRefed<dom::Blob> 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<CaptureTask> mTask;
};
VideoSegment* video =
const_cast<VideoSegment*> (static_cast<const VideoSegment*>(&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()
{

View File

@ -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<dom::MediaStreamTrack>
{
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<MediaStreamTrack> 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) {}
explicit CaptureTask(dom::ImageCapture* aImageCapture);
protected:
virtual ~CaptureTask() {}
@ -78,6 +75,8 @@ protected:
// event to script.
RefPtr<dom::ImageCapture> mImageCapture;
RefPtr<MediaStreamEventListener> mEventListener;
// True when an image is retrieved from MediaStreamGraph or MediaStreamGraph
// sends a track finish, end, or removed event.
bool mImageGrabbedOrTrackEnd;

View File

@ -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<CaptureTask> task =
new CaptureTask(this);
RefPtr<CaptureTask> task = new CaptureTask(this);
// It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold
// the reference.