为什么 ffmpeg 中的位移复杂滤波器使 Cb 和 Cr 平面的位移与 lum 不同?

问题描述 投票:0回答:2

我有一个使用 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 中使用的表达式与问题的目的无关。

在计算的最后,我得到的输入视频的像素没有正确移位,这意味着我可以清楚地看到一种在移位但黑白的视频下携带颜色信息的鬼影。 经过一些测试,我注意到创建的位移贴图只有亮度平面正确位移,而色度平面位移,但与亮度不同,亮度是输入视频中平面不对齐的根源,如您在下面的摘录中看到的框架:

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

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

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

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

感谢您的宝贵时间。

video ffmpeg video-processing yuv color-space
2个回答
1
投票
正如您所发现的,YUV420P 意味着 Cb 和 Cr 的采样率为一半。每个 Cb/Cr 像素/样本应用于 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
    

0
投票
我有同样的问题,但我没有使用 nullsrc 过滤器,而是使用自己的地图,不幸的是我没有用之前的答案来解决它。这是我正在使用的代码:

ffmpeg -i input.mp4 -i map.mp4 -i map.mp4 -filter_complex "[0][1][2]displace=edge=wrap" -c:v libx264 -pix_fmt yuv420p -t 8 outout.mp4
谢谢🙏

© www.soinside.com 2019 - 2024. All rights reserved.