FFmpeg TV vs PC Color Range Explained
When processing video with FFmpeg, understanding the difference
between the tv and pc color ranges is crucial
for preventing washed-out blacks or clipped highlights. This article
explains what these color ranges represent, how they differ in pixel
values, and how to correctly apply them in your FFmpeg video conversion
workflows.
What is the Difference?
The terms tv and pc refer to how color and
brightness values are mapped to digital data in a video signal. The
fundamental difference lies in the range of numerical values used to
represent black, white, and everything in between.
TV Range (Limited Range)
The tv color range—also known as limited
range, broadcast range, or MPEG
range—is the historical standard for television broadcasts and
analog-to-digital video.
In an 8-bit video system (which has a total of 256 possible values from 0 to 255): * Reference Black is mapped to value 16. * Reference White is mapped to value 235. * Values from 0 to 15 are reserved for “footroom” (to prevent signal clipping), and values from 236 to 255 are reserved for “headroom.”
PC Range (Full Range)
The pc color range—also known as full
range or JPEG range—is the standard for
computers, mobile devices, and internet-based media.
In an 8-bit system: * Reference Black is mapped to value 0. * Reference White is mapped to value 255. * The entire spectrum from 0 to 255 is utilized to display visual information.
Why Color Range Mismatches Occur
If FFmpeg or a media player does not correctly identify the color range of a video, it will interpret the pixel values incorrectly, leading to two common visual issues:
- Washed-Out Colors (Full-to-Limited Mishandling): If
a video recorded in
pc(full) range is mistakenly interpreted astv(limited) range, a media player will map the black level (16) and white level (235) to the screen, compressing the range. This makes blacks look dark gray and whites look light gray, giving the video a hazy, washed-out appearance. - Crushed Blacks and Blown-Out Whites (Limited-to-Full
Mishandling): If a
tv(limited) range video is incorrectly interpreted aspc(full) range, the media player scales the values. Value 16 is stretched down to 0, and 235 is stretched up to 255. This causes “clipping,” where subtle shadow details are lost to pure black and bright highlights are lost to pure white.
Managing Color Ranges in FFmpeg
In FFmpeg, you can explicitly set or convert color ranges using both video filters and output flags.
1. Specifying Color Range in the Scale Filter
The scale filter allows you to force an input range
(in_range) and convert it to a specific output range
(out_range).
To convert a full-range (pc) video to a limited-range
(tv) video:
ffmpeg -i input.mp4 -vf "scale=in_range=pc:out_range=tv" output.mp4To convert a limited-range (tv) video to a full-range
(pc) video:
ffmpeg -i input.mp4 -vf "scale=in_range=tv:out_range=pc" output.mp42. Setting Color Range Metadata Flags
Sometimes, the video frames are already in the correct range, but the
metadata flag is missing or incorrect, causing media players to render
it poorly. You can force the metadata tag without re-encoding the color
values using the -color_range option:
To flag the output video as limited range:
ffmpeg -i input.mp4 -c:v libx264 -color_range tv output.mp4To flag the output video as full range:
ffmpeg -i input.mp4 -c:v libx264 -color_range pc output.mp4