mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1126465 - Cancel sample requests when seeks start, disallow them while seeks are happening, and assert against seeks when samples arrive. r=mattwoodrow
The duplication of the IsSeeking() checks before all the Request{Audio,Video}Data callsites is ugly. We'll fix this in the next patch by applying the same disconnect treatment to the seek promise.
This commit is contained in:
parent
ef6fc9a828
commit
c6cbaf8bc1
@ -119,7 +119,7 @@ MediaSourceReader::RequestAudioData()
|
||||
mAudioPromise.Reject(DECODE_ERROR, __func__);
|
||||
return p;
|
||||
}
|
||||
if (mAudioIsSeeking) {
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called mid-seek. Rejecting.", this);
|
||||
mAudioPromise.Reject(CANCELED, __func__);
|
||||
return p;
|
||||
@ -148,6 +148,12 @@ MediaSourceReader::RequestAudioData()
|
||||
void
|
||||
MediaSourceReader::RequestAudioDataComplete(int64_t aTime)
|
||||
{
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestAudioDataComplete called mid-seek. Rejecting.", this);
|
||||
MOZ_RELEASE_ASSERT(mAudioPromise.IsEmpty()); // Already rejected in ::Seek().
|
||||
return;
|
||||
}
|
||||
|
||||
mAudioRequest.Begin(mAudioReader->RequestAudioData()
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnAudioDecoded,
|
||||
@ -163,6 +169,7 @@ MediaSourceReader::RequestAudioDataFailed(nsresult aResult)
|
||||
void
|
||||
MediaSourceReader::OnAudioDecoded(AudioData* aSample)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!IsSeeking());
|
||||
mAudioRequest.Complete();
|
||||
|
||||
MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
|
||||
@ -180,12 +187,7 @@ MediaSourceReader::OnAudioDecoded(AudioData* aSample)
|
||||
mDropAudioBeforeThreshold = false;
|
||||
}
|
||||
|
||||
// Any OnAudioDecoded callbacks received while mAudioIsSeeking must be not
|
||||
// update our last used timestamp, as these are emitted by the reader we're
|
||||
// switching away from.
|
||||
if (!mAudioIsSeeking) {
|
||||
mLastAudioTime = aSample->mTime + aSample->mDuration;
|
||||
}
|
||||
mLastAudioTime = aSample->mTime + aSample->mDuration;
|
||||
|
||||
mAudioPromise.Resolve(aSample, __func__);
|
||||
}
|
||||
@ -219,6 +221,7 @@ AdjustEndTime(int64_t* aEndTime, MediaDecoderReader* aReader)
|
||||
void
|
||||
MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!IsSeeking());
|
||||
mAudioRequest.Complete();
|
||||
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnAudioNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded());
|
||||
@ -265,7 +268,7 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
||||
mDropAudioBeforeThreshold = true;
|
||||
mDropVideoBeforeThreshold = true;
|
||||
}
|
||||
if (mVideoIsSeeking) {
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestVideoData called mid-seek. Rejecting.", this);
|
||||
mVideoPromise.Reject(CANCELED, __func__);
|
||||
return p;
|
||||
@ -298,6 +301,11 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
|
||||
void
|
||||
MediaSourceReader::RequestVideoDataComplete(int64_t aTime)
|
||||
{
|
||||
if (IsSeeking()) {
|
||||
MSE_DEBUG("MediaSourceReader(%p)::RequestVideoDataComplete called mid-seek. Rejecting.", this);
|
||||
MOZ_ASSERT(mVideoPromise.IsEmpty()); // Already rejected in ::Seek().
|
||||
return;
|
||||
}
|
||||
mVideoRequest.Begin(mVideoReader->RequestVideoData(false, 0)
|
||||
->RefableThen(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnVideoDecoded,
|
||||
@ -313,6 +321,7 @@ MediaSourceReader::RequestVideoDataFailed(nsresult aResult)
|
||||
void
|
||||
MediaSourceReader::OnVideoDecoded(VideoData* aSample)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!IsSeeking());
|
||||
mVideoRequest.Complete();
|
||||
|
||||
MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
|
||||
@ -330,12 +339,7 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
|
||||
mDropVideoBeforeThreshold = false;
|
||||
}
|
||||
|
||||
// Any OnVideoDecoded callbacks received while mVideoIsSeeking must be not
|
||||
// update our last used timestamp, as these are emitted by the reader we're
|
||||
// switching away from.
|
||||
if (!mVideoIsSeeking) {
|
||||
mLastVideoTime = aSample->mTime + aSample->mDuration;
|
||||
}
|
||||
mLastVideoTime = aSample->mTime + aSample->mDuration;
|
||||
|
||||
mVideoPromise.Resolve(aSample, __func__);
|
||||
}
|
||||
@ -343,6 +347,7 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
|
||||
void
|
||||
MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!IsSeeking());
|
||||
mVideoRequest.Complete();
|
||||
|
||||
MSE_DEBUG("MediaSourceReader(%p)::OnVideoNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded());
|
||||
@ -683,6 +688,15 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aIgnored /* Used only for ogg whi
|
||||
return p;
|
||||
}
|
||||
|
||||
// Any previous requests we've been waiting on are now unwanted.
|
||||
mAudioRequest.DisconnectIfExists();
|
||||
mVideoRequest.DisconnectIfExists();
|
||||
|
||||
// Additionally, reject any outstanding promises _we_ made that we might have
|
||||
// been waiting on the above to fulfill.
|
||||
mAudioPromise.RejectIfExists(CANCELED, __func__);
|
||||
mVideoPromise.RejectIfExists(CANCELED, __func__);
|
||||
|
||||
// Store pending seek target in case the track buffers don't contain
|
||||
// the desired time and we delay doing the seek.
|
||||
mPendingSeekTime = aTime;
|
||||
@ -858,11 +872,11 @@ MediaSourceReader::MaybeNotifyHaveData()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
bool haveAudio = false, haveVideo = false;
|
||||
if (!mAudioIsSeeking && mAudioTrack && HaveData(mLastAudioTime, MediaData::AUDIO_DATA)) {
|
||||
if (!IsSeeking() && mAudioTrack && HaveData(mLastAudioTime, MediaData::AUDIO_DATA)) {
|
||||
haveAudio = true;
|
||||
WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__);
|
||||
}
|
||||
if (!mVideoIsSeeking && mVideoTrack && HaveData(mLastVideoTime, MediaData::VIDEO_DATA)) {
|
||||
if (!IsSeeking() && mVideoTrack && HaveData(mLastVideoTime, MediaData::VIDEO_DATA)) {
|
||||
haveVideo = true;
|
||||
WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__);
|
||||
}
|
||||
|
@ -173,6 +173,7 @@ private:
|
||||
bool HaveData(int64_t aTarget, MediaData::Type aType);
|
||||
|
||||
void AttemptSeek();
|
||||
bool IsSeeking() { return mPendingSeekTime != -1; }
|
||||
|
||||
nsRefPtr<MediaDecoderReader> mAudioReader;
|
||||
nsRefPtr<MediaDecoderReader> mVideoReader;
|
||||
|
Loading…
Reference in New Issue
Block a user