YUV文件-y,u,v分量验证
通过程序采集yuv数据,并落1帧数据到文件中;
一、 此处记录下思路变化:
- 1、 第一步是了解YUV格式,为什么会比RGB节省空间;
- 2、 二则是按照YUV数据格式读取: 因为没有任何消息头尾的封装,所以只需要看YUV是什么格式,再按照字节读取分量即可;
- 3、 验证总结:
-
验证时,最好以图片进行验证,视频可能会出现未知问题
-
最开始以为黑白图片是只存储YUV的y分量,malloc 开辟的空间也为分辨率的大小,(注意不是总图片的大小),校验时通过ffmpeg无法成功打开;
-
报错: > packet size 204800 < expected frame_size 614400
-
后来想到:
生成图片或者视频时, 每一个像素都是有三分量构成,即使YUV422, YUV420等,也不是说无UV分量,而是共享,所以怎么可能存储图片的时候,把UV分量丢弃;
所以存储黑白照的时候,只需要将原始数据流的uv分量改为128即可;
-
二、 验证过程
此处只用一帧来进行测试说明
命令
- ffplay -f rawvideo -video_size 640*480 -pixel_format yuyv422 -i light.yuv
- vim -b light.yuv 以二进制打开yuv文件
在vim下,
:%!xxd 以16进制阅读yuv文件, 用于修改 yuv像素字节内容
:%!xxd -r , 恢复16进制到2进制文件, 用于让ffmpeg能够继续展示YUV文件
三、 yuv原始数据和图片
四、 vim修改数据和图片
vim修改完后,一定要恢复到2进制文件,否则无法使用ffmpeg打开
五、代码
点击查看代码
void imageDealYUV422(const struct SBufInfo *const localBuf)
{
//YUVYUV ; 2-48b-6B; (char *)
//YUYV ; 2-32b-4B;
int y_chunck_size = localBuf->length; // TODO: 当size 为 length 的 n分之一 时,以640*480打开yuv视频,会竖向出现相同视频n副
unsigned char *y_buf = (unsigned char *)malloc(y_chunck_size * sizeof(unsigned char *));
memset(y_buf, 0, y_chunck_size);
unsigned char *buf_ptr = y_buf;
int u_flag=0;
int v_flag=0;
for (int yIndex = 0; yIndex < localBuf->length;)
{
//获取原始数据亮度值
*buf_ptr = *((unsigned char *)(localBuf->start) + yIndex);
//用于修改u,v分量
if (yIndex % 2 != 0)
{
if(u_flag == 0){
*buf_ptr = 128;
v_flag = 0;
u_flag = 1;
}
else if (v_flag == 0)
{
*buf_ptr = 255;
v_flag = 1;
u_flag = 0;
}
}
yIndex += 1; // TODO: 当1为n时,以640*480打开yuv视频,会横向出现相同视频n副
buf_ptr += 1;
}
fwrite(y_buf, sizeof(unsigned char), y_chunck_size, lFile);
fflush(lFile);
free(y_buf);
y_buf=NULL;
}
六、.YUV文件颜色-测试分布
Y | U | V | 颜色 | 图像 |
---|---|---|---|---|
num | 0 | 0 | 浅绿色 | 有 |
0 | 128 | 128 | 黑色(无亮度) | 无 |
0 | 0 | 0 | 深绿色 | 无 |
0 | num | num | 绿色 | 无 |
0 | 128 | 0 | 深绿色 | 无 |
0 | 0 | 128 | 更深绿色 | 无 |
0 | 255 | 255 | 紫色 | 无 |
255 | 128 | 128 | 白色(最亮) | 无 |
255 | 0 | 0 | 亮绿色 | 无 |
255 | 0 | 128 | 亮黄色 | 无 |
255 | 128 | 0 | 亮蓝色 | 无 |
255 | 255 | 255 | 亮紫色 | 无 |
num | 128 | 128 | 黑白色 | 有 |
num | 0 | num | 浅黄绿色 | 有 |
num | 128 | num | 黑白色 | 有 |
num | num | 0 | 深黄绿色 | 有 |
num | num | 128 | 黑白色 | 有 |
目前还有一个问题未解决:
yuv视频流数据保存时,当存储到文件的缓冲区申请空间为总像素字节大小的n分之一时,ffmpeg读取的图像会上下分成n份;
如下: