diff --git a/src/media/video/v4l2/vaapi.cpp b/src/media/video/v4l2/vaapi.cpp index 3d3cec3b8d63584c0f5948031707ac8f66fa93c8..003d1d5cab7377f8294e1e373181d5aaa5a5561d 100644 --- a/src/media/video/v4l2/vaapi.cpp +++ b/src/media/video/v4l2/vaapi.cpp @@ -27,6 +27,8 @@ #include "video/v4l2/vaapi.h" #include "video/accel.h" +#include "fileutils.h" + #include <sstream> #include <stdexcept> #include <map> @@ -94,6 +96,30 @@ VaapiAccel::extractData(AVCodecContext* codecCtx, VideoFrame& container) bool VaapiAccel::init(AVCodecContext* codecCtx) +{ +#ifdef HAVE_VAAPI_ACCEL_DRM + // try all possible devices, use first one that works + const std::string path = "/dev/dri/"; + for (auto& entry : ring::fileutils::readDirectory(path)) { + // a drm device is either a card or a render node, check both + const std::string prefixCard = "card"; + if (!entry.compare(0, prefixCard.size(), prefixCard.c_str())) + if (open(codecCtx, path + entry)) + return true; + + const std::string prefixNode = "renderD"; + if (!entry.compare(0, prefixNode.size(), prefixNode.c_str())) + if (open(codecCtx, path + entry)) + return true; + } + return false; +#elif HAVE_VAAPI_ACCEL_X11 + return open(codecCtx, ":0"); // this is the default x11 device +#endif +} + +bool +VaapiAccel::open(AVCodecContext* codecCtx, std::string deviceName) { vaProfile_ = VAProfileNone; vaEntryPoint_ = VAEntrypointVLD; @@ -121,16 +147,9 @@ VaapiAccel::init(AVCodecContext* codecCtx) }; VAStatus status; - -#ifdef HAVE_VAAPI_ACCEL_DRM - const char* deviceName = "/dev/dri/card0"; // check for renderDX first? -#else - const char* deviceName = nullptr; // use default device -#endif - AVBufferRef* hardwareDeviceCtx; - if (av_hwdevice_ctx_create(&hardwareDeviceCtx, AV_HWDEVICE_TYPE_VAAPI, deviceName, nullptr, 0) < 0) { - RING_ERR("Failed to create VAAPI device"); + if (av_hwdevice_ctx_create(&hardwareDeviceCtx, AV_HWDEVICE_TYPE_VAAPI, deviceName.c_str(), nullptr, 0) < 0) { + RING_ERR("Failed to create VAAPI device using %s", deviceName.c_str()); av_buffer_unref(&hardwareDeviceCtx); return false; } @@ -216,7 +235,7 @@ VaapiAccel::init(AVCodecContext* codecCtx) return false; } - RING_DBG("VAAPI decoder initialized"); + RING_DBG("VAAPI decoder initialized via device: %s", deviceName.c_str()); ffmpegAccelCtx_.display = hardwareContext->display; ffmpegAccelCtx_.config_id = vaConfig_; diff --git a/src/media/video/v4l2/vaapi.h b/src/media/video/v4l2/vaapi.h index 989f26731767b8d61d4effe2dc94bc9e0279ecb1..249422f1b419db74e0840f9f9579ffda4204be56 100644 --- a/src/media/video/v4l2/vaapi.h +++ b/src/media/video/v4l2/vaapi.h @@ -76,6 +76,8 @@ class VaapiAccel : public HardwareAccel { VAContextID vaContext_; struct vaapi_context ffmpegAccelCtx_; + + bool open(AVCodecContext* codecCtx, std::string deviceName); }; }} // namespace ring::video