зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1103188 - Break out MediaTrackListListener to an interface. r=roc
Other modules than MediaTrackLists may want to receive updates on a DOMMediaStream's track set. This moves the MediaTrackListListener out of the MediaTrackList class into DOMMediaStream as a general interface. The logic for adding MediaTracks to the MediaTrackList when MediaStreamTracks are added or removed from a DOMMediaStream is moved to HTMLMediaElement as this fits the model better - HTMLMediaElement is the owner of the MediaTrackLists. --HG-- extra : commitid : 3I8mAeBB3oL extra : rebase_source : 66b8ffcfb5343811c181e4169f295b08494f2ee0
This commit is contained in:
Родитель
0239788481
Коммит
eb480b5acd
|
@ -71,6 +71,7 @@
|
|||
#include "MediaSourceDecoder.h"
|
||||
#include "AudioStreamTrack.h"
|
||||
#include "VideoStreamTrack.h"
|
||||
#include "MediaTrackList.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
|
@ -2105,6 +2106,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
|||
mPlayingThroughTheAudioChannel(false),
|
||||
mDisableVideo(false),
|
||||
mPlayBlockedBecauseHidden(false),
|
||||
mMediaStreamTrackListener(nullptr),
|
||||
mElementInTreeState(ELEMENT_NOT_INTREE),
|
||||
mHasUserInteraction(false)
|
||||
{
|
||||
|
@ -3100,10 +3102,34 @@ public:
|
|||
|
||||
mElement->NotifyMediaStreamTracksAvailable(aStream);
|
||||
}
|
||||
|
||||
private:
|
||||
HTMLMediaElement* mElement;
|
||||
};
|
||||
|
||||
class HTMLMediaElement::MediaStreamTrackListener :
|
||||
public DOMMediaStream::TrackListener
|
||||
{
|
||||
public:
|
||||
explicit MediaStreamTrackListener(HTMLMediaElement* aElement):
|
||||
mElement(aElement) {}
|
||||
|
||||
void NotifyTrackAdded(const nsRefPtr<MediaStreamTrack>& aTrack) override
|
||||
{
|
||||
mElement->NotifyMediaStreamTrackAdded(aTrack);
|
||||
}
|
||||
|
||||
void NotifyTrackRemoved(const nsRefPtr<MediaStreamTrack>& aTrack) override
|
||||
{
|
||||
mElement->NotifyMediaStreamTrackRemoved(aTrack);
|
||||
}
|
||||
|
||||
protected:
|
||||
~MediaStreamTrackListener() {}
|
||||
|
||||
HTMLMediaElement* const mElement;
|
||||
};
|
||||
|
||||
void HTMLMediaElement::UpdateSrcMediaStreamPlaying(uint32_t aFlags)
|
||||
{
|
||||
if (!mSrcStream) {
|
||||
|
@ -3198,14 +3224,14 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
|
|||
|
||||
UpdateSrcMediaStreamPlaying();
|
||||
|
||||
// Note: we must call DisconnectTrackListListeners(...) before dropping
|
||||
// mSrcStream.
|
||||
// If we pause this media element, track changes in the underlying stream
|
||||
// will continue to fire events at this element and alter its track list.
|
||||
// That's simpler than delaying the events, but probably confusing...
|
||||
mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks());
|
||||
ConstructMediaTracks();
|
||||
|
||||
mSrcStream->OnTracksAvailable(new MediaStreamTracksAvailableCallback(this));
|
||||
mMediaStreamTrackListener = new MediaStreamTrackListener(this);
|
||||
mSrcStream->RegisterTrackListener(mMediaStreamTrackListener);
|
||||
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
ChangeDelayLoadStatus(false);
|
||||
|
@ -3220,11 +3246,116 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback()
|
|||
|
||||
UpdateSrcMediaStreamPlaying(REMOVING_SRC_STREAM);
|
||||
|
||||
mSrcStream->DisconnectTrackListListeners(AudioTracks(), VideoTracks());
|
||||
mSrcStream->UnregisterTrackListener(mMediaStreamTrackListener);
|
||||
mMediaStreamTrackListener = nullptr;
|
||||
|
||||
mSrcStream = nullptr;
|
||||
}
|
||||
|
||||
static already_AddRefed<AudioTrack>
|
||||
CreateAudioTrack(AudioStreamTrack* aStreamTrack)
|
||||
{
|
||||
nsAutoString id;
|
||||
nsAutoString label;
|
||||
aStreamTrack->GetId(id);
|
||||
aStreamTrack->GetLabel(label);
|
||||
|
||||
return MediaTrackList::CreateAudioTrack(id, NS_LITERAL_STRING("main"),
|
||||
label, EmptyString(),
|
||||
aStreamTrack->Enabled());
|
||||
}
|
||||
|
||||
static already_AddRefed<VideoTrack>
|
||||
CreateVideoTrack(VideoStreamTrack* aStreamTrack)
|
||||
{
|
||||
nsAutoString id;
|
||||
nsAutoString label;
|
||||
aStreamTrack->GetId(id);
|
||||
aStreamTrack->GetLabel(label);
|
||||
|
||||
return MediaTrackList::CreateVideoTrack(id, NS_LITERAL_STRING("main"),
|
||||
label, EmptyString());
|
||||
}
|
||||
|
||||
void HTMLMediaElement::ConstructMediaTracks()
|
||||
{
|
||||
nsTArray<nsRefPtr<MediaStreamTrack>> tracks;
|
||||
mSrcStream->GetTracks(tracks);
|
||||
|
||||
int firstEnabledVideo = -1;
|
||||
for (const nsRefPtr<MediaStreamTrack>& track : tracks) {
|
||||
if (track->Ended()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AudioStreamTrack* t = track->AsAudioStreamTrack()) {
|
||||
nsRefPtr<AudioTrack> audioTrack = CreateAudioTrack(t);
|
||||
AudioTracks()->AddTrack(audioTrack);
|
||||
} else if (VideoStreamTrack* t = track->AsVideoStreamTrack()) {
|
||||
nsRefPtr<VideoTrack> videoTrack = CreateVideoTrack(t);
|
||||
VideoTracks()->AddTrack(videoTrack);
|
||||
firstEnabledVideo = (t->Enabled() && firstEnabledVideo < 0)
|
||||
? (VideoTracks()->Length() - 1)
|
||||
: firstEnabledVideo;
|
||||
}
|
||||
}
|
||||
|
||||
if (VideoTracks()->Length() > 0) {
|
||||
// If media resource does not indicate a particular set of video tracks to
|
||||
// enable, the one that is listed first in the element's videoTracks object
|
||||
// must be selected.
|
||||
int index = firstEnabledVideo >= 0 ? firstEnabledVideo : 0;
|
||||
(*VideoTracks())[index]->SetEnabledInternal(true, MediaTrack::FIRE_NO_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLMediaElement::NotifyMediaStreamTrackAdded(const nsRefPtr<MediaStreamTrack>& aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aTrack);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsString id;
|
||||
aTrack->GetId(id);
|
||||
|
||||
LOG(LogLevel::Debug, ("%p, Adding MediaTrack with id %s",
|
||||
this, NS_ConvertUTF16toUTF8(id).get()));
|
||||
#endif
|
||||
|
||||
if (AudioStreamTrack* t = aTrack->AsAudioStreamTrack()) {
|
||||
nsRefPtr<AudioTrack> audioTrack = CreateAudioTrack(t);
|
||||
AudioTracks()->AddTrack(audioTrack);
|
||||
} else if (VideoStreamTrack* t = aTrack->AsVideoStreamTrack()) {
|
||||
nsRefPtr<VideoTrack> videoTrack = CreateVideoTrack(t);
|
||||
VideoTracks()->AddTrack(videoTrack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLMediaElement::NotifyMediaStreamTrackRemoved(const nsRefPtr<MediaStreamTrack>& aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aTrack);
|
||||
|
||||
nsAutoString id;
|
||||
aTrack->GetId(id);
|
||||
|
||||
LOG(LogLevel::Debug, ("%p, Removing MediaTrack with id %s",
|
||||
this, NS_ConvertUTF16toUTF8(id).get()));
|
||||
|
||||
if (MediaTrack* t = AudioTracks()->GetTrackById(id)) {
|
||||
AudioTracks()->RemoveTrack(t);
|
||||
} else if (MediaTrack* t = VideoTracks()->GetTrackById(id)) {
|
||||
VideoTracks()->RemoveTrack(t);
|
||||
} else {
|
||||
// XXX Uncomment this when DOMMediaStream doesn't call NotifyTrackRemoved
|
||||
// multiple times for the same track, i.e., when it implements the
|
||||
// "addtrack" and "removetrack" events.
|
||||
// NS_ASSERTION(false, "MediaStreamTrack ended but did not exist in track lists");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTMLMediaElement::ProcessMediaFragmentURI()
|
||||
{
|
||||
nsMediaFragmentURIParser parser(mLoadingSrc);
|
||||
|
|
|
@ -671,6 +671,7 @@ protected:
|
|||
|
||||
class MediaLoadListener;
|
||||
class MediaStreamTracksAvailableCallback;
|
||||
class MediaStreamTrackListener;
|
||||
class StreamListener;
|
||||
class StreamSizeListener;
|
||||
|
||||
|
@ -760,6 +761,25 @@ protected:
|
|||
enum { REMOVING_SRC_STREAM = 0x1 };
|
||||
void UpdateSrcMediaStreamPlaying(uint32_t aFlags = 0);
|
||||
|
||||
/**
|
||||
* If loading and playing a MediaStream, for each MediaStreamTrack in the
|
||||
* MediaStream, create a corresponding AudioTrack or VideoTrack during the
|
||||
* phase of resource fetching.
|
||||
*/
|
||||
void ConstructMediaTracks();
|
||||
|
||||
/**
|
||||
* Called by our DOMMediaStream::TrackListener when a new MediaStreamTrack has
|
||||
* been added to the playback stream of |mSrcStream|.
|
||||
*/
|
||||
void NotifyMediaStreamTrackAdded(const nsRefPtr<MediaStreamTrack>& aTrack);
|
||||
|
||||
/**
|
||||
* Called by our DOMMediaStream::TrackListener when a MediaStreamTrack in
|
||||
* |mSrcStream|'s playback stream has ended.
|
||||
*/
|
||||
void NotifyMediaStreamTrackRemoved(const nsRefPtr<MediaStreamTrack>& aTrack);
|
||||
|
||||
/**
|
||||
* Returns an nsDOMMediaStream containing the played contents of this
|
||||
* element. When aFinishWhenEnded is true, when this element ends playback
|
||||
|
@ -1429,6 +1449,8 @@ protected:
|
|||
|
||||
nsRefPtr<VideoTrackList> mVideoTrackList;
|
||||
|
||||
nsRefPtr<MediaStreamTrackListener> mMediaStreamTrackListener;
|
||||
|
||||
enum ElementInTreeState {
|
||||
// The MediaElement is not in the DOM tree now.
|
||||
ELEMENT_NOT_INTREE,
|
||||
|
|
|
@ -498,7 +498,7 @@ DOMMediaStream::AddTrack(MediaStreamTrack& aTrack)
|
|||
nsRefPtr<TrackPort> trackPort =
|
||||
new TrackPort(inputPort, &aTrack, TrackPort::InputPortOwnership::OWNED);
|
||||
mTracks.AppendElement(trackPort.forget());
|
||||
NotifyMediaStreamTrackCreated(&aTrack);
|
||||
NotifyTrackAdded(&aTrack);
|
||||
|
||||
LOG(LogLevel::Debug, ("DOMMediaStream %p Added track %p", this, &aTrack));
|
||||
}
|
||||
|
@ -729,7 +729,7 @@ DOMMediaStream::CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
|
|||
new TrackPort(mPlaybackPort, track, TrackPort::InputPortOwnership::EXTERNAL);
|
||||
mTracks.AppendElement(playbackTrackPort.forget());
|
||||
|
||||
NotifyMediaStreamTrackCreated(track);
|
||||
NotifyTrackAdded(track);
|
||||
return track;
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,7 @@ DOMMediaStream::NotifyMediaStreamGraphShutdown()
|
|||
// to prevent leaks.
|
||||
mNotifiedOfMediaStreamGraphShutdown = true;
|
||||
mRunOnTracksAvailable.Clear();
|
||||
|
||||
mTrackListeners.Clear();
|
||||
mConsumersToKeepAlive.Clear();
|
||||
}
|
||||
|
||||
|
@ -812,7 +812,7 @@ DOMMediaStream::OnTracksAvailable(OnTracksAvailableCallback* aRunnable)
|
|||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::TracksCreated()
|
||||
DOMMediaStream::NotifyTracksCreated()
|
||||
{
|
||||
mTracksCreated = true;
|
||||
CheckTracksAvailable();
|
||||
|
@ -832,6 +832,49 @@ DOMMediaStream::CheckTracksAvailable()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::RegisterTrackListener(TrackListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mNotifiedOfMediaStreamGraphShutdown) {
|
||||
// No more tracks will ever be added, so just do nothing.
|
||||
return;
|
||||
}
|
||||
mTrackListeners.AppendElement(aListener);
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::UnregisterTrackListener(TrackListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mTrackListeners.RemoveElement(aListener);
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::NotifyTrackAdded(
|
||||
const nsRefPtr<MediaStreamTrack>& aTrack)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (int32_t i = mTrackListeners.Length() - 1; i >= 0; --i) {
|
||||
const nsRefPtr<TrackListener>& listener = mTrackListeners[i];
|
||||
listener->NotifyTrackAdded(aTrack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::NotifyTrackRemoved(
|
||||
const nsRefPtr<MediaStreamTrack>& aTrack)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (int32_t i = mTrackListeners.Length() - 1; i >= 0; --i) {
|
||||
const nsRefPtr<TrackListener>& listener = mTrackListeners[i];
|
||||
listener->NotifyTrackRemoved(aTrack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::CreateAndAddPlaybackStreamListener(MediaStream* aStream)
|
||||
{
|
||||
|
@ -840,104 +883,6 @@ DOMMediaStream::CreateAndAddPlaybackStreamListener(MediaStream* aStream)
|
|||
aStream->AddListener(mPlaybackListener);
|
||||
}
|
||||
|
||||
already_AddRefed<AudioTrack>
|
||||
DOMMediaStream::CreateAudioTrack(AudioStreamTrack* aStreamTrack)
|
||||
{
|
||||
nsAutoString id;
|
||||
nsAutoString label;
|
||||
aStreamTrack->GetId(id);
|
||||
aStreamTrack->GetLabel(label);
|
||||
|
||||
return MediaTrackList::CreateAudioTrack(id, NS_LITERAL_STRING("main"),
|
||||
label, EmptyString(),
|
||||
aStreamTrack->Enabled());
|
||||
}
|
||||
|
||||
already_AddRefed<VideoTrack>
|
||||
DOMMediaStream::CreateVideoTrack(VideoStreamTrack* aStreamTrack)
|
||||
{
|
||||
nsAutoString id;
|
||||
nsAutoString label;
|
||||
aStreamTrack->GetId(id);
|
||||
aStreamTrack->GetLabel(label);
|
||||
|
||||
return MediaTrackList::CreateVideoTrack(id, NS_LITERAL_STRING("main"),
|
||||
label, EmptyString());
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::ConstructMediaTracks(AudioTrackList* aAudioTrackList,
|
||||
VideoTrackList* aVideoTrackList)
|
||||
{
|
||||
MediaTrackListListener audioListener(aAudioTrackList);
|
||||
mMediaTrackListListeners.AppendElement(audioListener);
|
||||
MediaTrackListListener videoListener(aVideoTrackList);
|
||||
mMediaTrackListListeners.AppendElement(videoListener);
|
||||
|
||||
int firstEnabledVideo = -1;
|
||||
for (const nsRefPtr<TrackPort>& info : mTracks) {
|
||||
if (AudioStreamTrack* t = info->GetTrack()->AsAudioStreamTrack()) {
|
||||
nsRefPtr<AudioTrack> track = CreateAudioTrack(t);
|
||||
aAudioTrackList->AddTrack(track);
|
||||
} else if (VideoStreamTrack* t = info->GetTrack()->AsVideoStreamTrack()) {
|
||||
nsRefPtr<VideoTrack> track = CreateVideoTrack(t);
|
||||
aVideoTrackList->AddTrack(track);
|
||||
firstEnabledVideo = (t->Enabled() && firstEnabledVideo < 0)
|
||||
? (aVideoTrackList->Length() - 1)
|
||||
: firstEnabledVideo;
|
||||
}
|
||||
}
|
||||
|
||||
if (aVideoTrackList->Length() > 0) {
|
||||
// If media resource does not indicate a particular set of video tracks to
|
||||
// enable, the one that is listed first in the element's videoTracks object
|
||||
// must be selected.
|
||||
int index = firstEnabledVideo >= 0 ? firstEnabledVideo : 0;
|
||||
(*aVideoTrackList)[index]->SetEnabledInternal(true, MediaTrack::FIRE_NO_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::DisconnectTrackListListeners(const AudioTrackList* aAudioTrackList,
|
||||
const VideoTrackList* aVideoTrackList)
|
||||
{
|
||||
for (auto i = mMediaTrackListListeners.Length(); i > 0; ) { // unsigned!
|
||||
--i; // 0 ... Length()-1 range
|
||||
if (mMediaTrackListListeners[i].mMediaTrackList == aAudioTrackList ||
|
||||
mMediaTrackListListeners[i].mMediaTrackList == aVideoTrackList) {
|
||||
mMediaTrackListListeners.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aTrack);
|
||||
|
||||
for (uint32_t i = 0; i < mMediaTrackListListeners.Length(); ++i) {
|
||||
if (AudioStreamTrack* t = aTrack->AsAudioStreamTrack()) {
|
||||
nsRefPtr<AudioTrack> track = CreateAudioTrack(t);
|
||||
mMediaTrackListListeners[i].NotifyMediaTrackCreated(track);
|
||||
} else if (VideoStreamTrack* t = aTrack->AsVideoStreamTrack()) {
|
||||
nsRefPtr<VideoTrack> track = CreateVideoTrack(t);
|
||||
mMediaTrackListListeners[i].NotifyMediaTrackCreated(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::NotifyMediaStreamTrackEnded(MediaStreamTrack* aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aTrack);
|
||||
|
||||
nsAutoString id;
|
||||
aTrack->GetId(id);
|
||||
for (uint32_t i = 0; i < mMediaTrackListListeners.Length(); ++i) {
|
||||
mMediaTrackListListeners[i].NotifyMediaTrackEnded(id);
|
||||
}
|
||||
}
|
||||
|
||||
DOMLocalMediaStream::~DOMLocalMediaStream()
|
||||
{
|
||||
if (mInputStream) {
|
||||
|
|
|
@ -182,11 +182,31 @@ class DOMMediaStream : public DOMEventTargetHelper
|
|||
typedef dom::VideoTrack VideoTrack;
|
||||
typedef dom::AudioTrackList AudioTrackList;
|
||||
typedef dom::VideoTrackList VideoTrackList;
|
||||
typedef dom::MediaTrackListListener MediaTrackListListener;
|
||||
|
||||
public:
|
||||
typedef dom::MediaTrackConstraints MediaTrackConstraints;
|
||||
typedef uint8_t TrackTypeHints;
|
||||
|
||||
class TrackListener {
|
||||
NS_INLINE_DECL_REFCOUNTING(TrackListener)
|
||||
|
||||
public:
|
||||
/**
|
||||
* Called when the DOMMediaStream has a new track added, either by
|
||||
* JS (addTrack()) or the source creating one.
|
||||
*/
|
||||
virtual void
|
||||
NotifyTrackAdded(const nsRefPtr<MediaStreamTrack>& aTrack) {};
|
||||
|
||||
/**
|
||||
* Called when the DOMMediaStream removes a track, either by
|
||||
* JS (removeTrack()) or the source ending it.
|
||||
*/
|
||||
virtual void
|
||||
NotifyTrackRemoved(const nsRefPtr<MediaStreamTrack>& aTrack) {};
|
||||
|
||||
protected:
|
||||
virtual ~TrackListener() {}
|
||||
};
|
||||
|
||||
DOMMediaStream();
|
||||
|
||||
|
@ -394,23 +414,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If loading and playing a MediaStream in a media element, for each
|
||||
* MediaStreamTrack in the MediaStream, create a corresponding AudioTrack or
|
||||
* VideoTrack during the phase of resource fetching.
|
||||
*/
|
||||
void ConstructMediaTracks(AudioTrackList* aAudioTrackList,
|
||||
VideoTrackList* aVideoTrackList);
|
||||
|
||||
/**
|
||||
* MUST call this before the AudioTrackList or VideoTrackList go away
|
||||
*/
|
||||
void DisconnectTrackListListeners(const AudioTrackList* aAudioTrackList,
|
||||
const VideoTrackList* aVideoTrackList);
|
||||
|
||||
virtual void NotifyMediaStreamTrackCreated(MediaStreamTrack* aTrack);
|
||||
|
||||
virtual void NotifyMediaStreamTrackEnded(MediaStreamTrack* aTrack);
|
||||
void RegisterTrackListener(TrackListener* aListener);
|
||||
void UnregisterTrackListener(TrackListener* aListener);
|
||||
|
||||
protected:
|
||||
virtual ~DOMMediaStream();
|
||||
|
@ -420,14 +425,18 @@ protected:
|
|||
void InitTrackUnionStream(nsIDOMWindow* aWindow, MediaStreamGraph* aGraph);
|
||||
void InitAudioCaptureStream(nsIDOMWindow* aWindow, MediaStreamGraph* aGraph);
|
||||
void InitStreamCommon(MediaStream* aStream, MediaStreamGraph* aGraph);
|
||||
already_AddRefed<AudioTrack> CreateAudioTrack(AudioStreamTrack* aStreamTrack);
|
||||
already_AddRefed<VideoTrack> CreateVideoTrack(VideoStreamTrack* aStreamTrack);
|
||||
|
||||
void CheckTracksAvailable();
|
||||
|
||||
// Called when MediaStreamGraph has finished an iteration where tracks were
|
||||
// created.
|
||||
void TracksCreated();
|
||||
void NotifyTracksCreated();
|
||||
|
||||
void CheckTracksAvailable();
|
||||
// Dispatches NotifyTrackAdded() to all registered track listeners.
|
||||
void NotifyTrackAdded(const nsRefPtr<MediaStreamTrack>& aTrack);
|
||||
|
||||
// Dispatches NotifyTrackRemoved() to all registered track listeners.
|
||||
void NotifyTrackRemoved(const nsRefPtr<MediaStreamTrack>& aTrack);
|
||||
|
||||
class OwnedStreamListener;
|
||||
friend class OwnedStreamListener;
|
||||
|
@ -488,9 +497,8 @@ protected:
|
|||
|
||||
bool mNotifiedOfMediaStreamGraphShutdown;
|
||||
|
||||
// Send notifications to AudioTrackList or VideoTrackList, if this MediaStream
|
||||
// is consumed by a HTMLMediaElement.
|
||||
nsTArray<MediaTrackListListener> mMediaTrackListListeners;
|
||||
// The track listeners subscribe to changes in this stream's track set.
|
||||
nsTArray<nsRefPtr<TrackListener>> mTrackListeners;
|
||||
|
||||
private:
|
||||
void NotifyPrincipalChanged();
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
already_AddRefed<Promise>
|
||||
ApplyConstraints(const dom::MediaTrackConstraints& aConstraints, ErrorResult &aRv);
|
||||
|
||||
bool Ended() const { return mEnded; }
|
||||
// Notifications from the MediaStreamGraph
|
||||
void NotifyEnded() { mEnded = true; }
|
||||
|
||||
|
|
|
@ -16,33 +16,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void
|
||||
MediaTrackListListener::NotifyMediaTrackCreated(MediaTrack* aTrack)
|
||||
{
|
||||
if (!mMediaTrackList && !aTrack) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTrack->AsAudioTrack() && mMediaTrackList->AsAudioTrackList()) {
|
||||
mMediaTrackList->AddTrack(aTrack);
|
||||
} else if (aTrack->AsVideoTrack() && mMediaTrackList->AsVideoTrackList()) {
|
||||
mMediaTrackList->AddTrack(aTrack);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaTrackListListener::NotifyMediaTrackEnded(const nsAString& aId)
|
||||
{
|
||||
if (!mMediaTrackList) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nsRefPtr<MediaTrack> track = mMediaTrackList->GetTrackById(aId);
|
||||
if (track) {
|
||||
mMediaTrackList->RemoveTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
MediaTrackList::MediaTrackList(nsPIDOMWindow* aOwnerWindow,
|
||||
HTMLMediaElement* aMediaElement)
|
||||
: DOMEventTargetHelper(aOwnerWindow)
|
||||
|
|
|
@ -20,41 +20,6 @@ class AudioTrackList;
|
|||
class VideoTrackList;
|
||||
class AudioTrack;
|
||||
class VideoTrack;
|
||||
class MediaTrackList;
|
||||
|
||||
/**
|
||||
* This is for the media resource to notify its audio track and video track,
|
||||
* when a media-resource-specific track has ended, or whether it has enabled or
|
||||
* not. All notification methods are called from the main thread.
|
||||
*/
|
||||
class MediaTrackListListener
|
||||
{
|
||||
public:
|
||||
friend class mozilla::DOMMediaStream;
|
||||
|
||||
explicit MediaTrackListListener(MediaTrackList* aMediaTrackList)
|
||||
: mMediaTrackList(aMediaTrackList) {};
|
||||
|
||||
~MediaTrackListListener()
|
||||
{
|
||||
mMediaTrackList = nullptr;
|
||||
};
|
||||
|
||||
// Notify mMediaTrackList that a track has created by the media resource,
|
||||
// and this corresponding MediaTrack object should be added into
|
||||
// mMediaTrackList, and fires a addtrack event.
|
||||
void NotifyMediaTrackCreated(MediaTrack* aTrack);
|
||||
|
||||
// Notify mMediaTrackList that a track has ended by the media resource,
|
||||
// and this corresponding MediaTrack object should be removed from
|
||||
// mMediaTrackList, and fires a removetrack event.
|
||||
void NotifyMediaTrackEnded(const nsAString& aId);
|
||||
|
||||
protected:
|
||||
// A weak reference to a MediaTrackList object, its lifetime managed by its
|
||||
// owner.
|
||||
MediaTrackList* mMediaTrackList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class of AudioTrackList and VideoTrackList. The AudioTrackList and
|
||||
|
@ -120,7 +85,6 @@ public:
|
|||
IMPL_EVENT_HANDLER(addtrack)
|
||||
IMPL_EVENT_HANDLER(removetrack)
|
||||
|
||||
friend class MediaTrackListListener;
|
||||
friend class AudioTrack;
|
||||
friend class VideoTrack;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче