mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
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:
parent
f51937602c
commit
18c2b9cb12
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user