diff --git a/LICENSE b/LICENSE index 61f9268..0403087 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ MIT License +Copyright (c) 2023 Ryan He Copyright (c) 2021 Théo Le Calvar Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/README.md b/README.md index 6cab28e..28498cb 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,14 @@ -# Hardware h264 encoding using vaapi +# Hardware h264 encoding using NVIDIA NVENC -This plugin tries to enable hardware accelerated transcoding profiles using vaapi on linux. It should be considered experimental and tinkering will certainly be necessary to make this plugin work on your hardware. +This plugin tries to enable hardware accelerated transcoding profiles using nvenc on linux. It should be considered experimental and tinkering will certainly be necessary to make this plugin work on your hardware. -For more information on vaapi and hardware acceleration: +For more information on nvenc and hardware acceleration: - https://jellyfin.org/docs/general/administration/hardware-acceleration.html#enabling-hardware-acceleration - https://wiki.archlinux.org/index.php/Hardware_video_acceleration#Comparison_tables -# Building a compatible docker image +# Building and running a compatible docker image -Official docker images do not ship with required libraries for hardware transcode. -You can build your own image with the following Dockerfile: - -```Dockerfile -ARG VERSION=v4.2.0 -FROM chocobozzz/peertube:${VERSION}-bullseye - - -# install dependencies for vaapi -RUN apt update \ - && apt install -y --no-install-recommends wget apt-transport-https \ - && echo "deb http://deb.debian.org/debian/ $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) non-free" | tee /etc/apt/sources.list.d/non-free.list \ - && apt update \ - && apt install -y --no-install-recommends vainfo i965-va-driver-shaders \ - && apt install -y --no-install-recommends python3 \ - && rm /var/lib/apt/lists/* -fR -``` - -If you are using a recent Intel CPU (generation 8 and newer), replace `i965-va-driver-shaders` by `intel-media-va-driver-non-free`. - - -# Running the docker image - -In order to access the GPU inside docker, the `docker-compose.yml` should be adapted as follow. -Note that you must find the id of the `render` group on your machine. -You can use `grep render /etc/group | cut -d':' -f3` to find the id. - - -```yaml -version: "2" - -services: - peertube: - # replace image key with - build: - context: . - args: - VERSION: v5.0.1 - # usual peertube configuration - # ... - - # add these keys - group_add: - - - devices: - # VAAPI Devices - - /dev/dri:/dev/dri -``` + - https://github.com/ryanho/peertube-hwaccel diff --git a/package-lock.json b/package-lock.json index 3a78a07..296f40b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { - "name": "peertube-plugin-hardware-transcode-vaapi", - "version": "0.2.3", + "name": "peertube-plugin-hardware-transcode-nvenc", + "version": "0.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "peertube-plugin-hardware-transcode-vaapi", - "version": "0.2.3", + "name": "peertube-plugin-hardware-transcode-nvenc", + "version": "0.0.1", "license": "MIT", "devDependencies": { "@peertube/peertube-types": "^5.1.0", "@tsconfig/node16": "^1.0.3", - "typescript": "^5.0.4" + "typescript": "^5.1.6" } }, "node_modules/@aws-crypto/crc32": { @@ -4556,16 +4556,16 @@ "dev": true }, "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=14.17" } }, "node_modules/uid-safe": { @@ -8409,9 +8409,9 @@ "dev": true }, "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "dev": true }, "uid-safe": { diff --git a/package.json b/package.json index 5308b02..e10cfb0 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "peertube-plugin-hardware-transcode-vaapi", - "version": "0.2.9", + "name": "peertube-plugin-hardware-transcode-nvenc", + "version": "0.0.1", "license": "MIT", - "description": "Plugin that adds transcode profiles which use vaapi for hardware acceleration", + "description": "Plugin that adds transcode profiles which use NVIDIA NVENC for hardware acceleration", "engine": { "peertube": ">=5.1.0" }, @@ -10,9 +10,9 @@ "peertube", "plugin" ], - "homepage": "https://github.com/TheoLeCalvar/peertube-plugin-hardware-transcode-vaapi", - "author": "gdsn", - "bugs": "https://github.com/TheoLeCalvar/peertube-plugin-hardware-transcode-vaapi", + "homepage": "https://github.com/ryanho/peertube-plugin-hardware-transcode-nvenc", + "author": "ryanho", + "bugs": "https://github.com/ryanho/peertube-plugin-hardware-transcode-nvenc/issues", "library": "./dist/main.js", "files": [ "/dist" @@ -30,6 +30,6 @@ "devDependencies": { "@peertube/peertube-types": "^5.1.0", "@tsconfig/node16": "^1.0.3", - "typescript": "^5.0.4" + "typescript": "^5.1.6" } } diff --git a/src/main.ts b/src/main.ts index 1f5a6e1..6eb5968 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,7 +6,8 @@ let logger : Logger let transcodingManager : PluginTranscodingManager const DEFAULT_HARDWARE_DECODE : boolean = false -const DEFAULT_QUALITY : number = -1 +const DEFAULT_VOD_QUALITY : number = 15 +const DEFAULT_LIVE_QUALITY : number = 7 const DEFAULT_BITRATES : Map = new Map([ [VideoResolution.H_NOVIDEO, 64 * 1000], [VideoResolution.H_144P, 320 * 1000], @@ -20,12 +21,14 @@ const DEFAULT_BITRATES : Map = new Map([ interface PluginSettings { hardwareDecode : boolean - quality: number + vodQuality: number + liveQuality: number baseBitrate: Map } let pluginSettings : PluginSettings = { hardwareDecode: DEFAULT_HARDWARE_DECODE, - quality: DEFAULT_QUALITY, + vodQuality: DEFAULT_VOD_QUALITY, + liveQuality: DEFAULT_LIVE_QUALITY, baseBitrate: new Map(DEFAULT_BITRATES) } @@ -37,8 +40,8 @@ export async function register({settingsManager, peertubeHelpers, transcodingMan logger.info("Registering peertube-plugin-hardware-encode"); - const encoder = 'h264_vaapi' - const profileName = 'vaapi' + const encoder = 'h264_nvenc' + const profileName = 'nvenc' // Add trasncoding profiles transcodingManager.addVODProfile(encoder, profileName, vodBuilder) @@ -62,24 +65,40 @@ export async function register({settingsManager, peertubeHelpers, transcodingMan private: false }) registerSetting({ - name: 'quality', - label: 'Quality', + name: 'vod-quality', + label: 'VOD Quality', type: 'select', options: [ - { label: 'Automatic', value: '-1' }, - { label: '1', value: '1' }, - { label: '2', value: '2' }, - { label: '3', value: '3' }, - { label: '4', value: '4' }, - { label: '5', value: '5' }, - { label: '6', value: '6' }, - { label: '7', value: '7' } + { label: 'fastest', value: '12' }, + { label: 'faster', value: '13' }, + { label: 'fast', value: '14' }, + { label: 'medium (default)', value: '15' }, + { label: 'slow', value: '16' }, + { label: 'slower', value: '17' }, + { label: 'slowest', value: '18' } ], - descriptionHTML: 'This parameter controls the speed / quality tradeoff. Lower values mean better quality but slower encoding. Higher values mean faster encoding but lower quality. This setting is hardware dependent, you may need to experiment to find the best value for your hardware. Some hardware may have less than 7 levels of compression.', + descriptionHTML: 'This parameter controls the speed / quality tradeoff. Slower speed mean better quality. Faster speed mean lower quality. This setting is hardware dependent, you may need to experiment to find the best value for your hardware.', - default: DEFAULT_QUALITY.toString(), + default: DEFAULT_VOD_QUALITY.toString(), + private: false + }) + + registerSetting({ + name: 'live-quality', + label: 'Live Quality', + + type: 'select', + options: [ + { label: 'low latency (default)', value: '7' }, + { label: 'low latency high quality', value: '8' }, + { label: 'low latency high performance', value: '9' } + ], + + descriptionHTML: 'This parameter controls the speed / quality tradeoff. High performance mean lower quality.', + + default: DEFAULT_LIVE_QUALITY.toString(), private: false }) @@ -121,7 +140,8 @@ export async function unregister() { async function loadSettings(settingsManager: PluginSettingsManager) { pluginSettings.hardwareDecode = await settingsManager.getSetting('hardware-decode') == "true" - pluginSettings.quality = parseInt(await settingsManager.getSetting('quality') as string) || DEFAULT_QUALITY + pluginSettings.vodQuality = parseInt(await settingsManager.getSetting('vod-quality') as string) || DEFAULT_VOD_QUALITY + pluginSettings.liveQuality = parseInt(await settingsManager.getSetting('live-quality') as string) || DEFAULT_LIVE_QUALITY for (const [resolution, bitrate] of DEFAULT_BITRATES) { const key = `base-bitrate-${resolution}` @@ -131,7 +151,8 @@ async function loadSettings(settingsManager: PluginSettingsManager) { } logger.info(`Hardware decode: ${pluginSettings.hardwareDecode}`) - logger.info(`Quality: ${pluginSettings.quality}`) + logger.info(`VOD Quality: ${pluginSettings.vodQuality}`) + logger.info(`Live Quality: ${pluginSettings.liveQuality}`) } function printResolution(resolution : VideoResolution) : string { @@ -153,13 +174,12 @@ function printResolution(resolution : VideoResolution) : string { function buildInitOptions() { if (pluginSettings.hardwareDecode) { return [ - '-hwaccel vaapi', - '-vaapi_device /dev/dri/renderD128', - '-hwaccel_output_format vaapi', + '-hwaccel cuda', + '-hwaccel_output_format cuda' ] } else { return [ - '-vaapi_device /dev/dri/renderD128' + '-hwaccel cuda' ] } } @@ -183,11 +203,12 @@ async function vodBuilder(params: EncoderOptionsBuilderParams) : Promise