aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md12
-rw-r--r--TODO10
-rw-r--r--meson.build12
-rw-r--r--meson_options.txt2
-rw-r--r--project.conf2
-rw-r--r--src/codec_query/nvenc.c40
-rw-r--r--src/pipewire_audio.c3
7 files changed, 70 insertions, 11 deletions
diff --git a/README.md b/README.md
index 56cd972..d8dc8d5 100644
--- a/README.md
+++ b/README.md
@@ -31,8 +31,9 @@ This software works on X11 and Wayland on AMD, Intel and NVIDIA.
# Installation
If you are running an Arch Linux based distro then you can find gpu screen recorder in the official repositories under the name gpu-screen-recorder (`sudo pacman -S gpu-screen-recorder`).\
If you are running another distro then you can run `sudo ./install.sh`, but you need to manually install the dependencies, as described below.\
-You can also install gpu screen recorder ([the ui version](https://git.dec05eba.com/gpu-screen-recorder-gtk/)) from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder), which is the easiest method
-to install GPU Screen Recorder on non-arch based distros.\
+When you run `install.sh` it will build FFmpeg from source, which can take a while. You can build GPU Screen Recorder from source without building FFmpeg if you setup the meson project with the `-Dffmpeg_static=false` option, for example: `meson setup --buildtype=release -Dffmpeg_static=false -Dstrip=true build`.\
+You can also install GPU Screen Recorder from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder), which is the easiest method
+to install GPU Screen Recorder on non-arch based distros (it includes both this cli and the [UI version](https://git.dec05eba.com/gpu-screen-recorder-ui/about/)).\
You can alternatively install GPU Screen Recorder from one of the unofficial sources mentioned below.\
If you install GPU Screen Recorder flatpak, which is the ui version then you can still run GPU Screen Recorder command line by using the flatpak command option, for example `flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder -w screen -f 60 -o video.mp4`. Note that if you want to record your monitor on AMD/Intel then you need to install the flatpak system-wide (like so: `flatpak install --system com.dec05eba.gpu_screen_recorder`).
@@ -59,7 +60,7 @@ These are the dependencies needed to build GPU Screen Recorder:
* x11 (libx11, libxcomposite, libxrandr, libxfixes, libxdamage)
* wayland (wayland-client, wayland-egl, wayland-scanner)
-* ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter)
+* ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter) - Only needed if you build GPU Screen Recorder with `-Dffmpeg_static=false` meson option
* libva (and libva-drm)
* libpulse
* libdrm
@@ -228,6 +229,7 @@ Note: this issue doesn't happen when you using the vulkan video encoding option
## TEMPORARY ISSUES
1) Videos are in variable framerate format. Use MPV to play such videos, otherwise you might experience stuttering in the video if you are using a buggy video player. You can try saving the video into a .mkv file instead as some software may have better support for .mkv files (such as kdenlive). You can use the "-fm cfr" option to to use constant framerate mode.
2) FLAC audio codec is disabled at the moment because of temporary issues.
+3) Capturing webcam doesn't work on nvidia x11 when capturing a monitor at the same time.
# Examples
Look at the [scripts](https://git.dec05eba.com/gpu-screen-recorder/tree/scripts) directory for script examples. For example if you want to automatically save a recording/replay into a folder with the same name as the game you are recording.
@@ -256,7 +258,7 @@ See [https://git.dec05eba.com/?p=about](https://git.dec05eba.com/?p=about).
Some linux distros (such as manjaro and fedora) disable hardware accelerated h264/hevc on AMD/Intel because of "patent license issues". If you are using an arch-based distro then you can install mesa-git instead of mesa and if you are using another distro then you may have to switch to a better distro. On fedora based distros you can follow this: [Hardware Accelerated Codec](https://rpmfusion.org/Howto/Multimedia).\
You can alternatively install the flatpak version of GPU Screen Recorder from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder) which doesn't have this issue on any distro.
## I have an old nvidia GPU that supports nvenc but I get a cuda error when trying to record
-Newer ffmpeg versions don't support older nvidia cards. Try installing GPU Screen Recorder flatpak from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder) instead. It comes with a custom version of ffmpeg to support older nvidia GPUs.
+Newer ffmpeg versions don't support older nvidia cards. Try installing GPU Screen Recorder flatpak from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder) instead or use the [AppImage](https://github.com/pkgforge-dev/gpu-screen-recorder-AppImage/releases), which uses a custom version of ffmpeg to support older nvidia gpus. Alternatively you can build GPU Screen Recorder from source, which builds ffmpeg from source with a patch to support older nvidia gpus.
## I get a black screen/glitches while live streaming
It seems like ffmpeg earlier than version 6.1 has some type of bug. Install ffmpeg version 6.1 or later and then reinstall GPU Screen Recorder to fix this issue. The flatpak version of GPU Screen Recorder comes with a newer version of ffmpeg so no extra steps are needed.
## I can't play the video in my browser directly or in discord
@@ -326,3 +328,5 @@ This is a hyprland bug. Capture the monitor directly with `-w monitor` or use an
This is a bug in COSMIC and Wlroots. Their desktop portals send frame updates at low framerates (such as 25 fps) instead of the selected framerate (such as 60 fps). Capture a monitor directly instead (`-w DP-1` for example) to workaround that problem.
## How to adjust the volume of the recorded audio?
GPU Screen Recorder doesn't have the option to do that yet, but you can change the volume by starting recording and then open `pavucontrol`, go to the `Recording` tab and set the volume there. The system will remember the settings even after reboot, as long as the audio capture options remain the same.
+## My game and recorded video is stuttering but my frame rate is high
+This is an issue with linux kernel graphics scheduling when the gpu usage is 99-100%. The only fix available at the moment is to run X11 with the compositor disabled. There is no known fix on Wayland at the moment. Hopefully this issue will be fixed in linux soon.
diff --git a/TODO b/TODO
index 207f5a3..79a57a9 100644
--- a/TODO
+++ b/TODO
@@ -395,8 +395,6 @@ Add option to capture all monitors automatically.
Make -w optional, to only capture audio.
-Use GL_RGBA16F or GL_RGBA32F for hdr, that allows color values to be outside the 0.0 to 1.0 range.
-
https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_surface_SMPTE2086_metadata.txt
Doesn't work: sibs run --args -w "/dev/video0;camera_width=800;camera_height=600;pixfmt=yuyv" -fm content -o video.mp4
@@ -431,3 +429,11 @@ Take color pipeline into consideration in kms hdr capture. Right now kde only us
Maybe use 3D LUT for hdr tonemapping instead of per fragment math.
Update cuda to the use the same device as the opengl context (egl device).
+
+List all available drm monitors on wayland (from any device) and select the gpu to record with based on the device attached to the monitor.
+ Do this by modifying the for_each_active_monitor_output to also return the device associated with the monitor.
+
+Support capturing directly in tty by using gbm to open the device instead of using x11/wayland.
+ It cant work on pre-gbm nvidia gpus, but eh; they cant run anything except x11 anyways.
+
+In application audio, list all pipewire clients instead of nodes that we can capture. That way we can list applications to capture in --list-application-audio before they start playing audio.
diff --git a/meson.build b/meson.build
index 5a514fe..ae02d56 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('gpu-screen-recorder', 'c', version : '6.0.0', default_options : ['c_std=gnu11', 'warning_level=2'])
+project('gpu-screen-recorder', 'c', version : '6.0.1', default_options : ['c_std=gnu11', 'warning_level=2'])
add_project_arguments('-Wshadow', language : 'c')
if get_option('buildtype') == 'debug'
@@ -73,9 +73,17 @@ src += protocol_src
cc = meson.get_compiler('c')
m_dep = cc.find_library('m', required : true)
+ffmpeg_static_option = get_option('ffmpeg_static')
+if ffmpeg_static_option == 'auto'
+ ffmpeg_static = get_option('buildtype') == 'release'
+else
+ ffmpeg_static = ffmpeg_static_option == 'true'
+endif
+
# Overrides the libav* dependencies below with a statically linked ffmpeg built from source.
-if get_option('ffmpeg_static') == true
+if ffmpeg_static
subproject('ffmpeg')
+ add_project_arguments('-DGSR_FFMPEG_STATIC', language : 'c')
endif
dep = [
diff --git a/meson_options.txt b/meson_options.txt
index 23751b6..74f5bb0 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,4 +4,4 @@ option('nvidia_suspend_fix', type : 'boolean', value : true, description : 'Inst
option('portal', type : 'boolean', value : true, description : 'Build with support for xdg desktop portal ScreenCast capture (wayland only) (-w portal option). Requires pipewire')
option('app_audio', type : 'boolean', value : true, description : 'Build with support for recording a single audio source (-a app: option). Requires pipewire')
option('plugin_examples', type : 'boolean', value : false, description : 'Build plugin examples')
-option('ffmpeg_static', type : 'boolean', value : false, description : 'Download and build a minimal ffmpeg and the libraries it depends on from source with lto and link them statically into gpu-screen-recorder instead of using the system ffmpeg. Requires make, nasm, cmake and perl')
+option('ffmpeg_static', type : 'combo', choices : ['auto', 'true', 'false'], value : 'auto', description : 'Download and build a minimal ffmpeg and the libraries it depends on from source with lto and link them statically into gpu-screen-recorder instead of using the system ffmpeg. Requires make, nasm, cmake and perl. Set to auto to enable this in release builds and disable it in every other build type')
diff --git a/project.conf b/project.conf
index 47e993b..d22af59 100644
--- a/project.conf
+++ b/project.conf
@@ -1,7 +1,7 @@
[package]
name = "gpu-screen-recorder"
type = "executable"
-version = "6.0.0"
+version = "6.0.1"
platforms = ["posix"]
[config]
diff --git a/src/codec_query/nvenc.c b/src/codec_query/nvenc.c
index 4416b91..ad7acac 100644
--- a/src/codec_query/nvenc.c
+++ b/src/codec_query/nvenc.c
@@ -6,11 +6,21 @@
#include <dlfcn.h>
#include <string.h>
+#include <libavcodec/version.h>
+
#define NVENCAPI_MAJOR_VERSION_470 11
#define NVENCAPI_MINOR_VERSION_470 1
#define NVENCAPI_VERSION_470 (NVENCAPI_MAJOR_VERSION_470 | (NVENCAPI_MINOR_VERSION_470 << 24))
#define NVENCAPI_STRUCT_VERSION_CUSTOM(nvenc_api_version, struct_version) ((uint32_t)(nvenc_api_version) | ((struct_version)<<16) | (0x7 << 28))
+#define NVENCAPI_PACKED_VERSION(major, minor) (((major) << 4) | (minor))
+
+#if defined(GSR_FFMPEG_STATIC) || LIBAVCODEC_VERSION_MAJOR < 63
+#define FFMPEG_REQUIRED_NVENC_API_VERSION 0
+#else
+#define FFMPEG_REQUIRED_NVENC_API_VERSION NVENCAPI_PACKED_VERSION(13, 1)
+#endif
+
static void* open_nvenc_library(void) {
dlerror(); /* clear */
void *lib = dlopen("libnvidia-encode.so.1", RTLD_LAZY);
@@ -188,6 +198,33 @@ static bool get_supported_video_codecs(const NV_ENCODE_API_FUNCTION_LIST *functi
return success;
}
+static bool nvenc_driver_supports_ffmpeg_nvenc_api_version(void *nvenc_lib) {
+ if(FFMPEG_REQUIRED_NVENC_API_VERSION == 0)
+ return true;
+
+ typedef NVENCSTATUS NVENCAPI (*FUNC_NvEncodeAPIGetMaxSupportedVersion)(uint32_t *version);
+ FUNC_NvEncodeAPIGetMaxSupportedVersion nvEncodeAPIGetMaxSupportedVersion = (FUNC_NvEncodeAPIGetMaxSupportedVersion)dlsym(nvenc_lib, "NvEncodeAPIGetMaxSupportedVersion");
+ if(!nvEncodeAPIGetMaxSupportedVersion) {
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: failed to find NvEncodeAPIGetMaxSupportedVersion in libnvidia-encode.so");
+ return false;
+ }
+
+ uint32_t driver_nvenc_api_version = 0;
+ if(nvEncodeAPIGetMaxSupportedVersion(&driver_nvenc_api_version) != NV_ENC_SUCCESS) {
+ gsr_log(GSR_LOG_LEVEL_ERROR, "gsr_get_supported_video_codecs_nvenc: NvEncodeAPIGetMaxSupportedVersion failed");
+ return false;
+ }
+
+ if(driver_nvenc_api_version < FFMPEG_REQUIRED_NVENC_API_VERSION) {
+ gsr_log(GSR_LOG_LEVEL_WARNING, "gsr_get_supported_video_codecs_nvenc: your nvidia driver only supports nvenc api version %u.%u, but the FFmpeg version that GPU Screen Recorder uses requires nvenc api version %u.%u. Update your nvidia driver or use an older FFmpeg version to record with nvenc",
+ driver_nvenc_api_version >> 4, driver_nvenc_api_version & 0xf,
+ (uint32_t)FFMPEG_REQUIRED_NVENC_API_VERSION >> 4, (uint32_t)FFMPEG_REQUIRED_NVENC_API_VERSION & 0xf);
+ return false;
+ }
+
+ return true;
+}
+
bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_codecs, bool cleanup) {
memset(video_codecs, 0, sizeof(*video_codecs));
@@ -206,6 +243,9 @@ bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_code
if(!nvenc_lib)
goto done;
+ if(!nvenc_driver_supports_ffmpeg_nvenc_api_version(nvenc_lib))
+ goto done;
+
typedef NVENCSTATUS NVENCAPI (*FUNC_NvEncodeAPICreateInstance)(NV_ENCODE_API_FUNCTION_LIST *functionList);
FUNC_NvEncodeAPICreateInstance nvEncodeAPICreateInstance = (FUNC_NvEncodeAPICreateInstance)dlsym(nvenc_lib, "NvEncodeAPICreateInstance");
if(!nvEncodeAPICreateInstance) {
diff --git a/src/pipewire_audio.c b/src/pipewire_audio.c
index 8f40695..f4d2b27 100644
--- a/src/pipewire_audio.c
+++ b/src/pipewire_audio.c
@@ -447,7 +447,8 @@ static void on_node_info_cb(void *data, const struct pw_node_info *info) {
if(!info || !info->props || !self->running)
return;
- const char *node_name = spa_dict_lookup(info->props, PW_KEY_NODE_NAME);
+ const char *app_name = spa_dict_lookup(info->props, PW_KEY_APP_NAME);
+ const char *node_name = app_name ? app_name : spa_dict_lookup(info->props, PW_KEY_NODE_NAME);
if(!node_name)
return;