Bug 1057955: Stop the backend capture when the MSG track is stopped r=jib

This commit is contained in:
Randell Jesup 2014-08-27 01:03:50 -04:00
parent decf9b7b4e
commit 2fcda237b8
3 changed files with 72 additions and 8 deletions

View File

@ -230,9 +230,9 @@ public:
void ConstructMediaTracks(AudioTrackList* aAudioTrackList,
VideoTrackList* aVideoTrackList);
void NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack);
virtual void NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack);
void NotifyMediaStreamTrackEnded(MediaStreamTrack* aTrack);
virtual void NotifyMediaStreamTrackEnded(MediaStreamTrack* aTrack);
protected:
virtual ~DOMMediaStream();

View File

@ -7,6 +7,7 @@
#include "MediaManager.h"
#include "MediaStreamGraph.h"
#include "mozilla/dom/MediaStreamTrack.h"
#include "GetUserMediaRequest.h"
#include "nsHashPropertyBag.h"
#ifdef MOZ_WIDGET_GONK
@ -481,19 +482,23 @@ class nsDOMUserMediaStream : public DOMLocalMediaStream
public:
static already_AddRefed<nsDOMUserMediaStream>
CreateTrackUnionStream(nsIDOMWindow* aWindow,
MediaEngineSource *aAudioSource,
MediaEngineSource *aVideoSource)
GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource)
{
DOMMediaStream::TrackTypeHints hints =
(aAudioSource ? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
(aVideoSource ? DOMMediaStream::HINT_CONTENTS_VIDEO : 0);
nsRefPtr<nsDOMUserMediaStream> stream = new nsDOMUserMediaStream(aAudioSource);
nsRefPtr<nsDOMUserMediaStream> stream = new nsDOMUserMediaStream(aListener,
aAudioSource);
stream->InitTrackUnionStream(aWindow, hints);
return stream.forget();
}
nsDOMUserMediaStream(MediaEngineSource *aAudioSource) :
nsDOMUserMediaStream(GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource *aAudioSource) :
mListener(aListener),
mAudioSource(aAudioSource),
mEchoOn(true),
mAgcOn(false),
@ -529,6 +534,40 @@ public:
}
}
// For gUM streams, we have a trackunion which assigns TrackIDs. However, for a
// single-source trackunion like we have here, the TrackUnion will assign trackids
// that match the source's trackids, so we can avoid needing a mapping function.
// XXX This will not handle more complex cases well.
virtual void StopTrack(TrackID aTrackID)
{
if (mSourceStream) {
mSourceStream->EndTrack(aTrackID);
// We could override NotifyMediaStreamTrackEnded(), and maybe should, but it's
// risky to do late in a release since that will affect all track ends, and not
// just StopTrack()s.
if (GetDOMTrackFor(aTrackID)) {
mListener->StopTrack(aTrackID, !!GetDOMTrackFor(aTrackID)->AsAudioStreamTrack());
} else {
LOG(("StopTrack(%d) on non-existant track", aTrackID));
}
}
}
#if 0
virtual void NotifyMediaStreamTrackEnded(dom::MediaStreamTrack* aTrack)
{
TrackID trackID = aTrack->GetTrackID();
// We override this so we can also tell the backend to stop capturing if the track ends
LOG(("track %d ending, type = %s",
trackID, aTrack->AsAudioStreamTrack() ? "audio" : "video"));
MOZ_ASSERT(aTrack->AsVideoStreamTrack() || aTrack->AsAudioStreamTrack());
mListener->StopTrack(trackID, !!aTrack->AsAudioStreamTrack());
// forward to superclass
DOMLocalMediaStream::NotifyMediaStreamTrackEnded(aTrack);
}
#endif
// Allow getUserMedia to pass input data directly to PeerConnection/MediaPipeline
virtual bool AddDirectListener(MediaStreamDirectListener *aListener) MOZ_OVERRIDE
{
@ -576,6 +615,7 @@ public:
// explicitly destroyed too.
nsRefPtr<SourceMediaStream> mSourceStream;
nsRefPtr<MediaInputPort> mPort;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<MediaEngineSource> mAudioSource; // so we can turn on AEC
bool mEchoOn;
bool mAgcOn;
@ -708,8 +748,8 @@ public:
#endif
// Create a media stream.
nsRefPtr<nsDOMUserMediaStream> trackunion =
nsDOMUserMediaStream::CreateTrackUnionStream(window, mAudioSource,
mVideoSource);
nsDOMUserMediaStream::CreateTrackUnionStream(window, mListener,
mAudioSource, mVideoSource);
if (!trackunion) {
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
LOG(("Returning error for getUserMedia() - no stream"));
@ -2291,6 +2331,28 @@ GetUserMediaCallbackMediaStreamListener::StopScreenWindowSharing()
}
}
// Stop backend for track
void
GetUserMediaCallbackMediaStreamListener::StopTrack(TrackID aID, bool aIsAudio)
{
if (((aIsAudio && mAudioSource) ||
(!aIsAudio && mVideoSource)) && !mStopped)
{
// XXX to support multiple tracks of a type in a stream, this should key off
// the TrackID and not just the type
nsRefPtr<MediaOperationRunnable> runnable(
new MediaOperationRunnable(MEDIA_STOP_TRACK,
this, nullptr, nullptr,
aIsAudio ? mAudioSource : nullptr,
!aIsAudio ? mVideoSource : nullptr,
mFinished, mWindowID, nullptr));
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} else {
LOG(("gUM track %d ended, but we don't have type %s",
aID, aIsAudio ? "audio" : "video"));
}
}
// Called from the MediaStreamGraph thread
void

View File

@ -101,6 +101,8 @@ public:
void StopScreenWindowSharing();
void StopTrack(TrackID aID, bool aIsAudio);
// mVideo/AudioSource are set by Activate(), so we assume they're capturing
// if set and represent a real capture device.
bool CapturingVideo()