我是靠谱客的博主 搞怪玫瑰,最近开发中收集的这篇文章主要介绍RK Android平台RGA功能介绍和接口封装,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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位置

hardwarerockchiplibrga

 

由于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 : %sn",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 : %sn",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 : %sn",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 : %sn",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 : %sn",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 : %sn",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 =%dn",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=%pn",
										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 =%pn",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 =%pn",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 ,rotationcompositionscalecopy .... **********/
	//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 msn", usec1);
	if (ret) {
		printf("rgaFillColor error : %s,hnd=%pn",
										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;
}

 

最后

以上就是搞怪玫瑰为你收集整理的RK Android平台RGA功能介绍和接口封装的全部内容,希望文章能够帮你解决RK Android平台RGA功能介绍和接口封装所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(29)

评论列表共有 0 条评论

立即
投稿
返回
顶部