使用libav将rgb编码为yuv420p

时间:2013-02-12 08:28:20

标签: rgb multimedia yuv libav

我正在尝试使用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值 - 是否有一个如何在任何地方执行此操作的示例?

1 个答案:

答案 0 :(得分:0)

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

1)您将RGB数据转换为YUV,这将涉及一些重新排列。打包的RGB数据很好。你真的不需要调整它。实际上,最好不要按照缓存局部性的原因打包它。

2)如您所知,YUV 4:2:0为每个像素编码Y样本,但每个2x2块共享Cb和Cr值。但是,还有YUV 4:4:4数据。这是每个像素获得自己的Y,Cb和Cr样本的地方。转换RGB的简单策略 - &gt; YUV 4:2:0是转换RGB - &gt; YUV 4:4:4然后平均(算术平均值)每个2x2 Cb样本块。还有其他算法(比如过滤器涉及更多周围的样本),但是如果您只是试验这些东西是如何运作的话,这应该可行。

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

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