OpenHarmony AVCodec模块分析(三):Codec HDI适配(一)

一、简介

Codec HDI(Hardware Device Interface)对上层提供媒体编解码的驱动能力接口,主要功能有获取组件编解码能力,创建、销毁编解码器对象,启停编解码器操作,编解码处理、清除缓存、事件上报等。
Codec HDI 2.0接口依赖OpenMax IL的标准接口,Codec HDI通过调用封装好的libOMX_Core.z.so获取支持的编解码器组件和创建组件。
本文介绍AVCodec视频硬件编解码调用的Codec HDI 服务的适配方法

二、适配流程

1、版本信息

OpenHarmony-4.0-Release(不同版本代码可能略有不同)

2、适配方式

AVPlayer gstreamer引擎硬件编解码插件调用的Codec HDI codec_hdi_omx_service服务适配方法可参考 https://laval.csdn.net/64c8b15874de4411227abcab.html
本文介绍AVCodec视频硬件编解码调用的Codec HDI 服务的适配方法,HDI实现层位于drivers/peripheral/codec/hal/idl_service/src/目录。

AVCodec视频编解码服务层可通过passthrough和ipc方式与Codec HDI通信
foundation/multimedia/av_codec/services/engine/codec/video/hcodec/hcodec_list.cpp

bool IsPassthrough()
{
    static bool usePassthrough = OHOS::system::GetBoolParameter("hcodec.usePassthrough", true);
    LOGI("%{public}s mode", usePassthrough ? "passthrough" : "ipc");
    return usePassthrough;
}

sptr<ICodecComponentManager> GetManager()
{
    static sptr<ICodecComponentManager> compMgr = ICodecComponentManager::Get(IsPassthrough());
    return compMgr;
}

3、passthrough

如上代码,AVCodec视频编解码服务层默认通过passthrough方式与Codec HDI通信,这种方式两个模块都位于av_codec_service进程中,
这种方式不需要配置codec_host服务。

(1)配置codec_capabilities hcs文件

根据 drivers/peripheral/codec/hal/idl_service/src/codec_component_config.cpp文件

#define CODEC_CONFIG_NAME "media_codec_capabilities"

codec_capabilities hcs文件的match_attr 为media_codec_capabilities

以rk3568为例,添加 vendor/hihope/rk3568/hdf_config/uhdf/media_codec/media_codec_capabilities.hcs 文件

root {
    module = "master";
    codec_config {
        match_attr = "media_codec_capabilities";
        use_openmax = true;
        // capsMask: 0x01, Adaptive playback; 0x02, Secure playback; 0x04, Tunnel playback.
        // allocateMask: 0x01, Input buffer allocated within the Codec module;
        // allocateMask: 0x02, Input buffer allocated by an external user;
        // allocateMask: 0x04, Output buffer allocated within the Codec module;
        // allocateMask: 0x08, Output buffer allocated by an external user.

    VideoHwEncoders {
        /* node name explanation -- HDF_video_hw_enc_avc_rk:
        **
        **    HDF____________video__________________hw____________________enc____________avc_______rk
        **     |               |                    |                      |              |        |
        ** HDF or OMX    video or audio    hardware or software    encoder or decoder    mime    vendor
        */
        HDF_video_hw_enc_avc_rk {
            role = 1;
            type = 1;
            name = "OMX.rk.video_encoder.avc";
            supportProfiles = [1, 32768, 2, 32768, 8, 32768];
            maxInst = 4;
            isSoftwareCodec = false;
            processModeMask = [];
            capsMask = [0x01];
            minBitRate = 1;
            maxBitRate = 40000000;
            minWidth = 144;
            minHeight = 144;
            maxWidth = 4096;
            maxHeight = 4096;
            widthAlignment = 2;
            heightAlignment = 2;
            minBlockCount = 99;
            maxBlockCount = 8160;
            minBlocksPerSecond = 99;
            maxBlocksPerSecond = 489600;
            blockSizeWidth = 16;
            blockSizeHeight = 16;
            supportPixelFmts = [28, 24, 20, 12];
            measuredFrameRate = [320, 240, 165, 165, 720, 480, 149, 149, 1280, 720, 73, 73, 1920, 1080, 18, 18];
            bitRateMode = [1, 2];
            minFrameRate = 1;
            maxFrameRate = 60;
            canSwapWidthHeight = true;
        }
        ...
    }
    VideoHwDecoders {
        HDF_video_hw_dec_avc_rk {
            role = 1;
            type = 0;
            name = "OMX.rk.video_decoder.avc";
            supportProfiles = [1, 32768, 2, 32768, 8, 32768];
            maxInst = 6;
            isSoftwareCodec = false;
            processModeMask = [];
            capsMask = [0x01];
            minBitRate = 1;
            maxBitRate = 10000000;
            minWidth = 144;
            minHeight = 144;
            maxWidth = 4096;
            maxHeight = 4096;
            widthAlignment = 2;
            heightAlignment = 2;
            minBlockCount = 99;
            maxBlockCount = 34560;
            minBlocksPerSecond = 99;
            maxBlocksPerSecond = 2073600;
            blockSizeWidth = 16;
            blockSizeHeight = 16;
            supportPixelFmts = [24, 12, 20];
            measuredFrameRate = [320, 240, 617, 617, 720, 480, 559, 559, 1280, 720, 276, 276, 1920, 1080, 164, 164, 3840, 2160, 30, 30];
            bitRateMode = [];
            minFrameRate = 1;
            maxFrameRate = 60;
            canSwapWidthHeight = true;
        }
        ...
    }
}

}

该文件中每个参数的意义和如何适配可参考后续文章,但要注意match_attr 必须为media_codec_capabilities,初步适配时除name要和libOMX_Core.z.so中列举的组件名称保持一致,其他参数可仿照rk3568。

(2)hdf.hcs文件引入codec_capabilities hcs文件

以rk3568为例,vendor/hihope/rk3568/hdf_config/uhdf/hdf.hcs

+     #include "media_codec/media_codec_capabilities.hcs"

(3)OMX Wrapper的封装

封装实现libOMX_Core.z.so,供Codec HDI接口dlopen调用。
注意:passthrough方式编解码框架服务层和Codec HDI在同一个进程内,libOMX_Core.z.so一般位于vendor 目录下,可能会触发系统的沙盒管理,Codec HDI
dlopen libOMX_Core.z.so失败,有如下打印 “E C02500/codec_hdi_omx: Init() Failed to dlopen libOMX_Core.z.so.”
解决方案一(最优解):
在libOMX_Core.z.so 及其依赖的组件库和utils库的BUILD.gn 中增加 innerapi_tags = ["passthrough_indirect"]

解决方案二:
如果因为种种原因无法按方案一修改,可以关闭av_codec_service进程的沙箱管理
foundation/multimedia/av_codec/services/etc/av_codec_service.cfg

{
    "services" : [{
        "name" : "av_codec_service",
        "path" : ["/system/bin/sa_main", "/system/profile/av_codec_service.json"],
+       "sandbox" : 0,
        "uid" : "media",
        "gid" : ["media_rw", "system", "vcodec", "dev_dma_heap", "netsys_socket", "vendor_mpp_driver"],
        "secon" : "u:r:av_codec_service:s0"
        }
    ]
}

解决方案三、使用下面的IPC方式跨进程通信。

4、IPC

未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值