Configure Dither Filter and Range in FFmpeg zscale

The FFmpeg zscale filter, which leverages the high-performance zimg library, is an advanced alternative to the default scale filter. It offers superior quality for image resizing, bit depth conversion, and color space transformations. This article provides a direct, practical guide on how to configure the dither, scaling filter, and color range parameters within zscale to achieve optimal video encoding results.

The Basic Syntax

The zscale filter uses a key=value format, with parameters separated by colons. The basic syntax for configuring dither, scaling filter, and range looks like this:

zscale=dither=dither_type:filter=filter_type:range=range_type:in_range=input_range_type

1. Configuring Dither

Dithering is crucial when reducing bit depth (for example, converting 10-bit HDR video to 8-bit SDR) because it prevents color banding. You can configure this using the dither (or d) parameter.

Available Dither Types:

  • none: Disables dithering. This is the fastest option but can introduce visible banding.
  • ordered: Uses a pre-defined Bayer ordered dither pattern. It offers a good balance between speed and quality.
  • random: Adds random noise.
  • error_diffusion: Uses Floyd-Steinberg error diffusion. This provides the highest quality and smoothest gradients but is the most computationally expensive.

Example:

zscale=dither=error_diffusion

2. Configuring the Resampling Filter

The scaling filter determines the mathematical algorithm used to resize the video frame. You can configure this using the filter (or f) parameter.

Available Filter Types:

  • point: Nearest-neighbor interpolation. Very fast but causes heavy aliasing.
  • bilinear: Fast, but results in a soft, somewhat blurry image.
  • bicubic: A standard, well-balanced filter (default for many scalers).
  • spline16 / spline36: Spline-based interpolators that offer excellent sharpness with minimal artifacts.
  • lanczos: High-quality sinc filter that provides very sharp details, though it can occasionally introduce slight ringing artifacts.

Example:

zscale=filter=lanczos

3. Configuring Color Range

Color range defines the luminance levels of the video. It is critical to set this correctly to avoid washed-out blacks or crushed highlights. Use the range (or r) parameter for output, and in_range for input.

Available Range Types:

  • limited (or tv): Standard broadcasting range where luminance values are restricted (e.g., 16-235 for 8-bit).
  • full (or pc): PC range utilizing the entire spectrum (e.g., 0-255 for 8-bit).
  • input: Inherits the range from the input video (default).

Example:

To convert a limited-range input to a full-range output:

zscale=in_range=limited:range=full

Complete Command Example

To tie these configurations together, the following command rescales an input video to 1080p, applies a sharp Lanczos filter, uses ordered dithering, and ensures the output is set to limited (TV) range:

ffmpeg -i input.mp4 -vf "zscale=width=1920:height=1080:filter=lanczos:dither=ordered:range=limited" -c:v libx264 -crf 18 output.mp4