使用libav将rgb编码为yuv420p

问题描述 投票:0回答:2

我正在尝试使用 libav 将 RGB 图像数据向量(源自 .png 图像)转换为 YUV420p 格式。

在 libav 示例代码中,以下用于创建虚拟图像:

/* prepare a dummy image */
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
{
    int x, y, i;

    i = frame_index;

    /* Y */
    for(y=0;y<height;y++) {
        for(x=0;x<width;x++) {
            pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
        }
    }

    /* Cb and Cr */
    for(y=0;y<height/2;y++) {
        for(x=0;x<width/2;x++) {
            pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
            pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
        }
    }
}

这里有几件事我不太清楚:

首先,我是否需要重新排列输入向量中的 RGB 数据,使其适合编码为 YUV420p?

其次,我知道每个像素都有一个 Y 值,并且 Cb 和 Cr 值用于四个 (2x2) 像素。我不明白的是 RGB 数据如何“减少”为 Cb 和 Cr 值 - 有没有一个示例说明如何在任何地方执行此操作?

rgb multimedia yuv libav
2个回答
0
投票

我不完全确定你到底想达到什么目的,所以我会尽我所能直接回答你的问题(请随时跟进澄清评论):

1) 您将把 RGB 数据转换为 YUV,这将涉及一些重新排列。打包的 RGB 数据在原处就很好。你其实不需要调整它。实际上,出于缓存局部性的原因,最好将其保留原样。

2) 正如您已经了解的,YUV 4:2:0 为每个像素编码一个 Y 样本,但每个 2x2 块共享一个 Cb 和一个 Cr 值。不过,还有 YUV 4:4:4 数据。这是每个像素获取自己的 Y、Cb 和 Cr 样本的地方。转换 RGB -> YUV 4:2:0 的一个简单策略是转换 RGB -> YUV 4:4:4,然后对每个 2x2 Cb 样本块进行平均(算术平均)。还有其他算法(例如涉及更多周围样本的过滤器),但如果您只是尝试这些东西的工作原理,这应该可以工作。

另一种实验(和速度)策略是仅计算 Y 平面并将 Cb 和 Cr 平面保持在 128。这将产生灰度图像。

对于实际工作,您可能希望利用 libav 提供的内置转换工具。


0
投票

使用 libav example 将 RGB 图像数据向量(源自 .png 图像)转换为 YUV420p 格式。

© www.soinside.com 2019 - 2024. All rights reserved.