功能简介
OpenHarmony Codec HDI(Hardware Device Interface)驱动框架基于OpenMax实现了视频硬件编解码驱动,提供Codec基础能力接口给上层媒体服务调用,包括获取组件编解码能力、创建组件、参数设置、数据的轮转和控制、以及销毁组件等功能,实现对视频数据的编解码处理(可以将YUV/RGB等格式的视频数据编码成H264/H265等编码格式,也可以将H264/H265等裸流数据解码成YUV/RGB等格式数据)。本文主要介绍基于HDF(Hardware Driver Foundation)驱动框架开发的Codec编解码功能。
Codec HDI驱动框架基于HDF驱动框架实现。Codec HDI驱动架构组成:
图 1 Codec HDI驱动框架
- Codec HDI Callback Remote Service:匿名Callback服务,通过该服务,可以处理回调。
- Codec HDI Interface:提供了基于OpenMax的标准接口,上层可通过这些接口来实现硬件的编解码。
- Codec HDI Adapter:HDI 实现层,实现了HDI Interface接口,并与OpenMax IL 对接。
- OpenMax IL Interface:OpenMax IL接口,Codec HDI驱动直接对接OpenMax IL层。
- Vendor Impl:厂商适配层,各大厂商适配的OpenMax 实现层。
- Codec Hardware:硬件解码设备。
基本概念
在进行开发前,开发者应了解一下基本概念:
-
采样率
采样率就是每秒从连续信号中提取并组成离散信号的采样个数,用赫兹(Hz)来表示。
-
OpenMax IL
OpenMax IL定义了硬件或软件编解码的标准,使得应用程序和媒体框架能够以统一的方式与多媒体编解码器和支持的组件进行交互。
-
帧率
帧率就是每秒内传输的图片的帧数,也可以理解为图形处理器每秒能够刷新几次。帧率越大,画面越流畅;帧率越小,画面越有跳动感。
-
码率
视频的码率是指在单位时间内传输的视频数据数量,一般用kbps作为单位。码率越高,视频就越清晰,反之则画面粗糙而且多马赛克。
-
组件
组件就是指的OpenMax IL 组件,是对视频流中模块的抽象,本文中的组件指的是编解码组件,专门处理视频的编解码。
约束与限制
Codec HDI只针对标准系统,其它系统暂不支持。
接口约束和限制参考OpenMax IL标准。
开发指导
场景介绍
Codec模块主要完成对视频数据的硬件编解码,将H264等裸流数据转化成图形支持的YUV或者RGB数据,也支持将图形的YUV或RGB数据编码成H264等数据格式。
接口说明
-
icodec_component_manager.h
接口名称 功能描述 int32_t CreateComponent(sptr& component, uint32_t& componentId,
const std::string& compName, int64_t appData, const sptr& callbacks)创建Codec组件实例 int32_t DestoryComponent(uint32_t componentId) 销毁Codec组件实例 -
icodec_component.h
接口名称 功能描述 int32_t SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t>& cmdData) 发送命令给组件 int32_t GetParameter(uint32_t index, const std::vector<int8_t>& inParamStruct, std::vector<int8_t>& outParamStruct) 获取组件参数设置 int32_t SetParameter(uint32_t index, const std::vector<int8_t>& paramStruct) 设置组件需要的参数 int32_t GetState(CodecStateType& state) 获取组件的状态 int32_t UseBuffer(uint32_t portIndex, const OmxCodecBuffer& inBuffer, OmxCodecBuffer& outBuffer) 指定组件端口的buffer int32_t FreeBuffer(uint32_t portIndex, const OmxCodecBuffer& buffer) 释放buffer int32_t EmptyThisBuffer(const OmxCodecBuffer& buffer) 编解码输入待处理buffer int32_t FillThisBuffer(const OmxCodecBuffer& buffer) 编解码输出填充buffer -
icodec_callback.h
接口名称 功能描述 int32_t EventHandler(CodecEventType event, const EventInfo& info) 事件上报 int32_t EmptyBufferDone(int64_t appData, const OmxCodecBuffer& buffer) 上报输入buffer编码或者解码处理完毕 int32_t FillBufferDone(int64_t appData, const OmxCodecBuffer& buffer) 上报输出buffer填充完毕
更多接口请参考Codec驱动仓。
开发步骤
Codec HDI驱动的开发过程主要包含以下步骤:
Driver的注册及初始化
定义Codec HDI的HdfDriverEntry结构体,该结构体中定义了Driver初始化的方法,填充g_codeccomponentmanagerDriverEntry结构体,实现Bind、Init、Release函数指针。
static struct HdfDriverEntry g_codeccomponentmanagerDriverEntry = {
.moduleVersion = 1,
.moduleName = "codec_component_manager_service",
.Bind = HdfCodecComponentManagerDriverBind,
.Init = HdfCodecComponentManagerDriverInit,
.Release = HdfCodecComponentManagerDriverRelease,
}; // 将Codec HDI的HdfDriverEntry结构体注册到HDF上
-
HdfCodecComponentManagerDriverBind:将HDF中device绑定到HdfCodecComponentManagerHost,将codec service注册到HDF框架。
static int HdfCodecComponentManagerDriverBind(struct HdfDeviceObject *deviceObject) { CODEC_LOGI("HdfCodecComponentManagerDriverBind enter"); auto *hdfCodecComponentManagerHost = new (std::nothrow) HdfCodecComponentManagerHost; if (hdfCodecComponentManagerHost == nullptr) { CODEC_LOGE("failed to create create HdfCodecComponentManagerHost object"); return HDF_FAILURE; } hdfCodecComponentManagerHost->ioService.Dispatch = CodecComponentManagerDriverDispatch; hdfCodecComponentManagerHost->ioService.Open = NULL; hdfCodecComponentManagerHost->ioService.Release = NULL; auto serviceImpl = ICodecComponentManager::Get(true); if (serviceImpl == nullptr) { CODEC_LOGE("failed to get of implement service"); delete hdfCodecComponentManagerHost; return HDF_FAILURE; } hdfCodecComponentManagerHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, ICodecComponentManager::GetDescriptor()); if (hdfCodecComponentManagerHost->stub == nullptr) { CODEC_LOGE("failed to get stub object"); delete hdfCodecComponentManagerHost; return HDF_FAILURE; } deviceObject->service = &hdfCodecComponentManagerHost->ioService; return HDF_SUCCESS; }
-
HdfCodecComponentManagerDriverInit:加载HCS(HDF Configuration Source)中的属性配置。
static int HdfCodecComponentManagerDriverInit(struct HdfDeviceObject *deviceObject) { CODEC_LOGI("HdfCodecComponentManagerDriverInit enter"); if (DevHostRegisterDumpHost(CodecDfxService::DevCodecHostDump) != HDF_SUCCESS) { CODEC_LOGE("DevHostRegisterDumpHost error!"); } return HDF_SUCCESS; }
-
HdfCodecComponentTypeDriverRelease:释放驱动实例。
static void HdfCodecComponentManagerDriverRelease(struct HdfDeviceObject *deviceObject) { CODEC_LOGI("HdfCodec