[FFmpeg-devel] QSV Decoding - Issues and Regressions

Ivan Uskov ivan.uskov at nablet.com
Tue Aug 4 09:49:26 CEST 2015

Hello Ronald,

Tuesday, August 4, 2015, 5:24:45 AM, you wrote:

RSB> Hi Ivan,

RSB> On Mon, Aug 3, 2015 at 4:50 PM, Ivan Uskov <ivan.uskov at nablet.com> wrote:

>> Hello Ronald,
>> Monday, August 3, 2015, 11:37:22 PM, you wrote:
>> RSB> On Mon, Aug 3, 2015 at 3:25 PM, Ivan Uskov <ivan.uskov at nablet.com>
>> wrote:
>> >> By the way, about old implementation which "worked fine".
>> >> It just did drop all buffered frames at decoder re-init on new
>> >> sequence header, there is nice comment inside old qsvdec_h264.c:
>> >> /* TODO: flush delayed frames on reinit */
>> RSB> Each AVCodec has a flush function which should do this. So as you
>> RSB> suggested, you need a flushing state which means you will output "old"
>> RSB> frames while consuming new frames and caching them internally in some
>> way.
>> RSB> Then, when the decoder is flushed (either because flush was called, or
>> RSB> because all old cached frames have been returned), you can use all
>> queued
>> RSB> packets to reinit the hw and start outputing frames right away.
>> Thank you for suggestion but unfortunately AVCodec::flush is useless
>> for this issue. The AVCodec::flush intended to *drop* decoded frames
>> and reset decoder before seeking and it calls by module outside of decoder.
>> My task is keep all frames without losing and decoder initiates
>> "flushing" by itself. So it is different kind of "flush".

RSB> That's exactly what I said, I think you misunderstood.

RSB> Libav's decoder handles AVCodec.flush inside the size-change function.
But not qsv decoder ;-)
RSB> What I'm saying is to make it a state machine and move that code to
RSB> AVCodec.flush (if it's not there already), and otherwise (as part of your
RSB> state machine) buffer incoming patches after a size change until all
RSB> previous-sized packets have been processed.
I agree all about state machine. But still not sure that AVCodec.flush
(which is really a dummy yet) can be used during handling a frame size changing.
For the qsv decoder case the AVCodec.flush (called before seek)
1. call MFXVideoDECODE_Reset() to reset decoder.
2. discard any buffered frames.
At the same time during handling a frame size changing it is
1. defer re-init
2. deliver buffered output (no any discards) buffering input
3. when no frames at #2 destroy (not just reset) decoder, init new
For this sequence I do not see anything appropriate which can be taken
from AVCodec.flush, sorry.

RSB> Then, N new-sized frames later, you'll have N packets buffered, you can
RSB> input them into the decoder all at once and immediately start outputing
RSB> frames of the new size without additional delay except for the hw reinit.
Yes, it is exactly what will be implemented.
Thank you very much for suggestions.

Best regards,
 Ivan                            mailto:ivan.uskov at nablet.com

More information about the ffmpeg-devel mailing list