What You Will Learn
- The command for applying tone curve correction with the
curvesfilter - How to specify the master curve and individual RGB curves
- The list of built-in presets (
preset) and how to use them - Techniques for adjusting highlights and shadows independently
Tested with: FFmpeg 6.1 (verified against real FFmpeg)
Target OS: Windows / macOS / Linux
Basic Commands
Boost Contrast with the Master Curve (S-Curve)
ffmpeg -i input.mp4 -vf "curves=master='0/0 0.25/0.15 0.5/0.5 0.75/0.85 1/1'" output.mp4
master is a curve applied to all channels. 0/0 represents a control point in the form input value/output value. An S-curve increases contrast. If you only need a quick brightness or contrast tweak, adjusting them with the eq filter is simpler.
Adjust the Red Channel Only
ffmpeg -i input.mp4 -vf "curves=red='0/0 0.5/0.6 1/1'" output.mp4
With red, green, and blue you can specify the curve for each channel individually.
Use a Built-in Preset
ffmpeg -i input.mp4 -vf "curves=preset=vintage" output.mp4
You can pass any of the following preset names to preset.
List of Built-in Presets
| Preset Name | Description |
|---|---|
none | No change (default) |
color_negative | Negative inversion |
cross_process | Cross-process look |
darker | Darkens the whole image |
increase_contrast | Contrast enhancement |
lighter | Brightens the whole image |
linear_contrast | Linear contrast |
medium_contrast | Medium contrast |
negative | Negative |
strong_contrast | Strong contrast |
vintage | Vintage look |
ffmpeg -i input.mp4 -vf "curves=preset=cross_process" output.mp4
How to Write Control Points
Control points are listed in the form input value/output value, separated by spaces. The value range is 0.0 (darkest) to 1.0 (brightest).
master='0/0 0.5/0.7 1/1'
0/0— black (input 0 → output 0)0.5/0.7— lifts the midtones to make them brighter1/1— white (input 1 → output 1)
FFmpeg performs spline interpolation between the control points you specify. The more control points you add, the finer the adjustment you can make.
Combining Individual RGB Curves
ffmpeg -i input.mp4 \
-vf "curves=red='0/0 1/0.9':green='0/0 1/0.95':blue='0/0 0.8/1 1/1'" \
output.mp4
By slightly suppressing red and green while lifting the blue highlights, you get a cool-toned grade. To rotate the overall hue instead, pair this with adjusting hue and saturation with the hue filter.
Combining a Preset with the Master Curve
ffmpeg -i input.mp4 \
-vf "curves=preset=vintage:master='0/0 0.5/0.55 1/1'" \
output.mp4
This is a workflow where you establish the base tone with preset and fine-tune it with master.
Applying to Still Images
ffmpeg -i input.jpg -vf "curves=preset=increase_contrast" output.jpg
Bad Example
Bad example: control points are not in ascending order
ffmpeg -i input.mp4 -vf "curves=master='0/0 0.8/0.3 0.5/0.7 1/1'" output.mp4
The input values (the left-hand values) of the control points must always be in ascending order (small to large). If the order is reversed, you will get an error or an unintended result.
Caveats
- The
curvesfilter operates in the RGB color space. For YUV input, a conversion is performed internally. - At least two control points (
0/xand1/y) are required. - A preset and individual channels can be specified at the same time, but you need to be mindful of the processing order between
masterandpreset.
Measured Example
This example applies a gentle S-curve to a 1080p/30fps, 2-minute H.264 video:
ffmpeg -i input.mp4 \
-vf "curves=master='0/0 0.25/0.18 0.5/0.5 0.75/0.82 1/1'" \
-c:v libx264 -crf 23 -preset medium -c:a copy \
output.mp4
curves can be a little heavier than eq because it performs RGB conversion and interpolation per pixel. On a typical 8-core desktop, processing may take roughly 1.2–2.3x real time. Presets and extra control points do not usually change the cost dramatically, but chaining more filters does.
Raising contrast can emphasize edges and noise, so the same CRF may produce a slightly larger file. Darkening or simplifying the image can do the opposite. Results vary by environment.
In practice, start with a modest curve such as 0.25/0.2 and 0.75/0.8. Check for crushed blacks, clipped highlights, and banding in smooth skies or walls. Exporting one comparison frame as PNG makes A/B checks easier.
Related Filters
hue— adjusts hue, saturation, and brightnesseq— adjusts brightness, contrast, and gammacolorbalance— color correction for shadows, midtones, and highlightslut3d— color grading via a 3D LUT