如何使用 FFmpeg 将灰度视频流编码为 MPEG-1?
Posted
技术标签:
【中文标题】如何使用 FFmpeg 将灰度视频流编码为 MPEG-1?【英文标题】:How to encode grayscale video streams to MPEG-1 with FFmpeg? 【发布时间】:2012-01-11 01:41:43 【问题描述】:我有一个来自 Firewire 天文相机的灰度视频流,我想使用 FFmpeg 压缩视频流,但它不接受 MPEG1VIDEO 编解码器的单字节像素格式。如何使用 FFmpeg API 将灰度视频帧转换为 FFmpeg 接受的帧格式?
【问题讨论】:
【参考方案1】:MPEG-1 仅接受 YUV,因此您需要将帧转换为 YUV 格式。使用您通过调用sws_getContext()
创建的SwsContext
结构,然后使用sws_scale()
。
【讨论】:
是的,我的像素是灰度的,我已经尝试过“rawvideo”编解码器,但它没有给我任何压缩,这就是我真正想要的。 您应该使用 rawvideo 作为 input 编解码器。你可以为输出编解码器指定任何你想要的东西,事实上,你不需要 - ffmpeg 会猜测输出文件的扩展名使用的输出格式和编解码器 我使用的是C API,不是命令行工具,我的代码用灰度图像填充AVFrame缓冲区,然后调用编码器函数。 好的,现在我明白了。你说 MPEG1VIDEO 不接受字节像素格式。这是真的 - 它只接受YUV。因此,将您的框架转换为 yuv。使用 SwsContext 结构,通过调用 sws_getContext 创建,然后使用 sws_scale。我认为还有 img_convert 但我认为它已被弃用。我有代码可以在某处执行此操作,因此如果您遇到问题,我可以提供帮助。 我想了很多,我希望找到一个可以本地处理灰度的编解码器,同样感谢您的帮助,您能否编辑您的答案以反映这一点,我会接受.【参考方案2】:灰度和YUV的关系很简单——YUV的“Y”和灰度完全一样。
将灰度转换为 YUV 的更简单方法是
有关尺度之间的转换,请参阅this 参考:
因此:
Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 现在: 对于灰度图像 (W): R = W; G = W; B = W; 保持这个: Y[i] = 0.895 * W[i] + 16。 U[i] = 128(固定值) V[i] = 128(固定值)您实际上可以使用几乎相同的 Y[i] = W[i]。 128 值表示 0-256 有符号到无符号转换的缩放/移位基数中的“0”。
因此,您需要保留的只是将另一个内存区域 Y 和 U 创建为固定值,并将此帧提供给 ffmpeg。
我不确定,但通过适当地告诉 FFMPEG,它只在内部执行此操作。您提供的 RGB 值也同样包含在此处;这也不是 MPEG 原生的。
因此,请寻找能够让您执行此操作的 FFMPEG 的 API。
奖金 请记住,在过去的美好时光里,有黑白(灰度)电视机。新的彩电,需要兼容旧的,所以颜色信息以 U 和 V 的形式添加(有时也称为 YCbCr - 其中 Cb 和 Cr 被称为色度,分别是 UV 在这个上下文)。
【讨论】:
感谢您的信息,幸运的是 sws_getContext 和 sws_scale 函数非常有效地执行了转换。【参考方案3】:如果您只使用“色调”过滤器,它就可以工作;像这样:
ffmpeg -i inputfile.ogv -vf hue=s=0 outputfile-unsat.ogv
【讨论】:
我认为你误解了这个问题 旧答案,但问题是关于如何从科学设备中获取灰度视频并通过 FFmpeg 进行处理。【参考方案4】:ffmpeg 有任何问题都需要先下载最新版本,会修复一些bug:
https://ffmpeg.org/download.html#build-windows
【讨论】:
请不要将相同的答案粘贴到多个位置。此外,这个问题已经有了一个公认的答案——它与升级到最新版本无关。这是一个非常笼统的建议,并没有试图回答所提出的具体问题。以上是关于如何使用 FFmpeg 将灰度视频流编码为 MPEG-1?的主要内容,如果未能解决你的问题,请参考以下文章
使用ffmpeg libavcodec将视频流编码为H264,为啥持续时间为零