Android CCodec Codec2 (十五)C2DmaBufAllocator

news/2024/9/28 13:36:12/

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() {// 1int dma_heap_fd = open("/dev/dma_heap/system", O_RDONLY | O_CLOEXEC);if (dma_heap_fd < 0) {perror("open");exit(1);}// 2struct 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;// 3void *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);}// 4memset(dma_buf, 0xAA, heap_data.len);for (int i = 0; i < heap_data.len; i++) {printf("0x%02x ", ((unsigned char *)dma_buf)[i]);}// 5munmap(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.ppmy.cn/news/1531531.html

相关文章

排序 算法

八大排序算法 | 爱编程的大丙 (subingwen.cn) 冒泡排序 best: O(n), worst O(n^2) * 数组的相邻两个元素进行比较&#xff1a;nums[i] > nums[i1] -> swap(nums[i], nums[i1]) * 一次遍历后&#xff0c;最大元素移至数组末尾 * n长度数组&#xff0c;进行n-1次排序&…

怎么通过AI大模型开发一个网站?

目录 一、提示词与AI输出 二、网站效果 以前不会代码开发&#xff0c;写网站是不可能的事情&#xff0c;现在有了AI&#xff0c;一切都有了可能。以下是我通过通义千问大模型开发的简单网站。 一、提示词与AI输出 提示词1 你是python程序员&#xff0c;我有一个大的需求&am…

教师课堂管理测评:构建高效与和谐的教学环境

在教育的广阔天地里&#xff0c;课堂是知识传递、思维碰撞与情感交流的核心舞台。良好的课堂管理不仅是教学质量的基石&#xff0c;更是促进学生全面发展、培养未来社会所需人才的关键。本文将从课堂规则、课堂环境、时间管理、学生参与、行为管理、沟通技巧、资源管理、学生差…

改变安全策略的五大实践

随着网络威胁形势的加剧&#xff0c;网络安全计划必须不断发展以保护组织的使命。 为了管理这种持续的网络安全发展&#xff0c;应遵循五项关键的安全计划变更管理实践&#xff1a; 1. 识别并吸引受安全风险影响的业务利益相关者 随着新的网络安全风险被发现&#xff0c;受影…

K8s容器运行时,移除Dockershim后存在哪些疑惑?

K8s容器运行时&#xff0c;移除Dockershim后存在哪些疑惑&#xff1f; 大家好&#xff0c;我是秋意零。 K8s版本截止目前&#xff08;24/09&#xff09;已经发布到了1.31.x版本。早在K8s版本从1.24.x起&#xff08;22/05&#xff09;&#xff0c;默认的容器运行时就不再是Doc…

综合实践:JPA+Thymeleaf 增删改查

在Java Web开发中&#xff0c;使用JPA&#xff08;Java Persistence API&#xff09;作为ORM&#xff08;对象关系映射&#xff09;框架和Thymeleaf作为模板引擎来实现增删改查&#xff08;CRUD&#xff09;操作是一种常见且高效的方式。以下是一个简单的示例&#xff0c;展示如…

容器编排工具Docker Compose

目录 一、Docker Compose概述 1、主要功能 2、工作原理 二、常用命令参数 1、服务管理 2、构建和重新构建服务 三、Docker Compose的yml文件 1、服务 2、网络 3、存储卷 四、容器编排实现haproxy和nginx负载均衡 一、Docker Compose概述 1、主要功能 定义服务&#xf…

OpenCV 进行图像分割

介绍 图像分割是将数字图像划分互不相交的区域的过程,它可以降低图像的复杂性,从而使分析图像变得更简单。 图像分割技术 阈值法 基于边缘的分割 基于区域的分割 基于聚类的分割 基于分水岭的方法 基于人工神经网络的分割 在这里,我们选择基于聚类的分割 与分类算法不同,…