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
--- 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();