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
This commit is contained in:
ctai 2016-05-31 13:53:49 +08:00
Родитель edeaa48113
Коммит 608aa7e45b
3 изменённых файлов: 46 добавлений и 30 удалений

Просмотреть файл

@ -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<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()
{

Просмотреть файл

@ -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) {}
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;

Просмотреть файл

@ -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.