How to Change Color Matrix in FFmpeg for SD Video

This article explains how to adjust and set the color matrix coefficients for Standard Definition (SD) video using FFmpeg. You will learn how to convert color spaces (such as from HD BT.709 to SD BT.601) and how to correctly tag video metadata so media players render the colors accurately.

Understanding SD Color Matrices

Standard Definition (SD) video typically utilizes the BT.601 color matrix (often represented in FFmpeg as smpte170m or bt470bg). In contrast, High Definition (HD) video uses BT.709. If you play an SD video with the wrong color matrix settings, the colors may appear washed out, overly saturated, or shifted green/magenta.

To fix this, you can either convert the actual pixel values to the correct color space, tag the metadata to tell the player which color space to use, or do both.


Method 1: Converting the Color Space (Filter Method)

If your video was encoded with the wrong color coefficients (for example, an SD video using HD BT.709 colors), you can convert the actual color properties using FFmpeg filters.

Using the colormatrix Filter

The colormatrix filter allows you to convert directly from one color space to another. To convert a video from BT.709 to BT.601 (specifically smpte170m for SD):

ffmpeg -i input.mp4 -vf colormatrix=bt709:smpte170m -c:v libx264 -crf 18 -c:a copy output.mp4

Using the scale Filter

Alternatively, you can use the scale filter, which is highly efficient and handles color space conversion during scaling:

ffmpeg -i input.mp4 -vf scale=out_color_matrix=bt601 -c:v libx264 -crf 18 -c:a copy output.mp4

Method 2: Flagging the Metadata (No Re-encoding / Fast Method)

Sometimes the pixels are already correct, but the video file lacks the metadata flags telling the player to use BT.601. You can set these flags without re-encoding the video by using bitstream filters, which is extremely fast and preserves original quality.

For H.264 video, use the h264_metadata bitstream filter to set the transfer characteristics, color primaries, and color matrix to BT.601 (smpte170m):

ffmpeg -i input.mp4 -c:v copy -bsf:v h264_metadata=video_full_range_flag=0:colour_primaries=6:transfer_characteristics=6:matrix_coefficients=6 -c:a copy output.mp4

(Note: Value 6 corresponds to the BT.601/SMPTE170M standard in H.264 specifications).


To ensure maximum compatibility across all players and devices, it is best to convert the color space and explicitly write the metadata tags at the same time. Use the following command to encode the video with BT.601 colors and inject the correct tags:

ffmpeg -i input.mp4 -vf scale=out_color_matrix=bt601 -c:v libx264 -pix_fmt yuv420p -color_range tv -colorspace smpte170m -color_trc smpte170m -color_primaries smpte170m -crf 18 output.mp4

Command Breakdown: