如何通过GStreamer的avenc_jpeg2000编码器提高JPEG2000文件压缩率?
我使用gst-libav模块的avenc_jpeg2000插件,结合videotestsrc和filesink插件将原始图片编码为JPEG2000图片,执行命令:
gst-launch-1.0 videotestsrc num-buffers=1 ! avenc_jpeg2000 ! filesink location=/tmp/picture-ref.jp2
该流水线可正常运行,生成大小为31.85 KiB(32,616字节)的文件。
我希望将输出文件大小减半,通过提高avenc_jpeg2000编码器的压缩率实现,可接受有损压缩模式。但尝试调整bitrate和bitrate-tolerance属性后,文件大小无变化,执行sha224sum校验的结果一致:
d0da9118a9c93a0420d6d62f104e0d99fe6e50cda5e87a46cef126f9 /tmp/picture-ref.jp2 d0da9118a9c93a0420d6d62f104e0d99fe6e50cda5e87a46cef126f9 /tmp/picture-test-01.jp2
测试配置:i.MX 8M Plus、GStreamer 1.18.0、libav 1.18.0(发布日期:2020-09-08)。请问应如何操作来提高输出文件的压缩率?需调整编码器的哪些属性?
解决方案
为什么bitrate参数不生效?
你使用的libav 1.18.0版本中,avenc_jpeg2000基于FFmpeg的JPEG2000编码器默认采用无损编码或质量优先的逻辑,bitrate参数在这种模式下无法直接控制文件大小,需要切换到有损压缩模式并使用质量相关参数。
可调整的关键属性及示例命令
以下参数能有效控制压缩率,实现文件大小减半的目标:
qscale(质量缩放因子)
这是最直接的控制参数,取值范围通常为1~31(值越大,压缩率越高,画质损失越明显)。你可以逐步调整数值,直到文件大小接近15-16 KiB:gst-launch-1.0 videotestsrc num-buffers=1 ! avenc_jpeg2000 qscale=10 ! filesink location=/tmp/picture-test-qscale.jp2lossless(无损模式开关)
先显式关闭无损模式,再配合质量参数,确保编码器进入有损压缩逻辑:gst-launch-1.0 videotestsrc num-buffers=1 ! avenc_jpeg2000 lossless=false qscale=12 ! filesink location=/tmp/picture-test-lossless.jp2crf(恒定质量因子)
若你的版本支持CRF模式(部分旧版本可能有限制),可尝试该参数,取值范围0~51(0为无损,值越大压缩率越高):gst-launch-1.0 videotestsrc num-buffers=1 ! avenc_jpeg2000 crf=20 ! filesink location=/tmp/picture-test-crf.jp2
验证步骤
每次调整参数后,用ls -lh /tmp/picture-test-*.jp2查看文件大小,或用sha224sum确认文件已变更,同时检查图片画质是否符合预期。
内容的提问来源于stack exchange,提问作者qfr.bertin.group

