Skip to content

Instantly share code, notes, and snippets.

@bogsen
Last active June 28, 2024 13:46
Show Gist options
  • Save bogsen/37cbad60f6c10cdaddf3b07a56e06147 to your computer and use it in GitHub Desktop.
Save bogsen/37cbad60f6c10cdaddf3b07a56e06147 to your computer and use it in GitHub Desktop.
Fix Plex transcoding HDR videos very slowly when burning subtitles in at the same time

What?

For some reason, although Plex supports hardware-accelerated HDR tone mapping, Plex decides not to use it when subtitles need to be burned in. This results in extremely slow transcoding on hardware that should be able to keep up using hardware acceleration. I've noticed this issue on my server with Intel QuickSync, and this fix is made specifically for that case.

Before the fix, the SW tone mapping was only able to do 6-7 fps on a i5 7400T for an HDR 4K->1080p transcode. With the fix, that same transcode happens with HW tone mapping, and goes up to 82 fps. Even for HDR 4K->4K, this CPU is able to do 35 fps using QuickSync, thus keeping up with at least one video stream.

How do I fix this?

By wrapping "Plex Transcoder" with a script which replaces the software tone mapping with hardware tone mapping.

A filter configuration for software tone mapping looks like this: [0:0]scale=w=1920:h=1080:force_divisible_by=4[0];[0]format=p010,tonemap=mobius[1];[1]format=pix_fmts=nv12[2];[2]inlineass=font_scale=1.000000:font_path=/usr/lib/plexmediaserver/...[3];[3]hwupload[4]

A filter configuration for hardware tone mapping looks like this: [0:0]scale_vaapi=w=1920:h=1080:format=p010[0];[0]hwmap=derive_device=opencl,tonemap_opencl=tonemap=mobius:format=nv12:m=bt709:p=bt709:r=tv,hwdownload[1];[1]format=pix_fmts=nv12[2];[2]inlineass=font_scale=1.000000:font_path=/usr/lib/plexmediaserver/...[3];[3]hwupload[4]

For the linuxserver.io Plex docker image, I've attached a script which can be added into custom-cont-init.d (by using a bind mount) that fixes the issue described here. Use at your own risk, it may cause issues in other transcoding scenarios which I didn't test yet.

#!/bin/bash -ex
cd /usr/lib/plexmediaserver
if [ ! -f "Plex Transcoder.before-hdr-subtitles-fix" ]; then
mv "Plex Transcoder" "Plex Transcoder.before-hdr-subtitles-fix"
fi
cat >"Plex Transcoder" <<"EOF"
#!/usr/bin/env -S perl -l
use warnings;
use strict;
my $found = 0;
for my $arg (@ARGV) {
my $updated = $arg =~ s/(\[[\w:]+\])scale=(w=\d+:h=\d+)[^[]+(\[[\w:]+\]);\3format=p010,tonemap=(\w+)(\[[\w:]+\]);/$1scale_vaapi=$2:format=p010$3;$3hwmap=derive_device=opencl,tonemap_opencl=tonemap=$4:format=nv12:m=bt709:p=bt709:r=tv,hwdownload,format=pix_fmts=nv12$5;/r;
if ($updated ne $arg) {
print("Enabled HW tone mapping:");
print("Original: $arg");
print("Updated: $updated");
$arg = $updated;
$found = 1;
next;
}
$updated = $arg =~ s/(\[[\w:]+\])scale=(w=\d+:h=\d+)[^,[]+/$1hwupload,scale_vaapi=$2,hwdownload/r;
if ($updated ne $arg) {
print("Enabled HW scaling:");
print("Original: $arg");
print("Updated: $updated");
$arg = $updated;
$found = 1;
next;
}
}
if ($found) {
if (!defined $ENV{OCL_ICD_VENDORS}) {
$ENV{OCL_ICD_VENDORS} = '/config/Library/Application Support/Plex Media Server/Cache/cl-icds-linux-x86_64';
$ENV{cl_cache_dir} = '/config/Library/Application Support/Plex Media Server/Cache/Shaders/icr-97-linux-x86_64/';
}
unshift(@ARGV, "-hwaccel_output_format:0", "vaapi");
}
unshift(@ARGV, "/usr/lib/plexmediaserver/Plex Transcoder.before-hdr-subtitles-fix");
exec { $ARGV[0] } @ARGV;
EOF
chmod +x "Plex Transcoder"
@JshGrn
Copy link

JshGrn commented Jun 28, 2024

I am fully aware that it is a priority and understand it, but my suggestion is relating to perhaps Plex having a feature 'vote' where people could pool towards a target feature which would then allow for additional development for that said feature.

People do it on here quite often with large repos that are depended on for lots of people. I personally would put £100 GBP towards this, which may on its own be nothing but if a pool of other people that want to stay with Plex put together it should add up to enough for Plex to warrant additional development on the feature. (and others moving forward).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment