зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1272964: [MSE] P3. Do not skip over gaps when searching for the next keyframe. r=gerald
MozReview-Commit-ID: 1wPbp6JOaa8 --HG-- extra : rebase_source : 0bdbc9bfafe69d73b4a204e10b1377b6f184fdd4
This commit is contained in:
Родитель
1b551846ce
Коммит
6070728c61
|
@ -468,8 +468,10 @@ MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(media::TimeUnit aTimeThre
|
|||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
|
||||
if (buffered.Contains(aTimeThreadshold)) {
|
||||
bool found;
|
||||
parsed =
|
||||
mManager->SkipToNextRandomAccessPoint(mType, aTimeThreadshold, found);
|
||||
parsed = mManager->SkipToNextRandomAccessPoint(mType,
|
||||
aTimeThreadshold,
|
||||
MediaSourceDemuxer::EOS_FUZZ,
|
||||
found);
|
||||
if (found) {
|
||||
return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
|
||||
}
|
||||
|
|
|
@ -1896,6 +1896,7 @@ TrackBuffersManager::Seek(TrackInfo::TrackType aTrack,
|
|||
uint32_t
|
||||
TrackBuffersManager::SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aTimeThreadshold,
|
||||
const media::TimeUnit& aFuzz,
|
||||
bool& aFound)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
@ -1904,22 +1905,55 @@ TrackBuffersManager::SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
|||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
aFound = false;
|
||||
|
||||
uint32_t nextSampleIndex = trackData.mNextGetSampleIndex.valueOr(0);
|
||||
for (uint32_t i = nextSampleIndex; i < track.Length(); i++) {
|
||||
const RefPtr<MediaRawData>& sample = track[i];
|
||||
// SkipToNextRandomAccessPoint can only be called if aTimeThreadshold is known
|
||||
// to be buffered.
|
||||
|
||||
// So first determine the current position in the track buffer if necessary.
|
||||
if (trackData.mNextGetSampleIndex.isNothing()) {
|
||||
if (trackData.mNextSampleTimecode == TimeUnit()) {
|
||||
// First demux, get first sample.
|
||||
trackData.mNextGetSampleIndex = Some(0u);
|
||||
} else {
|
||||
int32_t pos = FindCurrentPosition(aTrack, aFuzz);
|
||||
if (pos < 0) {
|
||||
return 0;
|
||||
}
|
||||
trackData.mNextGetSampleIndex = Some(uint32_t(pos));
|
||||
}
|
||||
}
|
||||
|
||||
TimeUnit nextSampleTimecode = trackData.mNextSampleTimecode;
|
||||
TimeUnit nextSampleTime = trackData.mNextSampleTime;
|
||||
uint32_t i = trackData.mNextGetSampleIndex.ref();
|
||||
|
||||
for (; i < track.Length(); i++) {
|
||||
const MediaRawData* sample =
|
||||
GetSample(aTrack,
|
||||
i,
|
||||
nextSampleTimecode,
|
||||
nextSampleTime,
|
||||
aFuzz);
|
||||
if (!sample) {
|
||||
break;
|
||||
}
|
||||
if (sample->mKeyframe &&
|
||||
sample->mTime >= aTimeThreadshold.ToMicroseconds()) {
|
||||
trackData.mNextSampleTimecode =
|
||||
TimeUnit::FromMicroseconds(sample->mTimecode);
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->mTime);
|
||||
trackData.mNextGetSampleIndex = Some(i);
|
||||
aFound = true;
|
||||
break;
|
||||
}
|
||||
nextSampleTimecode =
|
||||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
nextSampleTime = TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
parsed++;
|
||||
}
|
||||
|
||||
// Adjust the next demux time and index so that the next call to
|
||||
// SkipToNextRandomAccessPoint will not count again the parsed sample as
|
||||
// skipped.
|
||||
trackData.mNextSampleTimecode = nextSampleTimecode;
|
||||
trackData.mNextSampleTime = nextSampleTime;
|
||||
trackData.mNextGetSampleIndex = Some(i);
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
|
@ -1930,6 +1964,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
const TimeUnit& aExpectedPts,
|
||||
const TimeUnit& aFuzz)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
|
||||
if (aIndex >= track.Length()) {
|
||||
|
@ -1995,6 +2030,37 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
}
|
||||
|
||||
// Our previous index has been overwritten, attempt to find the new one.
|
||||
int32_t pos = FindCurrentPosition(aTrack, aFuzz);
|
||||
if (pos < 0) {
|
||||
MSE_DEBUG("Couldn't find sample (pts:%lld dts:%lld)",
|
||||
trackData.mNextSampleTime.ToMicroseconds(),
|
||||
trackData.mNextSampleTimecode.ToMicroseconds());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const RefPtr<MediaRawData>& sample = track[pos];
|
||||
RefPtr<MediaRawData> p = sample->Clone();
|
||||
if (!p) {
|
||||
// OOM
|
||||
aError = true;
|
||||
return nullptr;
|
||||
}
|
||||
trackData.mNextGetSampleIndex = Some(uint32_t(pos)+1);
|
||||
trackData.mNextSampleTimecode =
|
||||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
int32_t
|
||||
TrackBuffersManager::FindCurrentPosition(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aFuzz)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& trackData = GetTracksData(aTrack);
|
||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
|
||||
for (uint32_t i = 0; i < track.Length(); i++) {
|
||||
const RefPtr<MediaRawData>& sample = track[i];
|
||||
TimeInterval sampleInterval{
|
||||
|
@ -2003,23 +2069,13 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
aFuzz};
|
||||
|
||||
if (sampleInterval.ContainsWithStrictEnd(trackData.mNextSampleTimecode)) {
|
||||
RefPtr<MediaRawData> p = sample->Clone();
|
||||
if (!p) {
|
||||
// OOM
|
||||
aError = true;
|
||||
return nullptr;
|
||||
}
|
||||
trackData.mNextGetSampleIndex = Some(i+1);
|
||||
trackData.mNextSampleTimecode = sampleInterval.mEnd;
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
return p.forget();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// We couldn't find our sample by decode timestamp. Attempt to find it using
|
||||
// presentation timestamp. There will likely be small jerkiness.
|
||||
for (uint32_t i = 0; i < track.Length(); i++) {
|
||||
for (uint32_t i = 0; i < track.Length(); i++) {
|
||||
const RefPtr<MediaRawData>& sample = track[i];
|
||||
TimeInterval sampleInterval{
|
||||
TimeUnit::FromMicroseconds(sample->mTime),
|
||||
|
@ -2027,31 +2083,19 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
|||
aFuzz};
|
||||
|
||||
if (sampleInterval.ContainsWithStrictEnd(trackData.mNextSampleTimecode)) {
|
||||
RefPtr<MediaRawData> p = sample->Clone();
|
||||
if (!p) {
|
||||
// OOM
|
||||
aError = true;
|
||||
return nullptr;
|
||||
}
|
||||
trackData.mNextGetSampleIndex = Some(i+1);
|
||||
// Estimate decode timestamp of the next sample.
|
||||
trackData.mNextSampleTimecode = sampleInterval.mEnd;
|
||||
trackData.mNextSampleTime =
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
return p.forget();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
MSE_DEBUG("Couldn't find sample (pts:%lld dts:%lld)",
|
||||
trackData.mNextSampleTime.ToMicroseconds(),
|
||||
trackData.mNextSampleTimecode.ToMicroseconds());
|
||||
return nullptr;
|
||||
// Still not found.
|
||||
return -1;
|
||||
}
|
||||
|
||||
TimeUnit
|
||||
TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aFuzz)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& trackData = GetTracksData(aTrack);
|
||||
MOZ_ASSERT(trackData.mNextGetSampleIndex.isSome());
|
||||
const TrackBuffersManager::TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
|
|
|
@ -145,10 +145,13 @@ public:
|
|||
const media::TimeUnit& aFuzz);
|
||||
uint32_t SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aTimeThreadshold,
|
||||
const media::TimeUnit& aFuzz,
|
||||
bool& aFound);
|
||||
already_AddRefed<MediaRawData> GetSample(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aFuzz,
|
||||
bool& aError);
|
||||
int32_t FindCurrentPosition(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aFuzz);
|
||||
media::TimeUnit GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aFuzz);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче