]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/pthread.c
linux: use number of CPUs as automatic thread count
[ffmpeg] / libavcodec / pthread.c
index ac15fefd683aad72a30087df13f8e3d524545e23..1800f291d738aa97c8f1684399bbf58b8a184938 100644 (file)
  */
 
 #include "config.h"
+
+#if HAVE_SCHED_GETAFFINITY
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+
 #include "avcodec.h"
 #include "internal.h"
 #include "thread.h"
@@ -133,6 +139,29 @@ typedef struct FrameThreadContext {
     int die;                       ///< Set when threads should exit.
 } FrameThreadContext;
 
+
+/* H264 slice threading seems to be buggy with more than 16 threads,
+ * limit the number of threads to 16 for automatic detection */
+#define MAX_AUTO_THREADS 16
+
+static int get_logical_cpus(AVCodecContext *avctx)
+{
+    int ret, nb_cpus = 1;
+#if HAVE_SCHED_GETAFFINITY
+    cpu_set_t cpuset;
+
+    CPU_ZERO(&cpuset);
+
+    ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
+    if (!ret) {
+        nb_cpus = CPU_COUNT(&cpuset);
+    }
+#endif
+    av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+    return FFMIN(nb_cpus, MAX_AUTO_THREADS);
+}
+
+
 static void* attribute_align_arg worker(void *v)
 {
     AVCodecContext *avctx = v;
@@ -237,6 +266,13 @@ static int thread_init(AVCodecContext *avctx)
     ThreadContext *c;
     int thread_count = avctx->thread_count;
 
+    if (!thread_count) {
+        int nb_cpus = get_logical_cpus(avctx);
+        // use number of cores + 1 as thread count if there is motre than one
+        if (nb_cpus > 1)
+            thread_count = avctx->thread_count = nb_cpus + 1;
+    }
+
     if (thread_count <= 1) {
         avctx->active_thread_type = 0;
         return 0;
@@ -697,6 +733,13 @@ static int frame_thread_init(AVCodecContext *avctx)
     FrameThreadContext *fctx;
     int i, err = 0;
 
+    if (!thread_count) {
+        int nb_cpus = get_logical_cpus(avctx);
+        // use number of cores + 1 as thread count if there is motre than one
+        if (nb_cpus > 1)
+            thread_count = avctx->thread_count = nb_cpus + 1;
+    }
+
     if (thread_count <= 1) {
         avctx->active_thread_type = 0;
         return 0;