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.

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.mp4

Command Breakdown: