]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qsvdec.c
Replace remaining occurances of av_free_packet with av_packet_unref
[ffmpeg] / libavcodec / qsvdec.c
index 51ad2f70909a70a7b9e15df13a8756eb2c372cd8..c451fb9614d960f73e88a062b8cd46b54c4e2f72 100644 (file)
@@ -49,7 +49,7 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
     }
 }
 
-int ff_qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
+static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
 {
     mfxVideoParam param = { { 0 } };
     mfxBitstream bs   = { { { 0 } } };
@@ -58,24 +58,30 @@ int ff_qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
                                        AV_PIX_FMT_NV12,
                                        AV_PIX_FMT_NONE };
 
+    ret = ff_get_format(avctx, pix_fmts);
+    if (ret < 0)
+        return ret;
+
+    avctx->pix_fmt      = ret;
+
     q->iopattern  = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
-    if (!q->session) {
-        if (avctx->hwaccel_context) {
-            AVQSVContext *qsv = avctx->hwaccel_context;
+    if (avctx->hwaccel_context) {
+        AVQSVContext *qsv = avctx->hwaccel_context;
 
-            q->session        = qsv->session;
-            q->iopattern      = qsv->iopattern;
-            q->ext_buffers    = qsv->ext_buffers;
-            q->nb_ext_buffers = qsv->nb_ext_buffers;
-        }
-        if (!q->session) {
+        q->session        = qsv->session;
+        q->iopattern      = qsv->iopattern;
+        q->ext_buffers    = qsv->ext_buffers;
+        q->nb_ext_buffers = qsv->nb_ext_buffers;
+    }
+    if (!q->session) {
+        if (!q->internal_qs.session) {
             ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
                                                q->load_plugins);
             if (ret < 0)
                 return ret;
-
-            q->session = q->internal_qs.session;
         }
+
+        q->session = q->internal_qs.session;
     }
 
     if (avpkt->size) {
@@ -123,11 +129,6 @@ int ff_qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
         return ff_qsv_error(ret);
     }
 
-    ret = ff_get_format(avctx, pix_fmts);
-    if (ret < 0)
-        return ret;
-
-    avctx->pix_fmt      = ret;
     avctx->profile      = param.mfx.CodecProfile;
     avctx->level        = param.mfx.CodecLevel;
     avctx->coded_width  = param.mfx.FrameInfo.Width;
@@ -293,7 +294,8 @@ static void close_decoder(QSVContext *q)
 {
     QSVFrame *cur;
 
-    MFXVideoDECODE_Close(q->session);
+    if (q->session)
+        MFXVideoDECODE_Close(q->session);
 
     cur = q->work_frames;
     while (cur) {
@@ -322,7 +324,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
     int flush    = !avpkt->size || q->reinit_pending;
 
     if (!q->engine_ready) {
-        ret = ff_qsv_decode_init(avctx, q, avpkt);
+        ret = qsv_decode_init(avctx, q, avpkt);
         if (ret)
             return ret;
     }
@@ -517,6 +519,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)
 {