一:首先进行YUV422对YUV420的转换
https://blog.csdn.net/li_wen01/article/details/53767245
YUV422的数据格式分布:
YUV420数据格式分布:
YUYV是交叉分布存储,每两组Y公用一组UV,YUV420是顺序存储,每4个Y共用一组UV分量,所以我们需要把YUYV的Y分量全部读取,然后隔行读取UV分量(eg:输入大小:640*480*2,输出大小640*480*3/2),将YUV分开存储。
void yuv22_cover_yuv420(char *i_buf,char o_buf,int width,int height)
{
int j,i;
char *y,*u,*v;
int index_y,index_u,index_v;
y=o_buf;
u=o_buf+(width*height);
v=o_buf+width*height+width*height/4);
index_y = 0;
index_u = 0;
index_v = 0;
for(j=0;j
for(i=0;i
*(y+(index_y++))= *(i_buf + width*j +i);
*(y+(index_y++))= *(i_buf + width*j +i+2);
if(j%2 == 0)
{
*(u + (index_u++)) = *(i_buf + width * j + i + 1);
*(v + (index_v++)) = *(i_buf + width * j + i + 3);
} }}}
二:
主要是从摄像头得到非压缩的YUV422的数据,然后进行编码
Image ->venc(编码通道)(可完成视频内容的遮挡和覆盖等内容REGION)->输出Coded stream,
VENC模块由编码通道子模块和编码协议子模块(H.264/H265/JPEG/MJPEG)组成,通道支持接收YUV个数图像输入,支持格式YUV420(H.264/H265/),YUV422(JPEG/MJPEG),通道模块接受外部原始图像数据,比较图像尺寸和编码通道尺寸,
如果输入图像比编码通道尺寸大,VENC按编码通道尺寸大小,调用VGS对原图像进行缩小,对缩小的图像进行编码。如果输入图像比编码通道尺寸小,直接丢弃,如果通道相当,直接编码。完成视频区域管理之后,图像被送入具体的协议类型编码通道,完成视频编码,输出码流。编码通道作为基本容器,保存编码通道的多种用户设置和管理通道的多种资源,编码控制器提供对编码参数的控制和调整,从而对输出码率进行控制。(码率控制,编码器两个概念)
1:码率控制:跟图像的压缩比和图像的质量有关,码率器提供了三种码率控制模式,CBR,VBR,FIXQP
CBR:固定比特率:保证编码平稳 ,VBR:可变波特率,图像质量平稳,FIXQP固定的QP值。
码流帧配置方式:单包模式和多包模式,多包模式:对于H264,I帧包含4个NAL包(4个NAL包分别为sps包、pps 包、sei包、Islice 包,这里假设pps 包只有一个,且4 个NAL包是独立的,包类型不同);单包模式对于H.264,当为I 帧时,调用HI_MPI_VENC_GetStream 接口,一个I 帧包含1个NAL包(该NAL包的包类型为Islice 包,且包含sps、pps、sei、
Islice 的数据);默认多包模式,
当用户调用分包接口,(例如:HI_MPI_VENC_SetH264SliceSplit 时,一帧会被分成多个slice,如果用户选择单包模式时,对于I 帧来说,该帧第一个ISlice 包会包含 sps、pps、sei 的数据,该帧的其他ISlice 则没有。即对于H.264,sps、pps、sei的数据只会出现在I 帧的第一个Islice 中并合为1个包,且包类型为ISlice;对于JPEG/MJPEG来说,图像参数包只会出现在一帧的第一个数据包中并合为1 个包,且包类型为数据包。
SPS+PPS+Islice+无效数据+码流。
编码帧存储:支持两种方式Private VB池创建编码通道时由VENC创建私有的VB池作为该通道的参考帧和重构帧buffer
UserVB不分配参考帧和重构帧,而是由用户调用接口HI_MPI_VB_CreatePool 创建一个视频缓存VB池,再通过调用接口HI_MPI_VENC_AttachVbPool 把某个编码通道绑定到固定的视频缓存VB池中。
编码帧的VB的大小:FrameSize = YHeaderSize + CHeaderSize + YSize + CSize
建议使用select方式获取码流,且按照如下的流程:(1)调用HI_MPI_VENC_Query 函数查询编码通道状态;(2)确保u32CurPacks和u32LeftStreamFrames 同时大于0;(3)调用malloc 分配u32CurPacks 个包信息结构体(4)调用HI_MPI_VENC_GetStream 获取编码码流;(5)调用HI_MPI_VENC_ReleaseStream 释放码流缓存。