mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Bug 1275538: P2. Drop decoded frames that we know are already too late. r=kamidphish
MozReview-Commit-ID: EZ2Ql2DtTKa --HG-- extra : rebase_source : 4dbffc3538e86562a6bb347354f4ff377e484f04
This commit is contained in:
parent
ca37fb4d46
commit
48f24d3464
@ -1422,6 +1422,27 @@ MediaFormatReader::Reset(TrackType aTrack)
|
||||
LOG("Reset(%s) END", TrackTypeToStr(aTrack));
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::DropDecodedSamples(TrackType aTrack)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
size_t lengthDecodedQueue = decoder.mOutput.Length();
|
||||
if (lengthDecodedQueue && decoder.mTimeThreshold.isSome()) {
|
||||
TimeUnit time =
|
||||
TimeUnit::FromMicroseconds(decoder.mOutput.LastElement()->mTime);
|
||||
if (time >= decoder.mTimeThreshold.ref().Time()) {
|
||||
// We would have reached our internal seek target.
|
||||
decoder.mTimeThreshold.reset();
|
||||
}
|
||||
}
|
||||
decoder.mOutput.Clear();
|
||||
decoder.mSizeOfQueue -= lengthDecodedQueue;
|
||||
if (aTrack == TrackInfo::kVideoTrack && mDecoder) {
|
||||
mDecoder->NotifyDecodedFrames(0, 0, lengthDecodedQueue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold)
|
||||
{
|
||||
@ -1429,6 +1450,15 @@ MediaFormatReader::SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold)
|
||||
MOZ_ASSERT(mVideo.HasPromise());
|
||||
LOG("Skipping up to %lld", aTimeThreshold.ToMicroseconds());
|
||||
|
||||
// We've reached SkipVideoDemuxToNextKeyFrame when our decoding is late.
|
||||
// As such we can drop all already decoded samples and discard all pending
|
||||
// samples.
|
||||
// TODO: Ideally we should set mOutputRequested to false so that all pending
|
||||
// frames are dropped too. However, we can't do such thing as the code assumes
|
||||
// that the decoder just got flushed. Once bug 1257107 land, we could set the
|
||||
// decoder threshold to the value of currentTime.
|
||||
DropDecodedSamples(TrackInfo::kVideoTrack);
|
||||
|
||||
mSkipRequest.Begin(mVideo.mTrackDemuxer->SkipToNextRandomAccessPoint(aTimeThreshold)
|
||||
->Then(OwnerThread(), __func__, this,
|
||||
&MediaFormatReader::OnVideoSkipCompleted,
|
||||
@ -1440,11 +1470,11 @@ void
|
||||
MediaFormatReader::VideoSkipReset(uint32_t aSkipped)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
// I think it's still possible for an output to have been sent from the decoder
|
||||
// and is currently sitting in our event queue waiting to be processed. The following
|
||||
// flush won't clear it, and when we return to the event loop it'll be added to our
|
||||
// output queue and be used.
|
||||
// This code will count that as dropped, which was the intent, but not quite true.
|
||||
|
||||
// Some frames may have been output by the decoder since we initiated the
|
||||
// videoskip process and we know they would be late.
|
||||
DropDecodedSamples(TrackInfo::kVideoTrack);
|
||||
// Report the pending frames as dropped.
|
||||
if (mDecoder) {
|
||||
mDecoder->NotifyDecodedFrames(0, 0, SizeOfVideoQueueInFrames());
|
||||
}
|
||||
@ -1483,6 +1513,9 @@ MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailu
|
||||
switch (aFailure.mFailure) {
|
||||
case DemuxerFailureReason::END_OF_STREAM: MOZ_FALLTHROUGH;
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
// Some frames may have been output by the decoder since we initiated the
|
||||
// videoskip process and we know they would be late.
|
||||
DropDecodedSamples(TrackInfo::kVideoTrack);
|
||||
// We can't complete the skip operation, will just service a video frame
|
||||
// normally.
|
||||
NotifyDecodingRequested(TrackInfo::kVideoTrack);
|
||||
|
@ -179,6 +179,7 @@ private:
|
||||
void Error(TrackType aTrack);
|
||||
void Reset(TrackType aTrack);
|
||||
void DrainComplete(TrackType aTrack);
|
||||
void DropDecodedSamples(TrackType aTrack);
|
||||
|
||||
bool ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user