【问题标题】:RGB-frame encoding - FFmpeg/libavRGB 帧编码 - FFmpeg/libav
【发布时间】:2014-02-24 09:56:01
【问题描述】:

我正在学习 FFmpeg 中的视频编码和解码。我在page 上尝试了代码示例(仅视频编码和解码部分)。这里创建的虚拟图像采用 YCbCr 格式。如何通过创建 RGB 帧来实现类似的编码?我被困在:

首先,如何创建这个 RGB 虚拟帧?

其次,如何编码呢?使用哪个编解码器?他们中的大多数仅适用于 YUV420p...

编辑:我有一个 YCbCr 编码器和解码器,正如 page 上给出的那样。问题是,我的数据库中有 RGB 帧序列,我需要对其进行编码。但编码器适用于 YCbCr。所以,我想知道以某种方式将 RGB 帧转换为 YCbCr(或 YUV420P),然后对其进行编码。 在解码结束时,我得到解码的 YCbCr 帧并将它们转换回 RGB。如何继续?

我确实尝试了 swscontext,但转换后的帧会丢失颜色信息并且还会出现缩放错误。我想过使用两个 for 循环和 colorspace conversion formulae 手动完成 但我无法使用 FFmpeg/libav 库访问帧的单个像素!就像在 OpenCV 中一样,我们可以通过以下方式轻松访问它: Mat img(x,y) 但这里没有这样的东西!我完全是这个领域的新手......

有人可以帮助我吗?

非常感谢!

【问题讨论】:

  • 同一个问题你问了 3 次!
  • huffyuv 和 libx264rgb 支持 rgb24 和 bgra。 utvideo 支持 rgb24 和 rgba。 ffv1 支持 bgr0 和 bgra。 qtrle 支持 rgb24、rgb555be 和 argb。见ffmpeg -h encoder=foo
  • @szatmary 是的,我无法正确发布它,遇到了一些问题。好的,请检查编辑,它更好地解释了我的问题。谢谢!

标签: video encoding ffmpeg video-encoding libavcodec


【解决方案1】:

转换的最佳方法是使用 swscale。您可以手动完成,但您的版本会慢一些。 ffmpeg 中没有访问像素数据的 API。您必须直接访问缓冲区 YUV420P 是平面格式,因此第一个缓冲区是 Y 平面,每个像素 1 个字节。 U/V 平面为 4 个像素的 1 个字节。这是因为在假设亮度 (Y) 通道包含最多信息的情况下,U 和 V 平面被缩放到 Y 平面的 1/4 大小。

00250     picture->data[0] = picture_buf;
00251     picture->data[1] = picture->data[0] + size;
00252     picture->data[2] = picture->data[1] + size / 4;

其次,我们来看看色彩空间的转换。

void YUVfromRGB(double& Y, double& U, double& V, const double R, const double G, const double B)
{
  Y =  0.257 * R + 0.504 * G + 0.098 * B +  16;
  U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  V =  0.439 * R - 0.368 * G - 0.071 * B + 128;
}

并插入一些虚拟值:

R = 255, G = 255, B = 255
Y =  235

R = 0, G = 0, B = 0
Y = 16

如您所见,范围 0 -> 255 被压缩为 16 -> 235。因此,我们已经证明了 RGB 颜色空间中的某些颜色在(数字)YUV 颜色空间中不存在。那么我们为什么要使用YUV呢?那就是色彩空间电视的使用可以追溯到 1950 年,当时彩色通道 (U/V) 被添加到现有的黑白通道 (Y) 中。

在这里阅读更多: http://en.wikipedia.org/wiki/YCbCr

缩放错误是您没有正确使用 swscale。很可能您不了解行步: http://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx

我不知道在 RGB 颜色空间中运行的任何视频编解码器。您可以使用 libswscale 在 RGB 和 YUV 之间进行转换(稍微有损)。

此视频将解释: https://xiph.org/video/vid2.shtml

【讨论】:

  • 事实上,这是在各种 RGB 颜色空间中本地运行的大量视频编解码器,尽管大多数自​​然的面向视频的编解码器都是严格的 YUV。
  • @MultimediaMike 你能推荐任何可以更好地减小文件大小的编解码器
  • @mmxprime 我需要更多地了解视频数据的具体类型。有很多视频编解码器,因为有很多不同的用例。
  • @MultimediaMike 嘿,请参阅编辑。我的问题现在得到了更好的解释。谢谢!
【解决方案2】:

我认为可以对原始视频进行编码。在您所指的示例中。您必须使用 CODEC_ID_RAWVIDEO 在 avcodec_find_encoder 中查找原始图像的编码器。在编解码器上下文 pix_fmt 即 c->pix_fmt 中,您可以使用 PIX_FMT_RGB24。最后,您需要创建虚拟 rgb24 帧而不是 YCbCr。

【讨论】:

  • 使用这个我们可以直接编码RGB吗?但是您的回答与下面 szatmary 的回答相矛盾
  • @praks411 如何创建虚拟 RGB 帧?这也是我提到的问题之一……我对 FFmpeg 库不太熟悉。这在 OpenCV 中会很容易。你能提出一些建议吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-01-27
  • 2021-08-08
  • 2016-06-26
  • 1970-01-01
  • 2016-11-10
  • 2015-05-21
  • 2014-04-23
  • 2020-08-24
相关资源
最近更新 更多