From c1cdcddf417bc5fb330f6b85155151a3edae9372 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 25 Feb 2024 00:57:01 +0100 Subject: [PATCH] Add vaapi hardware acceleration --- INSTALLING.md | 28 +++++++++++++++++++++++++--- docker-compose.dev.yml | 9 +++++++++ docker-compose.prod.yml | 9 +++++++++ docker-compose.yml | 9 +++++++++ transcoder/Dockerfile | 5 ++++- transcoder/Dockerfile.dev | 8 +++++++- transcoder/src/hwaccel.go | 19 ++++++++++++++++++- 7 files changed, 81 insertions(+), 6 deletions(-) diff --git a/INSTALLING.md b/INSTALLING.md index d76a90ac..00c28d07 100644 --- a/INSTALLING.md +++ b/INSTALLING.md @@ -60,6 +60,28 @@ stop Kyoo's services. You can then remove the configuration files. # Hardware Acceleration +## VA-API (intel, amd) + +First install necessary drivers on your system, when running `vainfo` you should have something like this: +``` +libva info: VA-API version 1.20.0 +libva info: Trying to open /run/opengl-driver/lib/dri/iHD_drv_video.so +libva info: Found init function __vaDriverInit_1_20 +libva info: va_openDriver() returns 0 +vainfo: VA-API version: 1.20 (libva 2.20.1) +vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 23.3.5 () +vainfo: Supported profile and entrypoints + VAProfileH264Main : VAEntrypointVLD + VAProfileH264Main : VAEntrypointEncSlice + ...Truncated... + VAProfileHEVCSccMain444_10 : VAEntrypointVLD + VAProfileHEVCSccMain444_10 : VAEntrypointEncSliceLP +``` +Kyoo will default to use your primary card (located at `/dev/dri/renderD128`). If you need to specify a secondary one, you +can use the `GOTRANSCODER_VAAPI_RENDERER` env-var to specify `/dev/dri/renderD129` or another one. + +Then you can simply run kyoo using `docker compose --profile vaapi up -d` (notice the `--profile vaapi` added) + ## Nvidia To enable nvidia hardware acceleration, first install necessary drivers on your system. @@ -70,7 +92,7 @@ follow the instructions on the official webpage or your distribution wiki. To test if everything works, you can run `sudo docker run --rm --gpus all ubuntu nvidia-smi`. If your version of docker is older, you might need to add `--runtime nvidia` like so: `sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi` -After that, you can now use `docker compose --profile nvidia up -d` to start kyoo with nvidia hardware acceleration. +After that, you can now use `docker compose --profile nvidia up -d` to start kyoo with nvidia hardware acceleration (notice the `--profile nvidia` added). -Note that most nvidia cards have an artifical limit on the number of encodes. You can confirm your card limit [here](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new). -This limit can also be remove by applying an [unofficial patch](https://github.com/keylase/nvidia-patch) to you driver. +Note that most nvidia cards have an artificial limit on the number of encodes. You can confirm your card limit [here](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new). +This limit can also be removed by applying an [unofficial patch](https://github.com/keylase/nvidia-patch) to you driver. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 3efa3fed..681957f1 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -87,6 +87,15 @@ services: - GOTRANSCODER_HWACCEL=nvidia profiles: ['nvidia'] + transcoder-vaapi: + <<: *transcoder-base + devices: + - /dev/dri:/dev/dri + environment: + - GOTRANSCODER_HWACCEL=vaapi + - GOTRANSCODER_VAAPI_RENDERER=${GOTRANSCODER_VAAPI_RENDERER:-/dev/dri/renderD128} + profiles: ['vaapi'] + ingress: image: nginx restart: on-failure diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 98bef1e4..9e0571ac 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -64,6 +64,15 @@ services: - GOTRANSCODER_HWACCEL=nvidia profiles: ['nvidia'] + transcoder-vaapi: + <<: *transcoder-base + devices: + - /dev/dri:/dev/dri + environment: + - GOTRANSCODER_HWACCEL=vaapi + - GOTRANSCODER_VAAPI_RENDERER=${GOTRANSCODER_VAAPI_RENDERER:-/dev/dri/renderD128} + profiles: ['vaapi'] + ingress: image: nginx restart: unless-stopped diff --git a/docker-compose.yml b/docker-compose.yml index 9cac5164..658e1642 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,6 +63,15 @@ services: - GOTRANSCODER_HWACCEL=nvidia profiles: ['nvidia'] + transcoder-vaapi: + <<: *transcoder-base + devices: + - /dev/dri:/dev/dri + environment: + - GOTRANSCODER_HWACCEL=vaapi + - GOTRANSCODER_VAAPI_RENDERER=${GOTRANSCODER_VAAPI_RENDERER:-/dev/dri/renderD128} + profiles: ['vaapi'] + ingress: image: nginx restart: on-failure diff --git a/transcoder/Dockerfile b/transcoder/Dockerfile index 5771885c..0e20b140 100644 --- a/transcoder/Dockerfile +++ b/transcoder/Dockerfile @@ -33,8 +33,11 @@ RUN go build -o ./transcoder # we use trixie (debian's testing because ffmpeg on latest is v5 and we need v6) # https://packages.debian.org/bookworm/ffmpeg for version tracking FROM debian:trixie-slim +RUN sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list.d/debian.sources RUN apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y ffmpeg libmediainfo-dev \ + && apt-get install --no-install-recommends --no-install-suggests -y \ + ffmpeg libmediainfo-dev \ + vainfo mesa-va-drivers intel-media-va-driver-non-free i965-va-driver-shaders \ && apt-get clean autoclean -y \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* diff --git a/transcoder/Dockerfile.dev b/transcoder/Dockerfile.dev index 5dd19813..e2d3abc5 100644 --- a/transcoder/Dockerfile.dev +++ b/transcoder/Dockerfile.dev @@ -23,9 +23,15 @@ ENV SSL_CERT_DIR=/etc/ssl/certs RUN update-ca-certificates RUN go install github.com/bokwoon95/wgo@latest +RUN sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list.d/debian.sources RUN apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ - ffmpeg libavformat-dev libavutil-dev libswscale-dev libmediainfo-dev \ + # runtime dependencies + ffmpeg libavformat-dev \ + # build dependencies + libavutil-dev libswscale-dev libmediainfo-dev \ + # hwaccel dependencies + vainfo mesa-va-drivers intel-media-va-driver-non-free i965-va-driver-shaders \ && apt-get clean autoclean -y \ && apt-get autoremove -y WORKDIR /app diff --git a/transcoder/src/hwaccel.go b/transcoder/src/hwaccel.go index cc0aa1c0..71609ae3 100644 --- a/transcoder/src/hwaccel.go +++ b/transcoder/src/hwaccel.go @@ -31,7 +31,6 @@ func DetectHardwareAccel() HwAccelT { return HwAccelT{ Name: "nvidia", DecodeFlags: []string{ - // TODO: check if this can always be enabled (for example with weird video formats) "-hwaccel", "cuda", // this flag prevents data to go from gpu space to cpu space // it forces the whole dec/enc to be on the gpu. We want that. @@ -47,6 +46,24 @@ func DetectHardwareAccel() HwAccelT { // since we use hwaccel_output_format, decoded data stays in gpu memory so we must not specify it (it errors) ScaleFilter: "scale_cuda=%d:%d", } + case "vaapi": + return HwAccelT{ + Name: name, + DecodeFlags: []string{ + "-hwaccel", "vaapi", + "-hwaccel_device", GetEnvOr("GOTRANSCODER_VAAPI_RENDERER", "/dev/dri/renderD128"), + "-hwaccel_output_format", "vaapi", + }, + EncodeFlags: []string{ + // h264_vaapi does not have any preset or scenecut flags. + "-c:v", "h264_vaapi", + // if the hardware decoder could not work and fallbacked to soft decode, we need to instruct ffmpeg to + // upload back frames to gpu space (after converting them) + // see https://trac.ffmpeg.org/wiki/Hardware/VAAPI#Encoding for more info + // "-vf", "format=nv12|vaapi,hwupload", + }, + ScaleFilter: "scale_vaapi=%d:%d", + } default: log.Printf("No hardware accelerator named: %s", name) os.Exit(2)