How to Change Video Color Matrix with FFmpeg
Adjusting color matrix coefficients in standard definition (SD) video is critical for avoiding washed-out colors or improper tinting during playback or upscaling. This guide explains how to convert SD color matrix coefficients—typically BT.601—to other standards like BT.709 using FFmpeg. You will learn how to transform the actual pixel values using video filters as well as how to update the metadata flags directly.
Understanding SD Color Matrices
Standard definition video predominantly uses the
BT.601 color matrix standard (often labeled as
smpte170m for NTSC or bt470bg for PAL). High
definition (HD) video uses BT.709. When playing an SD
video on modern displays or upscaling it to HD, incorrect matrix
interpretations can shift reds and greens. You can resolve this by
either recalculating the pixel data or by adjusting the stream's
metadata tags.
Method
1: Converting Pixel Data Using the colormatrix Filter
If your video was encoded using one matrix but needs to be physically
recalculated to conform to another, use the colormatrix
filter.
To convert an SD video from BT.601 (PAL/NTSC) to BT.709:
ffmpeg -i input_sd.mp4 -vf "colormatrix=bt601:bt709" -c:v libx264 -crf 18 -c:a copy output_bt709.mp4To convert an incorrectly tagged BT.709 file back to BT.601:
ffmpeg -i input_sd.mp4 -vf "colormatrix=bt709:bt601" -c:v libx264 -crf 18 -c:a copy output_bt601.mp4Method
2: High-Precision Conversion Using the colorspace
Filter
For higher precision and control over color primaries, transfer
characteristics, and matrix coefficients, use the modern
colorspace filter.
To convert a standard 576i/480i BT.601 video to BT.709:
ffmpeg -i input_sd.mp4 -vf "colorspace=space=bt709:primaries=bt709:trc=bt709:ispace=smpte170m:iprimaries=smpte170m:itrc=smpte170m" -c:v libx264 -crf 18 -c:a copy output_precise.mp4In this command:
ispace,iprimaries, anditrcdefine the incoming properties (BT.601/SMPTE170M).space,primaries, andtrcspecify the desired target properties (BT.709).
Method 3: Tagging Color Metadata Without Modifying Pixels
Sometimes the underlying pixel values are correct, but the media player misidentifies the colors because the container lacks proper signaling flags. You can set color metadata tags during encoding using output options:
ffmpeg -i input_sd.mp4 -c:v libx264 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -crf 18 -c:a copy output_tagged.mp4For H.264 streams, you can also inject these properties without
re-encoding the video by using the h264_metadata bitstream
filter:
ffmpeg -i input_sd.mp4 -c copy -bsf:v "h264_metadata=matrix_coefficients=6:colour_primaries=6:transfer_characteristics=6" output_flagged.mp4(Note: Value 6 corresponds to SMPTE170M / BT.601 in
standard ITU-T H.264 specifications, whereas 1 corresponds
to BT.709).