Bug 1229987: [MSE] P1. Ensure next random access point properly calculated after seek. r=gerald

When seeking, the next keyframe time would always be set to the seek time (as the next sample to be retrieved would be a keyframe). This could lead to the next key frame logic to be activated too aggressively.
This commit is contained in:
Jean-Yves Avenard 2015-12-06 08:51:34 -08:00
parent f51937602c
commit 18c2b9cb12
2 changed files with 32 additions and 19 deletions

View File

@ -295,7 +295,7 @@ MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
, mManager(aManager)
, mType(aType)
, mMonitor("MediaSourceTrackDemuxer")
, mLastSeek(Some(TimeUnit()))
, mReset(true)
{
}
@ -328,7 +328,8 @@ MediaSourceTrackDemuxer::Reset()
RefPtr<MediaSourceTrackDemuxer> self = this;
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction([self] () {
self->mLastSeek = Some(TimeUnit());
self->mNextSample.reset();
self->mReset = true;
self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
{
MonitorAutoLock mon(self->mMonitor);
@ -380,49 +381,58 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
if (!buffered.Contains(aTime)) {
mLastSeek = Some(aTime);
// We don't have the data to seek to.
return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
__func__);
}
TimeUnit seekTime =
mManager->Seek(mType, aTime, MediaSourceDemuxer::EOS_FUZZ);
bool error;
RefPtr<MediaRawData> sample =
mManager->GetSample(mType,
media::TimeUnit(),
error);
MOZ_ASSERT(!error && sample);
mNextSample = Some(sample);
mReset = false;
{
MonitorAutoLock mon(mMonitor);
mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
}
mLastSeek = Some(aTime);
return SeekPromise::CreateAndResolve(seekTime, __func__);
}
RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
{
if (mLastSeek) {
if (mReset) {
// If a seek (or reset) was recently performed, we ensure that the data
// we are about to retrieve is still available.
TimeIntervals buffered = mManager->Buffered(mType);
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
if (!buffered.Contains(mLastSeek.ref())) {
if (!buffered.Contains(TimeUnit::FromMicroseconds(0))) {
return SamplesPromise::CreateAndReject(
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
}
mLastSeek.reset();
mReset = false;
}
bool error;
RefPtr<MediaRawData> sample =
mManager->GetSample(mType,
MediaSourceDemuxer::EOS_FUZZ,
error);
if (!sample) {
if (error) {
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
bool error = false;
RefPtr<MediaRawData> sample;
if (mNextSample) {
sample = mNextSample.ref();
mNextSample.reset();
} else {
sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, error);
if (!sample) {
if (error) {
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
}
return SamplesPromise::CreateAndReject(
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
}
return SamplesPromise::CreateAndReject(
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
}
RefPtr<SamplesHolder> samples = new SamplesHolder;
samples->mSamples.AppendElement(sample);

View File

@ -129,7 +129,10 @@ private:
// Monitor protecting members below accessed from multiple threads.
Monitor mMonitor;
media::TimeUnit mNextRandomAccessPoint;
Maybe<media::TimeUnit> mLastSeek;
Maybe<RefPtr<MediaRawData>> mNextSample;
// Set to true following a reset. Ensure that the next sample demuxed
// is available at position 0.
bool mReset;
};
} // namespace mozilla