The FFmpeg crop filter often fails with NVIDIA hardware encoders because the pixel format requirements differ between software and GPU-based processing. The NVIDIA encoder expects specific aligned resolutions and pixel formats that standard cropping does not automatically provide, leading to encoding errors or black frames.
Understanding the Root Cause
When you attempt to use the
crop filter in conjunction with an NVIDIA video encoder such as
h264_nvenc or
hevc_nvenc, you may encounter immediate failure. This is not a bug in FFmpeg itself but a constraint of the hardware acceleration pipeline. Hardware encoders on NVIDIA GPUs typically require input frames to have dimensions that are multiples of 16 for width and height, depending on the specific codec and driver version. Additionally, they often expect specific pixel formats like
nv12 or
yuv420p rather than the raw RGB or other formats produced by standard demuxing.
If you simply apply a crop filter that results in odd numbers or non-aligned dimensions, the hardware encoder will reject the frame data. For example, cropping a 1920x1080 video to 1919x1079 will fail because 1919 is not divisible by 16. This strict alignment requirement is a common source of confusion for users who find that the same command works perfectly with a software encoder like
libx264.
Checking Your Current Setup
Before attempting a fix, it is helpful to verify if your current setup aligns with these constraints. You can test your command structure without actually encoding the full file by using a dummy output or checking the filter graph validation. As discussed in our guide on testing commands, verifying the syntax helps isolate whether the issue is structural or related to resource allocation. See
Possible Test FFmpeg Command Without Actual Running for methods to validate your filter chain before committing to a long encode job.
The Solution: Using the Scale Filter
The most reliable workaround is to combine the
crop filter with the
scale filter. The
crop filter extracts the desired region, but the
scale filter ensures that the resulting dimensions meet the alignment requirements of the NVIDIA encoder. By explicitly setting the scale parameters to round down to the nearest multiple of 16, you guarantee compatibility.
You should use the
scale filter with the
trunc(iw/2)*2 and
trunc(ih/2)*2 expressions, or more strictly for NVIDIA, multiples of 16. A robust formula often used is
scale=trunc(oh*a/2)*2:trunc(ow/2)*2, but for NVENC, targeting 16-pixel boundaries is safer.
Here is a corrected command structure:
ffmpeg -i input.mp4 -vf "crop=w:h:x:y,scale=trunc(iw/16)*16:trunc(ih/16)*16" -c:v h264_nvenc output.mp4
In this example, replace
w:h:x:y with your specific crop parameters. The
scale filter immediately following it adjusts the resolution to the nearest valid size for the GPU. Note that this might slightly change the aspect ratio or add black bars if not calculated carefully, so precise dimension management is key.
Alternative Approaches for Complex Cropping
If your cropping needs are complex, such as rotating or applying advanced geometric transformations, the basic crop and scale method might introduce artifacts. In such cases, consider using the
format filter to explicitly set the pixel format to
nv12 after scaling. This ensures the color space matches what the NVIDIA encoder expects.
ffmpeg -i input.mp4 -vf "crop=w:h:x:y,scale=trunc(iw/16)*16:trunc(ih/16)*16,format=nv12" -c:v h264_nvenc output.mp4
This approach is particularly useful when dealing with high-bit-depth sources or unusual color spaces. If you are experiencing resolution mismatches despite using crop, refer to our detailed analysis on resizing issues. Check out
Tried Resizing Video with FFmpeg, Got Different Strange Resolution? Try Crop for deeper insights into dimension handling.
Common Pitfalls and Debugging Steps
Even with the correct filters, several pitfalls can cause failures. First, ensure that your FFmpeg build includes NVIDIA support. You can check this by running
ffmpeg -encoders | grep nvenc. If no output appears, your installation lacks hardware acceleration capabilities.
Second, verify that the input video is not already in a compressed format that conflicts with the decoding process. Sometimes, pre-compressed videos have internal padding or alignment issues that crop filters cannot resolve. In these cases, re-encoding with a software encoder first, then passing to NVIDIA, might be necessary.
Third, check the logs for specific error codes. NVIDIA encoders often return cryptic errors like
Invalid argument or
Unsupported pixel format. These usually point directly to dimension or format mismatches addressed by the scale and format filters mentioned above.
Finally, remember that hardware encoding has different quality profiles. Ensure you are using appropriate preset settings (
-preset p4 to
p8) to balance speed and quality, especially when dealing with altered resolutions.
Frequently Asked Questions
Why does my crop work with libx264 but fail with h264_nvenc?
Software encoders like libx264 are more flexible with pixel formats and unaligned dimensions. Hardware encoders require strict alignment (multiples of 16) and specific pixel formats like nv12 to function correctly within the GPU memory space.
How do I calculate the correct scale values for my crop?
Use the expression
trunc(iw/16)*16:trunc(ih/16)*16 in the scale filter. This mathematically rounds down the width and height to the nearest multiple of 16, ensuring compatibility with most NVIDIA GPU encoders.
Can I use crop with HEVC NVENC?
Yes, the same principles apply to HEVC NVENC. You must still ensure that the final scaled dimensions are aligned to 16-pixel boundaries and that the pixel format is compatible, typically nv12 or yuv420p.
What if I need an odd dimension for artistic reasons?
Hardware encoders generally do not support odd dimensions. You must scale to the nearest even or 16-aligned number. You can then add black borders using the
pad filter if maintaining the exact visual composition is critical.
How do I verify my FFmpeg supports NVIDIA encoding?
Run the command
ffmpeg -encoders | findstr nvenc on Windows or
ffmpeg -encoders | grep nvenc on Linux. If you see entries like
h264_nvenc or
hevc_nvenc, your installation is properly configured for hardware acceleration.