Toybrick

标题: RK3399Pro入门教程(5)图形加速引擎RGA的使用 [打印本页]

作者: jefferyzhang    时间: 2019-4-15 17:48
标题: RK3399Pro入门教程(5)图形加速引擎RGA的使用
本帖最后由 jefferyzhang 于 2022-5-27 09:56 编辑

[attach]237[/attach]

简介

入门教学(1) 中,我们提到了RK自带的RGA核心,可以非常快速的处理二维图像的基本操作,例如
旋转、镜像、缩放、拷贝、剪裁、格式转换等等,那么这篇教学就将详细的说说如何使用。(Android和Linux用法是一致的)


设备节点

RGA的设备节点挂在:
  1. /dev/rga
复制代码


RGA库安装

如果大家不想了解更底层的细节,可以直接安装这个库来使用,我们已经帮大家封装了常用的操作和细节:
  1. sudo apt install rockchip-rga-dev
复制代码


Rockchip封装的LinuxRGA库源码 (new)

  1. https://github.com/rockchip-linux/linux-rga
  2. https://github.com/airockchip/librga
复制代码


如果想进一步了解RGA,可以研究下Android的Hardware/rockchip/librga来查看寄存器的配置等更详细的调用方式,或者使用该代码调用RGA。


示例代码下载地址

本教学的下载地址(已过期):
  1. https://github.com/Jerzha/samples-toybrick-rga.git
复制代码
新RGA教学sample在rga自带目录的sample目录下

注意:
1. sample地址里包含了rockchip_rga目录,该目录的内容就是dnf安装的librockchip_rga内容的源码,如果您不需要修改源码,可以直接dnf安装就好了
2. 如果没有交叉编译环境的话,请放在板子上编译

RGA注意事项

1. 16对齐。所有进入rga的图像的宽高需要进行16对齐,例如1920*1080的图像需要对齐成1920*1088。如果没有显式对齐的话,输出依然会是16对齐的,所以多出几个像素的奇怪的宽高,请不要认为是bug。
2. 可多线程调用来提高利用率
3. 或者设置回调函数的方式提高利用率(库没有提供回调函数注册)
4. RGA自带mmu,可以将虚拟地址转换成物理地址使用(IP核只认识物理地址)。当然如果预先知道物理地址,可以关闭mmu来提升速度。(库没有提供该功能)


基础使用流程(已过期,请参看新RGA Sample

1. 安装RGA库,详见wiki教学

2. 初始化RGA模块,生成context (多线程需要生成多个context)

  1. RockchipRga *mRga;
  2. if (!mRga) {
  3.     printf("create rga failed !\n");
  4.     abort();
  5. }
  6. mRga->ops->initCtx(mRga);
复制代码

3. 设置源(src)和目标(dst)的图片格式、宽高。(需要注意的是,图片格式我们引用Linux V4L2的标准图片格式定义)

  1. mRga->ops->setSrcFormat(mRga, V4L2_PIX_FMT_ABGR32, BUFFER_WIDTH, BUFFER_HEIGHT);
  2. mRga->ops->setDstFormat(mRga, V4L2_PIX_FMT_ABGR32, BUFFER_WIDTH, BUFFER_HEIGHT);
复制代码

4. 设置源(src)和目标(dst)图片的地址。(需要注意的是设置虚拟地址或者fd的接口是不一样的)

  1. mRga->ops->setSrcBufferPtr(mRga, srcBuffer);
  2. mRga->ops->setDstBufferPtr(mRga, dstBuffer);
复制代码

如果是fd(fd一般存在于通过drm申请的buffer), 当然这篇教学里用不到。

  1. mRga->ops->setSrcBufferFd(mRga, srcFd);
  2. mRga->ops->setDstBufferFd(mRga, dstFd);
复制代码

5. 如果只是拷贝和格式转换的话,那做到第四部就可以了。如果还有旋转剪裁等操作,需要再多设置几个:

旋转:
  1. mRga->ops->setRotate(mRga, RGA_ROTATE_90);  // RGA_ROTATE_180, RGA_ROTATE_270
复制代码

剪裁:
  1. mRga->ops->setSrcCrop(mRga, crop_x, crop_y, crop_w, crop_h);
复制代码

(库里提供的就这些。其他功能有需要的话需要自己新增接口了)

6. 插入rga任务队列,开始执行,同步等待返回。

  1. mRga->ops->go(mRga);
复制代码

该函数单个执行其实用不满RGA,因为在设置和返回结果时候RGA是空闲的。这时候可以通过多线程的调用来让RGA不停的排队工作。
或者还有一种更高级的方法就是设置回调函数,给RGA添加任务的时候立即返回,然后等RGA执行完毕后回调告诉程序已经结束,代价当然是程序复杂度就会变得很高。


结果总结

拷贝一张4096*2160的ARGB图像,如果使用malloc的内存(不连续),RGA拷贝速度是比CPU(有cache情况)慢的,测试代码RGA大概需要60ms。实际使用上RGA作为一个流处理器,并且使用CMA连续内容,速度会快非常多,cpu memcpy需要19ms(因为有cache,所以这个代码测试实际上也不能代表问题)如果是DRM分配的物理地址(连续地址)的话,RGA速度是比CPU快很多的,大概在低于15ms(具体数字还需要写代码测试)就可以完成一次搬运。
本篇教学只关注于如果教会大家用RGA,我们就不在这里写drm地址分配的问题了。


RGA优点:
1. 不占用CPU资源
2. DRM/CMA物理内存拷贝和转换速度很快

RGA缺点:
1. 对malloc的不连续的虚拟内存操作速度很慢



作者: hjf515    时间: 2019-4-18 15:38
跑了例程 rga_cpy,发现 checkData 函数中打印出很多dst和src 不一致的数据,这是不是说用 rga copy 有点不可靠。
如果用物理地址,rga cpy是否会更快些,请问在rk3399pro上如何申请物理内存?
物理内存 映射到 虚拟内存,我就可以通过mmap来实现。
作者: jefferyzhang    时间: 2019-4-18 16:59
hjf515 发表于 2019-4-18 15:38
跑了例程 rga_cpy,发现 checkData 函数中打印出很多dst和src 不一致的数据,这是不是说用 rga copy 有点不 ...

rga其实就是一个ioctl,填下结构体就可以了,建议你看库源码自己实现一个,或者用android写好的librga库来二次开发。那个不一致是库代码的bug,不是大问题。

物理地址请参看android的libgralloc库来分配,rk的drm留了一些第三方接口来分配CMA/DMA内存,或者你看rga的库里注释掉的代码也是有分配drm内存的方法。
作者: 盗骊_l    时间: 2019-7-8 16:15
您好,请问我在Android平台上应该怎么使用 RGA,头文件从哪里来?需要编译什么源码吗?
作者: jefferyzhang    时间: 2019-7-9 16:10
盗骊_l 发表于 2019-7-8 16:15
您好,请问我在Android平台上应该怎么使用 RGA,头文件从哪里来?需要编译什么源码吗? ...

android rga查看 device/rockchip/librga
用法不太一样
作者: 盗骊_l    时间: 2019-7-9 19:15
jefferyzhang 发表于 2019-7-9 16:10
android rga查看 device/rockchip/librga
用法不太一样

啊?上面不是说  Android和Linux一致吗?
https://github.com/Jerzha/samples-toybrick-rga上面的demo,我编译之后再Android上能正常跑,性能和你上面给出的基本一致。但是我自己写了个function,做格式转换,NV12转rgba,转换处理的rgba数据是错误的。
  1. //格式转换  NV12->ABGR
  2. void rga_convert()
  3. {
  4.     RockchipRga *rga = RgaCreate();

  5.     if (!rga) {
  6.         printf("create rga failed !\n");
  7.         abort();
  8.     }
  9.     rga->ops->initCtx(rga);
  10.     //V4L2_PIX_FMT_NV12  V4L2_PIX_FMT_ABGR32
  11.     rga->ops->setSrcFormat(rga, V4L2_PIX_FMT_NV12, BUFFER_WIDTH, BUFFER_HEIGHT);
  12.     rga->ops->setDstFormat(rga, V4L2_PIX_FMT_ABGR32, BUFFER_WIDTH, BUFFER_HEIGHT);

  13.     rga->ops->setSrcBufferPtr(rga, srcBuffer);
  14.     rga->ops->setDstBufferPtr(rga, dstBuffer);

  15.     rga->ops->go(rga);
  16. }
复制代码

作者: jefferyzhang    时间: 2019-7-10 16:39
盗骊_l 发表于 2019-7-9 19:15
啊?上面不是说  Android和Linux一致吗?
https://github.com/Jerzha/samples-toybrick-rga上面的demo, ...

驱动一样,用都可以用。只是android的封装会更高级一点。
你这里的转换代码没有问题,有问题要看看你开的buffer大小是不是对的。
作者: 15992605143    时间: 2019-9-6 22:31
rga可以按比例缩放吗?
作者: jefferyzhang    时间: 2019-9-8 12:10
15992605143 发表于 2019-9-6 22:31
rga可以按比例缩放吗?

当然可以。但是长宽只能是定点数
作者: 盗骊_l    时间: 2019-9-9 13:59
本帖最后由 盗骊_l 于 2019-9-9 14:03 编辑

请问,多线程使用的时候需要注意什么?
我现在遇到的问题:
1>.每个线程里,mpp解码后使用RGA进行格式转换,
  1. RockchipRga *rga = RgaCreate();
复制代码
,初始化一个rga的上下文,一路视频解码后使用RGA转换输出都正常,2路视频解码RGA转换一段时间后,设备重启,3路视频解码,10分钟左右就会造成,设备重启,请问这是什么原因?解码、格式转换结果都正常,就是多路多线程中,一段时间后会造成设备重启。
作者: jefferyzhang    时间: 2019-9-9 14:16
盗骊_l 发表于 2019-9-9 13:59
请问,多线程使用的时候需要注意什么?
我现在遇到的问题:
1>.每个线程里,mpp解码后使用RGA进行格式转换,, ...

设备重启请检查你自己的代码,RGA是物理的硬件,对内存溢出、地址越界是无法在CPU层面报错的,给什么搬运什么。越界就会覆盖其他地址,直接崩溃。
长宽都需要size需要16bit对齐。
作者: shopping    时间: 2019-9-17 17:15
老哥,最近抽时间看了下你发的一些资料,问一句:
1.目前我除了用 opencv 调取摄像头,将视频数据裁剪缩放后输入算法模型,然后将结果返回并显示。
2.我还可以用 GStreamer/MPP 来调用摄像头,用 RGA 裁剪缩放图片,然后输入算法模型,最后利用 GPU OpenGL来做显示。
看您资料里描述,方案2内存占用少,模型运算更快。
作者: jefferyzhang    时间: 2019-9-17 18:03
shopping 发表于 2019-9-17 17:15
老哥,最近抽时间看了下你发的一些资料,问一句:
1.目前我除了用 opencv 调取摄像头,将视频数据裁剪缩放 ...

所以要问啥呢?我看了半天不知道你问题是啥
作者: shopping    时间: 2019-9-18 09:45
jefferyzhang 发表于 2019-9-17 18:03
所以要问啥呢?我看了半天不知道你问题是啥

老哥,我想问的是,现在我想不用opencv库,因为它占用内存较大。所以替代方案就是:
GStreamer/MPP 来调用摄像头,用 RGA 裁剪缩放图片,然后输入算法模型,最后利用 GPU OpenGL来做显示。
这个方案对吗?
作者: jefferyzhang    时间: 2019-9-18 11:13
shopping 发表于 2019-9-18 09:45
老哥,我想问的是,现在我想不用opencv库,因为它占用内存较大。所以替代方案就是:
GStreamer/MPP 来调 ...

对的。没问题
作者: shopping    时间: 2019-9-18 11:22
jefferyzhang 发表于 2019-9-18 11:13
对的。没问题

千头万绪,理不清楚,现在感觉脑子一片混沌。再追问一下:Debian系统下,MPP OpenGL  GStreamer  RGA我都要自己编译安装?
作者: jefferyzhang    时间: 2019-9-18 14:15
shopping 发表于 2019-9-18 11:22
千头万绪,理不清楚,现在感觉脑子一片混沌。再追问一下:Debian系统下,MPP OpenGL  GStreamer  RGA我都 ...

请自行看wiki,全部都是dnf安装就可以。
当然除了opengl以外都有源码,愿意自己编译安装也行
作者: shopping    时间: 2019-9-20 14:45
本帖最后由 shopping 于 2019-9-20 14:47 编辑
jefferyzhang 发表于 2019-9-18 14:15
请自行看wiki,全部都是dnf安装就可以。
当然除了opengl以外都有源码,愿意自己编译安装也行 ...

呃,请问 OpenGL 要怎么安装?C:\Users\lenovo\Desktop\BUG.jpg还有我测试RGA时报了这样的问题,请问我这个RGA是安装好了?
作者: jefferyzhang    时间: 2019-9-20 16:30
shopping 发表于 2019-9-20 14:45
呃,请问 OpenGL 要怎么安装?还有我测试RGA时报了这样的问题,请问我这个RGA是安装好了? ...

rga不需要装,他是硬件的一个设备,挂载在/dev/rga下。
封装的rga库只是方便大家访问这个外设而已
作者: shopping    时间: 2019-9-20 17:07
jefferyzhang 发表于 2019-9-20 16:30
rga不需要装,他是硬件的一个设备,挂载在/dev/rga下。
封装的rga库只是方便大家访问这个外设而已 ...

难怪编译的时候是把它目录下的 cpp 文件给编译了,那 OpenGl 呢,老哥。
作者: jefferyzhang    时间: 2019-9-20 18:09
shopping 发表于 2019-9-20 17:07
难怪编译的时候是把它目录下的 cpp 文件给编译了,那 OpenGl 呢,老哥。

ogl请用dnf安装 ocl 包。 mali的 cl和gl是同一个so。
目前我们暂时只能放cl里,系统自带的gl依赖太多,我们还在整理。
作者: jefferyzhang    时间: 2019-9-20 18:10
rga那些库请看wiki文档,都有说如何安装
作者: shopping    时间: 2019-10-8 15:44
jefferyzhang 发表于 2019-9-20 18:09
ogl请用dnf安装 ocl 包。 mali的 cl和gl是同一个so。
目前我们暂时只能放cl里,系统自带的gl依赖太多,我 ...

老哥,关于这个OpenGL库,如果我直接用 FrameBuffer 显示图片/视频,这样是否可行?即 V4L2+ FrameBuffer方案。
作者: jefferyzhang    时间: 2019-10-9 10:35
shopping 发表于 2019-10-8 15:44
老哥,关于这个OpenGL库,如果我直接用 FrameBuffer 显示图片/视频,这样是否可行?即 V4L2+ FrameBuffer ...

Linux 4.x以后就改用DRM框架了,没有FB设备了
作者: shopping    时间: 2019-10-9 10:42
本帖最后由 shopping 于 2019-10-9 11:49 编辑
jefferyzhang 发表于 2019-10-9 10:35
Linux 4.x以后就改用DRM框架了,没有FB设备了

好吧,这几天的FB白看了,看样子最后还是得用 OpenGL 来做显示?还有老哥,V4L2它有解码功能这与MPP功能是重合的,如果我用V4L2解码,处理效率区别大吗?
麻烦指教一下,谢谢。

作者: jefferyzhang    时间: 2019-10-9 17:36
shopping 发表于 2019-10-9 10:42
好吧,这几天的FB白看了,看样子最后还是得用 OpenGL 来做显示?还有老哥,V4L2它有解码功能这与MPP功能是 ...

v4l2没有解码,openGL只是GPU接口,最终绘制还是要走到DRM。
作者: shopping    时间: 2019-10-9 19:31
jefferyzhang 发表于 2019-10-9 17:36
v4l2没有解码,openGL只是GPU接口,最终绘制还是要走到DRM。

老哥,我刚刚又看了一遍代码,V4L2框架调用摄像头输出格式已经是 yuv422 格式了,可以直接保存成 yuv文件的。https://www.cnblogs.com/surpassa ... lab1.html#!comments
作者: jefferyzhang    时间: 2019-10-10 08:33
shopping 发表于 2019-10-9 19:31
老哥,我刚刚又看了一遍代码,V4L2框架调用摄像头输出格式已经是 yuv422 格式了,可以直接保存成 yuv文件 ...

那是因为你的usb相机出来的格式就是yuv422
作者: shopping    时间: 2019-10-11 11:17
本帖最后由 shopping 于 2019-10-11 11:30 编辑
jefferyzhang 发表于 2019-10-10 08:33
那是因为你的usb相机出来的格式就是yuv422

老哥,用RGA转换格式出现花屏重影的问题。我自己写了个 yuv422 转 BGR 的函数,结果显示正常,RGA sample demo :https://github.com/Jerzha/samples-toybrick-rga .
  1. // rga start

  2.     srcBuffer = (unsigned char*)malloc(sizeof(unsigned char) * BUFFER_SIZE_src);  // yuyv  BUFFER_SIZE_src = MAGE_WIDTH*IMAGE_HEIGHT*2
  3.     dstBuffer = (unsigned char*)malloc(sizeof(unsigned char) * BUFFER_SIZE_det);  // RGB  BUFFER_SIZE_det = MAGE_WIDTH*IMAGE_HEIGHT*3

  4.     RockchipRga *mRga = RgaCreate();
  5.     if (!mRga) {
  6.         printf("create rga failed !\n");
  7.         abort();
  8.     }
  9.     mRga->ops->initCtx(mRga);
  10.     mRga->ops->setSrcFormat(mRga, V4L2_PIX_FMT_YUYV, IMAGE_WIDTH, IMAGE_HEIGHT);
  11.     mRga->ops->setDstFormat(mRga, V4L2_PIX_FMT_BGR24, IMAGE_WIDTH, IMAGE_HEIGHT);

  12.     struct v4l2_buffer enqueue,dequeue ;
  13.     memset(&enqueue, 0, sizeof(enqueue));
  14.     memset(&dequeue, 0, sizeof(dequeue));

  15.     enqueue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
  16.     enqueue.memory = V4L2_MEMORY_MMAP ;

  17.     dequeue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
  18.     dequeue.memory = V4L2_MEMORY_MMAP ;
  19.     while (1)
  20.     {
  21.     // loop start
  22.         // dequeue
  23.         ioctl(fd, VIDIOC_DQBUF, &dequeue) ; // get frame v4l2取缓存帧
  24.         //memcpy((void*)srcBuffer , buffers[dequeue.index].start , dequeue.length);
  25.         srcBuffer = (unsigned char *)buffers[dequeue.index].start;  // 将取出来的缓存帧起始地址赋给 srcBuffer

  26.         mRga->ops->setSrcBufferPtr(mRga, srcBuffer);
  27.         mRga->ops->setDstBufferPtr(mRga, dstBuffer);
  28.         mRga->ops->go(mRga);

  29.         unchar_to_Mat(dstBuffer);  // 将 unsigned char BGR格式转换为 Mat BGR格式
  30.         cv::imshow("image",img);
  31.         cv::waitKey(20);

  32.         //enqueue
  33.         enqueue.index = dequeue.index ;
  34.         ioctl(fd, VIDIOC_QBUF, &enqueue) ;  // enqueue

  35.     }
  36.     ioctl(fd, VIDIOC_STREAMOFF, &type);
  37.     free(srcBuffer);
  38.     free(dstBuffer);

  39.     for(int i=0;i<req.count;i++)
  40.     {
  41.     munmap(buffers[i].start,buffers[i].length);
  42.     }
  43.     return(TRUE);
  44. }
复制代码

作者: jefferyzhang    时间: 2019-10-11 14:28
shopping 发表于 2019-10-11 11:17
老哥,用RGA转换格式出现花屏重影的问题。我自己写了个 yuv422 转 BGR 的函数,结果显示正常,RGA sample  ...

RGA不支持BGR和422,422也是软转的
作者: shopping    时间: 2019-10-11 14:46
jefferyzhang 发表于 2019-10-11 14:28
RGA不支持BGR和422,422也是软转的

刚刚回去看了下官方文档,果然不支持 BGR 和 YUV422,又走了弯路。
作者: will92    时间: 2019-10-21 16:31
shopping 发表于 2019-10-11 14:46
刚刚回去看了下官方文档,果然不支持 BGR 和 YUV422,又走了弯路。

请问rga的官方文档在哪里可以找到呢?
作者: shopping    时间: 2019-10-21 17:00
will92 发表于 2019-10-21 16:31
请问rga的官方文档在哪里可以找到呢?

官方给的固件包里附带的,docs目录下。
作者: heyunteng251314    时间: 2019-10-29 16:01
版主你好!对于RGA模块,我有个疑问的是mRga->ops->go(mRga)这个函数的程序代码是跑在RGA模块上嘛?
我下这里面的DEMON(https://github.com/Jerzha/samples-toybrick-rga),是安卓的,哪有LINUX端的呢?
作者: jefferyzhang    时间: 2019-10-29 16:20
heyunteng251314 发表于 2019-10-29 16:01
版主你好!对于RGA模块,我有个疑问的是mRga->ops->go(mRga)这个函数的程序代码是跑在RGA模块上嘛?
我下这 ...

安卓linux是通用的,并且安卓有自己单独一套接口。
Linux你用这个就可以了。
RGA是一个IP核,不会执行cpu代码的。你说的go就是主控把数据送给rga正在处理了。
作者: heyunteng251314    时间: 2019-11-4 16:49
jefferyzhang 发表于 2019-10-29 16:20
安卓linux是通用的,并且安卓有自己单独一套接口。
Linux你用这个就可以了。
RGA是一个IP核,不会执行cpu ...

哦!谢谢
作者: 时光丶    时间: 2019-12-2 10:27
shopping 发表于 2019-10-21 17:00
官方给的固件包里附带的,docs目录下。

我找到了一个RKDocs文件夹,请问rga的文档叫啥?
作者: shopping    时间: 2019-12-2 10:39
时光丶 发表于 2019-12-2 10:27
我找到了一个RKDocs文件夹,请问rga的文档叫啥?

具体什么名字忘了,反正名字里面有RGA,记得docs目录下叫RGA的就一个,你直接搜RGA就行了

作者: 时光丶    时间: 2019-12-2 10:43
shopping 发表于 2019-12-2 10:39
具体什么名字忘了,反正名字里面有RGA,记得docs目录下叫RGA的就一个,你直接搜RGA就行了
...

那我的固件包里面没有叫rga的文件,能给我传一个吗?
作者: 时光丶    时间: 2019-12-2 17:17
rga->ops->setSrcFormat(rga,V4L2_PIX_FMT_NV21,1280,720);我从摄像头采集到的数据是nv21的,但是设置格式nv21他会阻塞在这里,是不是不支持nv21啊?我手动把数据转换成nv12然后换成nv12格式就没问题
作者: puresoy    时间: 2020-1-6 16:51
试了试 rga本身是能使的
但是在没有drm的情况下 rga_copy的速度甚至比memcpy的速度慢一半
可是ubuntu系统(Debian)下没有dnf 也不能用apt找到rockchip-drm-dev
那么请问 rockchip的drm内存 应该如何申请?
有rockchip-drm 的源码么?
应该如何得到这个开发包?

作者: jefferyzhang    时间: 2020-1-6 17:20
本帖最后由 jefferyzhang 于 2020-1-6 17:23 编辑
puresoy 发表于 2020-1-6 16:51
试了试 rga本身是能使的
但是在没有drm的情况下 rga_copy的速度甚至比memcpy的速度慢一半
可是ubuntu系统(D ...

1. drm接口是标准的,如何申请连续内存百度drm内存分配就可以,rockchip不会自己去折腾这个。
2. 代码可以参考android gralloc源码实现,不过你百度drm如何分配内存估计更快。
3. rockchip-drm也是开源的,在https://github.com/rockchip-linux/libdrm-rockchip (没有什么特别的东西,和libdrm基本是一样的)
4. 关于你说速度问题,rga copy就是dma搬运,连续内存速度快,不连续的随机内存dma速度当然没cpu快。跟是不是drm申请的内存是无关的,你目标是要申请连续内存。

作者: cjlongfei    时间: 2020-3-11 09:38
直接下载GITHUB上的源码,在板子上编译生成,rag_cpy,运行被Aborted了,是什么原因?好像是崩在RgaCreate这里,系统是fedora28
作者: jefferyzhang    时间: 2020-3-11 09:39
cjlongfei 发表于 2020-3-11 09:38
直接下载GITHUB上的源码,在板子上编译生成,rag_cpy,运行被Aborted了,是什么原因?好像是崩在RgaCreate这 ...

板子是什么
作者: cjlongfei    时间: 2020-3-11 10:01
jefferyzhang 发表于 2020-3-11 09:39
板子是什么

RK3399P的,我加SUDO和卸载之前安装的RGA库以后搞定了。现在可以了。
顺便问另外一个问题,在RTSP推流那个实验的时候,之前也是 rga有问题,现在RGA过了,但是报以下错误
是啥原因:
pictureSize=460800
__DD_H264VideoFileServerMediaSubsession::startStream__
StreamOn success!
V4L2FramedSource::doGetNextFrame use 317
mpp_rt: NOT found ion allocator
mpp_rt: found drm allocator
mpi: mpp version: Without VCS info
hal_h264e_api: vcodec type 00000000 can not find H.264 encoder device
mpp_hal: mpp_hal_init hal h264e_rkvenc init failed ret -1
mpp_hal: mpp_hal_init could not found coding type 7
mpp_enc: mpp_enc_init could not init hal
mpp: error found on mpp initialization
mpp: Assertion mEnc failed at control_enc:834
mpp_enc: mpp_enc_control found NULL input enc (nil) cmd 320003 param 258741672
mpp: command 320003 param 0xf6c15a8 ret -3
mpi control enc set prep cfg failed ret -3
test mpp setup failed ret -3
mpi_enc_test failed ret -3
V4L2FramedSource::doGetNextFrame use 29
mpi: mpp version: Without VCS info
hal_h264e_api: vcodec type 00000000 can not find H.264 encoder device
mpp_hal: mpp_hal_init hal h264e_rkvenc init failed ret -1
mpp_hal: mpp_hal_init could not found coding type 7
mpp_enc: mpp_enc_init could not init hal
mpp: error found on mpp initialization
Segmentation fault

作者: jefferyzhang    时间: 2020-3-11 10:14
cjlongfei 发表于 2020-3-11 10:01
RK3399P的,我加SUDO和卸载之前安装的RGA库以后搞定了。现在可以了。
顺便问另外一个问题,在RTSP推流那 ...

mpp: error found on mpp initialization
要么代码有问题,要么驱动有问题
作者: panziwen86    时间: 2020-4-7 15:46
我在RK3399Pro上使用samples-toybrick-rga进行格式转换,程序刚开始没有问题,图片格式转换也正常,但总是运行了几天时间后卡住了,加日志发现是一直卡在:
ret = ioctl(rga->rgaFd, RGA_BLIT_SYNC, &req);一直阻塞在这个调用里了,然后重启程序也还是阻塞在这里面了,必须重启系统才能再正常使用。
请问楼主知道这可能是什么问题吗??
作者: panziwen86    时间: 2020-4-7 15:51
cjlongfei 发表于 2020-3-11 09:38
直接下载GITHUB上的源码,在板子上编译生成,rag_cpy,运行被Aborted了,是什么原因?好像是崩在RgaCreate这 ...

估计你是没有修改/dev/rga设备文件的权限吧,sudo chmod 777 /dev/rga,或者sudo执行程序就可以了。
作者: jefferyzhang    时间: 2020-4-7 16:41
panziwen86 发表于 2020-4-7 15:46
我在RK3399Pro上使用samples-toybrick-rga进行格式转换,程序刚开始没有问题,图片格式转换也正常,但总是 ...

板子是什么?Toybrick板子不会出现这问题,如果是其他代理商的板子,请联系他们去debug。

如果是Toybrick的板子,怕你是传了错误的参数进去。跟硬件打交道和纯cpu不一样,参数传错、地址传错,出的错误就是毁灭性的,芯片是没办法知道你传的是不是对的。
作者: chansy    时间: 2020-4-10 16:47
cjlongfei 发表于 2020-3-11 10:01
RK3399P的,我加SUDO和卸载之前安装的RGA库以后搞定了。现在可以了。
顺便问另外一个问题,在RTSP推流那 ...

你解决了吗,要怎么修复?
作者: ddcat1991    时间: 2020-4-13 18:20
本帖最后由 ddcat1991 于 2020-4-13 18:23 编辑

弱弱的问一下, 这个RGA设备 支持 NV12->BGR24的图像转换吗?, 我转出来花屏了, (也可能是opencv使用方法不正确)

  1. rga->ops->setSrcFormat(rga, V4L2_PIX_FMT_NV12, BUFFER_WIDTH, BUFFER_HEIGHT);
  2. rga->ops->setDstFormat(rga, V4L2_PIX_FMT_BGR24, BUFFER_WIDTH, BUFFER_HEIGHT);
复制代码




作者: jefferyzhang    时间: 2020-4-13 22:36
ddcat1991 发表于 2020-4-13 18:20
弱弱的问一下, 这个RGA设备 支持 NV12->BGR24的图像转换吗?, 我转出来花屏了, (也可能是opencv使用方法不 ...

花瓶要自己看下宽高设置,以及宽度是否16对齐
作者: leonardo    时间: 2020-7-20 17:31
你好,

我们过去在其他平台上做视频图像相关的处理开发。目前想把所有开发移植到3399平台上来。我先描述一下之前的架构:
在之前的平台上,平台官方提供了标准的linux DMABUFF API,应用程序通过创建DMABUFF,然后交给底层驱动,底层驱动使用linux标准内核API,获得DMABUFF的物理地址,驱动将物理地址通知外设(PCIE视频采集卡),外设
直接将视频数据写入DMABUFF的物理地址中。应用层直接操作DMABUFF内的视频数据,然后将DMABUFF重新插入底层采集队列。整个操作都是符合linux DMABUFF(官方提供API来实现DMABUFF和CPU之间的cache一致性操作)和V4L2标准。

如果我们将这部分功能移植到3399平台的话有以下几点疑问:
1、3399运行的linux内核是否支持标准的PCIE驱动架构,标准的V4L2视频采集驱动(VB2驱动)和标准的DMABUFF映射操作?
2、3399的应用层是否也提供了标准的linux DMABUFF API,可以直接交给底层驱动,实现视频数据的零拷贝和非MMAP机制的操作?
作者: jefferyzhang    时间: 2020-7-20 18:01
leonardo 发表于 2020-7-20 17:31
你好,

我们过去在其他平台上做视频图像相关的处理开发。目前想把所有开发移植到3399平台上来。我先描述 ...

你发个帖子问不好么。。。发这只有我看得到。。
1. 支持
2. 支持
作者: leonardo    时间: 2020-7-20 19:44
jefferyzhang 发表于 2020-7-20 18:01
你发个帖子问不好么。。。发这只有我看得到。。
1. 支持
2. 支持

谢谢大神回复,我下次发帖子,太感谢了。
作者: JackXu9527    时间: 2020-7-23 22:54
jefferyzhang 发表于 2019-10-10 08:33
那是因为你的usb相机出来的格式就是yuv422

你好!请问对于网络摄像头的RTSP视频流如何在RK3399Pro上在android平台下如何读取并送SDK识别呢?
作者: jefferyzhang    时间: 2020-7-24 08:30
JackXu9527 发表于 2020-7-23 22:54
你好!请问对于网络摄像头的RTSP视频流如何在RK3399Pro上在android平台下如何读取并送SDK识别呢? ...

请写代码识别
作者: JackXu9527    时间: 2020-7-24 08:50
jefferyzhang 发表于 2020-7-24 08:30
请写代码识别

你好,我没看明白你说的意思。我已经从RTSP视频流中获取了单帧图像,我该如何处理转换为imagebuffer格式呢?我的问题在这个帖子里面,烦请你帮忙看看,十分感谢!http://t.rock-chips.com/forum.ph ... tid=1939&extra=
作者: jefferyzhang    时间: 2020-7-24 09:54
JackXu9527 发表于 2020-7-24 08:50
你好,我没看明白你说的意思。我已经从RTSP视频流中获取了单帧图像,我该如何处理转换为imagebuffer格式 ...

...

作者: JackXu9527    时间: 2020-7-24 10:28
jefferyzhang 发表于 2020-7-24 09:54
...

你好!请问Bitmap不能转为imagebuffer吗?
作者: jefferyzhang    时间: 2020-7-24 11:09
JackXu9527 发表于 2020-7-24 10:28
你好!请问Bitmap不能转为imagebuffer吗?

代码自己写,baidu、google。android又不是我们发明的,你不能不会写代码也跑来问我们吧
作者: JackXu9527    时间: 2020-7-25 17:13
jefferyzhang 发表于 2020-7-24 11:09
代码自己写,baidu、google。android又不是我们发明的,你不能不会写代码也跑来问我们吧 ...

我只是请教一下思路,你又是发省略号又是质问我,我不知道你哪来的那么大的火气?要是谷歌百度能找到我还在这请教你干嘛?你这么牛你咋不上天呢?我在猜想是不是你也有点不清楚在这用发火来搪塞用户……
作者: shushen    时间: 2020-8-22 12:01
JackXu9527 发表于 2020-7-25 17:13
我只是请教一下思路,你又是发省略号又是质问我,我不知道你哪来的那么大的火气?要是谷歌百度能找到我还 ...

哥們說的對,你們作爲官方最清楚你們的設備,我們能來到這裏就是已經嘗試了努力找不到途徑,你清楚了就回答哪裏的問題,不清楚了就說不清楚,我們另想辦法,你這麼湯賽的回答說是參數傳錯了,我們也知道參參數哪裏有錯導致的這個不用你說!
作者: ustcwzy1986    时间: 2020-9-7 14:56
你好,RGA库安装成功后,调用RgaCreate() 返回NULL
作者: xfxty    时间: 2020-10-28 13:14
您好,我用的是nanopim4,需要更新内核,实现dev/rga,现在编译好内核,设置了dtsi,更新内核后,仍不能发现/dev/rga。希望您可以帮助我
作者: guozhaozhong    时间: 2020-11-10 21:07
cjlongfei 发表于 2020-3-11 10:01
RK3399P的,我加SUDO和卸载之前安装的RGA库以后搞定了。现在可以了。
顺便问另外一个问题,在RTSP推流那 ...

请问这个问题怎么解决的?

作者: lily393    时间: 2020-11-23 17:11
jefferyzhang 发表于 2019-10-29 16:20
安卓linux是通用的,并且安卓有自己单独一套接口。
Linux你用这个就可以了。
RGA是一个IP核,不会执行cpu ...

也就是上面那个源码也适用于firefly的板子么?
作者: jefferyzhang    时间: 2020-11-23 20:12
lily393 发表于 2020-11-23 17:11
也就是上面那个源码也适用于firefly的板子么?

理论上是RK芯片和我们发布出去的开发版是可以的,但是需要开发商保证驱动是正确的。
我们只能保证发布出去的芯片RGA是正常的,但是无法保证代理商做的操作系统和驱动是否有正确更新和合并。

作者: lily393    时间: 2020-11-25 16:52
jefferyzhang 发表于 2019-4-18 16:59
rga其实就是一个ioctl,填下结构体就可以了,建议你看库源码自己实现一个,或者用android写好的librga库 ...

想问下 RGA加速 测试demo 跑出来rgb转nv12 要5ms   1280*720  resize 到720*480 后
要10ms  这个算正常么???
MODE = b
main, Unknow RGA mode
firefly@firefly:~/rk3399/src/test/rga_test/src$ sudo ./rga_test --cvtcolor
librga:RGA_GET_VERSION:3.02,3.020000
ctx=0xf2e6c40,ctx->rgaFd=3
Rga built version:version:1.00
Start selecting mode 0
im2d cvtcolor ..
MODE = 8
filePath:/usr/data/in0w1280-h720-rgba8888.bin
read size:3686400
open file
cvtcolor .... cost time 5281 us, Run successfully

open /usr/data/out0w1280-h720-nv12.bin and write ok
read size:1382400
firefly@firefly:~/rk3399/src/test/rga_test/src$ sudo ./rga_test --resize down
librga:RGA_GET_VERSION:3.02,3.020000
ctx=0x39aa3c40,ctx->rgaFd=3
Rga built version:version:1.00
Start selecting mode 0
im2d resize ..
down resize ...
MODE = 2
filePath:/usr/data/in0w1280-h720-rgba8888.bin
read size:3686400
open file
resizing .... cost time 9969 us, Run successfully

open /usr/data/out0w720-h480-rgba8888.bin and write ok
read size:1382400

作者: jefferyzhang    时间: 2020-11-25 16:54
lily393 发表于 2020-11-25 16:52
想问下 RGA加速 测试demo 跑出来rgb转nv12 要5ms   1280*720  resize 到720*480 后
要10ms  这个算正常 ...

使用DMA内存的话,这速度不正常;
如果使用的是虚拟内存的话,那很正常。
作者: lily393    时间: 2020-11-26 16:31
jefferyzhang 发表于 2020-11-25 16:54
使用DMA内存的话,这速度不正常;
如果使用的是虚拟内存的话,那很正常。 ...

用的是这个
        src = wrapbuffer_virtualaddr(yuv_buf, SRC_WIDTH, SRC_HEIGHT, SRC_FORMAT);
        dst = wrapbuffer_virtualaddr(rgb_buf, DST_WIDTH, DST_HEIGHT, DST_FORMAT);

用dma内存的话我应该是调这个?
        src = wrapbuffer_fd(fd1, SRC_WIDTH, SRC_HEIGHT, SRC_FORMAT);
        dst = wrapbuffer_fd(fd2, DST_WIDTH, DST_HEIGHT, DST_FORMAT);
作者: seanx    时间: 2020-11-27 10:00
本帖最后由 seanx 于 2020-11-27 10:01 编辑

请问一下:
1. 如果送入 RGA 的图像是通过 imread 等方式获取的,无法确保宽高 16 对齐,这种情况要怎么处理?难道要先用 CPU 搬一遍吗?(这种情况报错“ioctl: RGA_BLIT_SYNC failed, return -1”)
2. 确认一下 16 对齐是对输入输出均有此要求吗,还是只要求输入即可?如果要求输出,那如何得到没有填充的输出?经测试,如果输入宽高是 16 对齐的,那么输出宽高似乎可以不用对齐(直接设置为 1920x1080 可以得到正确输出)
作者: jefferyzhang    时间: 2020-11-27 22:41
seanx 发表于 2020-11-27 10:00
请问一下:
1. 如果送入 RGA 的图像是通过 imread 等方式获取的,无法确保宽高 16 对齐,这种情况要怎么处 ...

目前版本RGA不需要16对齐,mpp是需要对齐的
作者: xiayip    时间: 2020-11-30 23:26
你好, 请问会考虑利用RGA做图像去畸变吗, 谢谢
作者: xyyangkun    时间: 2021-3-16 09:50
你好,我想使用rga模块做两个视频的合成叠加,就是把一个视频叠加到另外一个视频中,视频是yuv422,如果视频最大是1080P60,rga模块是否可以达到每秒60帧的性能?
作者: jefferyzhang    时间: 2021-3-16 10:06
xyyangkun 发表于 2021-3-16 09:50
你好,我想使用rga模块做两个视频的合成叠加,就是把一个视频叠加到另外一个视频中,视频是yuv422,如果视频 ...

理论上能
作者: xinzhiling111    时间: 2021-5-24 18:33
rga进行图像缩放的时候,宽度和高度必须同时都是放大或者缩小吗?是否可以宽度缩小,高度放大?实际测试中发现,1280*720图像转618*458的时候正常,但是1280*720图像转1246*924的时候图片部分花掉了,刚好是下面部分,以左上角为原点的话,像是超过720的部分花掉了。
作者: jefferyzhang    时间: 2021-5-25 08:39
xinzhiling111 发表于 2021-5-24 18:33
rga进行图像缩放的时候,宽度和高度必须同时都是放大或者缩小吗?是否可以宽度缩小,高度放大?实际测试中 ...

可以。我暂时没遇到过这种问题。你用的是哪一套的rga封装?请用github rockchip-linux上那个最新的封装试下。

作者: miaozhihua    时间: 2021-6-29 21:17
各位大佬,我在github上下载最新代码,平台为3399+linux。我在sample中的rgaImdemo.cpp的基础上修改为通过drm申请mmap的fd方式,现在demo可以测试完成,速度比之前用malloc的也快了很多。但是demo跑完后系统桌面显示有些地方会出现花屏(花屏的现象是桌面某些地方会显示另外地方的内容,系统其他功能都正常,感觉是fb内容被破坏了),下面是我封装的创建drm mmap句柄的函数和执行到wrapbuffer_fd()函数调用为止的部分代码,帮忙看一下是否哪里有问题,十分感谢!
  1. <div style="color: #d4d4d4;background-color: #1e1e1e;font-family: 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 18px;line-height: 24px;white-space: pre;">
  2. <div><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">createDrmMap</span><span style="color: #d4d4d4;">(</span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">drm_fd</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">bpp</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">width</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">height</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">struct</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">fdmmap_s</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">*</span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;">{</span></div><div><span style="color: #569cd6;">struct</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">drm_mode_create_dumb</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">struct</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">drm_mode_map_dumb</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">map_arg</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> ret;</span></div><div><span style="color: #dcdcaa;">memset</span><span style="color: #d4d4d4;">(&arg, </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(arg));</span></div><div><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">bpp</span><span style="color: #d4d4d4;"> = bpp;</span></div><div><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">width</span><span style="color: #d4d4d4;"> = width;</span></div><div><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">height</span><span style="color: #d4d4d4;"> = height;</span></div><div><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"bpp=%d, width=%d, height=%d</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">bpp</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">width</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">height</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">ret = </span><span style="color: #dcdcaa;">drmIoctl</span><span style="color: #d4d4d4;">(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);</span></div><div><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (ret) {</span></div><div><span style="color: #dcdcaa;">perror</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"failed to create dumb buffer"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> ret;</span></div><div><span style="color: #d4d4d4;">}</span></div><div><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">handle</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">handle</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">pitch</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">pitch</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"bpp=%d, width=%d, height=%d, size=%d, pitch=%d</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">bpp</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">width</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">height</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">pitch</span><span style="color: #d4d4d4;">);</span></div>
  3. <div><span style="color: #dcdcaa;">memset</span><span style="color: #d4d4d4;">(&map_arg, </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(map_arg));</span></div><div><span style="color: #9cdcfe;">map_arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">handle</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">handle</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;">ret = </span><span style="color: #dcdcaa;">drmIoctl</span><span style="color: #d4d4d4;">(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);</span></div><div><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (ret)</span></div><div><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> ret;</span></div><div><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">buf</span><span style="color: #d4d4d4;"> = (</span><span style="color: #569cd6;">char</span><span style="color: #d4d4d4;"> *)</span><span style="color: #dcdcaa;">mmap</span><span style="color: #d4d4d4;">(</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, </span><span style="color: #9cdcfe;">map_arg</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">offset</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">buf</span><span style="color: #d4d4d4;"> == MAP_FAILED)</span></div><div><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> -</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #dcdcaa;">drmPrimeHandleToFD</span><span style="color: #d4d4d4;">(drm_fd, </span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">handle</span><span style="color: #d4d4d4;">, </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">, &</span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">fd</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"drm_fd=%d, map->fd=%d</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, drm_fd, </span><span style="color: #9cdcfe;">map</span><span style="color: #d4d4d4;">-></span><span style="color: #9cdcfe;">fd</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;">}</span></div><div><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">main</span><span style="color: #d4d4d4;">(</span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">argc</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">char</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">argv</span><span style="color: #d4d4d4;">[])</span></div><div><span style="color: #d4d4d4;">{</span></div><div><span style="color: #d4d4d4;">    </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> drm_fd, ret;</span></div><div><span style="color: #d4d4d4;">    drm_fd = </span><span style="color: #dcdcaa;">open</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"/dev/dri/card0"</span><span style="color: #d4d4d4;">, O_RDWR, </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">    </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;">( drm_fd <=</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;">    {</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #dcdcaa;">perror</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"open dri card0"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> -</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;">    }</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;">( </span><span style="color: #dcdcaa;">createDrmMap</span><span style="color: #d4d4d4;">(drm_fd, </span><span style="color: #dcdcaa;">get_bpp_from_format</span><span style="color: #d4d4d4;">(SRC_FORMAT), SRC_WIDTH, SRC_HEIGHT, &map_src)<</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;"> {</span></div><div><span style="color: #d4d4d4;">     </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"createDrmMap map_src error</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">     </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> -</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> }</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"map_src.size=%d</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">map_src</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;">( </span><span style="color: #dcdcaa;">createDrmMap</span><span style="color: #d4d4d4;">(drm_fd, </span><span style="color: #dcdcaa;">get_bpp_from_format</span><span style="color: #d4d4d4;">(DST_FORMAT), DST_WIDTH, DST_HEIGHT, &map_dst)<</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;"> {</span></div><div><span style="color: #d4d4d4;">     </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"createDrmMap map_dst error</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">     </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> -</span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> }</span></div><div><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"createDrmMap map_src/map_dst ok</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div>
  4. <div><span style="color: #d4d4d4;">        ret = </span><span style="color: #dcdcaa;">get_buf_from_file</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">map_src</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">buf</span><span style="color: #d4d4d4;">, SRC_FORMAT, SRC_WIDTH, SRC_HEIGHT, </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (!ret)</span></div><div><span style="color: #d4d4d4;">            </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"open src file ok</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #c586c0;">else</span></div><div><span style="color: #d4d4d4;">            </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">"can not open file</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;">(MODE == MODE_BLEND || MODE == MODE_FILL) {</span></div><div><span style="color: #d4d4d4;">            ret = </span><span style="color: #dcdcaa;">get_buf_from_file</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">map_dst</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">buf</span><span style="color: #d4d4d4;">, DST_FORMAT, DST_WIDTH, DST_HEIGHT, </span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">            </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (!ret)</span></div><div><span style="color: #d4d4d4;">                </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"open dst file</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">            </span><span style="color: #c586c0;">else</span></div><div><span style="color: #d4d4d4;">                </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">"can not open file</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        } </span><span style="color: #c586c0;">else</span><span style="color: #d4d4d4;"> {</span></div><div><span style="color: #d4d4d4;">    </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"map_dst.size=%d, get_bpp_from_format(DST_FORMAT)=%d</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">map_dst</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">get_bpp_from_format</span><span style="color: #d4d4d4;">(DST_FORMAT));</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #dcdcaa;">memset</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">map_dst</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">buf</span><span style="color: #d4d4d4;">,</span><span style="color: #b5cea8;">0x00</span><span style="color: #d4d4d4;">,</span><span style="color: #9cdcfe;">map_dst</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">size</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #6a9955;">    //        memset(map_dst.buf,0x00,DST_WIDTH*DST_HEIGHT*get_bpp_from_format(DST_FORMAT));</span></div><div><span style="color: #d4d4d4;">        }</span></div><div><span style="color: #d4d4d4;">        </span><span style="color: #dcdcaa;">printf</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"get_buf_from_file ok</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;">        src = </span><span style="color: #dcdcaa;">wrapbuffer_fd</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">map_src</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">fd</span><span style="color: #d4d4d4;">, SRC_WIDTH, SRC_HEIGHT, SRC_FORMAT);</span></div><div><span style="color: #d4d4d4;">        dst = </span><span style="color: #dcdcaa;">wrapbuffer_fd</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">map_dst</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">fd</span><span style="color: #d4d4d4;">, DST_WIDTH, DST_HEIGHT, DST_FORMAT);</span></div><div><span style="color: #d4d4d4;">        ......</span></div><div><span style="color: #d4d4d4;">}</span></div></div>
复制代码



作者: miaozhihua    时间: 2021-6-29 21:21
上面帖子贴出来的代码网页显示异常,下面再贴一份:

int createDrmMap(int drm_fd, int bpp, int width, int height, struct fdmmap_s *map)
{
struct drm_mode_create_dumb arg;
struct drm_mode_map_dumb map_arg;
int ret;
memset(&arg, 0, sizeof(arg));
arg.bpp = bpp;
arg.width = width;
arg.height = height;
printf("bpp=%d, width=%d, height=%d\n", arg.bpp, arg.width, arg.height);
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
if (ret) {
perror("failed to create dumb buffer");
return ret;
}
map->handle = arg.handle;
map->size = arg.size;
map->pitch = arg.pitch;
printf("bpp=%d, width=%d, height=%d, size=%d, pitch=%d\n", arg.bpp, arg.width, arg.height, arg.size, arg.pitch);

memset(&map_arg, 0, sizeof(map_arg));
map_arg.handle = map->handle;
ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);
if (ret)
return ret;
map->buf = (char *)mmap(0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, map_arg.offset);
if (map->buf == MAP_FAILED)
return -1;
drmPrimeHandleToFD(drm_fd, map->handle, 0, &map->fd);
printf("drm_fd=%d, map->fd=%d\n", drm_fd, map->fd);
return 0;
}
int main(int argc, char argv[])
{
        int drm_fd, ret;
    drm_fd = open("/dev/dri/card0", O_RDWR, 0);
    if( drm_fd <=0)
    {
        perror("open dri card0");
        return -1;
    }
if( createDrmMap(drm_fd, get_bpp_from_format(SRC_FORMAT), SRC_WIDTH, SRC_HEIGHT, &map_src)<0)
{
     printf("createDrmMap map_src error\n");
     return -1;
}
printf("map_src.size=%d\n", map_src.size);
if( createDrmMap(drm_fd, get_bpp_from_format(DST_FORMAT), DST_WIDTH, DST_HEIGHT, &map_dst)<0)
{
     printf("createDrmMap map_dst error\n");
     return -2;
}
printf("createDrmMap map_src/map_dst ok\n");

        ret = get_buf_from_file(map_src.buf, SRC_FORMAT, SRC_WIDTH, SRC_HEIGHT, 0);
        if (!ret)
            printf("open src file ok\n");
        else
            printf ("can not open file\n");
        if(MODE == MODE_BLEND || MODE == MODE_FILL) {
            ret = get_buf_from_file(map_dst.buf, DST_FORMAT, DST_WIDTH, DST_HEIGHT, 1);
            if (!ret)
                printf("open dst file\n");
            else
                printf ("can not open file\n");
        } else {
    printf("map_dst.size=%d, get_bpp_from_format(DST_FORMAT)=%d\n", map_dst.size, get_bpp_from_format(DST_FORMAT));
        memset(map_dst.buf,0x00,map_dst.size);
    //        memset(map_dst.buf,0x00,DST_WIDTH*DST_HEIGHT*get_bpp_from_format(DST_FORMAT));
        }
        printf("get_buf_from_file ok\n");
        src = wrapbuffer_fd(map_src.fd, SRC_WIDTH, SRC_HEIGHT, SRC_FORMAT);
        dst = wrapbuffer_fd(map_dst.fd, DST_WIDTH, DST_HEIGHT, DST_FORMAT);
                ......
}
作者: 会飞的大白菜    时间: 2021-9-29 18:30
大佬,你好,我现在做的是一个人脸识别的项目,为了减少cpu的负担,就需要拷贝每一帧的图像进行旋转处理,那么我怎么才能拷贝图像数据,然后进行旋转呢,我看了源代码,不是很能理解,基本上每个操作都需要读的bin文件是什么

作者: jefferyzhang    时间: 2021-9-30 09:09
会飞的大白菜 发表于 2021-9-29 18:30
大佬,你好,我现在做的是一个人脸识别的项目,为了减少cpu的负担,就需要拷贝每一帧的图像进行旋转处理, ...

https://github.com/rockchip-linux/linux-rga
用这个官方的rga封装,里头有sample和文档
作者: 随心    时间: 2021-11-8 19:24
你好,请问一下rga如何替换videoconvert
作者: Ainux    时间: 2022-1-11 15:27
版主:
        你好!
        此篇文档中的“基础使用流程”中的WIKI教程连接失效,无法打开,可否修改一下?
作者: Ainux    时间: 2022-1-11 15:31
Ainux 发表于 2022-1-11 15:27
版主:
        你好!
        此篇文档中的“基础使用流程”中的WIKI教程连接失效,无法打开,可否修改一 ...

DEBIAN10 librockchip_rga-devel源里无此包?
作者: Ainux    时间: 2022-1-11 15:48
本帖最后由 Ainux 于 2022-1-11 15:56 编辑
Ainux 发表于 2022-1-11 15:31
DEBIAN10 librockchip_rga-devel源里无此包?

DEBIAN10 源中包的名字是rockchip-rga/rockchip-rga-dev/rockchip-rga-dbgsym。
作者: gudesheng    时间: 2022-2-28 17:46
为啥github的官方rga没了
作者: btxc_cyy    时间: 2022-4-8 16:36
链接失效了啊,还有没有人维护这个库?
作者: jefferyzhang    时间: 2022-4-8 16:55
btxc_cyy 发表于 2022-4-8 16:36
链接失效了啊,还有没有人维护这个库?

下架审查,toybrick用户直接apt install rockchip-rga即可,其他客户请自行联系代理商或者业务获取
作者: btxc_cyy    时间: 2022-4-13 09:50
jefferyzhang 发表于 2022-4-8 16:55
下架审查,toybrick用户直接apt install rockchip-rga即可,其他客户请自行联系代理商或者业务获取 ...

apt install rockchip-rga后有下面的报错
root@debian10:/home/toybrick# apt install rockchip-rga
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
rockchip-rga : Depends: libc6 (>= 2.29) but 2.28-10+deb10u1 is to be installed
                Depends: libgcc-s1 (>= 3.0) but it is not installable
E: Unable to correct problems, you have held broken packages.
这个时已经更新过源之后的,用的也是官方给的debian10,这个有什么解决办法吗
作者: zhanggf    时间: 2022-4-25 05:01
请问我想将摄像头获取的两帧数据做异或运算。执行improcess_t报错Device or resource busy,请问是什么情况?执行imstatus = imcopy(rga_pre,rga_out);也会有同样的报错。

以下是错误打印:
RgaBlit(1387) RGA_BLIT fail: Device or resource busy
RgaBlit(1388) RGA_BLIT fail: Device or resource busy
fd-vir-phy-hnd-format[10, (nil), (nil), (nil), 0]
rect[0, 0, 1920, 1080, 1920, 1080, 512, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 1]
fd-vir-phy-hnd-format[17, (nil), (nil), (nil), 0]
rect[0, 0, 1920, 1080, 1920, 1080, 512, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 1]
This output the user patamaters when rga call blit fail
srect[x,y,w,h] = [0, 0, 0, 0] src[w,h,ws,hs] = [1920, 1080, 1920, 1080]

drect[x,y,w,h] = [0, 0, 0, 0] dst[w,h,ws,hs] = [1920, 1080, 1920, 1080]

usage[0x80000]

以下是代码:
            cam_frm_idx = camera_source_get_frame(pcam);
            printf("ncap:%u %d %d\n",Time_GetTickCount(),++ncap,cam_frm_idx);  
            if(cam_frm_idx_pre != -1)
            {
                if(outbuffer == NULL)
                    mpp_buffer_get(group,&outbuffer,pfmt->fmt.pix.width*pfmt->fmt.pix.height*3);

                MppBuffer prebuffer = camera_frame_to_buf(pcam, cam_frm_idx_pre);
                MppBuffer curbuffer = camera_frame_to_buf(pcam, cam_frm_idx);

                int pre_fd = mpp_buffer_get_fd(prebuffer);
                int cur_fd = mpp_buffer_get_fd(curbuffer);
                int out_fd = mpp_buffer_get_fd(outbuffer);
                rga_buffer_t rga_pre = wrapbuffer_fd(pre_fd, pfmt->fmt.pix.width,pfmt->fmt.pix.height, RK_FORMAT_RGB_888);
                rga_buffer_t rga_cur = wrapbuffer_fd(cur_fd, pfmt->fmt.pix.width,pfmt->fmt.pix.height, RK_FORMAT_RGB_888);
                rga_buffer_t rga_out = wrapbuffer_fd(out_fd, pfmt->fmt.pix.width,pfmt->fmt.pix.height, RK_FORMAT_RGB_888);


                IM_STATUS imstatus;
                {
                    im_opt_t opt;
                    int out_fence_fd;
                    im_rect srect;
                    im_rect drect;
                    im_rect prect;

                    empty_structure(NULL, NULL, NULL, &srect, &drect, &prect, &opt);
                    imstatus = improcess_t(rga_pre, rga_cur, rga_out, srect, drect, prect, -1, &out_fence_fd, &opt, IM_ALPHA_BLEND_XOR);
                }
                printf("imstatus xor:%u %d\n",Time_GetTickCount(),imstatus);

                printf("push back:%d\n",cam_frm_idx_pre);
                camera_source_put_frame(pcam, cam_frm_idx_pre);
            }
作者: ozgaga    时间: 2022-5-21 18:02
本帖最后由 ozgaga 于 2022-5-21 18:03 编辑

在RV1126上做图像降噪等处理(基于OpenCV,不知有没有更好的方案),但是RV1126的CPU似乎有点弱(bogomips仅100出头,四个核加起来500不到),处理起来非常慢
可以考虑使用CPU+RGA处理吗,不知道RGA能否做图像的卷积、加、减、点乘等操作,不知道RGA能接受多大的工作量
还有就是NPU能否用来做常规的图像处理
作者: 848451399    时间: 2022-6-16 15:48
请问有rga的源码吗,我的是3399pro板子,但是使用rga库的时候会报"/lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by librga.so)
"这个错,需要用源码重新编译一个库才能使用吗?
作者: jefferyzhang    时间: 2022-6-17 08:46
848451399 发表于 2022-6-16 15:48
请问有rga的源码吗,我的是3399pro板子,但是使用rga库的时候会报"/lib/aarch64-linux-gnu/libm.so.6: vers ...

https://github.com/airockchip/librga
作者: 848451399    时间: 2022-6-17 10:31
本帖最后由 848451399 于 2022-6-17 10:35 编辑
jefferyzhang 发表于 2022-6-17 08:46
https://github.com/airockchip/librga

我用的就是这里面的库.开发的时候用这个库会提示librga.so: undefined reference to `log@GLIBC_2.29'
作者: hjj414    时间: 2022-11-5 16:37
848451399 发表于 2022-6-17 10:31
我用的就是这里面的库.开发的时候用这个库会提示librga.so: undefined reference to `' ...

我的Ubuntu18.04的系统也有这个问题,通过下面的方式暂时能用了,
1. 下载glibc-2.29,交叉编译好,
2. 把编译出的libm-2.29.so放到板上,
3. 将libm.so.6链接到这个文件,就可以用librga.so的库了;
理论上GLIBC会兼容旧版本的,目前只替换了libm库,不知道对板上的其他应用有没有影响。。。




欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3