Skip to content

Video transcoding

Frameleaf keeps every original video untouched, and makes a playback copy when the original won’t play well everywhere, for example because of its codec, container or resolution. Playback copies are stored in UPLOAD_LOCATION/encoded-video and can always be made again. They’re created by the Playback videos job queue.

Edits you render in the editor and Studio exports use the same transcoding settings, including hardware acceleration where it’s safe. When an edit needs filters that only run on the processor, rendering switches to software by itself.

Find these in Administration, then Settings, then Video Transcoding Settings.

The policy decides which videos get a playback copy. HDR videos and videos with a pixel format other than YUV 4:2:0 are always transcoded, unless transcoding is turned off.

Policy Transcodes
All videos Every video
Optimal Videos above the target resolution, or not in an accepted format
Bitrate Videos above the maximum bitrate, or not in an accepted format
Required (default) Only videos not in an accepted format
Disabled No videos. Playback may break on some devices
Setting What it does Default
Video codec H.264 is widely compatible and quick, but makes much larger files. HEVC and VP9 are more efficient; VP9 plays better on the web but takes longer. AV1 is the most efficient but isn’t supported on older devices H.264
Audio codec AAC, MP3 or Opus. Opus is the highest quality but less compatible with old devices AAC
Accepted video codecs Codecs that don’t need transcoding (for the policies that use them) H.264
Accepted audio codecs Audio codecs that don’t need transcoding AAC, MP3, Opus
Accepted containers Containers that don’t need remuxing to MP4 MOV, OGG, WebM
Target resolution Higher keeps more detail but takes longer, makes larger files and can make the apps less responsive 720p
Constant rate factor (-crf) Quality level; lower is better but larger. Typical values: 23 for H.264, 28 for HEVC, 31 for VP9, 35 for AV1 23
Maximum bitrate Makes file sizes more predictable at a small cost to quality. 0 turns it off. At 720p, typical values are 2600 kbit/s for VP9 or HEVC and 4500 kbit/s for H.264. 5000, 5000k and 5M mean the same 0
Preset (-preset) Compression speed. Slower presets make smaller files and improve quality at a given bitrate. VP9 ignores speeds above faster ultrafast
Threads More threads encode faster but leave less room for other work. Don’t set more than your CPU cores; 0 uses everything 0
Tone-mapping Keeps HDR videos looking right when converted to SDR. Hable preserves detail, Mobius colour and Reinhard brightness Hable
Two-pass encoding Encodes twice for a better result. With H.264 and HEVC it needs a maximum bitrate and ignores CRF. Only NVENC supports it among the hardware options Off

The advanced options (maximum B-frames, reference frames, maximum keyframe interval, temporal AQ, constant quality mode, preferred hardware device) are best left alone unless you know you need them. Temporal AQ applies only to NVENC; the preferred hardware device applies only to VAAPI and Quick Sync and picks the /dev/dri node to use.

Real-time Transcoding is experimental. It transcodes while a video streams, which lets the player switch quality, but can add latency and stuttering if your server can’t keep up. It’s off by default. When on, it offers H.264 and HEVC at 480p, 720p and 1080p; choose only codecs your accelerator can encode if you use one.

A GPU can take most of the transcoding work off the processor.

Option Hardware Compose service
NVENC NVIDIA GPUs nvenc
Quick Sync Intel CPUs with integrated graphics, 7th generation or later quicksync
RKMPP Rockchip SoCs rkmpp
VAAPI AMD, NVIDIA and Intel vaapi (vaapi-wsl on WSL2)

Not supported: Raspberry Pi, and Quick Sync under WSL2. VAAPI works on NVIDIA and Intel too, but the specific options are better optimised for their own hardware.

Codec support depends on the hardware. H.264 and HEVC usually work; NVIDIA and AMD GPUs can’t encode VP9. Newer devices tend to give better quality.

NVENC

Quick Sync

  • VP9 needs a 9th generation Intel CPU or newer.
  • 11th generation and older CPUs may need low-power encoding turned on in the host’s graphics driver for VP9.
  • An 11th generation CPU on kernel 5.15 (as shipped with Ubuntu 22.04 LTS) needs a newer kernel.

RKMPP

  • A supported Rockchip SoC. Only RK3588 does tone-mapping in hardware; others tone-map in software but still encode in hardware.
  • Hardware tone-mapping needs /usr/lib/aarch64-linux-gnu/libmali.so.1 on the host. Install the libmali release for your Mali GPU (libmali-valhall-g610-g13p0-gbm on RK3588), then in hwaccel.transcoding.yml, under rkmpp, uncomment these three lines:
- /dev/mali0:/dev/mali0
- /etc/OpenCL:/etc/OpenCL:ro
- /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:ro
  1. Download hwaccel.transcoding.yml into the same folder as docker-compose.yml.
  2. In docker-compose.yml, under immich-server, uncomment the extends section and change cpu to nvenc, quicksync, rkmpp, vaapi or vaapi-wsl.
  3. Redeploy the server container.
  4. In Video Transcoding Settings, under Hardware Acceleration, set Acceleration API to the same option and save. On Jasper Lake and Elkhart Lake CPUs, also set Constant quality mode to CQP.
  5. Check Hardware decoding. It’s on by default, which accelerates decoding as well as encoding; turn it off if some videos fail to transcode.
immich-server:
container_name: frameleaf_server
image: ghcr.io/frameleaf/frameleaf-server:${FRAMELEAF_VERSION:-${IMMICH_VERSION:-release}}
extends:
file: hwaccel.transcoding.yml
service: quicksync

If you use a config file, set accel (for example qsv for Intel or nvenc for NVIDIA) and accelDecode:

{
"ffmpeg": {
"accel": "qsv",
"accelDecode": true
}
}

You don’t need to redo any transcoding jobs afterwards. Jobs that run after you turn it on use the GPU.

To confirm it’s working, run Settings, then Compute & jobs, then Hardware & GPU and its benchmark (see Hardware acceleration), or watch GPU use with nvtop (NVIDIA) or intel_gpu_top (Intel) while a video transcodes. No errors in the logs while transcoding is also a good sign.

Unraid, Portainer and single Compose files

Section titled “Unraid, Portainer and single Compose files”

Some platforms can’t use more than one Compose file. Copy the relevant section of hwaccel.transcoding.yml into the immich-server service instead of using extends. For Quick Sync, that’s just:

immich-server:
container_name: frameleaf_server
image: ghcr.io/frameleaf/frameleaf-server:${FRAMELEAF_VERSION:-${IMMICH_VERSION:-release}}
# No extends section
devices:
- /dev/dri:/dev/dri

Then continue from step 3 above.

On Unraid, with the all-in-one container:

  • Quick Sync: stop and edit the Frameleaf container, choose Add another Path, Port, Variable, Label or Device, and add a Device with any name and the value /dev/dri.
  • NVENC: add the variable NVIDIA_VISIBLE_DEVICES with the value all, switch the container to Advanced Mode, add --runtime=nvidia to Extra Parameters, and restart it.

Then continue from step 4 above.

  • Choose a slower preset than you would for software transcoding, to keep quality and file size in check.
  • Prefer the specific option for your hardware (NVENC, Quick Sync) over VAAPI.