Force Intermediate Pixel Format in FFmpeg Filtergraph
This article explains how to use the format filter in
FFmpeg to explicitly set intermediate pixel formats within a
filtergraph. You will learn why forcing these formats is necessary for
maintaining image quality, how the syntax works, and how to implement it
in both simple and complex filter chains.
Understanding the Need for Intermediate Pixel Formats
When processing video, FFmpeg automatically negotiates pixel formats between adjacent filters in a filtergraph. While this auto-negotiation is convenient, it can sometimes choose an suboptimal format, leading to unintended color space conversions, loss of chroma information, or compatibility issues with certain filters.
By inserting the format filter as an intermediate step,
you take manual control over the pixel format. This is highly useful
when you want to force high-bit depth processing (like
yuv420p10le) through a specific filter chain before
downsampling to a standard format (like yuv420p) for the
final output encoder.
The format Filter
Syntax
The basic syntax for the format filter is:
format=pix_fmts=pixel_format_name
Or, using the shorthand version:
format=pixel_format_name
To allow FFmpeg to choose from a list of acceptable formats, you can
separate multiple formats with a pipe (|) character:
format=yuv420p|yuv422p|yuv444p
How to Apply It in a Filtergraph
To force an intermediate pixel format, place the format
filter directly between the filters where you want the conversion to
occur.
Example 1: Simple Filterchain
In this example, we scale a video, force an intermediate conversion
to yuv444p for precision, and then let the encoder handle
the final output.
ffmpeg -i input.mp4 -vf "scale=1920:1080,format=yuv444p" output.mp4Example 2: Complex Filtergraph with Intermediate Formats
In a complex filtergraph (-filter_complex), you might
want to force a specific pixel format before overlaying elements or
applying color adjustments to prevent quality degradation.
Here, we force the video into high-precision rgb24 for a
custom filtering step, and then convert it back to yuv420p
at the end of the graph to ensure maximum playback compatibility:
ffmpeg -i input.mp4 -i logo.png -filter_complex "[0:v]scale=1920:1080,format=rgb24[bg];[bg][1:v]overlay=10:10,format=yuv420p[out]" -map "[out]" output.mp4In this command: 1. The background video (0:v) is scaled
and immediately converted to rgb24 using
format=rgb24. 2. The logo is overlaid onto the RGB
background. 3. The final combined stream is converted back to
yuv420p using format=yuv420p before being sent
to the encoder.