RGB-frame编码 - FFmpeg/libav

3
我正在学习FFmpeg中的视频编码和解码。我尝试了这个page上的代码示例(仅涉及视频编码和解码部分)。这里创建的虚拟图像是以YCbCr格式。如何通过创建RGB帧来实现类似的编码?我被卡住了:
首先,如何创建这个RGB虚拟帧?
其次,如何对其进行编码?使用哪种编解码器?它们中的大多数仅适用于YUV420p...
编辑:我有一个YCbCr编码器和解码器,就像这个page上所给出的一样。问题是,我的数据库中有RGB帧序列,我需要对其进行编码。但编码器是为YCbCr而设计的。因此,我想知道如何将RGB帧转换为YCbCr(或YUV420P),然后对其进行编码。在解码端,我得到了解码的YCbCr帧并将它们转换回RGB。如何继续前进?
我尝试了swscontext,但转换后的帧失去了颜色信息并且出现了缩放错误。我考虑使用两个for循环和颜色空间转换公式手动完成它,但是我无法使用FFmpeg/libav库访问帧的单个像素!就像在OpenCV中,我们可以轻松地使用类似于:Mat img(x,y) 的东西来访问它,但这里没有这样的东西!我完全是一个新手...

有人能帮帮我吗?

非常感谢!


你重复问了3遍相同的问题! - szatmary
2
huffyuvе’Њlibx264rgbж”ЇжЊЃrgb24е’ЊbgraгЂ‚utvideoж”ЇжЊЃrgb24е’ЊrgbaгЂ‚ffv1ж”ЇжЊЃbgr0е’ЊbgraгЂ‚qtrleж”ЇжЊЃrgb24гЂЃrgb555beе’ЊargbгЂ‚иЇ·еЏ‚и§Ѓffmpeg -h encoder=fooгЂ‚ - llogan
@szatmary 是的,我没能成功地发布它,遇到了一些问题。好的,请查看编辑部分,它更好地解释了我的问题。谢谢! - learner
2个回答

4
最好的转换方式是使用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。 - Multimedia Mike
@MultimediaMike,你能推荐一些可以提供更好文件大小压缩的编解码器吗? - nmxprime
@mmxprime 我需要了解更多关于特定类型的视频数据。由于有许多不同的用例,因此存在许多视频编解码器。 - Multimedia Mike
@MultimediaMike 你好,请看一下我的编辑。现在我的问题解释得更清楚了。谢谢! - learner

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

我们可以直接使用这个编码RGB吗?但是你的答案与下面szatmary的答案相矛盾。 - nmxprime
@praks411,我该如何创建虚拟的RGB帧?这也是我提到的问题之一...我对FFmpeg库不太熟悉。在OpenCV中,这将非常容易。 你能给些建议吗? 谢谢! - learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接