зеркало из https://github.com/mozilla/gecko-dev.git
Bug 866514. Part 1: Add DOMMediaStream::OnTracksAvailableCallback. r=jesup
--HG-- extra : rebase_source : 8d8da0bc2a55fa14f837cb85f35236ca33d2437d
This commit is contained in:
Родитель
b1b2cbcf67
Коммит
829a481dde
|
@ -113,7 +113,8 @@ private:
|
|||
};
|
||||
|
||||
DOMMediaStream::DOMMediaStream()
|
||||
: mStream(nullptr), mHintContents(0)
|
||||
: mStream(nullptr), mHintContents(0), mTrackTypesAvailable(0),
|
||||
mNotifiedOfMediaStreamGraphShutdown(false)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
@ -177,7 +178,7 @@ DOMMediaStream::IsFinished()
|
|||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
|
||||
{
|
||||
mWindow = aWindow;
|
||||
SetHintContents(aHintContents);
|
||||
|
@ -186,7 +187,7 @@ DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
|||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMMediaStream::InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
|
||||
{
|
||||
mWindow = aWindow;
|
||||
SetHintContents(aHintContents);
|
||||
|
@ -205,7 +206,7 @@ DOMMediaStream::InitStreamCommon(MediaStream* aStream)
|
|||
}
|
||||
|
||||
already_AddRefed<DOMMediaStream>
|
||||
DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
|
||||
{
|
||||
nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
|
||||
stream->InitSourceStream(aWindow, aHintContents);
|
||||
|
@ -213,7 +214,7 @@ DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents
|
|||
}
|
||||
|
||||
already_AddRefed<DOMMediaStream>
|
||||
DOMMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
|
||||
{
|
||||
nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
|
||||
stream->InitTrackUnionStream(aWindow, aHintContents);
|
||||
|
@ -233,16 +234,20 @@ DOMMediaStream::CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
|
|||
switch (aType) {
|
||||
case MediaSegment::AUDIO:
|
||||
track = new AudioStreamTrack(this, aTrackID);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_AUDIO;
|
||||
break;
|
||||
case MediaSegment::VIDEO:
|
||||
track = new VideoStreamTrack(this, aTrackID);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_VIDEO;
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unhandled track type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mTracks.AppendElement(track);
|
||||
|
||||
CheckTracksAvailable();
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
|
@ -260,6 +265,44 @@ DOMMediaStream::GetDOMTrackFor(TrackID aTrackID)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::NotifyMediaStreamGraphShutdown()
|
||||
{
|
||||
// No more tracks will ever be added, so just clear these callbacks now
|
||||
// to prevent leaks.
|
||||
mNotifiedOfMediaStreamGraphShutdown = true;
|
||||
mRunOnTracksAvailable.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::OnTracksAvailable(OnTracksAvailableCallback* aRunnable)
|
||||
{
|
||||
if (mNotifiedOfMediaStreamGraphShutdown) {
|
||||
// No more tracks will ever be added, so just delete the callback now.
|
||||
delete aRunnable;
|
||||
return;
|
||||
}
|
||||
mRunOnTracksAvailable.AppendElement(aRunnable);
|
||||
CheckTracksAvailable();
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::CheckTracksAvailable()
|
||||
{
|
||||
nsTArray<nsAutoPtr<OnTracksAvailableCallback> > callbacks;
|
||||
callbacks.SwapElements(mRunOnTracksAvailable);
|
||||
|
||||
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
|
||||
OnTracksAvailableCallback* cb = callbacks[i];
|
||||
if (~mTrackTypesAvailable & cb->GetExpectedTracks()) {
|
||||
// Some expected tracks not available yet. Try this callback again later.
|
||||
*mRunOnTracksAvailable.AppendElement() = callbacks[i].forget();
|
||||
continue;
|
||||
}
|
||||
cb->NotifyTracksAvailable(this);
|
||||
}
|
||||
}
|
||||
|
||||
DOMLocalMediaStream::~DOMLocalMediaStream()
|
||||
{
|
||||
if (mStream) {
|
||||
|
@ -283,7 +326,8 @@ DOMLocalMediaStream::Stop()
|
|||
}
|
||||
|
||||
already_AddRefed<DOMLocalMediaStream>
|
||||
DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow,
|
||||
TrackTypeHints aHintContents)
|
||||
{
|
||||
nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
|
||||
stream->InitSourceStream(aWindow, aHintContents);
|
||||
|
@ -291,7 +335,8 @@ DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintCon
|
|||
}
|
||||
|
||||
already_AddRefed<DOMLocalMediaStream>
|
||||
DOMLocalMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
|
||||
DOMLocalMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow,
|
||||
TrackTypeHints aHintContents)
|
||||
{
|
||||
nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
|
||||
stream->InitTrackUnionStream(aWindow, aHintContents);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsWrapperCache.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "StreamBuffer.h"
|
||||
#include "nsIRunnable.h"
|
||||
|
||||
class nsXPCClassInfo;
|
||||
|
||||
|
@ -49,6 +50,8 @@ class DOMMediaStream : public nsIDOMMediaStream,
|
|||
typedef dom::VideoStreamTrack VideoStreamTrack;
|
||||
|
||||
public:
|
||||
typedef uint8_t TrackTypeHints;
|
||||
|
||||
DOMMediaStream();
|
||||
virtual ~DOMMediaStream();
|
||||
|
||||
|
@ -83,36 +86,66 @@ public:
|
|||
*/
|
||||
bool CombineWithPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* Called when this stream's MediaStreamGraph has been shut down. Normally
|
||||
* MSGs are only shut down when all streams have been removed, so this
|
||||
* will only be called during a forced shutdown due to application exit.
|
||||
*/
|
||||
void NotifyMediaStreamGraphShutdown();
|
||||
|
||||
// Indicate what track types we eventually expect to add to this stream
|
||||
enum {
|
||||
HINT_CONTENTS_AUDIO = 1 << 0,
|
||||
HINT_CONTENTS_VIDEO = 1 << 1
|
||||
};
|
||||
TrackTypeHints GetHintContents() const { return mHintContents; }
|
||||
void SetHintContents(TrackTypeHints aHintContents) { mHintContents = aHintContents; }
|
||||
|
||||
/**
|
||||
* Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream.
|
||||
*/
|
||||
static already_AddRefed<DOMMediaStream>
|
||||
CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
|
||||
|
||||
// Hints to tell the SDP generator about whether this
|
||||
// MediaStream probably has audio and/or video
|
||||
enum {
|
||||
HINT_CONTENTS_AUDIO = 0x00000001U,
|
||||
HINT_CONTENTS_VIDEO = 0x00000002U
|
||||
};
|
||||
uint32_t GetHintContents() const { return mHintContents; }
|
||||
void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; }
|
||||
CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
|
||||
|
||||
/**
|
||||
* Create an nsDOMMediaStream whose underlying stream is a TrackUnionStream.
|
||||
*/
|
||||
static already_AddRefed<DOMMediaStream>
|
||||
CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
|
||||
CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
|
||||
|
||||
// Notifications from StreamListener
|
||||
// Notifications from StreamListener.
|
||||
// CreateDOMTrack should only be called when it's safe to run script.
|
||||
MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
|
||||
MediaStreamTrack* GetDOMTrackFor(TrackID aTrackID);
|
||||
|
||||
class OnTracksAvailableCallback {
|
||||
public:
|
||||
OnTracksAvailableCallback(uint8_t aExpectedTracks = 0)
|
||||
: mExpectedTracks(aExpectedTracks) {}
|
||||
virtual ~OnTracksAvailableCallback() {}
|
||||
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0;
|
||||
TrackTypeHints GetExpectedTracks() { return mExpectedTracks; }
|
||||
void SetExpectedTracks(TrackTypeHints aExpectedTracks) { mExpectedTracks = aExpectedTracks; }
|
||||
private:
|
||||
TrackTypeHints mExpectedTracks;
|
||||
};
|
||||
|
||||
// When one track of the appropriate type has been added for each bit set
|
||||
// in aCallback->GetExpectedTracks(), run aCallback->NotifyTracksAvailable.
|
||||
// It is allowed to do anything, including run script.
|
||||
// aCallback may run immediately during this call if tracks are already
|
||||
// available!
|
||||
// We only care about track additions, we'll fire the notification even if
|
||||
// some of the tracks have been removed.
|
||||
// Takes ownership of aCallback.
|
||||
void OnTracksAvailable(OnTracksAvailableCallback* aCallback);
|
||||
|
||||
protected:
|
||||
void Destroy();
|
||||
void InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
|
||||
void InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
|
||||
void InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
|
||||
void InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
|
||||
void InitStreamCommon(MediaStream* aStream);
|
||||
void CheckTracksAvailable();
|
||||
|
||||
class StreamListener;
|
||||
friend class StreamListener;
|
||||
|
@ -130,9 +163,13 @@ protected:
|
|||
nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks;
|
||||
nsRefPtr<StreamListener> mListener;
|
||||
|
||||
// tells the SDP generator about whether this
|
||||
// MediaStream probably has audio and/or video
|
||||
uint32_t mHintContents;
|
||||
nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable;
|
||||
|
||||
// Indicate what track types we eventually expect to add to this stream
|
||||
uint8_t mHintContents;
|
||||
// Indicate what track types have been added to this stream
|
||||
uint8_t mTrackTypesAvailable;
|
||||
bool mNotifiedOfMediaStreamGraphShutdown;
|
||||
};
|
||||
|
||||
class DOMLocalMediaStream : public DOMMediaStream,
|
||||
|
@ -153,13 +190,13 @@ public:
|
|||
* Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
|
||||
*/
|
||||
static already_AddRefed<DOMLocalMediaStream>
|
||||
CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
|
||||
CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
|
||||
|
||||
/**
|
||||
* Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
|
||||
*/
|
||||
static already_AddRefed<DOMLocalMediaStream>
|
||||
CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
|
||||
CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "AudioNodeEngine.h"
|
||||
#include "AudioNodeStream.h"
|
||||
#include <algorithm>
|
||||
#include "DOMMediaStream.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -1137,6 +1138,7 @@ public:
|
|||
{
|
||||
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
||||
"We should know the graph thread control loop isn't running!");
|
||||
|
||||
// mGraph's thread is not running so it's OK to do whatever here
|
||||
if (mGraph->IsEmpty()) {
|
||||
// mGraph is no longer needed, so delete it. If the graph is not empty
|
||||
|
@ -1144,6 +1146,13 @@ public:
|
|||
// detect that the manager has been emptied, and delete it.
|
||||
delete mGraph;
|
||||
} else {
|
||||
for (uint32_t i = 0; i < mGraph->mStreams.Length(); ++i) {
|
||||
DOMMediaStream* s = mGraph->mStreams[i]->GetWrapper();
|
||||
if (s) {
|
||||
s->NotifyMediaStreamGraphShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(mGraph->mForceShutDown, "Not in forced shutdown?");
|
||||
mGraph->mLifecycleState =
|
||||
MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION;
|
||||
|
|
|
@ -427,6 +427,12 @@ public:
|
|||
|
||||
bool HasCurrentData() { return mHasCurrentData; }
|
||||
|
||||
DOMMediaStream* GetWrapper()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only use DOMMediaStream on main thread");
|
||||
return mWrapper;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void AdvanceTimeVaryingValuesToCurrentTime(GraphTime aCurrentTime, GraphTime aBlockedTime)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче