为什么 Cb 和 Cr 平面通过 ffmpeg 中的置换复数过滤器与 lum 置换不同?

Why are Cb and Cr planes displaced differently from lum by the displace complex filter in ffmpeg?

我有一个用 yuv420p 像素格式编码的视频,我想置换它的像素。我正在使用 ffmpeg 及其新的置换过滤器。该过滤器将分别用于 X 轴和 Y 轴的两个位移图作为输入(要置换的视频和)。我决定使用 nullsrc 视频源过滤器和 geq 过滤器将置换贴图直接创建到 ffmpeg 中,以指定三个平面的值:lum、Cb、Cr。脚本如下:

ffmpeg INPUT.mp4 -f lavfi -i nullsrc=size=${WIDTH}x${HEIGHT}:d=0.1,geq='lum=128+30*sin(2*PI*X/400):Cb=128+30*sin(2*PI*X/400):Cr='128+30*sin(2*PI*X/400)' -f lavfi -i nullsrc=size=${WIDTH}x${HEIGHT}:d=0.1,geq='lum=128+30*sin(2*PI*X/400):Cb=128+30*sin(2*PI*X/400):Cr=128+30*sin(2*PI*X/400)' -lavfi '[0][1][2]displace' OUTPUT.mp4

我使用了 ffmpeg 文档中提供的示例,因为 geq 中使用的表达式与问题的目的无关。

在计算的过程中,我得到输入视频的像素没有正确移位,这意味着我可以清楚地看到一种在移位但 b/w 下的重影携带颜色信息视频. 经过一些测试,我注意到创建的位移图只有亮度平面正确位移,而色度平面位移,但不同于亮度,这是输入视频中平面不对齐的起源,如您在以下摘录中所见帧数:

我还注意到描述置换贴图的 Cb 和 Cr 平面的视频具有亮度平面分辨率的一半。

我的问题是:如何正确设置 geq 定义中的 Cr 和 Cb 平面,以便它们与亮度平面完全相同?

如果有人能向我解释为什么 ffmpeg 给我的亮度和 Cb、Cr 平面的输出如此不同,即使提供的功能是相同的,那也很好。

如果有帮助,我正在使用 ffmpeg 3.3 静态构建。

谢谢你的时间。

YUV420P 意味着 Cb 和 Cr 被采样,正如您发现的那样,采样率为一半。每个 Cb/Cr pixel/sample 应用于 4 个像素(在本例中为 2x2)。您的表达式将每个色度样本位移与亮度相同的量,这具有使有效位移加倍的效果。解决方法是将输入和置换贴图重新缩放到完全采样的色度平面,并根据需要在过滤结束时下采样到 4:2:0。

ffmpeg -i in.mp4 -f lavfi -i nullsrc=size=1280x720:d=0.1,format=yuv444p,geq=lum='128+30*sin(2*PI*X/400)':cb='(128+30*sin(2*PI*X/400))':cr='(128+30*sin(2*PI*X/400))' -lavfi [0]format=yuv444p[v];[v][1][1]displace,format=yuv420p out.mp4

要处理 YUV420P 输入,无需任何像素格式转换,请使用

ffmpeg -i in.mp4 -f lavfi -i nullsrc=size=1280x720:d=0.1,geq=lum='128+30*sin(2*PI*X/400)':cb='(128+15*sin(2*PI*2*X/400))':cr='(128+15*sin(2*PI*2*X/400))' -lavfi [0][1][1]displace out.mp4