qsvvpp: Perform full init only when needed
authorJoe Olivas <joseph.k.olivas@intel.com>
Sun, 2 Sep 2018 18:06:48 +0000 (20:06 +0200)
committerLuca Barbato <lu_zero@gentoo.org>
Tue, 4 Sep 2018 12:32:22 +0000 (12:32 +0000)
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 <joseph.k.olivas@intel.com>
Signed-off-by: Maxym Dmytrychenko <maxim.d33@gmail.com>
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
libavutil/hwcontext_qsv.c

index b3eb4a3..1887936 100644 (file)
 
 #include "config.h"
 
+#if HAVE_PTHREADS
+#include <pthread.h>
+#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)