Gstreamer videoconvert 颜色转换错误?
Gstreamer videoconvert color conversion wrong?
我正在启动一个 gst-launch-1.0
,它使用 nvgstcamera
捕捉相机图像。图像被编码为 VP9 视频。视频 tee
到 filesink
将视频保存在 webm 容器中,然后到 VP9 解码器将图像传输到 appsink
.
稍后,我想从保存的视频中提取帧,然后再次通过应用程序 运行 提取它们。重要的是,帧与视频捕获期间通过管道传输到 appsink
的帧完全相同。
遗憾的是,解码帧看起来略有不同,具体取决于您提取它们的方式。
一个最小的工作示例:
录音:
$ gst-launch-1.0 nvcamerasrc ! "video/x-raw(memory:NVMM), format=NV12" ! omxvp9enc ! tee name=splitter \
splitter. ! queue ! webmmux ! filesink location="record.webm" \
splitter. ! queue ! omxvp9dec ! nvvidconv ! "video/x-raw,format=RGBA" ! pngenc ! multifilesink location="direct_%d.png"
使用 nvvidconv
元素重播:
$ gst-launch-1.0 filesrc location=record.webm ! matroskademux ! omxvp9dec \
! nvvidconv ! pngenc ! multifilesink location="extracted_nvvidconv_%d.png"
使用 videoconvert
元素重播:
$ gst-launch-1.0 filesrc location=record.webm ! matroskademux ! omxvp9dec \
! videoconvert ! pngenc ! multifilesink location="extracted_videoconvert_%d.png"
测试图像差异:
$ compare -metric rmse direct_25.png extracted_nvvidconv_25.png null
0
$ compare -metric rmse direct_25.png extracted_videoconvert_25.png null
688.634 (0.0105079)
nvvidconv:
视频转换:
我猜这与 I420 到 RGB 的转换有关。所以 videoconvert
似乎使用了与 nvvidconv
.
不同的颜色转换
使用 gst-launch -v
启动管道表明两个重播管道的元素功能基本相同,唯一的区别是 videoconvert 默认使用 RGB,而 nvvidconv 使用 RGBA。但是,在 videoconvert
后面添加大写字符串 "video/x-raw,format=RGBA"
不会影响颜色转换。
请注意,这是在 Nvidia Jetson TX2 上进行的,我想在录制期间使用硬件加速 gstreamer 插件(omxvp9enc
、nvvidconv
),但在另一台机器上重播期间不会。
如何在不使用 Nvidia 的 Jetson 特定插件的情况下从视频中提取与录制过程中通过管道 运行 的图像相同的图像?
检查 colorimetry
信息 - https://developer.gnome.org/gst-plugins-libs/stable/gst-plugins-base-libs-gstvideo.html#GstVideoColorimetry
例如,Videoconvert 在转换图像时会考虑这些因素。取决于在输入和输出处找到的上限。
您可能需要检查 Tegra 在这里做什么。如果将信号解释为全范围或电视范围,则很可能存在差异。或者矩阵与 601 和 709 不同。
根据精度,转换过程中可能仍有一些损失。对于视频编解码器的指标,保持 YUV 颜色 space 并在必要时仅使用 RGB 进行显示可能是有意义的。
我正在启动一个 gst-launch-1.0
,它使用 nvgstcamera
捕捉相机图像。图像被编码为 VP9 视频。视频 tee
到 filesink
将视频保存在 webm 容器中,然后到 VP9 解码器将图像传输到 appsink
.
稍后,我想从保存的视频中提取帧,然后再次通过应用程序 运行 提取它们。重要的是,帧与视频捕获期间通过管道传输到 appsink
的帧完全相同。
遗憾的是,解码帧看起来略有不同,具体取决于您提取它们的方式。
一个最小的工作示例:
录音:
$ gst-launch-1.0 nvcamerasrc ! "video/x-raw(memory:NVMM), format=NV12" ! omxvp9enc ! tee name=splitter \
splitter. ! queue ! webmmux ! filesink location="record.webm" \
splitter. ! queue ! omxvp9dec ! nvvidconv ! "video/x-raw,format=RGBA" ! pngenc ! multifilesink location="direct_%d.png"
使用 nvvidconv
元素重播:
$ gst-launch-1.0 filesrc location=record.webm ! matroskademux ! omxvp9dec \
! nvvidconv ! pngenc ! multifilesink location="extracted_nvvidconv_%d.png"
使用 videoconvert
元素重播:
$ gst-launch-1.0 filesrc location=record.webm ! matroskademux ! omxvp9dec \
! videoconvert ! pngenc ! multifilesink location="extracted_videoconvert_%d.png"
测试图像差异:
$ compare -metric rmse direct_25.png extracted_nvvidconv_25.png null
0
$ compare -metric rmse direct_25.png extracted_videoconvert_25.png null
688.634 (0.0105079)
nvvidconv:
视频转换:
我猜这与 I420 到 RGB 的转换有关。所以 videoconvert
似乎使用了与 nvvidconv
.
使用 gst-launch -v
启动管道表明两个重播管道的元素功能基本相同,唯一的区别是 videoconvert 默认使用 RGB,而 nvvidconv 使用 RGBA。但是,在 videoconvert
后面添加大写字符串 "video/x-raw,format=RGBA"
不会影响颜色转换。
请注意,这是在 Nvidia Jetson TX2 上进行的,我想在录制期间使用硬件加速 gstreamer 插件(omxvp9enc
、nvvidconv
),但在另一台机器上重播期间不会。
如何在不使用 Nvidia 的 Jetson 特定插件的情况下从视频中提取与录制过程中通过管道 运行 的图像相同的图像?
检查 colorimetry
信息 - https://developer.gnome.org/gst-plugins-libs/stable/gst-plugins-base-libs-gstvideo.html#GstVideoColorimetry
例如,Videoconvert 在转换图像时会考虑这些因素。取决于在输入和输出处找到的上限。
您可能需要检查 Tegra 在这里做什么。如果将信号解释为全范围或电视范围,则很可能存在差异。或者矩阵与 601 和 709 不同。
根据精度,转换过程中可能仍有一些损失。对于视频编解码器的指标,保持 YUV 颜色 space 并在必要时仅使用 RGB 进行显示可能是有意义的。