How to Use the FFmpeg maskedclamp Filter

The maskedclamp filter in FFmpeg is a multi-stream video filter that limits the pixel values of a primary video stream based on the pixel values of two auxiliary streams representing lower and upper thresholds. This guide provides a straightforward overview of how the filter operates, its parameters, and practical command-line examples demonstrating how to clamp video dynamic range or reduce filtering artifacts like haloing and ringing.

What Does maskedclamp Do?

The maskedclamp filter takes three video inputs of identical dimensions and pixel formats:

  1. Source stream (first input): The video stream you want to modify.
  2. Lower bound stream (second input): Defines the minimum allowable pixel values.
  3. Upper bound stream (third input): Defines the maximum allowable pixel values.

For every pixel, the filter evaluates:

  • If the source pixel is brighter than the upper limit (plus an optional overshoot), it is clamped down to the upper limit.
  • If the source pixel is darker than the lower limit (minus an optional undershoot), it is clamped up to the lower limit.
  • If the source pixel lies between the lower and upper bounds, it remains unchanged.

Filter Syntax and Parameters

The basic filter signature is:

[base][lower][upper]maskedclamp=undershoot=0:overshoot=0:planes=15

Parameters

  • undershoot: An integer defining how far below the lower bound stream values a source pixel can go before being clamped. The default value is 0.
  • overshoot: An integer defining how far above the upper bound stream values a source pixel can go before being clamped. The default value is 0.
  • planes: A bitmask specifying which color planes to process. Defaults to 15 (all planes: Y, U, V, and A). To process only the luma channel (Y), set this to 1.

Basic Usage with Three Video Files

When using separate video files for the base, lower limit, and upper limit, map all three inputs into a filter_complex graph:

ffmpeg -i source.mp4 -i min_limit.mp4 -i max_limit.mp4 -filter_complex \
"[0:v][1:v][2:v]maskedclamp=undershoot=0:overshoot=0[v]" \
-map "[v]" -map 0:a? -c:v libx264 -crf 18 output.mp4

Practical Example: Clamping an Over-Sharpened Stream

A common use for maskedclamp is preventing edge overshoot or ringing caused by unsharp masking. You can generate the bounds directly within the filter graph using morphological operators like erosion (to create a dark/min bound) and dilation (to create a bright/max bound).

ffmpeg -i input.mp4 -filter_complex \
"[0:v]split=3[base][low_in][high_in]; \
 [base]unsharp=5:5:1.5[sharp]; \
 [low_in]erosion[low]; \
 [high_in]dilation[high]; \
 [sharp][low][high]maskedclamp=undershoot=2:overshoot=2[out]" \
-map "[out]" -c:v libx264 -crf 18 output.mp4

In this pipeline:

  1. The input is split into three identical branches.
  2. The sharp branch applies strong sharpening, which risks creating halos.
  3. The erosion filter shrinks bright details, creating a minimum boundary.
  4. The dilation filter expands bright details, creating a maximum boundary.
  5. maskedclamp forces the sharpened result to stay within the boundaries of the original image's local extremes, allowing a small overshoot and undershoot margin of 2 units to retain natural contrast.