当前位置: 首页 > article >正文

Android CCodec Codec2 (十五)C2DmaBufAllocator

Codec2框架采用了全新的Buffer分配机制C2Allocator,这一篇文章我们一起来瞧瞧C2DmaBufAllocator是如何工作的。

1、C2Allocator

C2Allocator声明在C2Buffer.h中,它定义了如下接口:

  • getName:返回Allocator独一无二的名称;
  • getId:返回Allocator独一无二的id;
  • getTraits:返回Allocator的特征;
  • newLinearAllocation:使用给定的capacity和usage分配一个1D的Allocation;
  • priorLinearAllocation:使用一个native handle创建一个1D的Allocation;
  • newGraphicAllocation:使用给定的width,height,format和usage分配一个2D的Allocation;
  • priorGraphicAllocation:使用一个native handle创建一个2D的Allocation;

在这里插入图片描述

可以发现几个创建Allocation的方法并不是纯虚函数,这是为什么呢?在头文件中有一串注释,翻译过来是这样:理论上Allocator可以同时支持1D和2D Allocation的分配,但是实际上,一个Allocator只会支持1D和2D中的一个。也就是说,C2Allocator接口的实现者会专注1D或2D的其中一个,不被支持的方法可以不用实现。

2、DMA

DMA(Direct Memory Access,直接内存访问)可以简单理解为是一种共享内存机制,具体的概念和工作原理有兴趣的同学可自行搜索,这一节我们简单看下如何分配出DmaBuf。

以下这段代码是笔者从C2DmaBufAllocator.cpp和BufferAllocator.cpp摘录拼凑出来的,编译之后可以成功运行:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <linux/dma-heap.h>
#include <string.h>

int main() {
    // 1
    int dma_heap_fd = open("/dev/dma_heap/system", O_RDONLY | O_CLOEXEC);
    if (dma_heap_fd < 0) {
        perror("open");
        exit(1);
    }
    // 2
    struct dma_heap_allocation_data heap_data = {
        .len = 4096,                        // 设置所需的缓冲区长度
        .fd_flags = O_RDWR | O_CLOEXEC,     // 设置缓冲区的文件描述符标志
    };

    if (ioctl(dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data) < 0) {
        perror("ioctl");
        close(dma_heap_fd);
        exit(1);
    }

    int dma_buf_fd = heap_data.fd;
    // 3
    void *dma_buf = mmap(NULL, heap_data.len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd, 0);
    if (dma_buf == MAP_FAILED) {
        perror("mmap");
        close(dma_buf_fd);
        close(dma_heap_fd);
        exit(1);
    }
    // 4
    memset(dma_buf, 0xAA, heap_data.len);

    for (int i = 0; i < heap_data.len; i++) {
        printf("0x%02x ", ((unsigned char *)dma_buf)[i]);
    }
    // 5
    munmap(dma_buf, heap_data.len);
    close(dma_buf_fd);
    close(dma_heap_fd);
}

分配使用DmaBuf有如下步骤:

  1. 打开DMA Heap设备/dev/dma_heap/system;
  2. 使用ioctl分配DMA缓冲区,返回的fd存在dma_heap_allocation_data中;
  3. 得到DMA缓冲区的文件描述符后,可以使用mmap将其映射到用户空间;
  4. 可以直接通过映射出来的dma_buf指针来访问DMA缓冲区;
  5. 使用完缓冲区之后要清理资源。

3、C2DmaBufAllocator

先来看C2DmaBufAllocator的创建过程:

4、C2LinearAllocation

5、C2DmaBufAllocation

关注公众号《青山渺渺》订阅合集阅读完整内容

请添加图片描述


http://www.kler.cn/a/323209.html

相关文章:

  • shell脚本配置nginx
  • AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
  • 从零开始学习 sg200x 多核开发之 uboot saveenv 功能使能
  • vue2和vue3:diff算法的区别?
  • 从零开始学习 sg200x 多核开发之 TF 存储卡根文件系统扩容
  • ollama+springboot ai+vue+elementUI整合
  • 自动化办公-python中的open()函数
  • 深入理解 Nuxt.js 中的 app:error:cleared 钩子
  • 【hot100-java】【划分字母区间】
  • 消息中间件 Kafka 快速入门与实战
  • 让具身智能更快更强!华东师大上大提出TinyVLA:高效视觉-语言-动作模型,遥遥领先
  • mysql复合查询 -- 合并查询(union,union all)
  • 指令个人记录
  • Lab1:虚拟机kolla安装部署openstack,并创建实例
  • [大语言模型-论文精读] MoRAG - 基于多部分融合的检索增强型人体动作生成
  • 海尔嵌入式硬件校招面试题及参考答案
  • Python in Excel作图分析实战!
  • 关于Obj文件格式介绍与Unity加载Obj文件代码参考
  • 阿里云k8s发布vue项目
  • 防砸安全鞋这样挑,舒适又安心!
  • 用矩阵和统计报告估计polynomial线性回归的系数python
  • 直线模组降噪攻略
  • 【开源免费】基于SpringBoot+Vue.JS技术交流分享平台(JAVA毕业设计)
  • 16 Midjourney从零到商用·实战篇:产品工业设计
  • 2024AI做PPT软件如何重塑演示文稿的创作
  • C语言VS实用调试技巧