FFmpeg xstack Pixel Offset Configuration Guide

This article explains how to precisely position multiple video inputs using the xstack filter in FFmpeg. You will learn how to configure the exact pixel offsets for each input stream using the layout parameter, enabling you to create custom grid layouts, picture-in-picture effects, or non-standard video collages with pixel-perfect accuracy.

Understanding the xstack Filter Syntax

The xstack filter combines several input videos into a single output canvas. To define where each video is placed, you must specify the number of inputs and their exact coordinate offsets using the layout option.

The basic syntax for the filter is:

-filter_complex "xstack=inputs=N:layout=X0_Y0|X1_Y1|X2_Y2..."

Configuring Offsets with Fixed Pixel Values

If you know the exact dimensions of your output canvas and your source videos, you can use hardcoded pixel offsets.

For example, if you have four 1920x1080 videos and want to arrange them in a 2x2 grid (resulting in a 3840x2160 output), the top-left pixel coordinates for each video are: * Video 0 (Top-Left): 0_0 * Video 1 (Top-Right): 1920_0 (Shifted 1920 pixels to the right) * Video 2 (Bottom-Left): 0_1080 (Shifted 1080 pixels down) * Video 3 (Bottom-Right): 1920_1080 (Shifted 1920 pixels right and 1080 pixels down)

The corresponding FFmpeg command is:

ffmpeg -i input0.mp4 -i input1.mp4 -i input2.mp4 -i input3.mp4 \
-filter_complex "xstack=inputs=4:layout=0_0|1920_0|0_1080|1920_1080" \
output.mp4

Configuring Offsets using Dynamic Variables

Hardcoding pixel values requires you to know the exact dimensions beforehand. To make your commands reusable, FFmpeg provides variables to reference the width (w) and height (h) of each input stream: * w0 and h0 for Input 0 * w1 and h1 for Input 1 * w2 and h2 for Input 2, and so on.

Using these variables, the 2x2 grid command can be written dynamically:

ffmpeg -i input0.mp4 -i input1.mp4 -i input2.mp4 -i input3.mp4 \
-filter_complex "xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0" \
output.mp4

In this setup: * 0_0 places the first video at the top-left origin. * w0_0 places the second video immediately to the right of the first video. * 0_h0 places the third video directly beneath the first video. * w0_h0 places the fourth video to the right of the third video and beneath the second.

Custom Asymmetric Layouts and Padding

You can use mathematical expressions within the offsets to create custom layouts, such as adding gaps (padding) between videos or leaving space for a background.

For example, if you want to place two 640x360 videos side-by-side but want a 20-pixel gap between them and a 10-pixel border at the top and left: * Video 0 Position: 10_10 (Offset by 10 pixels on both X and Y axes) * Video 1 Position: 10+w0+20_10 (Starts at 10 pixels + width of Video 0 + 20-pixel gap, and 10 pixels down)

The FFmpeg command for this custom offset layout is:

ffmpeg -i input0.mp4 -i input1.mp4 \
-filter_complex "xstack=inputs=2:layout=10_10|10+w0+20_10" \
output.mp4

Important Considerations

  1. Canvas Size: The xstack filter automatically calculates the size of the output canvas based on the maximum dimensions reached by your specified layouts.
  2. Unfilled Areas: Any areas of the output canvas not covered by an input video will be filled with black by default.
  3. Framerate and Pixel Format: For the best results and to prevent synchronization issues, ensure all input videos have the same framerate and pixel format before passing them into the xstack filter.