基本问题: 适合以无损方式存储/归档科学视频数据的编解码器是什么?
我正在尝试帮助我的研究小组存储/归档一些用显微镜录制的视频。这些(灰度)视频采用未压缩的(原始视频)BGR24 格式,660x492@61fps,通常约 1 分钟长。我的实验室同事对这些文件的庞大大小(每个文件数 GB)感到抓狂。我建议使用无损编解码器压缩它们。(这里需要无损是因为视频是科学数据;因此存在有损编解码器可能会以不良/意外的方式更改内容的风险。)
以下是我尝试的方法。首先,我截取其中一个视频的前 10 秒,然后使用 FFMpeg 将其转换为单色(原始)格式。
ffmpeg -t 10 -i RecordedData.avi -c:v rawvideo -pix_fmt gray raw_gray.mkv
然后,我尝试使用 libx264 的无损模式(通过设置-crf 0
)来压缩生成的文件
ffmpeg -i raw-gray.mkv -c:v libx264 -crf 0 -pix_fmt yuv420p -color_range pc x264-yuv420p.mkv
最后,我从原始和 h264 MKV 文件中提取了原始 YUV 数据并进行了比较。
ffmpeg -i raw-gray.mkv -c:v rawvideo -pix_fmt gray raw-gray.yuv
ffmpeg -i x264-yuv420p.mkv -c:v rawvideo -pix_fmt gray x264-decompressed.yuv
diff -sq raw-gray.yuv x264-decompressed.yuv
这里,diff
命令报告文件不同,而我预期它们是相同的。这是为什么?这只是一些轻微的舍入误差,还是我在进行 H264(据称无损)压缩后可能会丢失一些东西?发生了一些像素格式的转换(gray (YUV400) <-> YUV420
),但颜色(UV)通道应该为空,因为输入是单色的。
如果我确实丢失了某些内容,我可以做些什么来修复它?是否有其他(无损)编解码器可能更适合我的数据?
更新 1raw-gray.yuv
:我使用 hexdump 更详细地比较了未压缩的 YUV 数据(从未压缩)和x264-decompressed.yuv
(压缩然后解压缩)的内容。以下是前几个字节。
[raw-gray.yuv]
00000000 4e 50 51 53 53 52 51 50 51 51 50 4f 50 50 50 50
00000010 51 51 50 51 52 53 51 51 52 52 53 53 52 51 51 53
00000020 51 53 54 55 53 51 52 54 53 53 52 50 51 50 52 52
00000030 51 52 51 51 51 52 54 52 52 52 51 51 51 53 57 58
00000040 57 57 55 54 54 52 53 51 51 52 53 55 55 54 53 53
00000050 51 51 52 52 53 52 51 50 50 50 50 51 51 4f 4f 4e
00000060 4c 4d 4e 4d 4f 50 4f 50 51 51 51 52 52 52 52 50
00000070 50 50 52 52 53 55 55 55 57 52 53 53 53 54 56 56
[x264-decompressed.yuv]
00000000 53 55 56 57 57 56 56 55 56 56 55 54 55 55 55 55
00000010 56 56 55 56 56 57 56 56 56 56 57 57 56 56 56 57
00000020 56 57 58 59 57 56 56 58 57 57 56 55 56 55 56 56
00000030 56 56 56 56 56 56 58 56 56 56 56 56 56 57 5b 5c
00000040 5b 5b 59 58 58 56 57 56 56 56 57 59 59 58 57 57
00000050 56 56 56 56 57 56 56 55 55 55 55 56 56 54 54 53
00000060 51 52 53 52 54 55 54 55 56 56 56 56 56 56 56 55
00000070 55 55 56 56 57 59 59 59 5b 56 57 57 57 58 5a 5a
前一个文件中的值比后一个文件中的值少 4 到 5 个。进一步深入研究文件后,也会发现同样的情况。
更新 2:如果我在 RGB 模式下使用 libx264,除了执行以下操作之外,我还可以通过执行上述相同操作来获得与原始完全匹配的结果。
ffmpeg -i raw-gray.mkv -c:v libx264rgb -crf 0 -pix_fmt bgr24 x264-bgr24.mkv
ffmpeg -i x264-bgr24.mkv -c:v rawvideo -pix_fmt gray x264-bgr24-decomp.yuv
diff -sq raw-gray.yuv x264-bgr24-decomp.yuv
最后一个命令报告这两个文件相同。不幸的是,x264-bgr24.mkv
大约是 的3倍x264-yuv420.mkv
,因此RGB模式下的压缩效果不太好。
我读到过一些文章说,libx264 在 YUV 模式下可以高效压缩灰度视频,因为它意识到只有 Y 通道包含真实信息(单色视频的 U 和 V 通道均为零)。在 RGB 模式下,我相信所有通道对于单色输入都包含相同的信息。也许 libx264rgb 没有利用这一点。
所以,有没有办法让我使用 YUV 模式而不改变视频,因为这样压缩效率更高?
更新 3:我能够通过使用-pix_fmt yuvj420p
而不是 来解决 libx264 的问题-pix_fmt yuv420p -color_range pc
。然后,我在压缩/解压缩后准确重现原始文件。从 FFmpeg 文档中,我有一种印象,这两组标志是等效的,但显然事实并非如此。唯一的问题是,我收到后一组标志的警告:[swscaler @ 0x55b56347fe20] deprecated pixel format used, make sure you set the range correctly
。此外,我发现这个错误报告这可能与我的问题有关。我不确定不使用显然已弃用的 yuvj420p 像素格式的“正确”做法。
答案1
这不是您实际问题的直接答案,但我会考虑使用 FFmpeg 内部FFV1
编解码器:
$ ffmpeg -i raw-gray.mkv -c:v ffv1 ffv1.mkv
或者,它的第 3 版:
$ ffmpeg -i raw-gray.mkv -c:v ffv1 -level 3 ffv1.mkv
然后:
$ ffmpeg -i ffv1.mkv -c:v rawvideo -pix_fmt gray raw-gray.yuv
$ diff -sq raw-ffv1.yuv raw-gray.yuv
Files raw-ffv1.yuv and raw-gray.yuv are identical
使用 时,它在无损模式下不如 libx264 高效yuv420p
,但比使用 libx264 更高效bgr24
(在我的测试中,数据速率介于两者之间)。国会图书馆等一些机构也将 FFV1 视为适合的保存格式。