Skip to content

Commit

Permalink
🐛 fix(base): Device selection patch for gpu-screen-recorder (#93)
Browse files Browse the repository at this point in the history
## Description

Adds new `-device` argument for gpu-screen-recorder which allows
specifying a GPU to use (by `/dev/dri/cardN` path)

This fixes an issue with multi-gpu systems when device such as
`/dev/dri/card1` is passed through but gpu-screen-recorder will still
try to access `/dev/dri/card0` for capturing and failing.

Added relevant bits to `gpu_helpers.sh` to find the card path - I assume
all modern modesetting drivers will have a `/drm/` path that tells the
card number. If not, the script will fall back to gpu-screen-recorder's
own method of finding the card.

Edit: Forgot to mention patches are now copied to /tmp/ rather than
/etc/

Co-authored-by: Kristian Ollikainen <[email protected]>
  • Loading branch information
DatCaptainHorse and DatCaptainHorse authored Jul 7, 2024
1 parent cf69f6c commit 3df53e7
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 3 deletions.
23 changes: 23 additions & 0 deletions .patches/devicearg.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/src/main.cpp b/src/main.cpp
index 112a6ac..57bd9bf 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1906,6 +1906,7 @@ int main(int argc, char **argv) {
{ "-gopm", Arg { {}, true, false } }, // deprecated, used keyint instead
{ "-keyint", Arg { {}, true, false } },
{ "-encoder", Arg { {}, true, false } },
+ { "-device", Arg { {}, true, false } },
};

for(int i = 1; i < argc; i += 2) {
@@ -2226,6 +2227,10 @@ int main(int argc, char **argv) {
overclock = false;
}

+ const char *dri_device = args["-device"].value();
+ if (dri_device)
+ egl.dri_card_path = dri_device;
+
egl.card_path[0] = '\0';
if(wayland || egl.gpu_info.vendor != GSR_GPU_VENDOR_NVIDIA) {
// TODO: Allow specifying another card, and in other places
12 changes: 11 additions & 1 deletion .scripts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ selected_gpu_vendor=$(get_gpu_vendor "$selected_gpu")
# Convert lshw gathered bus id into Xorg compatible one
xorg_bus_id=$(get_gpu_bus_xorg "$selected_gpu")

# Get GPU card path if available
selected_gpu_card=""
gpu_screen_recorder_device_arg=""

card_result=$(get_gpu_card "$selected_gpu")
if [[ $? -eq 0 && -n "$card_result" ]]; then
selected_gpu_card="$card_result"
gpu_screen_recorder_device_arg="-device $selected_gpu_card"
fi

# Check if the selected GPU is an NVIDIA GPU
if [[ "${selected_gpu_vendor,,}" =~ "nvidia" ]]; then
echo "Selected GPU is NVIDIA. Handling NVIDIA-specific configuration..."
Expand Down Expand Up @@ -264,7 +274,7 @@ sudo chown nestri:nestri /usr/bin/gpu-screen-recorder
if [[ -z "${SESSION_ID}" ]]; then
echo "$(date +"[%Y-%m-%d %H:%M:%S]") No stream name was found, did you forget to set the env variable NAME?" && exit 1
else
/usr/bin/gpu-screen-recorder -v no -w screen -c flv -f "${REFRESH}" -a "$(pactl get-default-sink).monitor" | ffmpeg -hide_banner -v quiet -i pipe:0 -c copy -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | /usr/bin/warp --name "${SESSION_ID}" https://fst.so:4443 &
/usr/bin/gpu-screen-recorder $gpu_screen_recorder_device_arg -v no -w screen -c flv -f "${REFRESH}" -a "$(pactl get-default-sink).monitor" | ffmpeg -hide_banner -v quiet -i pipe:0 -c copy -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | /usr/bin/warp --name "${SESSION_ID}" https://fst.so:4443 &
fi

openbox-session &
Expand Down
34 changes: 34 additions & 0 deletions .scripts/gpu_helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

declare -ga gpu_map
declare -gA gpu_bus_map
declare -gA gpu_card_map
declare -gA gpu_product_map
declare -gA vendor_index_map
declare -gA vendor_full_map
Expand All @@ -22,6 +23,7 @@ get_gpu_info() {
# Clear out previous data
gpu_map=()
gpu_bus_map=()
gpu_card_map=()
gpu_product_map=()
vendor_index_map=()
vendor_full_map=()
Expand Down Expand Up @@ -72,12 +74,19 @@ get_gpu_info() {
local gpu_index="${vendor_index_map[$vendor]}"
local gpu_key="$vendor:$gpu_index"

# Get /dev/dri/cardN of GPU
local gpu_card=$({ ls -1d /sys/bus/pci/devices/*${bus_info#pci@}/drm/*; } 2>&1 | grep card* | grep -oP '(?<=card)\d+')

# Store info in maps
gpu_map+=("$gpu_key")
gpu_bus_map["$gpu_key"]="$bus_info"
gpu_product_map["$gpu_key"]="$product"
vendor_full_map["$gpu_key"]="$vendor_full"

if [[ -n "$gpu_card" ]]; then
gpu_card_map["$gpu_key"]="$gpu_card"
fi

# Clear values for additional GPUs
vendor=""
product=""
Expand Down Expand Up @@ -161,6 +170,12 @@ print_gpu_info() {
echo " Vendor: ${vendor_full_map[$selected_gpu]}"
echo " Product: ${gpu_product_map[$selected_gpu]}"
echo " Bus: ${gpu_bus_map[$selected_gpu]}"

# Check if card path was found
if [[ "${gpu_card_map[$selected_gpu]}" ]]; then
echo " Card: /dev/dri/card${gpu_card_map[$selected_gpu]}"
fi

echo
}

Expand Down Expand Up @@ -241,3 +256,22 @@ get_gpu_bus_xorg() {

echo $(convert_bus_id_to_xorg "${gpu_bus_map[$selected_gpu]}")
}

get_gpu_card() {
if ! check_and_populate_gpus; then
return 1
fi

local selected_gpu
if ! selected_gpu=$(check_selected_gpu "$1"); then
return 1
fi

# Check if card path was found
if [[ -z "${gpu_card_map[$selected_gpu]}" ]]; then
echo "No card device found for GPU: $selected_gpu" >&2
return 1
fi

echo "/dev/dri/card${gpu_card_map[$selected_gpu]}"
}
4 changes: 2 additions & 2 deletions base.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ ENV \
# Disable VSYNC for NVIDIA GPUs
__GL_SYNC_TO_VBLANK=0

COPY .patches /etc/
COPY .patches /tmp/

#Build and install gpu-screen-recorder
RUN apt-get update -y \
Expand Down Expand Up @@ -259,7 +259,7 @@ RUN apt-get update -y \
&& find . -maxdepth 1 -type f -name "*libnvrtc.so.*" -exec sh -c 'ln -snf $(basename {}) libnvrtc.so' \; \
&& mkdir -p /usr/local/nvidia/lib && mv -f libnvrtc* /usr/local/nvidia/lib \
&& git clone https://repo.dec05eba.com/gpu-screen-recorder && cd gpu-screen-recorder \
&& git apply /etc/connectcheckskip.patch \
&& git apply /tmp/connectcheckskip.patch && git apply /tmp/devicearg.patch \
&& meson setup build \
&& meson configure --prefix=/usr --buildtype=release -Dsystemd=true -Dstrip=true build \
&& ninja -C build install
Expand Down

0 comments on commit 3df53e7

Please sign in to comment.