How to Change Color Range Using FFmpeg Scale Filter

This guide explains how to convert and configure video color ranges between limited (TV) and full (PC) range in FFmpeg using the range options within the scale filter. You will learn the command syntax for pixel value scaling using in_range and out_range, how to properly tag container metadata to prevent washed-out colors, and the difference between scaling pixel values versus simply tagging them.


Understanding Color Ranges

Digital video typically operates in one of two color ranges:

  • Limited Range (tv / mpeg): Primarily used in broadcast and standard consumer video formats (e.g., standard H.264/H.265). Luminance (Y) spans from 16 to 235, and chrominance (U/V) spans from 16 to 240 in 8-bit systems.
  • Full Range (pc / jpeg): Primarily used in computer graphics, photography, and web standards. Values span the entire 0 to 255 spectrum in 8-bit systems.

If a video is encoded in full range but interpreted as limited range, blacks will appear crushed and whites blown out. Conversely, limited range content interpreted as full range will appear washed out with gray blacks.


Setting Color Range with the scale Filter

Within FFmpeg's scale video filter, you define and convert color ranges using the in_range and out_range options.

Parameter Values

  • limited, tv, or mpeg (Limited range)
  • full, pc, or jpeg (Full range)

1. Converting Limited Range to Full Range

To expand 16–235 levels to full 0–255 values while keeping the native resolution:

ffmpeg -i input.mp4 -vf "scale=in_range=limited:out_range=full" -c:v libx264 -crf 18 -c:a copy output.mp4

2. Converting Full Range to Limited Range

To compress 0–255 levels down into standard broadcast 16–235 values:

ffmpeg -i input.mp4 -vf "scale=in_range=full:out_range=limited" -c:v libx264 -crf 18 -c:a copy output.mp4

3. Combining Range Conversion with Resizing

You can chain resolution scaling with range conversion simultaneously:

ffmpeg -i input.mp4 -vf "scale=1920:1080:in_range=limited:out_range=full" -c:v libx264 -crf 18 -c:a copy output.mp4

Ensuring Proper Metadata Flagging

Scaling pixel values only modifies the underlying pixel data. Many media players rely on bitstream VUI (Video Usability Information) metadata to decide how to render the file.

To ensure the encoder writes the correct metadata tag matching your scaled output, combine the scale filter with the -color_range flag:

  • For full range output: -color_range pc (or -color_range 2)
  • For limited range output: -color_range tv (or -color_range 1)

Full Range Example:

ffmpeg -i input.mp4 -vf "scale=in_range=tv:out_range=pc" -color_range pc -c:v libx264 -crf 18 -c:a copy output.mp4

Limited Range Example:

ffmpeg -i input.mp4 -vf "scale=in_range=pc:out_range=tv" -color_range tv -c:v libx264 -crf 18 -c:a copy output.mp4

scale Conversion vs. setrange Filter

It is important not to confuse color range conversion with range retagging:

  • scale=in_range=...:out_range=...: Mathematically rescales the luminance and chrominance values of each pixel. Use this when the pixel values need to physically change.
  • setrange=... filter: Only changes the color range metadata property on frames inside the filter graph without recalculating or shifting pixel values. For example, if a video has full-range pixel values that were erroneously flagged as limited, you correct it using setrange=pc rather than scaling it.