Skip to content

Commit

Permalink
Bug 1779186 [Linux] Skip non-ref frames after seek when stream is dec…
Browse files Browse the repository at this point in the history
…oded by VA-API r=alwu

When stream is decoded by VA-API and position is changed we may see decoding artifacts.
MPV project uses AVDISCARD_NONREF frame skip until requested/decoded frames are synced so let's use the same approach.

Depends on D161723

Differential Revision: https://phabricator.services.mozilla.com/D161724
  • Loading branch information
stransky committed Nov 11, 2022
1 parent ae4b1bd commit 02eb199
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
24 changes: 24 additions & 0 deletions dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,13 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
packet.pos = aSample->mOffset;

mCodecContext->skip_frame = mFrameDrop;
#if MOZ_LOGGING
if (mFrameDrop == AVDISCARD_NONREF) {
FFMPEG_LOG("Frame skip AVDISCARD_NONREF");
}
#endif

#if LIBAVCODEC_VERSION_MAJOR >= 58
packet.duration = aSample->mDuration.ToMicroseconds();
int res = mLib->avcodec_send_packet(mCodecContext, &packet);
Expand Down Expand Up @@ -883,6 +890,18 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
RESULT_DETAIL("avcodec_receive_frame error: %s", errStr));
}

if (mFrameDrop == AVDISCARD_NONREF) {
FFMPEG_LOG("Requested pts %" PRId64 " decoded frame pts %" PRId64,
packet.pts, GetFramePts(mFrame) + mFrame->pkt_duration);
// Switch back to default frame skip policy if we hit correct
// decode times. 5 ms treshold is taken from mpv project which
// use similar approach after seek (feed_packet() at f_decoder_wrapper.c).
if (packet.pts - 5000 <= GetFramePts(mFrame) + mFrame->pkt_duration) {
FFMPEG_LOG("Set frame drop to AVDISCARD_DEFAULT.");
mFrameDrop = AVDISCARD_DEFAULT;
}
}

UpdateDecodeTimes(decodeStart);
decodeStart = TimeStamp::Now();

Expand Down Expand Up @@ -1213,9 +1232,14 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(

RefPtr<MediaDataDecoder::FlushPromise>
FFmpegVideoDecoder<LIBAV_VER>::ProcessFlush() {
FFMPEG_LOG("ProcessFlush()");
MOZ_ASSERT(mTaskQueue->IsOnCurrentThread());
mPtsContext.Reset();
mDurationMap.Clear();
// Discard non-ref frames on HW accelerated backend to avoid decode artifacts.
if (IsHardwareAccelerated()) {
mFrameDrop = AVDISCARD_NONREF;
}
return FFmpegDataDecoder::ProcessFlush();
}

Expand Down
1 change: 1 addition & 0 deletions dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class FFmpegVideoDecoder<LIBAV_VER>

DurationMap mDurationMap;
const bool mLowLatency;
AVDiscard mFrameDrop = AVDISCARD_DEFAULT;

// True if we're allocating shmem for ffmpeg decode buffer.
Maybe<Atomic<bool>> mIsUsingShmemBufferForDecode;
Expand Down

0 comments on commit 02eb199

Please sign in to comment.