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


原文阅读:
Android Codec2(十五)C2DmaBufAllocator

扫描下方二维码,关注公众号《青山渺渺》阅读音视频开发内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值