Re: [PATCH] Optimization on QSV Flush
Michael Henrik Bodenhoff via ffmpeg-devel <[email protected]> Tue, 4 Aug 2026 11:43:02 +0000
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <DU0PR02MB939452E4CBE40F1ABEB8EA78BCD42@DU0PR02MB9394.eurprd02.prod.outlook.com> |
Bumping this as it fixes an issue we are having when decoding keyframes only Michael Bodenhoff Principal Software Engineer www.milestonesys.com<http://www.milestonesys.com> ________________________________ From: Kumar, Pradeep via ffmpeg-devel <[email protected]> Sent: Tuesday, 7 July 2026 07.29 To: [email protected] <[email protected]> Cc: Kumar, Pradeep <[email protected]> Subject: [FFmpeg-devel] [PATCH] Optimization on QSV Flush Signed-off-by: Kumar, Pradeep <[email protected]> --- libavcodec/qsvdec.c | 72 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index a85c1785cf..510cff2887 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -572,6 +572,34 @@ static void qsv_clear_unused_frames(QSVContext *q) } } + +static void qsv_clear_async(QSVContext *q) +{ + QSVAsyncFrame aframe; + QSVFrame *cur; + if (q->async_fifo) { + while (av_fifo_read(q->async_fifo, &aframe, 1) >= 0) { + if (aframe.frame && aframe.frame->queued > 0) + aframe.frame->queued -= 1; + av_freep(&aframe.sync); + } + } + + cur = q->work_frames; + while (cur) { + cur->queued = 0; + if (cur->used && !cur->surface.Data.Locked) { + cur->used = 0; + av_frame_unref(cur->frame); + } + cur = cur->next; + } + + q->zero_consume_run = 0; + q->reinit_flag = 0; +} + + static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf) { QSVFrame *frame, **last; @@ -1207,11 +1235,51 @@ static int qsv_decode_frame(AVCodecContext *avctx, AVFrame *frame, static void qsv_decode_flush(AVCodecContext *avctx) { QSVDecContext *s = avctx->priv_data; + mfxStatus sts; + mfxVideoParam param = { { { 0 } } }; + int reset_succeeded = 0; qsv_clear_buffers(s); + qsv_clear_async(&s->qsv); + + // Intel Media SDK compatibility: Try decoder reset first to avoid + // expensive full teardown/reinit cycle (15-20ms -> 2-3ms optimization) + if (s->qsv.session && s->qsv.initialized) { + av_log(avctx, AV_LOG_DEBUG, + "Attempting QSV decoder reset for fast flush\n"); + + sts = MFXVideoDECODE_GetVideoParam(s->qsv.session, ¶m); + if (sts == MFX_ERR_NONE) { + // Restore critical parameters for reset + param.AsyncDepth = s->qsv.async_depth; + param.IOPattern = s->qsv.iopattern; + param.ExtParam = s->qsv.ext_buffers; + param.NumExtParam = s->qsv.nb_ext_buffers; + + sts = MFXVideoDECODE_Reset(s->qsv.session, ¶m); + if (sts >= 0) { + av_log(avctx, AV_LOG_DEBUG, + "QSV decoder reset successful (fast path)\n"); + s->qsv.frame_info = param.mfx.FrameInfo; + reset_succeeded = 1; + } else { + av_log(avctx, AV_LOG_WARNING, + "MFXVideoDECODE_Reset failed (%d)," + "forcing full reinit\n", sts); + } + } else { + av_log(avctx, AV_LOG_WARNING, + "MFXVideoDECODE_GetVideoParam failed (%d)," + "forcing full reinit\n", sts); + } + } - s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE; - s->qsv.initialized = 0; + if (!reset_succeeded) { + // Fallback to full reinitialization + av_log(avctx, AV_LOG_DEBUG, "Using full QSV decoder reinitialization\n"); + s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE; + s->qsv.initialized = 0; + } } #define OFFSET(x) offsetof(QSVDecContext, x) -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected] _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]