How to Use FFmpeg Waveform Filter for Luma
FFmpeg includes a built-in waveform filter that
generates a video scope to analyze pixel intensity distributions across
an image. This guide explains how to isolate and monitor luminance
(luma) values using the waveform filter, configure display parameters
such as component selection and intensity, and preview the waveform in
real time alongside your source footage using both ffmpeg
and ffplay.
Understanding the Waveform Filter for Luma
In YUV color spaces, luminance is represented by the \(Y\) plane, while \(U\) and \(V\) represent chrominance. By default, the
FFmpeg waveform filter displays all color components. To
inspect exposure levels, contrast, clipping, and black-crush accurately,
you must restrict the scope to display only the luma component
(Component 1).
Basic Syntax for Luma Analysis
To generate a waveform containing only the luma component, pass
c=1 (or components=1) into the filter
parameters.
Run the following command to export a video with the luma waveform:
ffmpeg -i input.mp4 -vf "waveform=c=1" -c:a copy output.mp4Essential Parameters for Luma Waveforms
You can customize the appearance and behavior of the luma waveform using these parameters:
components(c): Specifies which planes to render. Settingc=1analyzes solely the \(Y\) (luma) channel.mode(m): Sets the layout. The default isrow(horizontal trace). Usecolumn(vertical trace) to align the scope horizontally with the video frame's width:waveform=c=1:m=column.intensity(i): Adjusts the brightness of the waveform trace. The default value is0.04. Increasing this (e.g.,i=0.1) makes faint pixels more visible.filter(e): Changes the smoothing filter. Settinge=lowpassreduces noise, making large exposure shifts easier to interpret.flags(f): Controls overlay options. Setf=dotsto draw individual samples, orf=flatto draw solid traces.
Example with customized intensity and column layout:
ffmpeg -i input.mp4 -vf "waveform=c=1:m=column:i=0.1:f=lowpass" output.mp4Viewing Waveform and Video Side-by-Side
To monitor luma values alongside the original video, use FFmpeg's
split and hstack filters within a
-filter_complex graph:
ffmpeg -i input.mp4 -filter_complex "[0:v]split=2[orig][to_scope];[to_scope]waveform=c=1:m=column[scope];[orig][scope]hstack" -c:a copy output.mp4This splits the incoming video stream, generates a column-based luma waveform on the second stream, and stacks both streams horizontally.
Real-Time Playback with FFplay
To preview the luma waveform immediately without re-encoding to an
output file, use ffplay:
ffplay -vf "waveform=c=1:m=column" input.mp4For a live side-by-side view in ffplay:
ffplay -vf "split=2[v][s];[s]waveform=c=1:m=column[wf];[v][wf]hstack" input.mp4