Bug 1070127 - add placeholder tracks at DOMMediaStream creation. r=jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Sat, 11 Oct 2014 11:25:47 -0400
changeset 209973 400c4131858e9102f6f1d26f6603f9a7f16e0276
parent 209972 dc10fcd30554c85d2a720a7c5d135ea3ff788bb2
child 209974 6442a3773f2aafcc57753e7a689257a990339346
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjesup
bugs1070127
milestone35.0a1
Bug 1070127 - add placeholder tracks at DOMMediaStream creation. r=jesup
content/media/DOMMediaStream.cpp
content/media/DOMMediaStream.h
content/media/MediaStreamTrack.h
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -68,17 +68,17 @@ public:
 
       DOMMediaStream* stream = mListener->GetStream();
       if (!stream) {
         return NS_OK;
       }
 
       nsRefPtr<MediaStreamTrack> track;
       if (mEvents & MediaStreamListener::TRACK_EVENT_CREATED) {
-        track = stream->CreateDOMTrack(mID, mType);
+        track = stream->BindDOMTrack(mID, mType);
         stream->NotifyMediaStreamTrackCreated(track);
       } else {
         track = stream->GetDOMTrackFor(mID);
       }
       if (mEvents & MediaStreamListener::TRACK_EVENT_ENDED) {
         if (track) {
           track->NotifyEnded();
           stream->NotifyMediaStreamTrackEnded(track);
@@ -297,16 +297,28 @@ DOMMediaStream::AddPrincipalChangeObserv
 }
 
 bool
 DOMMediaStream::RemovePrincipalChangeObserver(PrincipalChangeObserver* aObserver)
 {
   return mPrincipalChangeObservers.RemoveElement(aObserver);
 }
 
+void
+DOMMediaStream::SetHintContents(TrackTypeHints aHintContents)
+{
+  mHintContents = aHintContents;
+  if (aHintContents & HINT_CONTENTS_AUDIO) {
+    CreateDOMTrack(0, MediaSegment::AUDIO);
+  }
+  if (aHintContents & HINT_CONTENTS_VIDEO) {
+    CreateDOMTrack(0, MediaSegment::VIDEO);
+  }
+}
+
 MediaStreamTrack*
 DOMMediaStream::CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
 {
   MediaStreamTrack* track;
   switch (aType) {
   case MediaSegment::AUDIO:
     track = new AudioStreamTrack(this, aTrackID);
     mTrackTypesAvailable |= HINT_CONTENTS_AUDIO;
@@ -315,16 +327,57 @@ DOMMediaStream::CreateDOMTrack(TrackID a
     track = new VideoStreamTrack(this, aTrackID);
     mTrackTypesAvailable |= HINT_CONTENTS_VIDEO;
     break;
   default:
     MOZ_CRASH("Unhandled track type");
   }
   mTracks.AppendElement(track);
 
+  return track;
+}
+
+MediaStreamTrack*
+DOMMediaStream::BindDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
+{
+  MediaStreamTrack* track = nullptr;
+  switch (aType) {
+  case MediaSegment::AUDIO: {
+    for (size_t i = 0; i < mTracks.Length(); ++i) {
+      track = mTracks[i]->AsAudioStreamTrack();
+      if (track) {
+        break;
+      }
+    }
+    if (track) {
+      track->BindTrackID(aTrackID);
+    } else {
+      track = CreateDOMTrack(aTrackID, aType);
+    }
+    MOZ_ASSERT(mTrackTypesAvailable & HINT_CONTENTS_AUDIO);
+    break;
+  }
+  case MediaSegment::VIDEO: {
+    for (size_t i = 0; i < mTracks.Length(); ++i) {
+      track = mTracks[i]->AsVideoStreamTrack();
+      if (track) {
+        break;
+      }
+    }
+    if (track) {
+      track->BindTrackID(aTrackID);
+    } else {
+      track = CreateDOMTrack(aTrackID, aType);
+    }
+    MOZ_ASSERT(mTrackTypesAvailable & HINT_CONTENTS_VIDEO);
+    break;
+  }
+  default:
+    MOZ_CRASH("Unhandled track type");
+  }
   CheckTracksAvailable();
 
   return track;
 }
 
 MediaStreamTrack*
 DOMMediaStream::GetDOMTrackFor(TrackID aTrackID)
 {
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -170,17 +170,17 @@ public:
 
   // Indicate what track types we eventually expect to add to this stream
   enum {
     HINT_CONTENTS_AUDIO = 1 << 0,
     HINT_CONTENTS_VIDEO = 1 << 1,
     HINT_CONTENTS_UNKNOWN = 1 << 2
   };
   TrackTypeHints GetHintContents() const { return mHintContents; }
-  void SetHintContents(TrackTypeHints aHintContents) { mHintContents = aHintContents; }
+  void SetHintContents(TrackTypeHints aHintContents);
 
   TrackTypeHints GetTrackTypesAvailable() const { return mTrackTypesAvailable; }
 
   /**
    * Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream.
    */
   static already_AddRefed<DOMMediaStream>
   CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
@@ -192,17 +192,18 @@ public:
   CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
 
   void SetLogicalStreamStartTime(StreamTime aTime)
   {
     mLogicalStreamStartTime = aTime;
   }
 
   // Notifications from StreamListener.
-  // CreateDOMTrack should only be called when it's safe to run script.
+  // BindDOMTrack should only be called when it's safe to run script.
+  MediaStreamTrack* BindDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
   MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
   MediaStreamTrack* GetDOMTrackFor(TrackID aTrackID);
 
   class OnTracksAvailableCallback {
   public:
     explicit OnTracksAvailableCallback(uint8_t aExpectedTracks = 0)
       : mExpectedTracks(aExpectedTracks) {}
     virtual ~OnTracksAvailableCallback() {}
--- a/content/media/MediaStreamTrack.h
+++ b/content/media/MediaStreamTrack.h
@@ -34,16 +34,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
                                            DOMEventTargetHelper)
 
   DOMMediaStream* GetParentObject() const { return mStream; }
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE = 0;
 
   DOMMediaStream* GetStream() const { return mStream; }
   TrackID GetTrackID() const { return mTrackID; }
+  void BindTrackID(TrackID aTrackID) { mTrackID = aTrackID; }
   virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
   virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
 
   // WebIDL
   virtual void GetKind(nsAString& aKind) = 0;
   void GetId(nsAString& aID);
   void GetLabel(nsAString& aLabel) { aLabel.Truncate(); }
   bool Enabled() { return mEnabled; }