How to Use FFmpeg Waveform to Inspect Luma and Chroma

The waveform video filter in FFmpeg allows you to visually inspect the luminance (luma) and chrominance (chroma) levels of a video stream, operating similarly to an oscilloscope or hardware waveform monitor used in professional broadcast environments. This guide explains the mechanics of the waveform filter, breaks down its essential parameters, and provides ready-to-use commands to inspect luma levels, analyze individual chroma planes, generate multi-channel parade displays, and overlay scopes directly onto your source footage.

Understanding the Waveform Filter

The waveform filter plots the intensity values of video pixels along vertical or horizontal axes. By default, the horizontal axis represents the spatial position across the frame, while the vertical axis represents the signal amplitude (from 0 to 255 for 8-bit video, or 0 to 1023 for 10-bit video).

Key parameters include:

  • mode (m): Determines layout. Options include row, column, parade, and stack.
  • components (c): Bitmask specifying which color components to display (e.g., 1 for Luma/Y, 2 and 4 for Chroma/U and V, or 7 for all three).
  • filter (f): Visual appearance of the trace (lowpass, flat, xflat, aflat).
  • intensity (i): Brightness of the plotted waveform.
  • graticule (g): Draws reference grid lines for measuring signal bounds.

Inspecting Luma (Brightness Distribution)

To measure exposure, detect crushed blacks, and identify blown-out highlights, isolate the luma (Y) channel.

Using ffplay to view the luma waveform in real time:

ffplay -i input.mp4 -vf "waveform=mode=column:components=1:filter=lowpass:graticule=green:flags=numbers"
  • components=1 limits the analysis to the first plane (Y/Luma).
  • filter=lowpass blends the signal traces for a traditional analog monitor look.
  • flags=numbers prints numerical scale markers along the graticule.

If data clusters touch the bottom threshold (0), shadows are clipping. If data reaches the top threshold (255 for 8-bit), highlights are clipping.

Inspecting Chroma (Color Distribution)

To check color balance and saturation limits, view the chroma channels (U and V for YUV video) either individually or side by side.

To inspect only the chroma planes:

ffplay -i input.mp4 -vf "waveform=mode=column:components=6:filter=flat:graticule=dots"

Setting components=6 activates planes 2 and 3 (\(2 + 4 = 6\)), which isolates U and V while hiding the luma trace.

Generating a Waveform Parade

A parade splits the video components into distinct, adjacent graphs, enabling direct comparison of color levels side-by-side.

YUV Parade

To view Luma (Y), Chroma Blue (U), and Chroma Red (V) side-by-side:

ffplay -i input.mp4 -vf "waveform=mode=parade:components=7:filter=lowpass:graticule=green"

RGB Parade

To assess color cast and tonal balance across Red, Green, and Blue channels, convert the pixel format to RGB before passing it to the waveform filter:

ffplay -i input.mp4 -vf "format=gbrp,waveform=mode=parade:components=7:filter=lowpass:graticule=green"

In an RGB parade, neutral whites and grays display equal signal heights across all three columns. If the Red column sits higher than Green and Blue in the upper registers, the image has a warm highlight cast.

Displaying Video and Waveform Side-by-Side

To monitor how visual adjustments impact the waveform simultaneously, combine the original video and the waveform display side-by-side using the hstack filter:

ffplay -i input.mp4 -vf "split=2[vid][scope]; [scope]waveform=mode=column:components=1:filter=lowpass:scale=digital[wave]; [vid][wave]scale2ref=iw:ih[v][w]; [v][w]hstack"

This pipeline duplicates the source stream, processes one copy into a luma waveform scaled to match the original video dimensions, and tiles them horizontally for real-time comparative inspection.