1.首先熟悉一下YUV的两种存储格式:
一个是打包格式,也就是YUV值按一定的顺序存放在一个数组中,4:2:2格式(YUY2、YUYV、YVYU、UYVY)都是用这种形式存放在内存当中的。
另一个种格式是:平面格式,Y、U、V都存放在各自的位置,4:2:0格式(YV12、IMC1、IMC3形式)用的这种存储方式,而4:2:0格式中的NV12存储则是Y单独存,UV则交错存储,如UVUVUV。
2.从UYVY422到IMC3的转换函数:
参数说明: srcY/U/V : 源数据,存储方式:UYVY
destY/U/V : 目标数据,存储方式: FOURCC:IMC3
width : 宽度
height : 高度
int UYVY_to_IMC3(const char * src, char * dst,int width, int height)
{
char * dst_y_even = dst;
char * dst_y_odd = dst + width;
char * dst_u = dst + width * height;
char * dst_v = dst_u + width * height / 4;
const char * src_even = src;
const char * src_odd = src + width * 2;
int i, j;
for ( i = 0; i < height / 2; ++i )
{
for ( j = 0; j < width / 2; ++j )
{
*dst_u++ = *src_even++;
*dst_y_even++ = *src_even++;
*dst_v++ = *src_even++;
*dst_y_even++ = *src_even++;
src_odd++;
*dst_y_odd++ = *src_odd++;
src_odd++;
*dst_y_odd++ = *src_odd++;
}
dst_y_even += width;
dst_y_odd += width;
src_even += width * 2;
src_odd += width * 2;
}
return 0;
}
用上面的函数转换出来的是YUV分开存储在内存中,通常还需要进行从IMC3到NV12的存储,这个操作简单,值得注意的是取UV分量和存放的时候比较容易出错。仔细点就OK了。
参考:《YUV格式详解》