aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Uskov <ivan.uskov@nablet.com>2015-07-13 10:17:54 -0400
committerMichael Niedermayer <michael@niedermayer.cc>2015-07-14 02:02:55 +0200
commitce91bab70f69acc1a7e5705af95cc6fa89765825 (patch)
treed2464e5c989adee7fc0278ae0cdef042fd80459a
parent96e1cc3f8b6b0b5b19820609b23642bde1ee7e7c (diff)
downloadffmpeg-ce91bab70f69acc1a7e5705af95cc6fa89765825.tar.gz
libavcodec/qsv.c: Issue fixed: QSV engine does not release display handler under linux platform.
Reviewed-by: Gwenole Beauchesne <gb.devel@gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/qsv.c38
-rw-r--r--libavcodec/qsv_internal.h11
-rw-r--r--libavcodec/qsvdec.c10
-rw-r--r--libavcodec/qsvdec.h2
-rw-r--r--libavcodec/qsvenc.c11
-rw-r--r--libavcodec/qsvenc.h2
6 files changed, 52 insertions, 22 deletions
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 697af872a6..4c8e6b01a9 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -85,7 +85,7 @@ int ff_qsv_error(int mfx_err)
return AVERROR_UNKNOWN;
}
}
-static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
+static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
{
// this code is only required for Linux. It searches for a valid
// display handle. First in /dev/dri/renderD then in /dev/dri/card
@@ -99,6 +99,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
char adapterpath[256];
int adapter_num;
+ qs->fd_display = -1;
+ qs->va_display = NULL;
+
//search for valid graphics device
for (adapter_num = 0;adapter_num < 6;adapter_num++) {
@@ -135,7 +138,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
} else {
av_log(avctx, AV_LOG_VERBOSE,
"mfx initialization: %s vaInitialize successful\n",adapterpath);
- ret = MFXVideoCORE_SetHandle(session,
+ qs->fd_display = fd;
+ qs->va_display = va_dpy;
+ ret = MFXVideoCORE_SetHandle(qs->session,
(mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR,
@@ -163,7 +168,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
* @param avctx ffmpeg metadata for this codec context
* @param session the MSDK session used
*/
-int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
+int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
const char *load_plugins)
{
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
@@ -172,17 +177,17 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
const char *desc;
int ret;
- ret = MFXInit(impl, &ver, session);
+ ret = MFXInit(impl, &ver, &qs->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, *session);
+ ret = ff_qsv_set_display_handle(avctx, qs);
if (ret < 0)
return ret;
- MFXQueryIMPL(*session, &impl);
+ MFXQueryIMPL(qs->session, &impl);
switch (MFX_IMPL_BASETYPE(impl)) {
case MFX_IMPL_SOFTWARE:
@@ -222,7 +227,7 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
}
- ret = MFXVideoUSER_Load(*session, &uid, 1);
+ ret = MFXVideoUSER_Load(qs->session, &uid, 1);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
plugin);
@@ -243,3 +248,22 @@ load_plugin_fail:
return 0;
}
+
+int ff_qsv_close_internal_session(QSVSession *qs)
+{
+ if (qs->session) {
+ MFXClose(qs->session);
+ qs->session = NULL;
+ }
+#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;
+ }
+#endif
+ return 0;
+}
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index ee48a0fb9d..3d949dc0fa 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -58,6 +58,14 @@ typedef struct QSVFrame {
struct QSVFrame *next;
} QSVFrame;
+typedef struct QSVSession {
+ mfxSession session;
+#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
+ int fd_display;
+ VADisplay va_display;
+#endif
+} QSVSession;
+
/**
* Convert a libmfx error code into a ffmpeg error code.
*/
@@ -65,7 +73,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, mfxSession *session,
+int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
const char *load_plugins);
+int ff_qsv_close_internal_session(QSVSession *qs);
#endif /* AVCODEC_QSV_INTERNAL_H */
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 67e8ef0ce5..52df028ce3 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -51,13 +51,13 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
{
if (!session) {
- if (!q->internal_session) {
- int ret = ff_qsv_init_internal_session(avctx, &q->internal_session, NULL);
+ if (!q->internal_qs.session) {
+ int ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, NULL);
if (ret < 0)
return ret;
}
- q->session = q->internal_session;
+ q->session = q->internal_qs.session;
} else {
q->session = session;
}
@@ -282,9 +282,7 @@ int ff_qsv_decode_close(QSVContext *q)
av_freep(&cur);
cur = q->work_frames;
}
-
- if (q->internal_session)
- MFXClose(q->internal_session);
+ ff_qsv_close_internal_session(&q->internal_qs);
return 0;
}
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 373cc72b2a..210e9a9786 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -40,7 +40,7 @@ typedef struct QSVContext {
// the session we allocated internally, in case the caller did not provide
// one
- mfxSession internal_session;
+ QSVSession internal_qs;
/**
* a linked list of frames currently being used by QSV
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 3f376399c9..576bf68e18 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -217,12 +217,12 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
}
if (!q->session) {
- ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
+ ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
q->load_plugins);
if (ret < 0)
return ret;
- q->session = q->internal_session;
+ q->session = q->internal_qs.session;
}
ret = init_video_param(avctx, q);
@@ -460,10 +460,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
QSVFrame *cur;
MFXVideoENCODE_Close(q->session);
- if (q->internal_session)
- MFXClose(q->internal_session);
- q->session = NULL;
- q->internal_session = NULL;
+ q->session = NULL;
+
+ ff_qsv_close_internal_session(&q->internal_qs);
cur = q->work_frames;
while (cur) {
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 8195d9b049..4789675290 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -39,7 +39,7 @@ typedef struct QSVEncContext {
QSVFrame *work_frames;
mfxSession session;
- mfxSession internal_session;
+ QSVSession internal_qs;
int packet_size;
int width_align;