YUV文件-y,u,v分量验证

通过程序采集yuv数据,并落1帧数据到文件中;

一、 此处记录下思路变化:

  • 1、 第一步是了解YUV格式,为什么会比RGB节省空间;
  • 2、 二则是按照YUV数据格式读取: 因为没有任何消息头尾的封装,所以只需要看YUV是什么格式,再按照字节读取分量即可;
  • 3、 验证总结:
    1. 验证时,最好以图片进行验证,视频可能会出现未知问题

    2. 最开始以为黑白图片是只存储YUV的y分量,malloc 开辟的空间也为分辨率的大小,(注意不是总图片的大小),校验时通过ffmpeg无法成功打开;

    3. 报错: > packet size 204800 < expected frame_size 614400

    4. 后来想到:
      生成图片或者视频时, 每一个像素都是有三分量构成,即使YUV422, YUV420等,也不是说无UV分量,而是共享,所以怎么可能存储图片的时候,把UV分量丢弃;
      所以存储黑白照的时候,只需要将原始数据流的uv分量改为128即可;

二、 验证过程

此处只用一帧来进行测试说明

命令

  1. ffplay -f rawvideo -video_size 640*480 -pixel_format yuyv422 -i light.yuv
  2. vim -b light.yuv 以二进制打开yuv文件
    在vim下,
    :%!xxd 以16进制阅读yuv文件, 用于修改 yuv像素字节内容
    :%!xxd -r , 恢复16进制到2进制文件, 用于让ffmpeg能够继续展示YUV文件

三、 yuv原始数据和图片

YUV_0_255_255
YUV_0_255_255

四、 vim修改数据和图片

YUV_255_255_255
YUV_255_255_255

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份;
如下:

posted @ 2023-08-02 18:58  uagvdu  阅读(178)  评论(0编辑  收藏  举报