From f2bfb769797ae748764624b2fea1242e92890fe3 Mon Sep 17 00:00:00 2001
From: Ivan Uskov <ivan.uskov@nablet.com>
Date: Wed, 7 Oct 2015 10:10:18 -0400
Subject: [PATCH] libavcodec/qsv.c: Re-design session control and internal
 allocation. Now instance of AVQSVContext uses for external and internal
 session allocation Internal QSV session allocation now does create one global
 instance of AVQSVContext, common for all qsv components (decoder, vpp,
 encoder)

---
 libavcodec/qsv.c          | 102 ++++++++++++++++++++++++++++++++++------------
 libavcodec/qsv.h          |   6 +++
 libavcodec/qsv_internal.h |  16 +++++---
 libavcodec/qsvdec.c       |  52 ++++++++---------------
 libavcodec/qsvdec.h       |  13 +-----
 libavcodec/qsvdec_h2645.c |   2 +-
 libavcodec/qsvdec_mpeg2.c |   2 +-
 libavcodec/qsvdec_vc1.c   |   2 +-
 libavcodec/qsvenc.c       |  37 ++++++-----------
 libavcodec/qsvenc.h       |   5 +--
 10 files changed, 128 insertions(+), 109 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 4c8e6b0..6ced294 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -30,6 +30,8 @@
 #include "avcodec.h"
 #include "qsv_internal.h"
 
+static AVQSVContext* g_av_qsv = NULL;
+
 int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
 {
     switch (codec_id) {
@@ -85,7 +87,7 @@ int ff_qsv_error(int mfx_err)
         return AVERROR_UNKNOWN;
     }
 }
-static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
+static int ff_qsv_set_display_handle(AVCodecContext *avctx, AVQSVContext *av_qsv)
 {
     // this code is only required for Linux.  It searches for a valid
     // display handle.  First in /dev/dri/renderD then in /dev/dri/card
@@ -98,9 +100,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
     int fd = -1;
     char adapterpath[256];
     int adapter_num;
-
-    qs->fd_display = -1;
-    qs->va_display = NULL;
+    QSVControl* qc = av_qsv->ctl_struct;
+    qc->fd_display = -1;
+    qc->va_display = NULL;
 
     //search for valid graphics device
     for (adapter_num = 0;adapter_num < 6;adapter_num++) {
@@ -138,9 +140,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
         } else {
             av_log(avctx, AV_LOG_VERBOSE,
             "mfx initialization: %s vaInitialize successful\n",adapterpath);
-            qs->fd_display = fd;
-            qs->va_display = va_dpy;
-            ret = MFXVideoCORE_SetHandle(qs->session,
+            qc->fd_display = fd;
+            qc->va_display = va_dpy;
+            ret = MFXVideoCORE_SetHandle(av_qsv->session,
                   (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR,
@@ -165,11 +167,12 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
  * but the older /dev/dri/card interface is also searched
  * for broader compatibility.
  *
- * @param avctx    ffmpeg metadata for this codec context
- * @param session  the MSDK session used
+ * @param avctx   ffmpeg metadata for this codec context
+ * @param av_qsv  global instance of AVQSVContext
  */
-int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
-                                 const char *load_plugins)
+static int ff_qsv_init_internal_session(AVCodecContext *avctx,
+                                        AVQSVContext *av_qsv,
+                                        const char *load_plugins)
 {
     mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
     mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
@@ -177,17 +180,17 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
     const char *desc;
     int ret;
 
-    ret = MFXInit(impl, &ver, &qs->session);
+    ret = MFXInit(impl, &ver, &av_qsv->session);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n");
         return ff_qsv_error(ret);
     }
 
-    ret = ff_qsv_set_display_handle(avctx, qs);
+    ret = ff_qsv_set_display_handle(avctx, av_qsv);
     if (ret < 0)
         return ret;
 
-    MFXQueryIMPL(qs->session, &impl);
+    MFXQueryIMPL(av_qsv->session, &impl);
 
     switch (MFX_IMPL_BASETYPE(impl)) {
     case MFX_IMPL_SOFTWARE:
@@ -227,7 +230,7 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
 
             }
 
-            ret = MFXVideoUSER_Load(qs->session, &uid, 1);
+            ret = MFXVideoUSER_Load(av_qsv->session, &uid, 1);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
                        plugin);
@@ -249,21 +252,66 @@ load_plugin_fail:
     return 0;
 }
 
-int ff_qsv_close_internal_session(QSVSession *qs)
+int ff_qsv_init_av_qsv_context(AVCodecContext *avctx, AVQSVContext** av_qsv,
+                                 const char *load_plugins)
 {
-    if (qs->session) {
-        MFXClose(qs->session);
-        qs->session = NULL;
+    int ret = 0;
+
+    if (*av_qsv)
+        return 0; //already inited.
+
+    if (avctx->hwaccel_context) {
+        av_log(avctx, AV_LOG_VERBOSE,"externalAVQSVContext available \n");
+        *av_qsv = avctx->hwaccel_context;
+    } else {
+        if (!g_av_qsv) {
+            av_log(avctx, AV_LOG_VERBOSE,"Allocating new global AVQSVContext\n");
+            g_av_qsv = av_qsv_alloc_context();
+            g_av_qsv->ctl_struct = av_mallocz(sizeof(QSVControl));
+            ((QSVControl*)g_av_qsv->ctl_struct)->ref_count = 1;
+
+            ret = ff_qsv_init_internal_session(avctx, g_av_qsv, load_plugins);
+            if (ret)
+                ff_qsv_release_av_qsv_context(avctx, &g_av_qsv);
+        } else {
+            ((QSVControl*)g_av_qsv->ctl_struct)->ref_count++;
+        }
+        *av_qsv = g_av_qsv;
     }
+
+    return ret;
+}
+int ff_qsv_release_av_qsv_context(AVCodecContext *avctx, AVQSVContext** av_qsv)
+{
+    QSVControl* qc;
+
+    if (g_av_qsv && *av_qsv!=g_av_qsv)
+        return 0; //nothing to release
+
+    *av_qsv = NULL;
+    qc = g_av_qsv->ctl_struct;
+    qc->ref_count--;
+
+    av_log(avctx, AV_LOG_VERBOSE,
+           "releasing global AVQSVContext, ref count %d\n",
+            qc->ref_count);
+
+    if (qc->ref_count)
+        return 0;
+
+    if (g_av_qsv->session)
+        MFXClose(g_av_qsv->session);
+
 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
-    if (qs->va_display) {
-        vaTerminate(qs->va_display);
-        qs->va_display = NULL;
-    }
-    if (qs->fd_display > 0) {
-        close(qs->fd_display);
-        qs->fd_display = -1;
-    }
+    if (qc->va_display)
+        vaTerminate(qc->va_display);
+    if (qc->fd_display > 0)
+        close(qc->fd_display);
 #endif
+
+    av_free(g_av_qsv->ctl_struct);
+    av_freep(&g_av_qsv);
+
     return 0;
 }
+
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index 6049629..34721fa 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -48,6 +48,12 @@ typedef struct AVQSVContext {
      */
     mfxExtBuffer **ext_buffers;
     int         nb_ext_buffers;
+
+   /**
+    * Uses when context allocates internally by ffmpeg.
+    * MUST be NULL if instance of AVQSVContext creates by external application
+    */
+    void* ctl_struct;
 } AVQSVContext;
 
 /**
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index b9ad199..19d26ef 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -36,7 +36,7 @@
 #include <va/va_drm.h>
 #endif
 
-#include <mfx/mfxvideo.h>
+#include "qsv.h"
 
 #include "libavutil/frame.h"
 
@@ -60,13 +60,17 @@ typedef struct QSVFrame {
     struct QSVFrame *next;
 } QSVFrame;
 
-typedef struct QSVSession {
-    mfxSession session;
+/**
+ * Uses to control AVQSVContext instance when it allocated internally by ffmpeg
+ * At this case AVQSVContext::ctl_struct points to this structure
+ */
+typedef struct QSVControl {
+    int        ref_count;
 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
     int        fd_display;
     VADisplay  va_display;
 #endif
-} QSVSession;
+} QSVControl;
 
 /**
  * Convert a libmfx error code into a ffmpeg error code.
@@ -75,8 +79,8 @@ int ff_qsv_error(int mfx_err);
 
 int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id);
 
-int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
+int ff_qsv_init_av_qsv_context(AVCodecContext *avctx, AVQSVContext** av_qsv,
                                  const char *load_plugins);
-int ff_qsv_close_internal_session(QSVSession *qs);
+int ff_qsv_release_av_qsv_context(AVCodecContext *avctx, AVQSVContext** av_qsv);
 
 #endif /* AVCODEC_QSV_INTERNAL_H */
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 9fefc41..e992a8f 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -58,25 +58,11 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt
                                        AV_PIX_FMT_NV12,
                                        AV_PIX_FMT_NONE };
 
-    q->iopattern  = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
-    if (!q->session) {
-        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) {
-            ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
-                                               q->load_plugins);
-            if (ret < 0)
-                return ret;
+    ret = ff_qsv_init_av_qsv_context(avctx, &q->av_qsv, q->load_plugins);
+    if (ret < 0)
+        return ret;
 
-            q->session = q->internal_qs.session;
-        }
-    }
+    q->av_qsv->iopattern  = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
 
     if (avpkt->size) {
         bs.Data       = avpkt->data;
@@ -94,7 +80,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt
 
     param.mfx.CodecId = ret;
 
-    ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, &param);
+    ret = MFXVideoDECODE_DecodeHeader(q->av_qsv->session, &bs, &param);
     if (MFX_ERR_MORE_DATA==ret) {
         /* this code means that header not found so we return packet size to skip
            a current packet
@@ -104,14 +90,14 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt
         av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
         return ff_qsv_error(ret);
     }
-    param.IOPattern   = q->iopattern;
+    param.IOPattern   = q->av_qsv->iopattern;
     param.AsyncDepth  = q->async_depth;
-    param.ExtParam    = q->ext_buffers;
-    param.NumExtParam = q->nb_ext_buffers;
+    param.ExtParam    = q->av_qsv->ext_buffers;
+    param.NumExtParam = q->av_qsv->nb_ext_buffers;
     param.mfx.FrameInfo.BitDepthLuma   = 8;
     param.mfx.FrameInfo.BitDepthChroma = 8;
 
-    ret = MFXVideoDECODE_Init(q->session, &param);
+    ret = MFXVideoDECODE_Init(q->av_qsv->session, &param);
     if (ret < 0) {
         if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
             av_log(avctx, AV_LOG_ERROR,
@@ -293,8 +279,8 @@ static void close_decoder(QSVContext *q)
 {
     QSVFrame *cur;
 
-    if (q->session)
-        MFXVideoDECODE_Close(q->session);
+    if (q->av_qsv && q->av_qsv->session)
+        MFXVideoDECODE_Close(q->av_qsv->session);
 
     cur = q->work_frames;
     while (cur) {
@@ -353,8 +339,8 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
         if (ret < 0)
             return ret;
         do {
-            ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
-                                                  insurf, &outsurf, &sync);
+            ret = MFXVideoDECODE_DecodeFrameAsync(q->av_qsv->session,
+                          flush ? NULL : &bs, insurf, &outsurf, &sync);
             if (ret != MFX_WRN_DEVICE_BUSY)
                 break;
             av_usleep(500);
@@ -415,7 +401,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,
         av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);
         out_frame->queued = 0;
 
-        MFXVideoCORE_SyncOperation(q->session, sync, 60000);
+        MFXVideoCORE_SyncOperation(q->av_qsv->session, sync, 60000);
 
         src_frame = out_frame->frame;
 
@@ -531,12 +517,12 @@ void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
     if (q->reinit_pending) {
         close_decoder(q);
     } else if (q->engine_ready) {
-        ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
+        ret = MFXVideoDECODE_GetVideoParam(q->av_qsv->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);
+        ret = MFXVideoDECODE_Reset(q->av_qsv->session, &param);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
         }
@@ -564,13 +550,11 @@ void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
     av_fifo_reset(q->input_fifo);
 }
 
-int ff_qsv_decode_close(QSVContext *q)
+int ff_qsv_decode_close(AVCodecContext *avctx, QSVContext *q)
 {
     close_decoder(q);
 
-    q->session = NULL;
-
-    ff_qsv_close_internal_session(&q->internal_qs);
+    ff_qsv_release_av_qsv_context(avctx, &q->av_qsv);
 
     av_fifo_free(q->async_fifo);
     q->async_fifo = NULL;
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 97a3315..41d8b38 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -36,12 +36,7 @@
 #include "qsv_internal.h"
 
 typedef struct QSVContext {
-    // the session used for decoding
-    mfxSession session;
-
-    // the session we allocated internally, in case the caller did not provide
-    // one
-    QSVSession internal_qs;
+    AVQSVContext* av_qsv;
 
     /**
      * a linked list of frames currently being used by QSV
@@ -68,12 +63,8 @@ typedef struct QSVContext {
 
     // options set by the caller
     int async_depth;
-    int iopattern;
 
     char *load_plugins;
-
-    mfxExtBuffer **ext_buffers;
-    int         nb_ext_buffers;
 } QSVContext;
 
 int ff_qsv_map_pixfmt(enum AVPixelFormat format);
@@ -84,6 +75,6 @@ int ff_qsv_decode(AVCodecContext *s, QSVContext *q,
 
 void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q);
 
-int ff_qsv_decode_close(QSVContext *q);
+int ff_qsv_decode_close(AVCodecContext *avctx, QSVContext *q);
 
 #endif /* AVCODEC_QSVDEC_H */
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index 92b4109..f9b17f4 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -55,7 +55,7 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx)
 {
     QSVH2645Context *s = avctx->priv_data;
 
-    ff_qsv_decode_close(&s->qsv);
+    ff_qsv_decode_close(avctx, &s->qsv);
 
     av_bitstream_filter_close(s->bsf);
 
diff --git a/libavcodec/qsvdec_mpeg2.c b/libavcodec/qsvdec_mpeg2.c
index d9052e0..05e6d97 100644
--- a/libavcodec/qsvdec_mpeg2.c
+++ b/libavcodec/qsvdec_mpeg2.c
@@ -36,7 +36,7 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx)
 {
     QSVMPEG2Context *s = avctx->priv_data;
 
-    ff_qsv_decode_close(&s->qsv);
+    ff_qsv_decode_close(avctx, &s->qsv);
 
     return 0;
 }
diff --git a/libavcodec/qsvdec_vc1.c b/libavcodec/qsvdec_vc1.c
index fcf101f..4bcd16b 100644
--- a/libavcodec/qsvdec_vc1.c
+++ b/libavcodec/qsvdec_vc1.c
@@ -38,7 +38,7 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx)
 {
     QSVVC1Context *s = avctx->priv_data;
 
-    ff_qsv_decode_close(&s->qsv);
+    ff_qsv_decode_close(avctx, &s->qsv);
 
     return 0;
 }
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 55140e1..c13c10c 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -207,7 +207,7 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
     q->param.ExtParam    = ext_buffers;
     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
 
-    ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
+    ret = MFXVideoENCODE_GetVideoParam(q->av_qsv->session, &q->param);
     if (ret < 0)
         return ff_qsv_error(ret);
 
@@ -244,27 +244,15 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
     if (!q->async_fifo)
         return AVERROR(ENOMEM);
 
-    if (avctx->hwaccel_context) {
-        AVQSVContext *qsv = avctx->hwaccel_context;
-
-        q->session         = qsv->session;
-        q->param.IOPattern = qsv->iopattern;
-    }
-
-    if (!q->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;
-    }
+    ret = ff_qsv_init_av_qsv_context(avctx, &q->av_qsv, q->load_plugins);
+    if (ret < 0)
+        return ret;
 
     ret = init_video_param(avctx, q);
     if (ret < 0)
         return ret;
 
-    ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
+    ret = MFXVideoENCODE_Query(q->av_qsv->session, &q->param,&q->param);
     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
     } else if (ret < 0) {
@@ -272,13 +260,13 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
         return ff_qsv_error(ret);
     }
 
-    ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
+    ret = MFXVideoENCODE_QueryIOSurf(q->av_qsv->session, &q->param, &q->req);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
         return ff_qsv_error(ret);
     }
 
-    ret = MFXVideoENCODE_Init(q->session, &q->param);
+    ret = MFXVideoENCODE_Init(q->av_qsv->session, &q->param);
     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
     } else if (ret < 0) {
@@ -455,7 +443,7 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
     bs->MaxLength = new_pkt.size;
 
     do {
-        ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
+        ret = MFXVideoENCODE_EncodeFrameAsync(q->av_qsv->session, NULL, surf, bs, &sync);
         if (ret == MFX_WRN_DEVICE_BUSY) {
             av_usleep(500);
             continue;
@@ -494,7 +482,7 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
 
-        MFXVideoCORE_SyncOperation(q->session, sync, 60000);
+        MFXVideoCORE_SyncOperation(q->av_qsv->session, sync, 60000);
 
         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
@@ -545,11 +533,10 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
 {
     QSVFrame *cur;
 
-    if (q->session)
-        MFXVideoENCODE_Close(q->session);
-    q->session = NULL;
+    if (q->av_qsv->session)
+        MFXVideoENCODE_Close(q->av_qsv->session);
 
-    ff_qsv_close_internal_session(&q->internal_qs);
+    ff_qsv_release_av_qsv_context(avctx, &q->av_qsv);
 
     cur = q->work_frames;
     while (cur) {
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 2a21f82..2fd8417 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -37,10 +37,9 @@
 typedef struct QSVEncContext {
     AVCodecContext *avctx;
 
-    QSVFrame *work_frames;
+    AVQSVContext* av_qsv;
 
-    mfxSession session;
-    QSVSession internal_qs;
+    QSVFrame *work_frames;
 
     int packet_size;
     int width_align;
-- 
1.8.3.1

