RK Android平台RGA功能介绍和接口封装

19 篇文章 11 订阅
19 篇文章 1 订阅

RK RGA说明:

⽬前实现的api功能涵盖拷⻉、旋转、裁剪、缩放、格式转换和合成,⽬前仅需要关注以下2个API即可,使⽤如下的2个函数就能满⾜上述功能。
int  RgaBlit(rga_info *src, rga_info *dst, rga_info *src1) ; 
int  rga_set_rect(rga_rect_t *rect,int  x, int  y, int  w, int  h, int  sw, int  sh, int  f);

librga接口函数

librga 是⽤CPP 编写的
在⽂件RockchipRga.h 中有以下类的⽅法提供接⼝:
/*  初始化rga */
int  RkRgaInit();
/*  申请buffer */
int  RkRgaGetAllocBuffer(bo_t *bo_info,  int  width,  int  height, int  
bpp);
/*  释放buffer */
int  RkRgaFree(bo_t *bo_info);
/*  映射buffer 到⽤户空间 */
int  RkRgaGetMmap(bo_t *bo_info);
/*  解除映射buffer */
int  RkRgaUnmap(bo_t *bo_info);
/*  获取buffer 的fd */
int  RkRgaGetBufferFd (bo_t *bo_info,  int  *fd);
/*  调⽤rga 的接⼝ */
int  RkRgaBlit(rga_info_t *src, rga_info_t *dst, rga_info_t *src1);

支持的图像格式:

HAL_PIXEL_FORMAT_RGB_565:       "rgb565";
HAL_PIXEL_FORMAT_RGB_888:         "rgb888";
HAL_PIXEL_FORMAT_RGBA_8888:       "rgba8888" ;
HAL_PIXEL_FORMAT_RGBX_8888:       "rgbx8888";
HAL_PIXEL_FORMAT_BGRA_8888:       "bgra8888" ;
HAL_PIXEL_FORMAT_YCrCb_420_SP:      "crcb420sp" ;
HAL_PIXEL_FORMAT_YCrCb_NV12:       "nv12" ;
HAL_PIXEL_FORMAT_YCrCb_NV12_VIDEO:   "nv12" ;
HAL_PIXEL_FORMAT_YCrCb_NV12_10:     "nv12_10" ;

Android librga Demo位置

hardware\rockchip\librga

 

由于Demo是一个个单独的单独的例子,仅实现了裁剪、旋转、合成、缩放、格式转换中的一种,不能直接拿来做接口函数

而且也不清楚RGA处理这些操作的先后顺序,以及RGA是否支持同时处理裁剪、旋转缩放、格式转换,

经尝试,RGA支持同时裁剪、旋转等操作,也就是说只要传入源图片及其信息和期望输出图片信息即可一步完成转换

RGA是先裁剪(如果有),再旋转、合成、格式转换的,所以传入裁剪offset_x ,y就按照旋转前的坐标传入,裁剪宽高

要根据输出图像旋转角度判断是否交换宽高值作为裁剪的宽高

 

统一接口函数实现

typedef struct _rgaImage{
	void* buf;
	int width;
	int height;
	int format;
}rgaImage;

int rgaTool(rgaImage srcImage,rgaImage dstImage,int rotate,int offset_x,int offset_y)
{
		char* buf = NULL;
	int ret = 0;
	RockchipRga& rkRga(RockchipRga::get());

    GraphicBufferMapper &mgbMapper = GraphicBufferMapper::get();

	/********** apply for src_buffer **********/
#ifdef ANDROID_7_DRM
    sp<GraphicBuffer> gbs(new GraphicBuffer(srcImage.width,srcImage.height,srcImage.format,
        GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_FB));
#else
    sp<GraphicBuffer> gbs(new GraphicBuffer(srcImage.width,srcImage.height,srcImage.format,
        GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN));
#endif

    if (gbs->initCheck()) {
        printf("GraphicBuffer_src error : %s\n",strerror(errno));
        return ret;
    } else
        printf("GraphicBuffer_src %s \n","ok");
        
    /********** apply for dst_buffer **********/
#ifdef ANDROID_7_DRM
    sp<GraphicBuffer> gbd(new GraphicBuffer(dstImage.width,dstImage.height,dstImage.format,
        GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_FB));
#else
    sp<GraphicBuffer> gbd(new GraphicBuffer(dstImage.width,dstImage.height,dstImage.format,
        GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN));
#endif

    if (gbd->initCheck()) {
        printf("GraphicBuffer_dst error : %s\n",strerror(errno));
        return ret;
    } else
        printf("GraphicBuffer_dst %s \n","ok");

	/********** map buffer_address to userspace **********/
    
#ifdef ANDROID_8
    buffer_handle_t importedHandle_src;
    buffer_handle_t importedHandle_dst;
    mgbMapper.importBuffer(gbs->handle, &importedHandle_src);
    mgbMapper.importBuffer(gbd->handle, &importedHandle_dst);
    gbs->handle = importedHandle_src;
    gbd->handle = importedHandle_dst;
#else
    mgbMapper.registerBuffer(gbs->handle);
    mgbMapper.registerBuffer(gbd->handle);
#endif

	/********** write data to src_buffer or init buffer**********/
    ret = gbs->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&buf);
    if (ret) {
        printf("lock buffer_src error : %s\n",strerror(errno));
        return ret;
    } else 
        printf("lock buffer_src %s \n","ok");

	memcpy(buf,srcImage.buf,get_buf_size_by_w_h_f(srcImage.width,srcImage.height,srcImage.format));
	
    ret = gbs->unlock();
    if (ret) {
        printf("unlock buffer_src error : %s\n",strerror(errno));
        return ret;
    } else 
        printf("unlock buffer_src %s \n","ok");
	
	/********** write data to dst_buffer or init buffer **********/
    ret = gbd->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&buf);
    if (ret) {
        printf("lock buffer_dst error : %s\n",strerror(errno));
        return ret;
    } else 
        printf("lock buffer_dst %s \n","ok");

    memset(buf,0x00,4*dstImage.width*dstImage.height);

    ret = gbd->unlock();
    if (ret) {
        printf("unlock buffer_dst error : %s\n",strerror(errno));
        return ret;
    } else 
        printf("unlock buffer_dst %s \n","ok");
	
	
/********** 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;
	src.hnd = gbs->handle;
	
	memset(&dst, 0, sizeof(rga_info_t));
	dst.fd = -1;
	dst.mmuFlag = 1;
	dst.hnd = gbd->handle;
	
	/********** get src_Fd **********/
	ret = rkRga.RkRgaGetBufferFd(gbs->handle, &src.fd);
	printf("src.fd =%d\n",src.fd);
	if (ret) {
		printf("rgaGetsrcFd fail : %s,hnd=%p \n",
										strerror(errno),(void*)(gbd->handle));
	}
	/********** get dst_Fd **********/
	ret = rkRga.RkRgaGetBufferFd(gbd->handle, &dst.fd);
	printf("dst.fd =%d \n",dst.fd);
	if (ret) {
		printf("rgaGetdstFd error : %s,hnd=%p\n",
										strerror(errno),(void*)(gbd->handle));
	}
	/********** if not fd, try to check phyAddr and virAddr **************/
#ifndef RK3188
	if(src.fd <= 0|| dst.fd <= 0)
#endif
	{
	/********** 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");
				return ret;
			}
		}
		
		/********** 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");
				return ret;
			}		
		}
	}
	/********** set the rect_info **********/
	if(rotate == 4 || rotate == 7)
		rga_set_rect(&src.rect, offset_x,offset_y,dstImage.height,dstImage.width,srcImage.width/*stride*/,srcImage.height,srcImage.format);
	else
		rga_set_rect(&src.rect, offset_x,offset_y,dstImage.width,dstImage.height,srcImage.width/*stride*/,srcImage.height,srcImage.format);
	rga_set_rect(&dst.rect, 0,0,dstImage.width,dstImage.height,dstImage.width/*stride*/,dstImage.height,dstImage.format);
	
	/************ set the rga_mod ,rotation\composition\scale\copy .... **********/
	//src.rotation = 0;
	src.rotation = rotate;;
	//src.rotation = HAL_TRANSFORM_ROT_180;
	//src.rotation = HAL_TRANSFORM_ROT_270;	
	
	/********** 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("rgaTool cost_time=%ld ms\n", usec1);
	if (ret) {
		printf("rgaFillColor error : %s,hnd=%p\n",
										strerror(errno),(void*)(gbd->handle));
	}

	{
		/********** output buf data  **********/
		char* dstbuf = NULL;
		ret = gbd->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&dstbuf);
		memcpy(dstImage.buf,dstbuf,get_buf_size_by_w_h_f(dstImage.width,dstImage.height,dstImage.format));
		ret = gbd->unlock();
	}
	return ret;
}

 

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
要测试 RK3568 芯片上 RGA(Rockchip Graphics Accelerator)的性能,可以采用以下方法: 1. 使用标准测试套件:使用专门为图像处理硬件设计的标准测试套件,如Khronos Group的OpenVX、BenchMarkXPRT等。这些套件提供了一系列的图像处理任务和性能指标,可以用于评估 RGA 的性能。通过运行这些测试套件,并记录执行时间、帧率等指标,可以对 RGA 进行客观的性能评估。 2. 自定义测试用例:根据实际的应用需求,开发自定义的测试用例。选择常见的图像处理任务,如图像缩放、旋转、颜色空间转换等,并使用不同尺寸和类型的图像进行测试。通过测量处理时间或帧率,可以评估 RGA 的性能。 3. 实际应用场景测试:将 RGA 集成到实际的应用场景中,并进行性能测试。例如,在嵌入式系统、智能摄像头或移动设备中使用 RGA 进行图像处理任务,并记录处理时间、功耗等指标。这样可以了解 RGA 在实际应用中的性能表现。 在进行测试时,还应该考虑以下因素: - 图像大小和处理复杂度:使用不同分辨率和复杂度的图像,以覆盖更广泛的使用场景。 - 硬件配置:通过调整芯片的工作频率、内存带宽等参数,可以测试不同配置下 RGA 的性能表现。 - 算法优化:尝试不同的算法和优化技术,以获得更好的性能结果。 需要注意的是,测试结果可能会受到多个因素的影响,如芯片的工作状态、温度等。因此,在进行性能测试时,应该进行多次测试,并取平均值来获得更准确的性能评估。同时,也可以参考厂商提供的技术文档和性能数据,以获取更详细和准确的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Free飝Fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值