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.mp4

To 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.mp4

Method 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.mp4

In this command:

  • ispace, iprimaries, and itrc define the incoming properties (BT.601/SMPTE170M).
  • space, primaries, and trc specify 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.mp4

For 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).