From 642fd4769becc2f4827f8375a3d9e8edd2f5df77 Mon Sep 17 00:00:00 2001 From: Joe Olivas Date: Sun, 2 Sep 2018 20:06:48 +0200 Subject: qsvvpp: Perform full init only when needed Removing unused VPP sessions by initializing only when used in order to help reduce CPU utilization. Thanks to Maxym for the guidance. Signed-off-by: Joe Olivas Signed-off-by: Maxym Dmytrychenko Signed-off-by: Luca Barbato --- libavutil/hwcontext_qsv.c | 83 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 6 deletions(-) (limited to 'libavutil/hwcontext_qsv.c') diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index b3eb4a3ea6..1887936e33 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -23,6 +23,10 @@ #include "config.h" +#if HAVE_PTHREADS +#include +#endif + #if CONFIG_VAAPI #include "hwcontext_vaapi.h" #endif @@ -56,7 +60,13 @@ typedef struct QSVDeviceContext { typedef struct QSVFramesContext { mfxSession session_download; + int session_download_init; mfxSession session_upload; + int session_upload_init; +#if HAVE_PTHREADS + pthread_mutex_t session_lock; + pthread_cond_t session_cond; +#endif AVBufferRef *child_frames_ref; mfxFrameSurface1 *surfaces_internal; @@ -147,12 +157,19 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx) MFXClose(s->session_download); } s->session_download = NULL; + s->session_download_init = 0; if (s->session_upload) { MFXVideoVPP_Close(s->session_upload); MFXClose(s->session_upload); } s->session_upload = NULL; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_destroy(&s->session_lock); + pthread_cond_destroy(&s->session_cond); +#endif av_freep(&s->mem_ids); av_freep(&s->surface_ptrs); @@ -535,13 +552,16 @@ static int qsv_frames_init(AVHWFramesContext *ctx) s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId; } - ret = qsv_init_internal_session(ctx, &s->session_download, 0); - if (ret < 0) - return ret; + s->session_download = NULL; + s->session_upload = NULL; - ret = qsv_init_internal_session(ctx, &s->session_upload, 1); - if (ret < 0) - return ret; + s->session_download_init = 0; + s->session_upload_init = 0; + +#if HAVE_PTHREADS + pthread_mutex_init(&s->session_lock, NULL); + pthread_cond_init(&s->session_cond, NULL); +#endif return 0; } @@ -740,6 +760,32 @@ static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, mfxSyncPoint sync = NULL; mfxStatus err; + int ret = 0; + + while (!s->session_download_init && !s->session_download && !ret) { +#if HAVE_PTHREADS + if (pthread_mutex_trylock(&s->session_lock) == 0) { +#endif + if (!s->session_download_init) { + ret = qsv_init_internal_session(ctx, &s->session_download, 0); + if (s->session_download) + s->session_download_init = 1; + } +#if HAVE_PTHREADS + pthread_mutex_unlock(&s->session_lock); + pthread_cond_signal(&s->session_cond); + } else { + pthread_mutex_lock(&s->session_lock); + while (!s->session_download_init && !s->session_download) { + pthread_cond_wait(&s->session_cond, &s->session_lock); + } + pthread_mutex_unlock(&s->session_lock); + } +#endif + } + + if (ret < 0) + return ret; if (!s->session_download) { if (s->child_frames_ref) @@ -787,6 +833,31 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, mfxSyncPoint sync = NULL; mfxStatus err; + int ret; + + while (!s->session_upload_init && !s->session_upload && !ret) { +#if HAVE_PTHREADS + if (pthread_mutex_trylock(&s->session_lock) == 0) { +#endif + if (!s->session_upload_init) { + ret = qsv_init_internal_session(ctx, &s->session_upload, 1); + if (s->session_upload) + s->session_upload_init = 1; + } +#if HAVE_PTHREADS + pthread_mutex_unlock(&s->session_lock); + pthread_cond_signal(&s->session_cond); + } else { + pthread_mutex_lock(&s->session_lock); + while (!s->session_upload_init && !s->session_upload) { + pthread_cond_wait(&s->session_cond, &s->session_lock); + } + pthread_mutex_unlock(&s->session_lock); + } +#endif + } + if (ret < 0) + return ret; if (!s->session_upload) { if (s->child_frames_ref) -- cgit v1.2.3