RGA的使用

RGA即二维图像辅助计算单元,该单元可以在极短时间内拷贝、旋转、格式转换、缩放、混合图片。

rk官方RGA库链接:https://github.com/rockchip-linux/linux-rga

运行时间对比

memcpy > RGA with vir addr > RGA with phy addr

暂时没空整理,先把整个代码贴出来吧。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h> #include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h> #include <RgaApi.h>
#include <im2d.h> #include <drm/drm.h>
#include "drm/drm_mode.h" #define RGA_ALIGN(x, a) (((x) + (a)-1) / (a) * (a))
#define BUF_WIDTH 1280
#define BUF_HEIGHT 720 #define BUF_SIZE (BUF_WIDTH * BUF_HEIGHT * 4) uint8_t *srcBuffer;
uint8_t *dstBuffer; rga_info_t src;
rga_info_t dst;
rga_info_t src1; /**
* @brief
*
* @param
*
* @return
*/
int get_elapse_in_ms(struct timeval *tv)
{
struct timeval this_tv; gettimeofday(&this_tv, NULL);
uint64_t diff_sec = this_tv.tv_sec - tv->tv_sec;
int elapse_in_ms; if (diff_sec == 0)
{
elapse_in_ms = (this_tv.tv_usec - tv->tv_usec) / 1000.0;
}
else
{
elapse_in_ms = ((--diff_sec) * 1000) + ((1000000 - tv->tv_usec) + this_tv.tv_usec) / 1000.0;
}
return elapse_in_ms;
} /**
* @brief get time elapse in us
*
* @param timeval tv
*
* @return
*/
int get_elapse_in_us(struct timeval *tv)
{
struct timeval this_tv; gettimeofday(&this_tv, NULL);
uint64_t diff_sec = this_tv.tv_sec - tv->tv_sec;
int elapse_in_us; if (diff_sec == 0)
{
elapse_in_us = (this_tv.tv_usec - tv->tv_usec);
}
else
{
elapse_in_us = ((--diff_sec) * 1000000) + ((1000000 - tv->tv_usec) + this_tv.tv_usec);
}
return elapse_in_us;
} /**
* @brief
*
* @param
*
* @return
*/
void make_random_data()
{
int rand_fd;
rand_fd = open("/dev/urandom", O_RDONLY);
read(rand_fd, srcBuffer, BUF_SIZE);
close(rand_fd);
} void check_data()
{
for (int i = 0; i < BUF_SIZE; i++)
{
if (srcBuffer[i] != dstBuffer[i])
{
printf("[diff at pos: %d] src: [%d] dst: [%d]\n", i, srcBuffer[i], dstBuffer[i]);
}
}
} void rga_copy_vir()
{
src.virAddr = srcBuffer;
dst.virAddr = dstBuffer; rga_set_rect(&src.rect, 0, 0, BUF_WIDTH, BUF_HEIGHT, BUF_WIDTH, BUF_HEIGHT, RK_FORMAT_RGBA_8888);
rga_set_rect(&dst.rect, 0, 0, BUF_WIDTH, BUF_HEIGHT, BUF_WIDTH, BUF_HEIGHT, RK_FORMAT_RGBA_8888); c_RkRgaBlit(&src, &dst, NULL);
} int rga_copy()
{
bo_t bo_src, bo_dst;
int buff_fd_src, buff_fd_dst;
struct timeval tv; static const char *card = "/dev/dri/card0";
int drm_fd;
int flag = O_RDWR | O_CLOEXEC;
drm_fd = open(card, flag);
if (drm_fd < 0)
{
fprintf(stderr, "Fail to open %s: %m\n", card);
return -errno;
} ioctl(drm_fd, DRM_IOCTL_SET_MASTER, 0); // memset(&src, 0x0, sizeof(rga_info_t));
// memset(&dst, 0x0, sizeof(rga_info_t));
// src.fd = -1;
// dst.fd = -1;
// src.mmuFlag = 1;
// dst.mmuFlag = 1; /* create dumb */
struct drm_mode_create_dumb arg;
struct drm_mode_create_dumb arg2;
int ret; memset(&arg, 0, sizeof(arg));
arg.bpp = 32;
arg.width = BUF_WIDTH;
arg.height = BUF_HEIGHT; memset(&arg2, 0, sizeof(arg2));
arg2.bpp = 32;
arg2.width = BUF_WIDTH;
arg2.height = BUF_HEIGHT;
// arg.flags = 0; ret = ioctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
if (ret)
{
fprintf(stderr, "can't alloc drm dumb buffer src!\n");
return -errno;
} ret = ioctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg2);
if (ret)
{
fprintf(stderr, "can't alloc drm dumb buffer dst!\n");
return -errno;
} printf("arg %u %u %lu \n", arg.handle, arg.pitch, arg.size);
printf("arg2 %u %u %lu \n", arg2.handle, arg2.pitch, arg2.size); /*
// create a dumb scanout buffer
struct drm_mode_create_dumb {
__u32 height;
__u32 width;
__u32 bpp;
__u32 flags;
// handle, pitch, size will be returned
__u32 handle;
__u32 pitch;
__u64 size;
};
*/ bo_src.fd = drm_fd;
bo_src.handle = arg.handle;
bo_src.size = arg.size;
bo_src.pitch = arg.pitch; bo_dst.fd = drm_fd;
bo_dst.handle = arg2.handle;
bo_dst.size = arg2.size;
bo_dst.pitch = arg2.pitch; /* map dumb */
struct drm_mode_map_dumb arg_map_src;
struct drm_mode_map_dumb arg_map_dst;
void *map_src;
void *map_dst; memset(&arg_map_src, 0, sizeof(arg_map_src));
memset(&arg_map_dst, 0, sizeof(arg_map_dst)); arg_map_src.handle = bo_src.handle;
arg_map_dst.handle = bo_dst.handle; ret = ioctl(bo_src.fd, DRM_IOCTL_MODE_MAP_DUMB, &arg_map_src);
if (ret)
{
fprintf(stderr, "can't map drm dumb buffer src!\n");
return -errno;
} ret = ioctl(bo_dst.fd, DRM_IOCTL_MODE_MAP_DUMB, &arg_map_dst);
if (ret)
{
fprintf(stderr, "can't map drm dumb buffer dst!\n");
return -errno;
} map_src = mmap(0, bo_src.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo_src.fd, arg_map_src.offset);
if (map_src == MAP_FAILED)
return -errno; bo_src.ptr = map_src;
printf("bo_src.ptr %p\n", bo_src.ptr);
printf("bo_src.size %d\n", bo_src.size);
printf("arg_map_src.offset %p\n", arg_map_src.offset); map_dst = mmap(0, bo_dst.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo_dst.fd, arg_map_dst.offset);
if (map_dst == MAP_FAILED)
return -EINVAL; bo_dst.ptr = map_dst;
printf("arg_map_dst.offset %p\n", arg_map_dst.offset); c_RkRgaGetBufferFd(&bo_src, &buff_fd_src);
c_RkRgaGetBufferFd(&bo_dst, &buff_fd_dst); printf(" buff_fd_src %d\n", buff_fd_src);
printf(" buff_fd_dst %d\n", buff_fd_src); src.fd = buff_fd_src;
dst.fd = buff_fd_dst; src.phyAddr = map_src;
dst.phyAddr = map_dst; rga_set_rect(&src.rect, 0, 0, BUF_WIDTH, BUF_HEIGHT, BUF_WIDTH, BUF_HEIGHT, RK_FORMAT_RGBA_8888);
rga_set_rect(&dst.rect, 0, 0, BUF_WIDTH, BUF_HEIGHT, BUF_WIDTH, BUF_HEIGHT, RK_FORMAT_RGBA_8888); memcpy(map_src, srcBuffer, BUF_SIZE);
printf("%p\n", map_src); gettimeofday(&tv, NULL);
c_RkRgaBlit(&src, &dst, NULL);
printf("[c_RkRgaBlit with phyAddr] elapse time: %d us\n", get_elapse_in_us(&tv)); /**
* Destroy the dumb, did last.
*/
struct drm_mode_destroy_dumb destroy_arg; /* unmap */
munmap(map_src, BUF_SIZE);
munmap(map_dst, BUF_SIZE); memset(&destroy_arg, 0x0, sizeof(arg));
destroy_arg.handle = bo_src.handle;
ioctl(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); memset(&destroy_arg, 0x0, sizeof(destroy_arg));
destroy_arg.handle = bo_dst.handle;
ioctl(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); close(drm_fd);
} int main(int argc, char **argv)
{
struct timeval tv; srcBuffer = (unsigned char *)malloc(BUF_SIZE);
dstBuffer = (unsigned char *)malloc(BUF_SIZE); make_random_data();
printf("%s\n", querystring(RGA_VERSION));
printf("%s\n", querystring(RGA_MAX_INPUT));
printf("%s\n", querystring(RGA_INPUT_FORMAT)); gettimeofday(&tv, NULL);
memcpy(dstBuffer, srcBuffer, BUF_SIZE); printf("[memcpy] elapse time: %d us\n", get_elapse_in_us(&tv));
check_data();
memset(dstBuffer, 0x0, BUF_SIZE); gettimeofday(&tv, NULL);
rga_copy_vir();
printf("[rgacpy with virAddr] elapse time: %d us\n",get_elapse_in_us(&tv));
// check_data();
rga_copy();
printf("data haven't been checked!\n"); free(srcBuffer);
free(dstBuffer); return 0;
}

rockchip-rk3399 RGA的使用的更多相关文章

  1. crosss compile VLC with OpenMAX on ARM board(RockChip RK3399),in order to use Hard Acceleration when decode video

    reference:http://www.x90x90x90.com/en/raspberry-pi-3-howto-compile-vlc-with-hardware-acceleration/ 1 ...

  2. RK3399配置笔记

    1. adb shell 默认超级管理员 在build/core/main.mk下将ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1改成ADDITIONAL_D ...

  3. 瑞芯微RK3399宣布系统开源,进入百余种行业市场!

    集微网消息,2月24日瑞芯微官方突然宣布, Rockchip RK3399Linux系统开源!作为Rockchip旗舰级芯片,RK3399具有高性能.高扩展.全能型应用特性. 这一重磅消息立马刷爆朋友 ...

  4. [RK3399] 虚拟按键栏显示不全或者方向不对

    CPU:RK3399 系统:Android 7.1 同样的系统代码,换了一个小分辨率的屏,虚拟按键栏就出现显示不全,而且方向不对 出现这种问题的原因是显示密度和屏不匹配,需要适当的降低显示密度即可 d ...

  5. [RK3399] 调试串口ttyS2改为普通串口

    CPU:RK3399 系统:Android 7.1 串口需求量大时,会选择使用 spi 转串口,但是数据量大或者波特率较高时,传输会丢包. 调试串口 ttyS2 也可以让出来,供上层使用,下面是将 t ...

  6. RK3399 4G模块移远EC20移植调试

    转载请注明出处:https://www.cnblogs.com/lialong1st/p/11266330.html CPU:RK3399 系统:Android 7.1 1.通过串口打印或者adb获取 ...

  7. 瑞芯微RK3399六核-迅为3399开发板介绍

    迅为3399开发板基于瑞芯微的RK3399处理器设计,Rockchip RK3399是瑞芯微推出的一款低功耗.高性能的应用处理器芯片,该芯片基于Big.Little架构,即具有独立的NEON协同处理器 ...

  8. Rock Pi开发笔记(二):入手Rock Pi 4B plus(基于瑞星微RK3399)板子并制作系统运行

    前言   入手rock pi 4b plus板子,查看具体的实物,然后制作系统,刷系统,让摇滚派的ubuntu系统运行起来.   Rock Pi 4B plus 介绍   ROCK Pi 4 是 Ra ...

  9. PCI 设备调试手段

    Author: Younix Platform: RK3399 OS: Android 6.0 Kernel: 4.4 Version: v2017.04 一PCI 设备调试手段 busybox ls ...

  10. http://www.artrobot.com/北京钢铁侠

    http://www.artrobot.com/ 钢铁侠ROS智能机器人 钢铁侠ROS智能机器人 型号 ARTrobot-ROS 产品图片:   产品概述: ARTrobot-ROS全开放机器人套件服 ...

随机推荐

  1. Jenkins配置代码化

    目录 一.简介 二.init.groovy 脚本命令行调试 一.简介 Jenkins用久了,会有一种莫名的紧张感.因为没人清楚Jenkins都配置了什么,以至于没人敢动它. 但凡使用界面进行配置的都会 ...

  2. Linux服务加入systemctl|service管理

    一.加入systemctl 1.添加 vim /usr/lib/systemd/system/user_timejob.service # copy to /usr/lib/systemd/syste ...

  3. [BUUCTF]REVERSE——[ACTF新生赛2020]usualCrypt

    [ACTF新生赛2020]usualCrypt 附件 步骤: 例行检查,无壳,32位程序 32位ida载入,直接看main函数 逻辑很简单,一开始让我们输入一个字符串,然后该字符串经过sub_4010 ...

  4. [BUUCTF]PWN——jarvisoj_level3

    jarvisoj_level3 附件 步骤 例行检查,32位,nx保护 运行一下程序 32位ida载入,shift+f12没有看到程序里有可以直接利用的后面函数,根据运行时的字符串找到了程序的关键函数 ...

  5. CF205A Little Elephant and Rozdil 题解

    Content 有一头小象住在 \(\texttt{Rozdil}\) 小镇里,它想去其他的小镇旅行. 这个国家一共有 \(n\) 个小镇,第 \(i\) 个小镇距离 \(\texttt{Rozdil ...

  6. java 编程基础 Class对象 反射:动态代理 和AOP:java.lang.reflect.Proxy:(Proxy.newProxyInstance(newProxyInstance​(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h))

    为什么我们使用动态代理 静态代理会让类变多了,多了代理类,工作量变大了,且不易扩展.比如我们上节课的例子,要实现不同的扩展方法就要编写不同的代理类,非常麻烦.   Proxy类的使用规则 Proxy提 ...

  7. 权限设计的idea

    1.角色增加两个字段,一级部门(如钻井事业部),党组织角色(或者团委在线角色)当然或者是其他的团委在线角色 2.增加一张表,标示在线模块(如党组织在线,团委在线,工会在线,纪检在线), 3.菜单(栏目 ...

  8. Vue-Router(一)

    Vue-Router(一) 简介 vue-router是Vuejs的官方推荐路由,让用 Vue.js 构建单页应用变得非常容易.目前Vue路由最新的版本是4.x版本. vue-router是基于路由和 ...

  9. RPA账户和密码管理方案

    如何将登录业务系统的账户和密码"更好的,更合适"地交给RPA? 相信很多小伙伴们在做RPA的时候, 都会或多或少的遇到类似的问题. 正常情况下IT管理人员都会给真实的业务人员分配业 ...

  10. Java的运行机制

    Java程序运行机制 编译型(操作系统 c/c++) 解释型(网页 不追求速度) 程序运行机制