Bug 1272916: [MSE] P1. Don't rely only on dts gap to establish if we have a gap in our source buffer. r?gerald
Also check that the pts have similar gap.
MozReview-Commit-ID: 4Hk24S78HjF
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -1964,44 +1964,70 @@ TrackBuffersManager::SkipToNextRandomAcc
break;
}
parsed++;
}
return parsed;
}
+const MediaRawData*
+TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
+ size_t aIndex,
+ const TimeUnit& aExpectedDts,
+ const TimeUnit& aExpectedPts,
+ const TimeUnit& aFuzz)
+{
+ const TrackBuffer& track = GetTrackBuffer(aTrack);
+
+ if (aIndex >= track.Length()) {
+ // reached the end.
+ return nullptr;
+ }
+
+ const RefPtr<MediaRawData>& sample = track[aIndex];
+ if (!aIndex || sample->mTimecode <= (aExpectedDts + aFuzz).ToMicroseconds() ||
+ sample->mTime <= (aExpectedPts + aFuzz).ToMicroseconds()) {
+ return sample;
+ }
+
+ // Gap is too big. End of Stream or Waiting for Data.
+ // TODO, check that we have continuous data based on the sanitized buffered
+ // range instead.
+ return nullptr;
+}
+
already_AddRefed<MediaRawData>
TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
const TimeUnit& aFuzz,
bool& aError)
{
MOZ_ASSERT(OnTaskQueue());
auto& trackData = GetTracksData(aTrack);
const TrackBuffer& track = GetTrackBuffer(aTrack);
aError = false;
- if (!track.Length() ||
- (trackData.mNextGetSampleIndex.isSome() &&
- trackData.mNextGetSampleIndex.ref() >= track.Length())) {
+ if (!track.Length()) {
return nullptr;
}
if (trackData.mNextGetSampleIndex.isNothing() &&
trackData.mNextSampleTimecode == TimeUnit()) {
// First demux, get first sample.
trackData.mNextGetSampleIndex = Some(0u);
}
if (trackData.mNextGetSampleIndex.isSome()) {
- const RefPtr<MediaRawData>& sample =
- track[trackData.mNextGetSampleIndex.ref()];
- if (trackData.mNextGetSampleIndex.ref() &&
- sample->mTimecode > (trackData.mNextSampleTimecode + aFuzz).ToMicroseconds()) {
- // Gap is too big. End of Stream or Waiting for Data.
+ const MediaRawData* sample =
+ GetSample(aTrack,
+ trackData.mNextGetSampleIndex.ref(),
+ trackData.mNextSampleTimecode,
+ trackData.mNextSampleTime,
+ aFuzz);
+ if (!sample) {
return nullptr;
}
RefPtr<MediaRawData> p = sample->Clone();
if (!p) {
aError = true;
return nullptr;
}
@@ -2073,28 +2099,30 @@ TrackBuffersManager::GetNextRandomAccess
const TimeUnit& aFuzz)
{
auto& trackData = GetTracksData(aTrack);
MOZ_ASSERT(trackData.mNextGetSampleIndex.isSome());
const TrackBuffersManager::TrackBuffer& track = GetTrackBuffer(aTrack);
uint32_t i = trackData.mNextGetSampleIndex.ref();
TimeUnit nextSampleTimecode = trackData.mNextSampleTimecode;
+ TimeUnit nextSampleTime = trackData.mNextSampleTime;
for (; i < track.Length(); i++) {
- const RefPtr<MediaRawData>& sample = track[i];
- if (sample->mTimecode > (nextSampleTimecode + aFuzz).ToMicroseconds()) {
- // Gap is too big. End of Stream or Waiting for Data.
+ const MediaRawData* sample =
+ GetSample(aTrack, i, nextSampleTimecode, nextSampleTime, aFuzz);
+ if (!sample) {
break;
}
if (sample->mKeyframe) {
return TimeUnit::FromMicroseconds(sample->mTime);
}
nextSampleTimecode =
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
+ nextSampleTime = TimeUnit::FromMicroseconds(sample->GetEndTime());
}
return TimeUnit::FromInfinity();
}
void
TrackBuffersManager::TrackData::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
{
for (TrackBuffer& buffer : mBuffers) {
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -335,16 +335,21 @@ private:
const media::TimeIntervals& aIntervals,
TrackData& aTrackData);
void RemoveFrames(const media::TimeIntervals& aIntervals,
TrackData& aTrackData,
uint32_t aStartIndex);
// Find index of sample. Return a negative value if not found.
uint32_t FindSampleIndex(const TrackBuffer& aTrackBuffer,
const media::TimeInterval& aInterval);
+ const MediaRawData* GetSample(TrackInfo::TrackType aTrack,
+ size_t aIndex,
+ const media::TimeUnit& aExpectedDts,
+ const media::TimeUnit& aExpectedPts,
+ const media::TimeUnit& aFuzz);
void UpdateBufferedRanges();
void RejectProcessing(nsresult aRejectValue, const char* aName);
void ResolveProcessing(bool aResolveValue, const char* aName);
MozPromiseRequestHolder<CodedFrameProcessingPromise> mProcessingRequest;
MozPromiseHolder<CodedFrameProcessingPromise> mProcessingPromise;
// Trackbuffers definition.
nsTArray<TrackData*> GetTracksList();