mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 803976: Implementation of LocalMediaStreams for .stop() r=roc,anant
This commit is contained in:
parent
8f9c42aa87
commit
d6cc9a88c2
@ -2007,11 +2007,14 @@ void
|
||||
SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mData->AppendFrom(aSegment);
|
||||
} else {
|
||||
NS_ERROR("Append to non-existent track!");
|
||||
// ::EndAllTrackAndFinished() can end these before the sources notice
|
||||
if (!mFinished) {
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mData->AppendFrom(aSegment);
|
||||
} else {
|
||||
NS_ERROR("Append to non-existent track!");
|
||||
}
|
||||
}
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
@ -2052,11 +2055,14 @@ void
|
||||
SourceMediaStream::EndTrack(TrackID aID)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mCommands |= TRACK_END;
|
||||
} else {
|
||||
NS_ERROR("End of non-existant track");
|
||||
// ::EndAllTrackAndFinished() can end these before the sources call this
|
||||
if (!mFinished) {
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mCommands |= TRACK_END;
|
||||
} else {
|
||||
NS_ERROR("End of non-existant track");
|
||||
}
|
||||
}
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
@ -2074,15 +2080,28 @@ SourceMediaStream::AdvanceKnownTracksTime(StreamTime aKnownTime)
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::Finish()
|
||||
SourceMediaStream::FinishWithLockHeld()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUpdateFinished = true;
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::EndAllTrackAndFinish()
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (uint32_t i = 0; i < mUpdateTracks.Length(); ++i) {
|
||||
SourceMediaStream::TrackData* data = &mUpdateTracks[i];
|
||||
data->mCommands |= TRACK_END;
|
||||
}
|
||||
}
|
||||
FinishWithLockHeld();
|
||||
// we will call NotifyFinished() to let GetUserMedia know
|
||||
}
|
||||
|
||||
void
|
||||
MediaInputPort::Init()
|
||||
{
|
||||
|
@ -553,7 +553,19 @@ public:
|
||||
* when all tracks have ended and when latest time sent to
|
||||
* AdvanceKnownTracksTime() has been reached.
|
||||
*/
|
||||
void Finish();
|
||||
void FinishWithLockHeld();
|
||||
void Finish()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
FinishWithLockHeld();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* End all tracks and Finish() this stream. Used to voluntarily revoke access
|
||||
* to a LocalMediaStream.
|
||||
*/
|
||||
void EndAllTrackAndFinish();
|
||||
|
||||
// XXX need a Reset API
|
||||
|
||||
|
@ -28,6 +28,29 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
// LocalMediaStream currently is the same C++ class as MediaStream;
|
||||
// they may eventually split
|
||||
DOMCI_DATA(LocalMediaStream, nsDOMLocalMediaStream)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMLocalMediaStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMLocalMediaStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMMediaStream, nsDOMMediaStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMLocalMediaStream)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(LocalMediaStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMLocalMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMLocalMediaStream)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMLocalMediaStream)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMLocalMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMLocalMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
nsDOMMediaStream::~nsDOMMediaStream()
|
||||
{
|
||||
if (mStream) {
|
||||
@ -42,6 +65,15 @@ nsDOMMediaStream::GetCurrentTime(double *aCurrentTime)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMLocalMediaStream::Stop()
|
||||
{
|
||||
if (mStream && mStream->AsSourceStream()) {
|
||||
mStream->AsSourceStream()->EndAllTrackAndFinish();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMMediaStream>
|
||||
nsDOMMediaStream::CreateInputStream(uint32_t aHintContents)
|
||||
{
|
||||
@ -52,6 +84,16 @@ nsDOMMediaStream::CreateInputStream(uint32_t aHintContents)
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMLocalMediaStream>
|
||||
nsDOMLocalMediaStream::CreateInputStream(uint32_t aHintContents)
|
||||
{
|
||||
nsRefPtr<nsDOMLocalMediaStream> stream = new nsDOMLocalMediaStream();
|
||||
stream->SetHintContents(aHintContents);
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
stream->mStream = gm->CreateInputStream(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMMediaStream>
|
||||
nsDOMMediaStream::CreateTrackUnionStream()
|
||||
{
|
||||
@ -61,6 +103,15 @@ nsDOMMediaStream::CreateTrackUnionStream()
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMLocalMediaStream>
|
||||
nsDOMLocalMediaStream::CreateTrackUnionStream()
|
||||
{
|
||||
nsRefPtr<nsDOMLocalMediaStream> stream = new nsDOMLocalMediaStream();
|
||||
MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
|
||||
stream->mStream = gm->CreateTrackUnionStream(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsDOMMediaStream::CombineWithPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
class nsXPCClassInfo;
|
||||
|
||||
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
|
||||
// GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
|
||||
// currentTime getter.
|
||||
@ -23,6 +25,7 @@
|
||||
*/
|
||||
class nsDOMMediaStream : public nsIDOMMediaStream
|
||||
{
|
||||
friend class nsDOMLocalMediaStream;
|
||||
typedef mozilla::MediaStream MediaStream;
|
||||
|
||||
public:
|
||||
@ -82,4 +85,28 @@ protected:
|
||||
uint32_t mHintContents;
|
||||
};
|
||||
|
||||
class nsDOMLocalMediaStream : public nsDOMMediaStream,
|
||||
public nsIDOMLocalMediaStream
|
||||
{
|
||||
public:
|
||||
nsDOMLocalMediaStream() {}
|
||||
virtual ~nsDOMLocalMediaStream() {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMLocalMediaStream, nsDOMMediaStream)
|
||||
NS_DECL_NSIDOMLOCALMEDIASTREAM
|
||||
|
||||
NS_FORWARD_NSIDOMMEDIASTREAM(nsDOMMediaStream::)
|
||||
|
||||
/**
|
||||
* Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
|
||||
*/
|
||||
static already_AddRefed<nsDOMLocalMediaStream> CreateInputStream(uint32_t aHintContents);
|
||||
|
||||
/**
|
||||
* Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
|
||||
*/
|
||||
static already_AddRefed<nsDOMLocalMediaStream> CreateTrackUnionStream();
|
||||
};
|
||||
|
||||
#endif /* NSDOMMEDIASTREAM_H_ */
|
||||
|
@ -1518,6 +1518,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MediaStream, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(LocalMediaStream, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
#endif
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpRequestUpload, nsEventTargetSH,
|
||||
@ -4128,6 +4130,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_BEGIN(MediaStream, nsIDOMMediaStream)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMediaStream)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(LocalMediaStream, nsIDOMLocalMediaStream)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocalMediaStream)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
#endif
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(XMLHttpRequestUpload, nsIXMLHttpRequestUpload)
|
||||
|
@ -426,6 +426,7 @@ DOMCI_CLASS(TimeRanges)
|
||||
|
||||
// Media streams
|
||||
DOMCI_CLASS(MediaStream)
|
||||
DOMCI_CLASS(LocalMediaStream)
|
||||
#endif
|
||||
|
||||
DOMCI_CLASS(XMLHttpRequestUpload)
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
break;
|
||||
|
||||
case STOP:
|
||||
mDOMPreview->Stop();
|
||||
mDOMPreview->StopPreview();
|
||||
break;
|
||||
|
||||
case STARTED:
|
||||
@ -238,9 +238,9 @@ DOMCameraPreview::Started()
|
||||
}
|
||||
|
||||
void
|
||||
DOMCameraPreview::Stop()
|
||||
DOMCameraPreview::StopPreview()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Stop() not called from main thread");
|
||||
NS_ASSERTION(NS_IsMainThread(), "StopPreview() not called from main thread");
|
||||
if (mState != STARTED) {
|
||||
return;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
|
||||
void Start(); // called by the MediaStreamListener to start preview
|
||||
void Started(); // called by the CameraControl when preview is started
|
||||
void Stop(); // called by the MediaStreamListener to stop preview
|
||||
void StopPreview(); // called by the MediaStreamListener to stop preview
|
||||
void Stopped(bool aForced = false);
|
||||
// called by the CameraControl when preview is stopped
|
||||
void Error(); // something went wrong, NS_RELEASE needed
|
||||
|
@ -244,11 +244,11 @@ public:
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
|
||||
// Create a media stream.
|
||||
nsCOMPtr<nsDOMMediaStream> stream;
|
||||
nsRefPtr<nsDOMLocalMediaStream> stream;
|
||||
uint32_t hints = (mAudioSource ? nsDOMMediaStream::HINT_CONTENTS_AUDIO : 0);
|
||||
hints |= (mVideoSource ? nsDOMMediaStream::HINT_CONTENTS_VIDEO : 0);
|
||||
|
||||
stream = nsDOMMediaStream::CreateInputStream(hints);
|
||||
stream = nsDOMLocalMediaStream::CreateInputStream(hints);
|
||||
|
||||
nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
|
||||
(nsGlobalWindow::GetInnerWindowWithId(mWindowID));
|
||||
@ -299,7 +299,7 @@ public:
|
||||
MutexAutoLock lock(MediaManager::Get()->GetMutex());
|
||||
if (activeWindows->Get(mWindowID)) {
|
||||
LOG(("Returning success for getUserMedia()"));
|
||||
success->OnSuccess(stream);
|
||||
success->OnSuccess(static_cast<nsIDOMLocalMediaStream*>(stream));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
|
||||
MM_LOG(("started all sources"));
|
||||
nsCOMPtr<GetUserMediaNotificationEvent> event =
|
||||
nsRefPtr<GetUserMediaNotificationEvent> event =
|
||||
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STARTING);
|
||||
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
@ -153,7 +153,7 @@ public:
|
||||
// Do this after stopping all tracks with EndTrack()
|
||||
mSourceStream->Finish();
|
||||
|
||||
nsCOMPtr<GetUserMediaNotificationEvent> event =
|
||||
nsRefPtr<GetUserMediaNotificationEvent> event =
|
||||
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STOPPING);
|
||||
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
@ -175,7 +175,7 @@ private:
|
||||
MediaOperation mType;
|
||||
nsRefPtr<MediaEngineSource> mAudioSource;
|
||||
nsRefPtr<MediaEngineSource> mVideoSource;
|
||||
nsCOMPtr<nsDOMMediaStream> mStream;
|
||||
nsRefPtr<nsDOMMediaStream> mStream;
|
||||
SourceMediaStream *mSourceStream;
|
||||
};
|
||||
|
||||
@ -228,11 +228,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotifyFinished(MediaStreamGraph* aGraph)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIThread> mMediaThread;
|
||||
nsRefPtr<MediaEngineSource> mAudioSource;
|
||||
nsRefPtr<MediaEngineSource> mVideoSource;
|
||||
nsCOMPtr<nsDOMMediaStream> mStream;
|
||||
nsRefPtr<nsDOMMediaStream> mStream;
|
||||
bool mValid;
|
||||
};
|
||||
|
||||
|
@ -10,3 +10,10 @@ interface nsIDOMMediaStream : nsISupports
|
||||
{
|
||||
readonly attribute double currentTime;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(210a16e3-2a38-4ae9-b0f6-0fb5a8252814)]
|
||||
interface nsIDOMLocalMediaStream : nsIDOMMediaStream
|
||||
{
|
||||
void stop();
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,7 @@ interface nsIDOMGetUserMediaSuccessCallback : nsISupports
|
||||
{
|
||||
/*
|
||||
* value must be a nsIDOMBlob if picture is true and a
|
||||
* nsIDOMMediaStream if either audio or video are true.
|
||||
* nsIDOMLocalMediaStream if either audio or video are true.
|
||||
*/
|
||||
void onSuccess(in nsISupports value);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user