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

View File

@ -129,7 +129,10 @@ private:
// Monitor protecting members below accessed from multiple threads. // Monitor protecting members below accessed from multiple threads.
Monitor mMonitor; Monitor mMonitor;
media::TimeUnit mNextRandomAccessPoint; 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 } // namespace mozilla