Search code examples
ffmpegrgbyuvlibx264

Why does my H.264 video have a green overlay after video filter is applied?


When executing the following code:

ffmpeg -i input.mov -c:v libx264 -preset veryslow -pix_fmt yuv420p -filter_complex "drawtext=fontfile=font.ttf:fontcolor=white@1:fontsize=h/6:x=(w-text_w)/2:y=(h-text_h)/2:text='Henk de Vries'[watermark];[0][watermark]blend=all_mode=difference:all_opacity=1" output.mp4

The output file has a green overlay. When using other blend modes, results vary with some modes displaying correct colors and others green and pink.

I know that the input file has yuv420p colorspacing. I think the blend filter only supports rgba modes but I am not sure.

How can I avoid the green overlay and get the original colors? (e.i. what the original input video looks like)


Solution

  • You're blending a video with a nearly identical copy in difference mode, so most of the pixels will be zero-ed out. In YUV encoding, a 0-valued pixel in both the chroma channels represents green. The luma channel (Y) isn't a pure representation of luminance, and so a value of luma 0 along with both chroma as 0 results in a green colour being rendered.

    Rotem's answer is on the right lines but no intermediate files are required. Simply convert to RGB space beforehand.

    ffmpeg -i input.mov -c:v libx264 -preset veryslow -pix_fmt yuv420p -filter_complex "[0]format=gbrp,split=2[text][orig];[text]drawtext=fontfile=font.ttf:fontcolor=white@1:fontsize=h/6:x=(w-text_w)/2:y=(h-text_h)/2:text='Henk de Vries'[watermark];[orig][watermark]blend=all_mode=difference:all_opacity=1" output.mp4