YUYV编码成h.264:Linux视频采集与编码(二)

YUYV编码成h.264:Linux视频采集与编码(二)

标签: h.264linux存储
12737人阅读 评论(5) 收藏 举报
本文章已收录于:
分类:

用V4L2成功采集到了YUYV视频,然后需要将它编码成h.264文件,因为之前有做过将yuv420编码成h.264的程序,所以觉得将yuv422编码成h.264也是大同小异,应该挺简单的。

于是我很开心的写编码函数了,编码yuv420我是参考的这篇这篇博文,我马上下手,我感到圣母玛丽亚正在向我招手,我觉得我马上就要成功啦 ^_^

可是,我知道,作为一个程序员,如果不遇上一些问题,不遇到一些困难,都会不好意思滴 ^_^

是啊,我遇到困难了,我编码出来的视频是花的,红红绿绿,好像春天百花齐放!


因为参考编码yuv420的代码中也是隔行扫描的,它的yuv序列是下面这样:

YYYY

YYYY

UVUV

于是我天真的认为我的yuv422保存的也是这样的序列,因为它们都是隔行扫描啊。

后来知道了YUYV隔行扫描序列不是这样的,yuv422的序列应该是下面这样:

YU YV YU YV YU YV

就是说UV确实是交叉存储,只不过得和Y一起交叉。

知道了这样的存储序列,要把其编码成h.264就简单啦。

下面看我的编码代码:

  1. char *y = en->picture->img.plane[0];  
  2.     char *u = en->picture->img.plane[1];  
  3.     char *v = en->picture->img.plane[2];  
  4.   
  5.     int is_y = 1, is_u = 1;  
  6.     int y_index = 0, u_index = 0, v_index = 0;  
  7.   
  8.     int yuv422_length = 2 * en->param->i_width * en->param->i_height;  
  9.   
  10.     //序列为YU YV YU YV,一个yuv422帧的长度 width * height * 2 个字节  
  11.     for (i = 0; i < yuv422_length; ++i) {  
  12.         if (is_y) {  
  13.             *(y + y_index) = *(in + i);  
  14.             ++y_index;  
  15.             is_y = 0;  
  16.         } else {  
  17.             if (is_u) {  
  18.                 *(u + u_index) = *(in + i);  
  19.                 ++u_index;  
  20.                 is_u = 0;  
  21.             } else {  
  22.                 *(v + v_index) = *(in + i);  
  23.                 ++v_index;  
  24.                 is_u = 1;  
  25.             }  
  26.             is_y = 1;  
  27.         }  
  28.     }  
char *y = en->picture->img.plane[0];
	char *u = en->picture->img.plane[1];
	char *v = en->picture->img.plane[2];

	int is_y = 1, is_u = 1;
	int y_index = 0, u_index = 0, v_index = 0;

	int yuv422_length = 2 * en->param->i_width * en->param->i_height;

	//序列为YU YV YU YV,一个yuv422帧的长度 width * height * 2 个字节
	for (i = 0; i < yuv422_length; ++i) {
		if (is_y) {
			*(y + y_index) = *(in + i);
			++y_index;
			is_y = 0;
		} else {
			if (is_u) {
				*(u + u_index) = *(in + i);
				++u_index;
				is_u = 0;
			} else {
				*(v + v_index) = *(in + i);
				++v_index;
				is_u = 1;
			}
			is_y = 1;
		}
	}

注:in 是指向yuv422序列的指针,即指向了yuv422的起始地址。

我们只要将yuv422序列中的 

y 赋值给 plane[0]

u 赋值给 plane[1]

v 赋值给 plane[2], 就可以编码了。


2
0
 
 
我的同类文章
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值