Wren TVDocs

Running a server

Transcoding and hardware acceleration

When Wren TV transcodes, which GPUs it uses, and how to pass a GPU through to Docker.

Wren TV avoids transcoding. Most plays are direct play or a lossless remux, which use almost no CPU. Transcoding only happens when:

  • the player can't decode the video codec at all (for example HEVC in a browser without HEVC support),
  • the player can't show HDR, so the video must be tone-mapped to SDR, or
  • the viewer picked a lower quality than the file's bitrate.

A transcode produces 8-bit SDR H.264 video in HLS. Seeking starts a new encode from the new position.

Hardware acceleration

With hwaccel: auto (the default), the server tries the likely GPUs for the platform at start-up, runs a tiny test encode on each, and uses the first that works. If none works, it uses software encoding (libx264).

PlatformTried in order
macOSVideoToolbox
LinuxNVIDIA (NVENC), Intel (Quick Sync), VAAPI (Intel and AMD)
WindowsNVIDIA (NVENC), Intel (Quick Sync), AMD (AMF)

The Manage status page shows which encoder is in use. To pin one, set Hardware acceleration in Manage → Settings, transcode.hwaccel, or WRENTV_HWACCEL:

ValueUses
autoDetect (the default)
videotoolboxApple VideoToolbox
nvencNVIDIA NVENC
qsvIntel Quick Sync
vaapiVAAPI on Linux (Intel or AMD). The device is transcode.vaapi_device, default /dev/dri/renderD128
amfAMD AMF on Windows
noneSoftware only

Decoding also runs on the GPU when it can, so 4K HEVC sources don't load the CPU.

HDR to SDR tone mapping

When an HDR10 or Dolby Vision file has to be transcoded for an SDR screen, its colours are tone-mapped so it doesn't look washed out:

  • On the GPU with VideoToolbox, Quick Sync and VAAPI.
  • On the CPU otherwise, with ffmpeg's zscale and the Hable curve. This needs an ffmpeg built with zimg, which jellyfin-ffmpeg and most distribution builds have.

Docker

The Docker image bundles jellyfin-ffmpeg, which supports every method above. You only need to give the container the GPU.

Intel and AMD (Quick Sync, VAAPI)

yaml    devices:
      - /dev/dri:/dev/dri

If it doesn't get picked up, check that the user running Docker's containers can read /dev/dri/renderD128 (it usually belongs to the render group).

NVIDIA (NVENC)

Install the NVIDIA Container Toolkit on the host, then:

yaml    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu, video, compute, utility]

Native installs

  • Linux: the service user needs to be in the render and video groups for /dev/dri. The provided systemd unit does that. Use an ffmpeg with your GPU's support built in. jellyfin-ffmpeg is a good choice.
  • macOS: VideoToolbox works with Homebrew's ffmpeg.
  • Windows: use the jellyfin-ffmpeg portable build, and an up-to-date GPU driver.

Scratch space

Transcoded segments are written to <data>/transcode and cleaned up when playback stops. Put it on a fast disk, or in RAM, with transcode.scratch_dir. With Docker you can mount it:

yaml    volumes:
      - /dev/shm/wrentv:/config/transcode

ffmpeg location

The server looks for ffmpeg and ffprobe on the PATH. Point it elsewhere with transcode.ffmpeg_path and transcode.ffprobe_path, or WRENTV_FFMPEG and WRENTV_FFPROBE.

Wren TV is in early access. Something here wrong or missing? Tell us in the beta.