Bug 1291946 - Append the latest video frames from updateTracks. r?pehrsons. draft
authorctai <ctai@mozilla.com>
Wed, 10 Aug 2016 10:31:14 +0800
changeset 410891 d97438fab8d2de6412f639d70232a9376f0ee3cc
parent 406450 1a5b53a831e5a6c20de1b081c774feb3ff76756c
child 530620 527049b7fe93217c4704be153a6acdadc17b0ff5
push id28779
push userbmo:ctai@mozilla.com
push dateWed, 07 Sep 2016 02:29:14 +0000
reviewerspehrsons
bugs1291946
milestone51.0a1
Bug 1291946 - Append the latest video frames from updateTracks. r?pehrsons. In some cases, we need to resend missed VideoSegment to new added MediaStreamVideoSink. Append the latest video frames from updateTracks. MozReview-Commit-ID: 76RFs5fgKpY
dom/media/MediaSegment.h
dom/media/MediaStreamGraph.cpp
dom/media/VideoSegment.h
--- a/dom/media/MediaSegment.h
+++ b/dom/media/MediaSegment.h
@@ -396,16 +396,24 @@ public:
     return amount;
   }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
+  Chunk* GetLastChunk()
+  {
+    if (mChunks.IsEmpty()) {
+      return nullptr;
+    }
+    return &mChunks[mChunks.Length() - 1];
+  }
+
 protected:
   explicit MediaSegmentBase(Type aType) : MediaSegment(aType) {}
 
   /**
    * Appends the contents of aSource to this segment, clearing aSource.
    */
   void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
   {
@@ -443,24 +451,16 @@ protected:
   {
     MOZ_ASSERT(aDuration >= 0);
     Chunk* c = mChunks.AppendElement();
     c->mDuration = aDuration;
     mDuration += aDuration;
     return c;
   }
 
-  Chunk* GetLastChunk()
-  {
-    if (mChunks.IsEmpty()) {
-      return nullptr;
-    }
-    return &mChunks[mChunks.Length() - 1];
-  }
-
   void RemoveLeading(StreamTime aDuration, uint32_t aStartIndex)
   {
     NS_ASSERTION(aDuration >= 0, "Can't remove negative duration");
     StreamTime t = aDuration;
     uint32_t chunksToRemove = 0;
     for (uint32_t i = aStartIndex; i < mChunks.Length() && t > 0; ++i) {
       Chunk* c = &mChunks[i];
       if (c->GetDuration() > t) {
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -2865,17 +2865,35 @@ SourceMediaStream::AddDirectTrackListene
     // The track might be removed from mUpdateTrack but still exist in
     // mTracks.
     auto streamTrack = FindTrack(aTrackID);
     bool foundTrack = !!streamTrack;
     if (foundTrack) {
       MediaStreamVideoSink* videoSink = listener->AsMediaStreamVideoSink();
       // Re-send missed VideoSegment to new added MediaStreamVideoSink.
       if (streamTrack->GetType() == MediaSegment::VIDEO && videoSink) {
-        videoSink->SetCurrentFrames(*(static_cast<VideoSegment*>(streamTrack->GetSegment())));
+        VideoSegment videoSegment;
+        if (mTracks.GetForgottenDuration() < streamTrack->GetSegment()->GetDuration()) {
+          videoSegment.AppendSlice(*streamTrack->GetSegment(),
+                                   mTracks.GetForgottenDuration(),
+                                   streamTrack->GetSegment()->GetDuration());
+        } else {
+          VideoSegment* streamTrackSegment = static_cast<VideoSegment*>(streamTrack->GetSegment());
+          VideoChunk* lastChunk = streamTrackSegment->GetLastChunk();
+          if (lastChunk) {
+            StreamTime startTime = streamTrackSegment->GetDuration() - lastChunk->GetDuration();
+            videoSegment.AppendSlice(*streamTrackSegment,
+                                     startTime,
+                                     streamTrackSegment->GetDuration());
+          }
+        }
+        if (found) {
+          videoSegment.AppendSlice(*data->mData, 0, data->mData->GetDuration());
+        }
+        videoSink->SetCurrentFrames(videoSegment);
       }
     }
 
     if (found && (isAudio || isVideo)) {
       for (auto entry : mDirectTrackListeners) {
         if (entry.mListener == listener &&
             (entry.mTrackID == TRACK_ANY || entry.mTrackID == aTrackID)) {
           listener->NotifyDirectListenerInstalled(
--- a/dom/media/VideoSegment.h
+++ b/dom/media/VideoSegment.h
@@ -89,17 +89,17 @@ struct VideoChunk {
     // - mFrame
     return 0;
   }
 
   PrincipalHandle GetPrincipalHandle() const { return mFrame.GetPrincipalHandle(); }
 
   StreamTime mDuration;
   VideoFrame mFrame;
-  mozilla::TimeStamp mTimeStamp;
+  TimeStamp mTimeStamp;
 };
 
 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
 public:
   typedef mozilla::layers::Image Image;
   typedef mozilla::gfx::IntSize IntSize;
 
   VideoSegment();