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 : d01e8752b2aeaa3cc19897b6e8855f01f5163302
This commit is contained in:
Jean-Yves Avenard 2016-05-17 16:18:07 +08:00
Родитель c1bf16766d
Коммит c505cae198
3 изменённых файлов: 87 добавлений и 38 удалений

Просмотреть файл

@ -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__);
}

Просмотреть файл

@ -1910,6 +1910,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());
@ -1918,22 +1919,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;
}
@ -1944,6 +1978,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
const TimeUnit& aExpectedPts,
const TimeUnit& aFuzz)
{
MOZ_ASSERT(OnTaskQueue());
const TrackBuffer& track = GetTrackBuffer(aTrack);
if (aIndex >= track.Length()) {
@ -2009,6 +2044,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{
@ -2017,23 +2083,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),
@ -2041,31 +2097,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);