Commit ce91bab7 authored by Ivan Uskov's avatar Ivan Uskov Committed by Michael Niedermayer

libavcodec/qsv.c: Issue fixed: QSV engine does not release display handler under linux platform.

Reviewed-by: 's avatarGwenole Beauchesne <gb.devel@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 96e1cc3f
...@@ -85,7 +85,7 @@ int ff_qsv_error(int mfx_err) ...@@ -85,7 +85,7 @@ int ff_qsv_error(int mfx_err)
return AVERROR_UNKNOWN; 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 // this code is only required for Linux. It searches for a valid
// display handle. First in /dev/dri/renderD then in /dev/dri/card // 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) ...@@ -99,6 +99,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
char adapterpath[256]; char adapterpath[256];
int adapter_num; int adapter_num;
qs->fd_display = -1;
qs->va_display = NULL;
//search for valid graphics device //search for valid graphics device
for (adapter_num = 0;adapter_num < 6;adapter_num++) { for (adapter_num = 0;adapter_num < 6;adapter_num++) {
...@@ -135,7 +138,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session) ...@@ -135,7 +138,9 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
} else { } else {
av_log(avctx, AV_LOG_VERBOSE, av_log(avctx, AV_LOG_VERBOSE,
"mfx initialization: %s vaInitialize successful\n",adapterpath); "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); (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
if (ret < 0) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
...@@ -163,7 +168,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session) ...@@ -163,7 +168,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
* @param avctx ffmpeg metadata for this codec context * @param avctx ffmpeg metadata for this codec context
* @param session the MSDK session used * @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) const char *load_plugins)
{ {
mfxIMPL impl = MFX_IMPL_AUTO_ANY; mfxIMPL impl = MFX_IMPL_AUTO_ANY;
...@@ -172,17 +177,17 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, ...@@ -172,17 +177,17 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
const char *desc; const char *desc;
int ret; int ret;
ret = MFXInit(impl, &ver, session); ret = MFXInit(impl, &ver, &qs->session);
if (ret < 0) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n");
return ff_qsv_error(ret); return ff_qsv_error(ret);
} }
ret = ff_qsv_set_display_handle(avctx, *session); ret = ff_qsv_set_display_handle(avctx, qs);
if (ret < 0) if (ret < 0)
return ret; return ret;
MFXQueryIMPL(*session, &impl); MFXQueryIMPL(qs->session, &impl);
switch (MFX_IMPL_BASETYPE(impl)) { switch (MFX_IMPL_BASETYPE(impl)) {
case MFX_IMPL_SOFTWARE: case MFX_IMPL_SOFTWARE:
...@@ -222,7 +227,7 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, ...@@ -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) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n", av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
plugin); plugin);
...@@ -243,3 +248,22 @@ load_plugin_fail: ...@@ -243,3 +248,22 @@ load_plugin_fail:
return 0; 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;
}
...@@ -58,6 +58,14 @@ typedef struct QSVFrame { ...@@ -58,6 +58,14 @@ typedef struct QSVFrame {
struct QSVFrame *next; struct QSVFrame *next;
} QSVFrame; } 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. * Convert a libmfx error code into a ffmpeg error code.
*/ */
...@@ -65,7 +73,8 @@ int ff_qsv_error(int mfx_err); ...@@ -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_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); const char *load_plugins);
int ff_qsv_close_internal_session(QSVSession *qs);
#endif /* AVCODEC_QSV_INTERNAL_H */ #endif /* AVCODEC_QSV_INTERNAL_H */
...@@ -51,13 +51,13 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format) ...@@ -51,13 +51,13 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format)
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session) static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
{ {
if (!session) { if (!session) {
if (!q->internal_session) { if (!q->internal_qs.session) {
int ret = ff_qsv_init_internal_session(avctx, &q->internal_session, NULL); int ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
q->session = q->internal_session; q->session = q->internal_qs.session;
} else { } else {
q->session = session; q->session = session;
} }
...@@ -282,9 +282,7 @@ int ff_qsv_decode_close(QSVContext *q) ...@@ -282,9 +282,7 @@ int ff_qsv_decode_close(QSVContext *q)
av_freep(&cur); av_freep(&cur);
cur = q->work_frames; cur = q->work_frames;
} }
ff_qsv_close_internal_session(&q->internal_qs);
if (q->internal_session)
MFXClose(q->internal_session);
return 0; return 0;
} }
...@@ -40,7 +40,7 @@ typedef struct QSVContext { ...@@ -40,7 +40,7 @@ typedef struct QSVContext {
// the session we allocated internally, in case the caller did not provide // the session we allocated internally, in case the caller did not provide
// one // one
mfxSession internal_session; QSVSession internal_qs;
/** /**
* a linked list of frames currently being used by QSV * a linked list of frames currently being used by QSV
......
...@@ -217,12 +217,12 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) ...@@ -217,12 +217,12 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
} }
if (!q->session) { 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); q->load_plugins);
if (ret < 0) if (ret < 0)
return ret; return ret;
q->session = q->internal_session; q->session = q->internal_qs.session;
} }
ret = init_video_param(avctx, q); ret = init_video_param(avctx, q);
...@@ -460,10 +460,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) ...@@ -460,10 +460,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
QSVFrame *cur; QSVFrame *cur;
MFXVideoENCODE_Close(q->session); MFXVideoENCODE_Close(q->session);
if (q->internal_session)
MFXClose(q->internal_session);
q->session = NULL; q->session = NULL;
q->internal_session = NULL;
ff_qsv_close_internal_session(&q->internal_qs);
cur = q->work_frames; cur = q->work_frames;
while (cur) { while (cur) {
......
...@@ -39,7 +39,7 @@ typedef struct QSVEncContext { ...@@ -39,7 +39,7 @@ typedef struct QSVEncContext {
QSVFrame *work_frames; QSVFrame *work_frames;
mfxSession session; mfxSession session;
mfxSession internal_session; QSVSession internal_qs;
int packet_size; int packet_size;
int width_align; int width_align;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment