libavcodec/qsvdec.c: correct flush() handler has been implemented
authorIvan Uskov <ivan.uskov@nablet.com>
Thu, 6 Aug 2015 16:10:24 +0000 (12:10 -0400)
committerMichael Niedermayer <michael@niedermayer.cc>
Mon, 7 Sep 2015 20:04:02 +0000 (22:04 +0200)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavcodec/qsvdec.c
libavcodec/qsvdec.h
libavcodec/qsvdec_h2645.c
libavcodec/qsvdec_mpeg2.c
libavcodec/qsvdec_vc1.c

index 51ad2f7..00990ba 100644 (file)
@@ -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)
 {
index 5211fb2..2b989c2 100644 (file)
@@ -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 */
index 569b765..2d78722 100644 (file)
@@ -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)
index 975dd9e..36fd3b0 100644 (file)
@@ -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 = {
index a80fc83..3311d90 100644 (file)
@@ -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,