使用DRM分配两块连续的物理内存,一块放原始数据,一块放处理后的数据?也就是
rga_buffer_t src = wrapbuffer_physicaladdr(phy_addr_in, w_in, h_in, fmt_in);
rga_buffer_t dst = wrapbuffer_physicaladdr(phy_addr_out, w_out, h_out, fmt_out);
录屏操作,也就是拿到RGB数据然后DRM分配一块内存(w*h*2),通过memcpy将RGB565数据写入到物理内存(通过mmap拿到了这个物理内存的虚拟内存就可以用memcpy)。然后DRM再分配一次内存(w*h*1.5),同时mmap拿到这个NV12的虚拟内存。有了这两个物理内存物理地址构建RGA的Buffer。再执行格式转换,将RGB对应的内存里数据给到RGA硬件RGA将这个RGB数据转换后写入到NV12对应的物理内存。然后用户态就可以拿到NV12里面的数据封装成MP4文件。
获取RGB数据 → DRM分配输入buf + mmap → memcpy写入RGB
→ DRM分配输出buf + mmap → 获取两个物理地址
→ 构造RGA src/dst → 加锁 → improcess转换
→ 解锁 → 从输出buf虚拟地址读取NV12 → 封装MP4
-
获取 RGB565 数据(例如从屏幕捕获、解码等,数据在 CPU 可访问的内存中)。
-
DRM 分配输入缓冲区(大小 =
width * height * 2,因为 RGB565 每像素 2 字节),并mmap得到虚拟地址。 -
将 RGB 数据
memcpy到输入缓冲区的虚拟地址,这样输入缓冲区同时具备物理地址(供 RGA 读取)和虚拟地址(供 CPU 写入)。 -
DRM 分配输出缓冲区(大小 =
width * height * 1.5,NV12 每像素 1.5 字节),并mmap得到虚拟地址,供 CPU 后续读取结果。 -
获取两个缓冲区的物理地址,构造 RGA 描述符:
rga_buffer_t src = wrapbuffer_physicaladdr( (void*)phy_addr, width, height, format, create.pitch, // 使用 DRM 返回的 pitch 作为 stride height // 垂直 stride 通常等于 height ); rga_buffer_t dst = wrapbuffer_physicaladdr( (void*)other_phy_addr, c_width, c_height, format, create.pitch, // 使用 DRM 返回的 pitch 作为 stride c_height // 垂直 stride 通常等于 height ); -
加锁并执行 RGA 转换:
pthread_mutex_lock(&g_rga_mtx); im_rect src_rect = {0, 0, w, h}; im_rect dst_rect = {0, 0, w, h}; IM_STATUS ret = improcess(src, dst, {}, {}, src_rect, dst_rect, {}, IM_SYNC);//同步 pthread_mutex_unlock(&g_rga_mtx); -
从输出缓冲区的虚拟地址读取 NV12 数据(可以直接使用指针,或
memcpy到应用缓冲区),然后封装成 MP4 等。