Generate Map Files for FFmpeg Remap Filter
This article explains how to generate the X and Y coordinate map
files required by the FFmpeg remap filter. You will learn
the underlying format requirements of these map files, how to
programmatically generate them using a Python script, and how to apply
them to your video files using FFmpeg.
Understanding FFmpeg Remap Map Files
The FFmpeg remap filter rearranges pixels from a source
video to a destination video based on two map files: an
X-map and a Y-map.
- The X-map determines which horizontal coordinate (column) of the source video is mapped to each pixel of the destination video.
- The Y-map determines which vertical coordinate (row) of the source video is mapped to each pixel of the destination video.
Both map files must have the exact resolution of the desired
output video. They are typically formatted as raw binary
streams of 16-bit unsigned integers (gray16le for pixel
values from 0 to 65535) or 32-bit
floating-point numbers (grayf32le for sub-pixel
precision).
Step 1: Generate Map Files Using Python
The easiest way to generate these binary files is using Python with
the numpy library. The following script generates an
identity map (which leaves the image unchanged) and demonstrates how to
apply a simple transformation—such as shifting the video
horizontally.
import numpy as np
# Define the target output resolution
width = 1920
height = 1080
# Create a grid of coordinates corresponding to the destination image
# x represents column indices, y represents row indices
x, y = np.meshgrid(np.arange(width), np.arange(height))
# --- Define Your Transformation Here ---
# As an example, we will shift the source image 150 pixels to the right.
# This means destination coordinate (x) pulls from source coordinate (x - 150).
source_x = x - 150
source_y = y
# Clip the coordinates to ensure they stay within valid source video boundaries
# to prevent out-of-bounds rendering artifacts.
source_x = np.clip(source_x, 0, width - 1)
source_y = np.clip(source_y, 0, height - 1)
# ---------------------------------------
# Convert the coordinate arrays to 16-bit unsigned little-endian integers (gray16le)
x_map_raw = source_x.astype(np.uint16)
y_map_raw = source_y.astype(np.uint16)
# Save the arrays to raw binary files
x_map_raw.tofile('x_map.bin')
y_map_raw.tofile('y_map.bin')
print("Map files 'x_map.bin' and 'y_map.bin' generated successfully.")For sub-pixel precision using grayf32le, cast the final
arrays to np.float32 instead of np.uint16 and
save them using .tofile().
Step 2: Apply the Maps in FFmpeg
Once you have generated x_map.bin and
y_map.bin, you must tell FFmpeg to read them as raw video
streams and feed them into the remap filter.
Use the following command to apply the maps to an input video:
ffmpeg -i input.mp4 \
-f rawvideo -pix_fmt gray16le -s 1920x1080 -i x_map.bin \
-f rawvideo -pix_fmt gray16le -s 1920x1080 -i y_map.bin \
-filter_complex "[0:v][1:v][2:v]remap[out]" \
-map "[out]" -c:a copy output.mp4Command Breakdown:
-f rawvideo: Instructs FFmpeg to treat the incoming map files as raw, unformatted video data.-pix_fmt gray16le: Specifies that the map files consist of 16-bit little-endian integers. If you used floats in Python, change this tograyf32le.-s 1920x1080: Defines the resolution of the map files, which must match the dimensions configured in your generator script.-filter_complex "[0:v][1:v][2:v]remap[out]": Takes the primary video source[0:v], the X-map[1:v], and the Y-map[2:v], maps the pixels, and outputs the result to[out].