Bug 1423253 - Change CanvasCaptureMediaStream's driver to push instead of pull. r=padenot

Differential Revision: https://phabricator.services.mozilla.com/D22900

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andreas Pehrson 2019-03-22 11:42:10 +00:00
Родитель 9ca802f154
Коммит 1b9ef949cd
2 изменённых файлов: 21 добавлений и 105 удалений

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

@ -8,7 +8,6 @@
#include "DOMMediaStream.h"
#include "ImageContainer.h"
#include "MediaStreamGraph.h"
#include "MediaStreamListener.h"
#include "gfxPlatform.h"
#include "mozilla/Atomics.h"
#include "mozilla/dom/CanvasCaptureMediaStreamBinding.h"
@ -22,100 +21,17 @@ using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
class OutputStreamDriver::TrackListener : public MediaStreamTrackListener {
public:
TrackListener(TrackID aTrackId, const PrincipalHandle& aPrincipalHandle,
SourceMediaStream* aSourceStream)
: mEnded(false),
mSourceStream(aSourceStream),
mTrackId(aTrackId),
mPrincipalHandle(aPrincipalHandle),
mMutex("CanvasCaptureMediaStream OutputStreamDriver::StreamListener") {
MOZ_ASSERT(mSourceStream);
}
void Forget() {
EndTrack();
mSourceStream->EndTrack(mTrackId);
MutexAutoLock lock(mMutex);
mImage = nullptr;
}
void EndTrack() { mEnded = true; }
void SetImage(const RefPtr<layers::Image>& aImage, const TimeStamp& aTime) {
MutexAutoLock lock(mMutex);
mImage = aImage;
mImageTime = aTime;
}
void NotifyPull(MediaStreamGraph* aGraph, StreamTime aEndOfAppendedData,
StreamTime aDesiredTime) override {
// Called on the MediaStreamGraph thread.
TRACE_AUDIO_CALLBACK_COMMENT("SourceMediaStream %p track %i",
mSourceStream.get(), mTrackId);
MOZ_ASSERT(mSourceStream);
StreamTime delta = aDesiredTime - aEndOfAppendedData;
MOZ_ASSERT(delta > 0);
MutexAutoLock lock(mMutex);
RefPtr<Image> image = mImage;
IntSize size = image ? image->GetSize() : IntSize(0, 0);
VideoSegment segment;
segment.AppendFrame(image.forget(), delta, size, mPrincipalHandle, false,
mImageTime);
mSourceStream->AppendToTrack(mTrackId, &segment);
if (mEnded) {
mSourceStream->EndTrack(mTrackId);
}
}
void NotifyEnded() override {
Forget();
mSourceStream->Graph()->DispatchToMainThreadStableState(
NS_NewRunnableFunction(
"OutputStreamDriver::TrackListener::RemoveTrackListener",
[self = RefPtr<TrackListener>(this), this]() {
if (!mSourceStream->IsDestroyed()) {
mSourceStream->RemoveTrackListener(this, mTrackId);
}
}));
}
void NotifyRemoved() override { Forget(); }
protected:
~TrackListener() = default;
private:
Atomic<bool> mEnded;
const RefPtr<SourceMediaStream> mSourceStream;
const TrackID mTrackId;
const PrincipalHandle mPrincipalHandle;
Mutex mMutex;
// The below members are protected by mMutex.
RefPtr<layers::Image> mImage;
TimeStamp mImageTime;
};
OutputStreamDriver::OutputStreamDriver(SourceMediaStream* aSourceStream,
const TrackID& aTrackId,
const PrincipalHandle& aPrincipalHandle)
: FrameCaptureListener(),
mTrackId(aTrackId),
mSourceStream(aSourceStream),
mTrackListener(
new TrackListener(aTrackId, aPrincipalHandle, aSourceStream)) {
mPrincipalHandle(aPrincipalHandle) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mSourceStream);
MOZ_ASSERT(IsTrackIDExplicit(mTrackId));
mSourceStream->AddTrack(aTrackId, new VideoSegment());
mSourceStream->AddTrackListener(mTrackListener, aTrackId);
mSourceStream->SetPullingEnabled(aTrackId, true);
// All CanvasCaptureMediaStreams shall at least get one frame.
mFrameCaptureRequested = true;
@ -123,16 +39,24 @@ OutputStreamDriver::OutputStreamDriver(SourceMediaStream* aSourceStream,
OutputStreamDriver::~OutputStreamDriver() {
MOZ_ASSERT(NS_IsMainThread());
// MediaStreamGraph will keep the listener alive until it can end the track in
// the graph on the next NotifyPull().
mTrackListener->EndTrack();
EndTrack();
}
void OutputStreamDriver::EndTrack() { mTrackListener->EndTrack(); }
void OutputStreamDriver::EndTrack() {
MOZ_ASSERT(NS_IsMainThread());
mSourceStream->EndTrack(mTrackId);
}
void OutputStreamDriver::SetImage(const RefPtr<layers::Image>& aImage,
const TimeStamp& aTime) {
mTrackListener->SetImage(aImage, aTime);
MOZ_ASSERT(NS_IsMainThread());
TRACE_COMMENT("SourceMediaStream %p track %i", mSourceStream.get(), mTrackId);
VideoSegment segment;
segment.AppendFrame(do_AddRef(aImage), 1, aImage->GetSize(), mPrincipalHandle,
false, aTime);
mSourceStream->AppendToTrack(mTrackId, &segment);
}
// ----------------------------------------------------------------------

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

@ -14,7 +14,6 @@ class nsIPrincipal;
namespace mozilla {
class DOMMediaStream;
class MediaStreamListener;
class SourceMediaStream;
namespace layers {
@ -44,16 +43,10 @@ class OutputStreamFrameListener;
* | Canvas | SetFrameCapture() | (FrameCaptureListener) |
* |________| ------------------------> |________________________|
* |
* | SetImage()
* | SetImage() -
* | AppendToTrack()
* |
* v
* ____________________
* |Stream/TrackListener|
* ---------------------------------------| (All image access |---------------
* === MediaStreamGraph Thread === | Mutex Guarded) |
* |____________________|
* ^ |
* NotifyPull() | | AppendToTrack()
* | v
* ___________________________
* | |
* | MSG / SourceMediaStream |
@ -93,12 +86,11 @@ class OutputStreamDriver : public FrameCaptureListener {
protected:
virtual ~OutputStreamDriver();
class StreamListener;
class TrackListener;
private:
const TrackID mTrackId;
const RefPtr<SourceMediaStream> mSourceStream;
const RefPtr<TrackListener> mTrackListener;
const PrincipalHandle mPrincipalHandle;
};
class CanvasCaptureMediaStream : public DOMMediaStream {