RK3399-RGA使用

目录

  • 前言
  • 正文
    • 资料的下载
    • RGA的作用
    • rga demo
    • 我的需求
    • 解释一下我使用的资料
    • 正式看一下我的代码
  • 参考

前言

由于工作要用到这个功能。所以,弄了很久,后面发现的几个问题,确实都是比较比较low导致的。这里做一个记录,防止以后再犯。

正文

资料的下载

这里有我下载的所有的资料,也有一个是我这边调整了makefile才弄出来的。
地址如下,如果有积分的可以支持一下CSDN

RGA的作用

RGA就是一个用来处理图片的硬件,和CPU相互独立,可以独立完成图片的处理。

rga demo

首先,贴出他这个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文件,我咋不自己编一编。偏要用人家的,其实他在根目录给的那个库时有问题的呀,一调用就会出现问题了。
所以,我重新调整了一下这些文件,以及一些库的位置,我使用的是这个文件夹:
RK3399-RGA使用_第1张图片
里面的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

参考

你可能感兴趣的:(Linux,Linux,RK3399)