From 16a8352c230582010c1e1a50bb058bdec92434dc Mon Sep 17 00:00:00 2001
From: Ivan Uskov <ivan.uskov@nablet.com>
Date: Mon, 25 Apr 2016 08:53:49 -0400
Subject: [PATCH] libavcodec/qsvdec.c: Restoring decoding functionality after
 unsuccessful merge from libav.

---
 libavcodec/qsvdec.c | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index c17606d..1844226 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -289,14 +289,8 @@ static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
     f->rndx = 0;
 }
 
-
-static void close_decoder(QSVContext *q)
+static void clear_async_fifo(QSVContext *q)
 {
-    QSVFrame *cur;
-
-    if (q->session)
-        MFXVideoDECODE_Close(q->session);
-
     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
         QSVFrame *out_frame;
         mfxSyncPoint *sync;
@@ -306,6 +300,16 @@ static void close_decoder(QSVContext *q)
 
         av_freep(&sync);
     }
+}
+
+static void close_decoder(QSVContext *q)
+{
+    QSVFrame *cur;
+
+    if (q->session)
+        MFXVideoDECODE_Close(q->session);
+
+    clear_async_fifo(q);
 
     cur = q->work_frames;
     while (cur) {
@@ -359,16 +363,16 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
         bs.TimeStamp  = avpkt->pts;
     }
 
-    sync = av_mallocz(sizeof(*sync));
-    if (!sync) {
-        av_freep(&sync);
-        return AVERROR(ENOMEM);
-    }
 
     while (1) {
         ret = get_surface(avctx, q, &insurf);
         if (ret < 0)
             return ret;
+
+        sync = av_mallocz(sizeof(*sync));
+        if (!sync)
+            return AVERROR(ENOMEM);
+
         do {
             ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
                                                   insurf, &outsurf, sync);
@@ -380,7 +384,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
         if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
             /* TODO: handle here minor sequence header changing */
         } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
-            av_fifo_reset(q->input_fifo);
+            clear_async_fifo(q);
             flush = q->reinit_pending = 1;
             continue;
         }
@@ -398,10 +402,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
             out_frame->queued = 1;
             av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
             av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);
-
             continue;
-        } else {
-            av_freep(&sync);
         }
         if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
             break;
@@ -413,6 +414,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
         av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
         bs.DataOffset = avpkt->size;
     }
+    av_freep(&sync);
 
     if (buffered) {
         qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
@@ -423,7 +425,6 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
     }
 
     if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
-        av_freep(&sync);
         av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
         return ff_qsv_error(ret);
     }
@@ -577,7 +578,7 @@ void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
     }
 
     /* Reset output surfaces */
-    av_fifo_reset(q->async_fifo);
+    clear_async_fifo(q);
 
     /* Reset input packets fifo */
     while (av_fifo_size(q->pkt_fifo)) {
-- 
1.8.3.1

