OpenHarmony AVCodec模块分析(三):Codec HDI适配(一)
一、简介 Codec HDI(Hardware Device Interface)对上层提供媒体编解码的驱动能力接口,主要功能有获取组件编解码能力,创建、销毁编解码器对象,启停编解码器操作,编解码处理、清除缓存、事件上报等。 Codec HDI 2.0接口依赖OpenMax IL的标准接口,Codec HDI通过调用封装好的libOMX_Core.z.so获取支持的编解码器组件和创建组件。本文介绍
一、简介
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
未完待续
更多推荐
所有评论(0)