Re: review

"Kumar, Pradeep via ffmpeg-devel" <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <PH7PR11MB8597A3B6C9D5E2207A1CCA76F6D22@PH7PR11MB8597.namprd11.prod.outlook.com>
Hi Team,
Please review this.

This is done in context to save time for customer when flush is happened.
-thanks
Pradeep Kumar
​​
________________________________
From: Kumar, Pradeep via ffmpeg-devel <[email protected]>
Sent: Thursday, March 5, 2026 4:08 PM
To: [email protected] <[email protected]>
Cc: Kumar, Pradeep <[email protected]>
Subject: [FFmpeg-devel] review

Hi Team,
Please review this.

This is done in context to save time for customer when flush is happened.
-thanks
Pradeep Kumar

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
0001-avcodec-qsvdec-use-MFXVideoDECODE_Reset-on-flush-for.patch (application/octet-stream, 5 KB)
From a7449f432d1cdeadf7a85e7ebb8d2850f65ad68d Mon Sep 17 00:00:00 2001
From: Pradeep Kumar <[email protected]>
Date: Thu, 30 Jul 2026 14:39:34 +0530
Subject: [PATCH] avcodec/qsvdec: use MFXVideoDECODE_Reset on flush for fast
 keyframe decode path

The existing flush implementation always performs a full teardown and
reinitialization of the MFX session, which takes ~40-100 ms per call.
This is a critical regression for applications that decode only keyframes
and must flush the decoder between every frame (e.g. video management
software seeking and displaying I-frames).

Replace the unconditional reinit in qsv_decode_flush() with an in-place
MFXVideoDECODE_Reset() call when a live session exists.  Reset is
sufficient to clear the decoder state and is ~20x faster than a full
teardown+reinit cycle on ADL/RPL/PTL integrated graphics.

New flush logic:
- Call qsv_clear_async() only on the fast-reset path, immediately
  before MFXVideoDECODE_Reset().  This is the only place it is needed:
  Intel MediaSDK/VPL requires all outstanding async operations to be
  drained before Reset is called.
- On the full-reinit fallback (no session, or Reset fails), call
  qsv_decode_close_qsvcontext() which already drains the async fifo,
  frees the work-frame list and uninits pool/session.  A separate
  qsv_clear_async() call there was therefore redundant.
- After a full teardown, explicitly null q->session so the reinit
  guard in qsv_process_data() (if !q->session) correctly triggers
  instead of dereferencing the freed handle.

Signed-off-by: Pradeep <[email protected]>
---
 libavcodec/qsvdec.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index a85c1785cf..58457dd23a 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -572,6 +572,33 @@ 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 +1234,55 @@ 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 } } };
 
     qsv_clear_buffers(s);
 
+    // Fast path: reset the decoder in-place without tearing down the session.
+    // qsv_clear_async() is only needed here because MFXVideoDECODE_Reset
+    // requires all outstanding async operations to be drained first.
+    // On the full-reinit path below, qsv_decode_close_qsvcontext() already
+    // handles async/frame/pool cleanup, so calling qsv_clear_async() there
+    // would be redundant.
+    if (s->qsv.session && s->qsv.initialized) {
+        qsv_clear_async(&s->qsv);
+
+        sts = MFXVideoDECODE_GetVideoParam(s->qsv.session, &param);
+        if (sts < 0) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "MFXVideoDECODE_GetVideoParam failed (%d), forcing full reinit\n", sts);
+            goto full_reinit;
+        }
+
+        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, &param);
+        if (sts < 0) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "MFXVideoDECODE_Reset failed (%d), forcing full reinit\n", sts);
+            goto full_reinit;
+        }
+
+        s->qsv.frame_info = param.mfx.FrameInfo;
+        return;
+    }
+
+full_reinit:
+    // Full teardown: session missing, not yet initialized, or reset failed.
+    // qsv_decode_close_qsvcontext() clears async frames, the work-frame list,
+    // pool and session state, so no separate qsv_clear_async() is needed.
+    qsv_decode_close_qsvcontext(&s->qsv);
+    // qsv_decode_close_qsvcontext() does not null q->session (it doesn't need
+    // to on codec close). Since the QSVContext lives on across flush(), clear
+    // the dangling handle so the reinit path in qsv_process_data() takes the
+    // "no session" branch instead of dereferencing freed memory.
+    s->qsv.session      = NULL;
     s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE;
-    s->qsv.initialized = 0;
+    s->qsv.initialized  = 0;
 }
 
 #define OFFSET(x) offsetof(QSVDecContext, x)
-- 
2.53.0.windows.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.