[Bug]: The AMF Decoder Flush method does not flush the decoder completely
Describe the bug Decoding artefacts occur (randomly) at the beginning of a seek although the decoder has been drained and subsequently flushed. (When seeking to new position, a "Drain" is called followed by QueryOutputs until EOF. Then eventually a Flush is called.)
Output of the decoder have been dumped to files and artefacts are already present.
The first I-Frame does not present artefacts but subsequent pictures (Ps & Bs) are. Artefacts on Ps and Bs clearly shows portion of pictures/packets that had been pushed to the decoder BEFORE the drain/flush as if the decoder had retained some internal buffers despite the Flush.
IF the call to "Flush" is followed by a "ReInit" (everything else kept the same), the artefacts do not appear anymore. It therefore seems that the Flush is sometimes not complete.
To Reproduce Occurs randomly but easy to reproduce with long GOP IBBP streams and rapid seek changes.
Setup (please complete the following information): OS: Windows 10 Driver Version: 32.0.12019.1028 & 32.12033.1030 GPU: RX 7600 Which component has the issue: AMF Decoder
Debug Log (please upload or paste):
Expected behavior No decoding artefacts.
Screenshots In the attached archive file, img_39_xx and img_40_xx are decoder outputs before the seek while subsequent indices are decoder outputs after the seek (i.e. after a drain and a flush of the decoder). img_41_xx is the I-frame that is correctly decoded. Subsequent images are Ps and Bs that clearly show artefacts coming from pictures before the flush. Archive.zip
Additional context Add any other context about the problem here.
Does the AMD team need clarifications or more information to start considering this issue?
Sorry for the delay. Few things need to be discussed:
- Flush is not needed to be called after Drain + QueryOutput loop. Flush means that the caller is not interested in remaining frames inside decoder and they need to be dropped. Drain + QueryOutput allow get the remaining frames from decoder.
- So if you want seek, you can just call Flush.
- 1 and 2 don't explain the problem you observe.
- The actual seek happens inside demuxer/container reader. AMF PlaybackHW uses FFmpeg to read files and seek. FFmpeg seek can be done different ways and to avoid visible artifacts this sample app seeks to the nearest IDR-frame (not I-frame). Do you seek to I-frame or to IDR-frame?
- The reason for IDR is that P-frames and B-frames can refer frames before the last I-frame. You may have this special clip or stream.
- Another reason for corruption during seek can be container. I saw files with MP4 file extension but in reality they are MPEGTS file format. FFmpeg uses probing and sets-up the correct demuxer but MPEGTS don't have seek to IDR-frame capabilities.
- You may want to try PlaybackHW sample and seek there ("Toolbar" in menu). If you see a corruption, please share the actual file.
I came across a similar problem some month ago with at least two different HEVC files (one MPEG TS and one in an MP4 container). The issue was, that after seeking to the last IDR frame in the stream, the last 2 or 3 frames of that "GOP" (for the lack of a better word) couldn't be decoded at all.
a) no seeking no problems b) after seeking to any IDR (except the last one) all subsequent frames were decoded correctly c) after seeking to the last IDR the last 2 or 3 frames of the stream were missing
I was only able to solve c) by terminating the current decoder before that seek and setting up a new one. This is needed for HEVC and AV1 but not for AVC. Since the problem was solved for me I didn't bother to keep more info but to the best of my memory it was this file here. Sample was created with ffmpeg and one of these arguments:
ffmpeg.exe -r 30 -y -f lavfi -i testsrc=size=3840x2160:rate=1:duration=300 -pix_fmt yuv420p -c:v libx265 -b:v 12M -g 24 -x265-params open-gop=0 hevc_uhd_opengop_0.ts
ffmpeg.exe -r 30 -y -f lavfi -i testsrc=size=3840x2160:rate=1:duration=300 -pix_fmt yuv420p -c:v libx265 -b:v 12M -g 24 -x265-params open-gop=1 hevc_uhd_opengop_1.ts
In contrast to the things described above, whenever there were artifacts in decoded video frames after seeking, seeking even one more IDR / I ahead solved the problem.
Could you please describe your call sequence, in particular, did call Drain() and QueryOutput() in a loop till AMF_EOF to get last few frames?
I gonna need some time to check. I'll get back to you asap for the call sequence in use