Android CCodec Codec2 (二四)C2GraphicBlock

在这一篇文章中,我们将了解C2GraphicBlock、C2BufferQueueBlockPoolData与C2GraphicView的实现。

1、fetchGraphicBlock

首先提出一个疑问:C2PooledBlockPool(没有surface)和C2BufferQueueBlockPool(有surface)分配的2D buffer有什么异同呢?想要回答这个问题还要再看一下fetchGraphicBlock方法。

1.1、C2PooledBlockPool

前面的文章提到C2PooledBlockPool可以分配2D buffer,将这句话补充完整:在没有surface的video decoder流程中,2D buffer由C2PooledBlockPool使用C2AllocatorGralloc来分配。需要注意的是,整个分配过程是在组件进程(HAL)中完成的,分配的buffer由bufferpool管理。

简单看下C2PooledBlockPool的fetchGraphicBlock实现:

class C2PooledBlockPool::Impl {
public:
    c2_status_t fetchGraphicBlock(
            uint32_t width, uint32_t height, uint32_t format,
            C2MemoryUsage usage,
            std::shared_ptr<C2GraphicBlock> *block) {

        std::shared_ptr<bufferpool::BufferPoolData> bufferPoolData;
        native_handle_t *cHandle = nullptr;
        // 1. 通过bufferpool获取一个native_handle_t,以及bufferPoolData
        ResultStatus status = mBufferPoolManager->allocate(
                mConnectionId, params, &cHandle, &bufferPoolData);
        if (status == ResultStatus::OK) {
            std::shared_ptr<C2GraphicAllocation> alloc;
            // 2. 创建C2PooledBlockPoolData
            std::shared_ptr<C2PooledBlockPoolData> poolData =
                std::make_shared<C2PooledBlockPoolData>(bufferPoolData);
            // 3. 使用handle创建C2GraphicAllocation
            c2_status_t err = mAllocator->priorGraphicAllocation(
                    cHandle, &alloc);
            if (err == C2_OK && poolData && alloc) {
                // 4. 创建C2GraphicBlock
                *block = _C2BlockFactory::CreateGraphicBlock(
                        alloc, poolData, C2Rect(width, height));
                if (*block) {
                    return C2_OK;
                }
            }
            return C2_NO_MEMORY;
        }
        return C2_CORRUPTED;
    }
}
  1. C2PooledBlockPool通过HAL层的ClientManager拿到native_handle_t(clone)和BufferPoolData;
  2. 将BufferPoolData封装为C2PooledBlockPoolData,BufferPoolData存储有ConnectionId和buffer在bufferpool中的id;
  3. 使用handle创建C2GraphicAllocation;
  4. 调用CreateGraphicBlock创建出C2GraphicBlock。

请添加图片描述

1.2、C2BufferQueueBlockPool

接着再看C2BufferQueueBlockPool::fetchGraphicBlock实现:

class C2BufferQueueBlockPool
public:
    c2_status_t fetchGraphicBlock(
            uint32_t width,
            uint32_t height,
            uint32_t format,
            C2MemoryUsage usage,
            std::shared_ptr<C2GraphicBlock> *block /* nonnull */,
            C2Fence *fence) {
        // ...
        c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block, 
    }
}

class C2BufferQueueBlockPool::Impl
privatec2_status_t fetchFromIgbp_l(
            uint32_t width,
            uint32_t height,
            uint32_t format,
            C2MemoryUsage usage,
            std::shared_ptr<C2GraphicBlock> *block /* nonnull */,
            C2Fence *c2Fence) {

        C2Handle *c2Handle = android::WrapNativeCodec2GrallocHandle(
                slotBuffer->handle,
                slotBuffer->width,
                slotBuffer->height,
                slotBuffer->format,
                slotBuffer->usage,
                slotBuffer->stride,
                slotBuffer->getGenerationNumber(),
                mProducerId, slot);
        if (c2Handle) {
            std::shared_ptr<C2GraphicAllocation> alloc;
            // 1. 创建C2GraphicAllocation
            c2_status_t err = mAllocator->priorGraphicAllocation(c2Handle, &alloc);
            // 2. 创建C2BufferQueueBlockPoolData
            std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
                    std::make_shared<C2BufferQueueBlockPoolData>(
                            slotBuffer->getGenerationNumber(),
                            mProducerId, slot,
                            mIgbpValidityToken, mProducer, mSyncMem);
            mPoolDatas[slot] = poolData;
            // 3. 创建C2GraphicBlock
            *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
            return C2_OK;
        }
    }
}

详细流程在前面两篇文章中已经讲过了,这里只做简单概括:

  1. 从producer的dequeueBuffer方法拿到slotId;
  2. 调用producer的requestBuffer拿到native_handle_t,封装到GraphicBuffer中;
  3. 从GraphicBuffer中拿到相关信息,封装成C2Handle;
  4. 使用C2Handle创建C2GraphicAllocation;
  5. 使用generation、producerId,slotId、producer实例、C2SurfaceSyncMemory实例创建C2BufferQueueBlockPoolData;
  6. 使用C2GraphicAllocation和C2BufferQueueBlockPoolData创建出C2GraphicBlock;

1.3、对比与小结

2、C2BufferQueueBlockPoolData

3、_C2BlockFactory

4、C2Block2D::Impl

5、_C2MappingBlock2DImpl::Mapped

6、C2GraphicBlock

7、C2GraphicView

8、小结


原文阅读:
Android Codec2(二四)C2GraphicBlock

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青山渺渺

感谢支持

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

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

打赏作者

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

抵扣说明:

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

余额充值