[FFmpeg-cvslog] libavcodec/qsvdec.c: correct flush() handler has been implemented

Ivan Uskov git at videolan.org
Mon Sep 7 22:13:57 CEST 2015


ffmpeg | branch: master | Ivan Uskov <ivan.uskov at nablet.com> | Thu Aug  6 12:10:24 2015 -0400| [3f8e2e9953240365361e939ca2ecd788dd5bef59] | committer: Michael Niedermayer

libavcodec/qsvdec.c: correct flush() handler has been implemented

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3f8e2e9953240365361e939ca2ecd788dd5bef59
---

 libavcodec/qsvdec.c       |   45 +++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/qsvdec.h       |    2 ++
 libavcodec/qsvdec_h2645.c |    4 ++--
 libavcodec/qsvdec_mpeg2.c |    2 ++
 libavcodec/qsvdec_vc1.c   |    8 +++++++-
 5 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 51ad2f7..00990ba 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -517,6 +517,51 @@ int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
     return ret;
 }
+/*
+ This function resets decoder and corresponded buffers before seek operation
+*/
+void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
+{
+    QSVFrame *cur;
+    AVPacket pkt;
+    int ret = 0;
+    mfxVideoParam param = { { 0 } };
+
+    if (q->reinit_pending) {
+        close_decoder(q);
+    } else if (q->engine_ready) {
+        ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
+        }
+
+        ret = MFXVideoDECODE_Reset(q->session, &param);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
+        }
+
+        /* Free all frames*/
+        cur = q->work_frames;
+        while (cur) {
+            q->work_frames = cur->next;
+            av_frame_free(&cur->frame);
+            av_freep(&cur);
+            cur = q->work_frames;
+        }
+    }
+
+    /* Reset output surfaces */
+    av_fifo_reset(q->async_fifo);
+
+    /* Reset input packets fifo */
+    while (av_fifo_size(q->pkt_fifo)) {
+        av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
+        av_packet_unref(&pkt);
+    }
+
+    /* Reset input bitstream fifo */
+    av_fifo_reset(q->input_fifo);
+}
 
 int ff_qsv_decode_close(QSVContext *q)
 {
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 5211fb2..2b989c2 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -84,6 +84,8 @@ int ff_qsv_decode(AVCodecContext *s, QSVContext *q,
                   AVFrame *frame, int *got_frame,
                   AVPacket *avpkt);
 
+void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q);
+
 int ff_qsv_decode_close(QSVContext *q);
 
 #endif /* AVCODEC_QSVDEC_H */
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index 569b765..2d78722 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -137,8 +137,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data,
 
 static void qsv_decode_flush(AVCodecContext *avctx)
 {
-//    QSVH2645Context *s = avctx->priv_data;
-    /* TODO: flush qsv engine if necessary */
+    QSVH2645Context *s = avctx->priv_data;
+    ff_qsv_decode_reset(avctx, &s->qsv);
 }
 
 #define OFFSET(x) offsetof(QSVH2645Context, x)
diff --git a/libavcodec/qsvdec_mpeg2.c b/libavcodec/qsvdec_mpeg2.c
index 975dd9e..36fd3b0 100644
--- a/libavcodec/qsvdec_mpeg2.c
+++ b/libavcodec/qsvdec_mpeg2.c
@@ -57,6 +57,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data,
 
 static void qsv_decode_flush(AVCodecContext *avctx)
 {
+    QSVMPEG2Context *s = avctx->priv_data;
+    ff_qsv_decode_reset(avctx, &s->qsv);
 }
 
 AVHWAccel ff_mpeg2_qsv_hwaccel = {
diff --git a/libavcodec/qsvdec_vc1.c b/libavcodec/qsvdec_vc1.c
index a80fc83..3311d90 100644
--- a/libavcodec/qsvdec_vc1.c
+++ b/libavcodec/qsvdec_vc1.c
@@ -52,6 +52,12 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data,
     return ff_qsv_decode(avctx, &s->qsv, frame, got_frame, avpkt);
 }
 
+static void qsv_decode_flush(AVCodecContext *avctx)
+{
+    QSVVC1Context *s = avctx->priv_data;
+    ff_qsv_decode_reset(avctx, &s->qsv);
+}
+
 AVHWAccel ff_vc1_qsv_hwaccel = {
     .name           = "vc1_qsv",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -81,7 +87,7 @@ AVCodec ff_vc1_qsv_decoder = {
     .id             = AV_CODEC_ID_VC1,
     .init           = NULL,
     .decode         = qsv_decode_frame,
-    .flush          = NULL,
+    .flush          = qsv_decode_flush,
     .close          = qsv_decode_close,
     .capabilities   = AV_CODEC_CAP_DELAY,
     .priv_class     = &class,



More information about the ffmpeg-cvslog mailing list