由于工作要用到这个功能。所以,弄了很久,后面发现的几个问题,确实都是比较比较low导致的。这里做一个记录,防止以后再犯。
这里有我下载的所有的资料,也有一个是我这边调整了makefile才弄出来的。
地址如下,如果有积分的可以支持一下CSDN
RGA就是一个用来处理图片的硬件,和CPU相互独立,可以独立完成图片的处理。
首先,贴出他这个demo。
rgacopy.cpp
的代码如下:
/*
* Copyright (C) 2016 Rockchip Electronics Co.Ltd
* Authors:
* Zhiqin Wei
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#define LOG_NDEBUG 0
#define LOG_TAG "rgaClip"
#include
#include
#include
#include
#include
#include
#include
#include
#include
///
//#include "../drmrga.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
///
int main()
{
int ret = 0;
int srcWidth,srcHeight,srcFormat;
int dstWidth,dstHeight,dstFormat;
bo_t bo_src, bo_dst;
srcWidth = 1280;
srcHeight = 720;
srcFormat = RK_FORMAT_RGBA_8888;
//srcFormat = RK_FORMAT_RGB_565;
//srcFormat = RK_FORMAT_YCrCb_420_SP;
dstWidth = 1280;
dstHeight = 720;
dstFormat = RK_FORMAT_RGBA_8888;
//dstFormat = RK_FORMAT_YCrCb_420_SP;
RockchipRga rkRga;
rkRga.RkRgaInit();
/********** apply for src buffer and dst buffer **********/
//char* buf = NULL;
ret = rkRga.RkRgaGetAllocBuffer(&bo_src, srcWidth, srcHeight, 32);
ret = rkRga.RkRgaGetAllocBuffer(&bo_dst, dstWidth, dstHeight, 32);
/********** map buffer_address to userspace **********/
rkRga.RkRgaGetMmap(&bo_src);
rkRga.RkRgaGetMmap(&bo_dst);
/********** read data from *.bin file **********/
#if 1
get_buf_from_file(bo_src.ptr, srcFormat, srcWidth, srcHeight, 0);
#else
memset(buf,0x55,4*1280*720);
#endif
#if 1
//get_buf_from_file(bo_dst.ptr, dstFormat, dstWidth, dstHeight, 1);
#else
memset(buf,0x00,4*1280*720);
#endif
while(1) {
/********** rga_info_t Init **********/
rga_info_t src;
rga_info_t dst;
memset(&src, 0, sizeof(rga_info_t));
src.fd = -1;
src.mmuFlag = 1;
memset(&dst, 0, sizeof(rga_info_t));
dst.fd = -1;
dst.mmuFlag = 1;
/********** get src_Fd **********/
ret = rkRga.RkRgaGetBufferFd(&bo_src, &src.fd);
printf("src.fd =%d \n",src.fd);
if (ret) {
printf("rgaGetsrcFd fail : %s\n", strerror(errno));
}
/********** get dst_Fd **********/
ret = rkRga.RkRgaGetBufferFd(&bo_dst, &dst.fd);
printf("dst.fd =%d \n",dst.fd);
if (ret) {
printf("rgaGetdstFd error : %s\n", strerror(errno));
}
/********** if not fd, try to check phyAddr and virAddr **************/
if(src.fd <= 0|| dst.fd <= 0)
{
/********** check phyAddr and virAddr ,if none to get virAddr **********/
if (( src.phyAddr != 0 || src.virAddr != 0 ) || src.hnd != NULL ){
//ret = RkRgaGetHandleMapAddress( gbs->handle, &src.virAddr );
printf("src.virAddr =%p\n",src.virAddr);
if(!src.virAddr){
printf("err! src has not fd and address for render ,Stop!\n");
break;
}
}
/********** check phyAddr and virAddr ,if none to get virAddr **********/
if (( dst.phyAddr != 0 || dst.virAddr != 0 ) || dst.hnd != NULL ){
//ret = RkRgaGetHandleMapAddress( gbd->handle, &dst.virAddr );
printf("dst.virAddr =%p\n",dst.virAddr);
if(!dst.virAddr){
printf("err! dst has not fd and address for render ,Stop!\n");
break;
}
}
}
/********** set the rect_info **********/
rga_set_rect(&src.rect, 0,0,srcWidth,srcHeight,srcWidth/*stride*/,srcHeight,srcFormat);
rga_set_rect(&dst.rect, 0,0,dstWidth,dstHeight,dstWidth/*stride*/,dstHeight,dstFormat);
/************ set the rga_mod ,rotation\composition\scale\copy .... **********/
/********** call rga_Interface **********/
struct timeval tpend1, tpend2;
long usec1 = 0;
gettimeofday(&tpend1, NULL);
ret = rkRga.RkRgaBlit(&src, &dst, NULL);
gettimeofday(&tpend2, NULL);
usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000;
printf("cost_time=%ld ms\n", usec1);
if (ret) {
printf("rgaFillColor error : %s\n",
strerror(errno));
}
{
/********** output buf data to file **********/
//char* dstbuf = NULL;
output_buf_data_to_file(bo_dst.ptr, dstFormat, dstWidth, dstHeight, 0);
}
printf("threadloop\n");
usleep(500000);
break;
}
return 0;
}
我这里稍微解释一下,因为这里程序用的c。所以,他这里使用的是先将要处理的图片弄成in文件。然后,将这个文件经过rga处理,生成一个Out文件。从而将YUV的图片转成RGB888格式的图片,当然,上面的这个demo的一些格式写的不对,我后面会贴我处理的函数。
因为上面的demo都是使用文件的,而我这里的需求应该才是大部分人的需求:我这里的需求是 我自己会有个相机,然后该相机采集图像,是会有一个buf的,我只需要把这个buf传入,经过RGA处理,然后输出另一个Buf传给我就可以了。inBuf->rga处理->outBuf.
首先,我出现的第一个问题,就是随意的去引用了他的库,人家明明给了makefile,也给了cpp文件,我咋不自己编一编。偏要用人家的,其实他在根目录给的那个库时有问题的呀,一调用就会出现问题了。
所以,我重新调整了一下这些文件,以及一些库的位置,我使用的是这个文件夹:
里面的Makefile做了一定修改,你可以直接make。 注意,那个库的位置放在rga-lib/lib底下。注意查找。这样,你就可以在里面的发现有个librga.so的文件。将这个文件放在你的应用库的目录之下。
下面这个就是我进行RGA转换的函数:
code
void McStreamE2V570SCCif::rgaFormatChange(char *srcBuf)//这个srcBuf就是传入的图像的数据,注意图像要是YUYV的
{
int ret = 0;
int srcFormat = RK_FORMAT_YCrCb_420_SP;
int dstFormat = RK_FORMAT_RGB_888;
if(m_bInitCapFinish==false)
{
ret = m_iRkRga.RkRgaInit();
ret = m_iRkRga.RkRgaGetAllocBuffer(&m_fBoSrc, m_iWidth, m_iHeight, 32);
ret = m_iRkRga.RkRgaGetAllocBuffer(&m_fBoDst, m_iWidth, m_iHeight, 32);
m_iRkRga.RkRgaGetMmap(&m_fBoSrc);
m_iRkRga.RkRgaGetMmap(&m_fBoDst);
memset(&m_fRgaInfoSrc, 0, sizeof(rga_info_t));
m_fRgaInfoSrc.fd = -1;
m_fRgaInfoSrc.mmuFlag = 1;
memset(&m_fRgaInfoDst, 0, sizeof(rga_info_t));
m_fRgaInfoDst.fd = -1;
m_fRgaInfoDst.mmuFlag = 1;
ret = m_iRkRga.RkRgaGetBufferFd(&m_fBoSrc, &m_fRgaInfoSrc.fd);
printf("src.fd =%d \n",m_fRgaInfoSrc.fd);
if (ret) {
printf("rgaGetsrcFd fail : %s\n", strerror(errno));
}
ret = m_iRkRga.RkRgaGetBufferFd(&m_fBoDst, &m_fRgaInfoDst.fd);
printf("dst.fd =%d \n",m_fRgaInfoDst.fd);
if (ret) {
printf("rgaGetdstFd error : %s\n", strerror(errno));
}
rga_set_rect(&m_fRgaInfoSrc.rect, 0,0,m_iWidth,m_iHeight,m_iWidth/*stride*/,m_iHeight,srcFormat);
rga_set_rect(&m_fRgaInfoDst.rect, 0,0,m_iWidth,m_iHeight,m_iWidth/*stride*/,m_iHeight,dstFormat);
m_bInitCapFinish = true;
}
memcpy(m_fBoSrc.ptr,srcBuf,m_tempBuffer.length/2);//这里将srcBuf的内容拷贝到m_fBoSrc里面去。再调用rga的接口,再将数据buf弄出来就可以了。
ret = m_iRkRga.RkRgaBlit(&m_fRgaInfoSrc, &m_fRgaInfoDst, NULL);
memcpy(m_tempBuffer.start,m_fBoDst.ptr,m_tempBuffer.length);
}
上面就是所有的操作过程,希望你也能成功使用这个rga。
如果你没有积分可以下载上面的文件的话,你可以从这里下载,如果对你有帮助,希望能给点鼓励喔!! 感谢,感谢~
下载地址:https://wwha.lanzouf.com/ieJkawfkp8f 密码:1111