最好的转换方法是使用 swscale。您可以手动执行此操作,但您的版本会较慢。 ffmpeg 中没有访问像素数据的 API。您必须直接访问缓冲区 YUV420P 是平面格式,因此第一个缓冲区是 Y 平面,每个像素 1 个字节。
U/V 平面为 1 个字节,对应 4 个像素。这是因为在亮度 (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 http://en.wikipedia.org/wiki/YCbCr
缩放错误是您没有正确使用 swscale。您很可能不理解线步幅:http://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx.
我不知道有任何视频编解码器可以在 RGB 色彩空间中运行。您可以使用 libswscale 在 RGB 和 YUV 之间进行转换(略有损耗)。
该视频将解释:https://xiph.org/video/vid2.shtml https://xiph.org/video/vid2.shtml