summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Lambers <marlam@marlam.de>2010-11-28 18:37:27 +0100
committerMartin Lambers <marlam@marlam.de>2010-11-28 18:37:27 +0100
commit4e87aef9d7840d2b387e7efd932908a33057bd84 (patch)
tree36ff203dca7fc7cbcbadbe45d6fa6626edb177f1
parent4d066fa853d025e960ac097234596b92103ec1d1 (diff)
downloadbino-4e87aef9d7840d2b387e7efd932908a33057bd84.tar.gz
Decoder: enable multithreaded decoding.
Always use as many decoding threads for video as there are processors in the system.
-rw-r--r--configure.ac1
-rw-r--r--src/decoder_ffmpeg.cpp37
2 files changed, 38 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 1c1bdf7..b41f7bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,6 +58,7 @@ if test "$HAVE_LIBSWSCALE" != "1"; then
AC_MSG_WARN([$libswscale_PKG_ERRORS])
AC_MSG_WARN([libswscale is provided by ffmpeg; Debian package: libswscale-dev])
fi
+AC_CHECK_FUNCS([sysconf])
dnl OpenAL
PKG_CHECK_MODULES([libopenal], [openal >= 0.0], [HAVE_LIBOPENAL=1], [HAVE_LIBOPENAL=0])
diff --git a/src/decoder_ffmpeg.cpp b/src/decoder_ffmpeg.cpp
index c471edc..e2e765a 100644
--- a/src/decoder_ffmpeg.cpp
+++ b/src/decoder_ffmpeg.cpp
@@ -33,6 +33,12 @@ extern "C"
#include <cerrno>
#include <cstring>
+#if HAVE_SYSCONF
+# include <unistd.h>
+#else
+# include <windows.h>
+#endif
+
#include "debug.h"
#include "blob.h"
#include "exc.h"
@@ -79,6 +85,31 @@ static std::string my_av_strerror(int err)
return std::string(b.ptr<const char>());
}
+static int decoding_threads()
+{
+ // Use one decoding thread per processor.
+ static long n = -1;
+ if (n < 0)
+ {
+#ifdef HAVE_SYSCONF
+ n = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ n = si.dwNumberOfProcessors;
+#endif
+ if (n < 1)
+ {
+ n = 1;
+ }
+ else if (n > 64)
+ {
+ n = 64;
+ }
+ }
+ return n;
+}
+
static void my_av_log(void *ptr, int level, const char *fmt, va_list vl)
{
static std::string line;
@@ -201,6 +232,11 @@ void decoder_ffmpeg::open(const std::string &filename)
{
throw exc(filename + " stream " + str::from(i) + ": invalid frame size");
}
+ _stuff->video_codec_ctxs[j]->thread_count = decoding_threads();
+ if (avcodec_thread_init(_stuff->video_codec_ctxs[j], _stuff->video_codec_ctxs[j]->thread_count) != 0)
+ {
+ _stuff->video_codec_ctxs[j]->thread_count = 1;
+ }
_stuff->video_codecs.push_back(avcodec_find_decoder(_stuff->video_codec_ctxs[j]->codec_id));
if (!_stuff->video_codecs[j])
{
@@ -318,6 +354,7 @@ void decoder_ffmpeg::open(const std::string &filename)
static_cast<float>(video_frame_rate_numerator(i))
/ static_cast<float>(video_frame_rate_denominator(i)),
video_duration(i) / 1e6f);
+ msg::inf(" using up to %d threads for decoding", _stuff->video_codec_ctxs.at(i)->thread_count);
}
for (int i = 0; i < audio_streams(); i++)
{