RGA模块在本项目的作用
由于网页显示的图像是RGB的彩色图像,所以我们需要使用RGA模块把每一帧的NV12的灰度图像转换成RGB的彩色图像。这篇博客主要的内容是RGA模块的初始化和如何获取经过RGA处理,拿到彩色的RGB数据。
我们要使用到rga模块,我们就要先认识一下rga模块
RGA_ATTR_S数据结构,初始化出rga模块
这里使用的结构体是RGA_ATTR_S。RGA_ATTR_S结构体里面包含了两个重要的结构体,分别是stImgIn和stImgOut。stImgIn是视频输入的结构体,stImgOut是处理后的视频结构体。除了这两个重要的结构体外,还有公共参数需要设置
stImgIn是视频输入的结构体,是我传入的NV12视频,stImgOut是处理后的视频结构体,是处理好的RGB彩色视频。
接下来来看一下RGA工作原理,你能理解RGA的参数怎么填了。
重点:转换过后它还是vi数据, 但是图像已经变成彩色的了
stImgIn结构体的设置:
stImgIn.u32Width:视频输入的分辨率宽度,这里使用的是1920
stImgIn.u32Height:视频输入的分辨率高度,这里使用的是1080
stImgIn.u32HorStride:视频输入的分辨率虚宽,虚宽的数值跟分辨率宽度数值一致都是1920
stImgIn.u32VirStride:视频输入的分辨率虚高,虚高的数值跟分辨率高度数值一致都是1080
stImgIn.imgType:视频输入的格式,这里设置的是NV12也就是IMAGE_TYPE_NV12
stImgIn.u32X:设置stImgIn的X坐标 //默认是0
stImgIn.u32Y:设置stImgIn的Y坐标//默认是0
stImgOut结构体的设置:
stImgOut.u32Width:视频输出的分辨率宽度,这里使用的是1920
stImgOut.u32Height:视频输出的分辨率高度,这里使用的是1080
stImgOut.u32HorStride:视频输出的分辨率虚宽,虚宽的数值跟分辨率宽度数值一致都是1920
stImgOut.u32VirStride:视频输出的分辨率虚高,虚高的数值跟分辨率高度数值一致都是1080
stImgOut.imgType:视频输出的格式,这里设置的是RGB格式,IMAGE_TYPE_RGB888。
stImgOut.u32X:设置stImgOut的X坐标
stImgOut.u32Y:设置stImgOut的Y坐标
RGA公共参数
u16BufPoolCnt:缓冲区计数,默认是3
u16Rotation:旋转角度,这里填0,没有旋转角度
enFlip:镜像控制,这里选择RGA_FLIP_H,水平镜像处理
bEnBufPool:使能缓冲池
//RGA模块
//配置RA参数
RGA_ATTR_S rga;
rga.stImgIn.u32Height = 1080;
rga.stImgIn.u32Width = 11920;
rga.stImgIn.u32X = 0;
rga.stImgIn.u32Y = 0;
rga.stImgIn.imgType = IMAGE_TYPE_NA12;
rga.stImgIn.u32HorStride =1920;
rga.stImgIn.u32VerStride = 1080;
rga.stImgOut.u32Height 1080;
rga.stImgOut.u32Width = 1920;
rga.stImgOut.u32X = 0;
rga.stImgOut.u32Y = 0;
rga.stImgOut.imgType = IMAGE_TYPE_RGB888;
rga.stImgOut.u32HorStride = 1920;
rga.stImgOut.u32VerStride = 1080;
rga.u16BufPoolCnt = 3; //缓冲区计数一般默认是3
rga.u16Rotaion = 0; //旋转角度,这里默认是0
rga.enFlip = RGA_FLIP_H; //水平镜像处理
rga.bEnBufPool = RK_TRUE; //使能缓冲池
//使能RGA模块通道
ret = RK_MPI_RGA_CreateChn(RGA_ID, &rga);
if(ret)
{
prinf("RK_MPI_RGA_CreateChn 失败\n");
}
else{
printf("RK_MPI_RGA_CreateChn 成功\n");
}
设置完上述的参数后,调用RK_MPI_RGA_CreateChn设置RGA模块,第一个参数是RGA的通道号:0,第二个参数是RGA_ATTR_S结构体指针。
然后就创建线程,去获取rga转换后的每一帧数据。
创建get_vi_rga_thread线程获取RGA码流数据
void* get_vi_rag_thread(void* args)
{
//MEDIA_BUFFER就是void*类型
MEDIA_BUFFER mb;
while(!quit)
{
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_RGA, RGA_ID, -1);
if(!mb)
{
printf("RK_MPI_SYS_GetMediaBuffer 获取数据失败 \n");
break; //不要在这里循环了
}
//todo....
//要把数据考到贡献内存里面去
// 释放mb数据
RK_MPI_MB_ReleaseBuffer(mb);
}
}
需要调用pthread_create创建get_vi_rga_thread线程,我们来看get_vi_rga_thread线程里面的内容。在这个线程里面,需要调用RK_MPI_SYS_GetMediaBuffer获取RGA模块的数据。而RGA数据的来源是上节课我们讲解的get_camera_vi_thread线程发送的每一帧NV12数据(具体的流程如下图),最后把RGA的数据赋值到共享内存里面,(共享内存的内容下一篇分享)。