Bug 1201363 - MediaStreamVideoSink for ImageCapture case. r?roc
Make CaptureTask to inherite from MediaStreamVideoSink. The main change is to move the logic of |NotifyQueuedTrackChanges| to |SetCurrentFrames|.
--- a/dom/media/imagecapture/CaptureTask.cpp
+++ b/dom/media/imagecapture/CaptureTask.cpp
@@ -53,57 +53,47 @@ CaptureTask::AttachStream()
MOZ_ASSERT(NS_IsMainThread());
RefPtr<dom::VideoStreamTrack> track = mImageCapture->GetVideoStreamTrack();
RefPtr<DOMMediaStream> domStream = track->GetStream();
domStream->AddPrincipalChangeObserver(this);
RefPtr<MediaStream> stream = domStream->GetPlaybackStream();
- stream->AddListener(this);
+ stream->AddVideoOutput(this);
}
void
CaptureTask::DetachStream()
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<dom::VideoStreamTrack> track = mImageCapture->GetVideoStreamTrack();
RefPtr<DOMMediaStream> domStream = track->GetStream();
domStream->RemovePrincipalChangeObserver(this);
RefPtr<MediaStream> stream = domStream->GetPlaybackStream();
- stream->RemoveListener(this);
+ stream->RemoveVideoOutput(this);
}
void
CaptureTask::PrincipalChanged(DOMMediaStream* aMediaStream)
{
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::SetCurrentFrames(const VideoSegment& aSegment)
{
if (mImageGrabbedOrTrackEnd) {
return;
}
- if (aTrackEvents == MediaStreamListener::TRACK_EVENT_ENDED) {
- PostTrackEndEvent();
- return;
- }
-
// 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
{
@@ -112,61 +102,48 @@ 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::ConstChunkIterator iter(aSegment);
+ while (!iter.IsEnded()) {
+ VideoChunk chunk = *iter;
- // 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;
+ // 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();
}
- iter.Next();
- }
- }
-}
+ MOZ_ASSERT(image);
+ mImageGrabbedOrTrackEnd = true;
-void
-CaptureTask::NotifyEvent(MediaStreamGraph* aGraph, MediaStreamGraphEvent aEvent)
-{
- if (((aEvent == EVENT_FINISHED) || (aEvent == EVENT_REMOVED)) &&
- !mImageGrabbedOrTrackEnd) {
- PostTrackEndEvent();
+ // 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();
}
}
void
CaptureTask::PostTrackEndEvent()
{
mImageGrabbedOrTrackEnd = true;
--- a/dom/media/imagecapture/CaptureTask.h
+++ b/dom/media/imagecapture/CaptureTask.h
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CAPTURETASK_H
#define CAPTURETASK_H
#include "DOMMediaStream.h"
#include "MediaStreamGraph.h"
+#include "MediaStreamVideoSink.h"
namespace mozilla {
namespace dom {
class Blob;
class ImageCapture;
} // namespace dom
@@ -22,30 +23,23 @@ class ImageCapture;
* ImageEncoder. The whole procedures start at AttachStream(), 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 MediaStreamVideoSink,
public DOMMediaStream::PrincipalChangeObserver
{
public:
- // MediaStreamListener methods.
- void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
- StreamTime aTrackOffset,
- uint32_t aTrackEvents,
- const MediaSegment& aQueuedMedia,
- MediaStream* aInputStream,
- TrackID aInputTrackID) override;
-
- void NotifyEvent(MediaStreamGraph* aGraph,
- MediaStreamGraphEvent aEvent) override;
+ // MediaStreamVideoSink methods.
+ virtual void SetCurrentFrames(const VideoSegment& aSegment) override;
+ virtual void ClearFrames() override {}
// DOMMediaStream::PrincipalChangeObserver method.
void PrincipalChanged(DOMMediaStream* aMediaStream) 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.