YUV格式学习:填充YUV444以及YUYV、YVYU、UYVY、VYUY
来源:互联网 发布:微信改单三中三软件 编辑:程序博客网 时间:2024/05/20 09:48
两年多以前,写了一个生成UYVY格式的函数。记得那时我们部门4、5个人在“小黑屋”里开发新平台,我要在“踢啊”某个芯片上实现屏幕的显示,其格式是UYVY,由于无实际的图像,于是就动手自己写了一个。虽然我们大费周折实现视频的显示、菜单功能,但可惜未使用。
YUV444格式没有进行压缩,占用空间为with*height*3,与RGB占用空间相同。在转换上也很方便,但很多编码器似乎不太支持该格式。或许和其占用空间有莫大的关联吧。
YUYV、YVYU、UYVY、VYUY,都是YUV422的打包格式——即在内存中,Y、U、V都是挨着排序的。它们的名称就表示了Y、U、V的顺序。像YUYV,就是Y、U、Y、V、Y、U、Y、V。在填充这些格式时,就显得很容易、简单了。
另外一种常见的格式是YUV420。从本文章开始,会集中写一下关于YUV的格式转换的文字,但又没有研究很多,像采样的具体过程也没有很了解。这里放一张上,可以直观了解YUV422、YUV420的样子。
回到主题上,本文代码是从两年前写的函数基本上修改得来的。填充的内容是不同的颜色条。先上代码,如下:
void init_yuv_buf(YUV_TYPE type, unsigned char* buf, int width, int height){ unsigned char *src = buf; int i, j; /* unsigned int rainbow_rgb[] = { 0xFF0000, 0xFF6100, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xA020F0, 0x000000, 0xFFFFFF, 0xF4A460}; */ // 由上数组转换而成 unsigned int rainbow_yuv[] = { 0x4c54ff, 0x8534d6, 0xe10094, 0x952b15, 0xb2ab00, 0x1dff6b, 0x5dd2af, 0xbb1654, 0x9c4bc5, 0xb450ad}; unsigned char *p_y = src; unsigned char *p_u = src+width*height; unsigned char *p_v = src+2*width*height; int slice = height / 10; for (i = 0; i < height; i++) // h { int index = i / slice; unsigned char y = (rainbow_yuv[index] & 0xff0000 ) >> 16; unsigned char u = (rainbow_yuv[index] & 0x00ff00) >> 8; unsigned char v = (rainbow_yuv[index] & 0x0000ff); if (type == FMT_YUV444) { for (j=0;j<width;j++) // w { *p_y++ = y; *p_u++ = u; *p_v++ = v; } } else { for (j=0; j<width*2; j+=4) // w { if (type == FMT_YUYV) { src[i*width*2+j+0] = y; // Y0 src[i*width*2+j+1] = u; // U src[i*width*2+j+2] = y; // Y1 src[i*width*2+j+3] = v; // V } if (type == FMT_YVYU) { src[i*width*2+j+0] = y; // Y0 src[i*width*2+j+1] = v; // V src[i*width*2+j+2] = y; // Y1 src[i*width*2+j+3] = u; // U } else if (type == FMT_UYVY) { src[i*width*2+j+0] = u; // U src[i*width*2+j+1] = y; // Y0 src[i*width*2+j+2] = v; // V src[i*width*2+j+3] = y; // Y1 } else if (type == FMT_VYUY) { src[i*width*2+j+0] = v; // V src[i*width*2+j+1] = y; // Y0 src[i*width*2+j+2] = u; // U src[i*width*2+j+3] = y; // Y1 } } } }}
其中rainbow_yuv是由rainbow_rgb数组值转换而成的。因为我确定颜色是使用RGB空间的。使用的转换函数如下:
int rgb2YCbCr(unsigned int rgbColor, int* Y, int* Cb, int* Cr){ unsigned char r, g, b; int y, cb, cr; r = (rgbColor&0x00ff0000) >> 16; g = (rgbColor&0x0000ff00) >> 8; b = rgbColor & 0xff; y = (int)( 0.299 * r + 0.587 * g + 0.114 * b); cb = (int)(-0.16874 * r - 0.33126 * g + 0.50000 * b + 128); if (cb < 0) cb = 0; cr = (int)( 0.50000 * r - 0.41869 * g - 0.08131 * b + 128); if (cr < 0) cr = 0; *Y = y; *Cb = cb; *Cr = cr; return 0;}
对于YUV444而言,Y、U、V占用的空间均为width*height,故在填充时,就分别指定3个分量的指针,然后依次填充即可。
对于YUYV、YVYU、UYVY、VYUY这四种格式,实际上是YUV422采集空间,2个Y对应1个U和1个U。Y、U、V3个分量连续存储,根据顺序,就得到4个格式了。从代码看到,就是根据不同的格式宏定义来调整3个分量。
总之,本文代码没什么技术含量,但对于我的学习,还是有帮助的,姑且写之,姑且用之。
李迟 2015.8.5 晚上
- YUV格式学习:填充YUV444以及YUYV、YVYU、UYVY、VYUY
- YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB24
- 关于RGB、YUY2、YUYV、YVYU、UYVY、AYUV DirectShow中常见的RGB/YUV格式
- 关于RGB、YUY2、YUYV、YVYU、UYVY、AYUV DirectShow中常见的RGB/YUV格式
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解
- RGB、YUY2、YUYV、YVYU、UYVY、AYUV格式详解
- YUV444,YUV422P,YUVY,YUYV,UYVY,NV21,NV12
- 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV
- RGB、 YUY2、YUYV、YVYU、UYVY与AYUV
- 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV_
- 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV_
- 谈谈RGB、YUY2、YUYV、YVYU、UYVY、AYUV
- 关于RGB、YUY2、YUYV、YVYU、UYVY、AYUV
- RGB、YUY2、YUYV、YVYU、UYVY与AYUV
- 关于RGB、YUY2、YUYV、YVYU、UYVY、AYUV
- RGB、YUY2、YUYV、YVYU、UYVY与AYUV
- hdu-1016
- javascript实现html页面之间的参数传递
- PHP get_class 返回对象的类名
- yii2关于HTTP请求处理的总结
- Sublime text 2/3 中 Package Control 的安装与使用方法
- YUV格式学习:填充YUV444以及YUYV、YVYU、UYVY、VYUY
- 验证二叉查找树
- 小白学开发(iOS)OC_ set方法的内存管理分析(2015-08-04)
- Lua实现类的封装
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
- C# 中如何调用DLL文件(分两种情况,托管与非托管)
- leetcode数据库sql之Delete Duplicate Emails
- 文章标题
- 【iOS知识学习】_iOS动态改变TableView Cell高度