Transcoding
Odeion streams media to clients using HLS (HTTP Live Streaming). When a client requests playback, Odeion either serves the original file directly (direct play) or transcodes it on the fly to a format the client can handle.
Transcoding Profiles
Section titled “Transcoding Profiles”Each playback session uses a profile that determines the output codec, resolution, and bitrate. The client app selects a profile based on the user’s quality preference and device capabilities.
| Profile | Video | Audio | Max Width | Video Bitrate | Audio Bitrate |
|---|---|---|---|---|---|
native | Direct play | Direct play | Original | Original | Original |
4k | H.264 | AAC | 2160p | 20 Mbps | 256 kbps |
hd | H.264 | AAC | 1080p | 8 Mbps | 192 kbps |
mobile | H.264 | AAC | 720p | 2 Mbps | 128 kbps |
sd | H.264 | AAC | 480p | 1 Mbps | 96 kbps |
360p | H.264 | AAC | 360p | 600 kbps | 64 kbps |
audio | None | AAC | N/A | N/A | 192 kbps |
compatible | VP9 | Opus | Original | 4 Mbps | 192 kbps |
hdr | Passthrough | AAC | Original | Original | 192 kbps |
surround | H.264 | Passthrough | 1080p | 8 Mbps | Original |
hdr-surround | Passthrough | Passthrough | Original | Original | Original |
The native profile sends the file as-is without any transcoding. This uses the least server resources but requires the client to support the file’s codecs and container format.
The compatible profile uses VP9 and Opus, which are royalty-free codecs supported in all Chromium-based browsers, including Linux builds without proprietary codec support.
The hdr profile copies the video stream without re-encoding, which preserves HDR10 and HLG metadata. Audio is transcoded to stereo AAC. The client must support HDR decoding.
The surround profile transcodes video to H.264 but copies the audio stream (AC-3, E-AC-3, DTS) for surround sound receivers. The client must support the original audio codec.
The hdr-surround profile copies both video and audio streams without modification. This provides the best quality for home theater setups that support both HDR and surround audio.
Transcoder Pools
Section titled “Transcoder Pools”Odeion uses a pool system to manage transcoding resources. Each pool represents a set of transcoding capacity, either CPU-based or tied to a specific GPU. Pools control how many streams can transcode simultaneously and which hardware is used.
How Pools Work
Section titled “How Pools Work”Every pool has a priority, a maximum number of slots, and can be enabled or disabled. When a new stream needs transcoding, Odeion picks the best available pool automatically:
- Disabled pools and GPU pools with unavailable hardware are skipped.
- Pools that are already at their slot limit are skipped.
- Among the remaining pools, the one with the highest priority is selected. If multiple pools share the same priority, the one with the lowest current load is chosen.
Each active transcode holds a slot in its assigned pool. When playback ends or the session times out, the slot is released back to the pool.
Managing Pools
Section titled “Managing Pools”Pools are managed from Admin > Transcoding > Pools. From this page you can:
- Create new CPU or GPU pools
- Set the priority, slot limit, and FFmpeg thread count for each pool
- Enable or disable pools without deleting them
- Scan for available GPUs on the system
- Probe a GPU pool’s capabilities (which codecs and filters it supports)
A typical setup might include one GPU pool for hardware-accelerated transcoding and one CPU pool as a fallback. Give the GPU pool a higher priority so it is preferred, and use the CPU pool to handle overflow when the GPU is fully loaded.
GPU Health Checks
Section titled “GPU Health Checks”Odeion checks GPU availability every 60 seconds. If a GPU becomes inaccessible (for example, the device is removed or the driver crashes), the pool is automatically bypassed and new sessions fall through to lower-priority pools. When the GPU comes back, Odeion detects this and re-enables the pool.
GPU Transcoding
Section titled “GPU Transcoding”GPU-accelerated transcoding offloads video encoding and decoding to dedicated hardware, significantly reducing CPU usage and allowing more concurrent streams.
VAAPI (Intel and AMD)
Section titled “VAAPI (Intel and AMD)”VAAPI (Video Acceleration API) works with Intel and AMD GPUs on Linux. In Docker, you need to pass through the GPU render device:
devices: - /dev/dri:/dev/driThis exposes all render nodes (typically /dev/dri/renderD128 and similar). When creating a GPU pool, select the VAAPI device that corresponds to your GPU.
NVENC (NVIDIA)
Section titled “NVENC (NVIDIA)”NVENC works with NVIDIA GPUs and requires the NVIDIA Container Toolkit. See the Installation page for Docker configuration.
NVIDIA GPUs use the CUDA API. When creating a GPU pool, select the CUDA device (identified by ordinal: 0, 1, etc. for multi-GPU systems).
Capability Probing
Section titled “Capability Probing”When a GPU pool is created, Odeion automatically probes the GPU to discover exactly which encoders, decoders, and filters it supports. This varies by GPU generation. For example, AV1 encoding is only available on newer Intel and NVIDIA hardware.
Probing runs test encodes against the GPU to verify each capability actually works, rather than relying on driver-reported features alone. You can re-probe a pool at any time from the admin panel if you update your GPU drivers.
Typical capabilities include:
- Encoders: H.264, HEVC, AV1 (GPU-dependent)
- Decoders: H.264, HEVC, AV1, VP9, MPEG-2 (GPU-dependent)
- Filters: Scaling, deinterlacing, HDR tone mapping
HDR Tone Mapping
Section titled “HDR Tone Mapping”If your GPU supports tone mapping filters (tonemap_vaapi, tonemap_cuda, or libplacebo), Odeion can convert HDR content to SDR on the GPU during transcoding. This allows HDR source files to be played on devices that only support SDR, without heavy CPU usage. Tone mapping capability is detected automatically during probing.
Session Management
Section titled “Session Management”Each active playback that requires transcoding creates a session. Sessions are tracked by the server and assigned to a transcoder pool.
If multiple users (or devices) request the same content with the same profile, they share a single transcoding session rather than starting separate encodes. This means two people watching the same movie at the same quality only use one pool slot.
Sessions have an idle timeout. If a client stops requesting new segments, the session is cleaned up and the FFmpeg process is terminated after the timeout period.
Transcoded segments are cached on disk so that rewinding or replaying a section does not require re-transcoding.
Settings
Section titled “Settings”Transcoding settings are configured from Admin > Transcoding > Settings:
| Setting | Default | Description |
|---|---|---|
| Max global sessions | 0 (unlimited) | Total concurrent transcoding sessions across all users. Set this based on your server’s capacity. |
| Session idle timeout | 120 seconds | How long a session stays alive after the last segment request before being cleaned up. |
| Max cache size | 32 GB | Maximum disk space for cached transcoded segments. Set to 0 for unlimited. |
Monitoring
Section titled “Monitoring”Active sessions can be viewed from Admin > Transcoding > Sessions. Each session shows the media being played, the transcoding profile, which pool it is using, bandwidth usage, and connected users. Administrators can terminate individual sessions from this page.