diff --git a/design/codec_hdi/hdi2.0_usage_demo.md b/design/codec_hdi/hdi2.0_usage_demo.md
new file mode 100644
index 0000000000000000000000000000000000000000..378d851f8d34f26885008263282062c404d83bbb
--- /dev/null
+++ b/design/codec_hdi/hdi2.0_usage_demo.md
@@ -0,0 +1,566 @@
+# CODEC HDI 2.0
+
+- **[CODEC HDI 2.0概述](#section1000)**
+
+- **[CODEC HDI 2.0框架介绍](#section2000)**
+
+- **[CODEC HDI 2.0开发](#section3000)**
+
+- **[CODEC HDI 2.0开发实例](#section4000)**
+ - [接口及回调初始化](#section4100)
+ - [组件初始化](#section4200)
+ - [设置编解码参数和配置信息](#section4300)
+ - [申请输入输出Buffer](#section4400)
+ - [编解码](#section4500)
+ - [组件回调处理](#section4600)
+ - [组件释放](#section4700)
+
+- **[总结](#section9999)**
+
+# CODEC HDI 2.0概述
+
+Codec HDI2.0 提供了基于OMX的一整套编解码接口,程序通过简单的几步,即可实现基于OMX的硬件编解码。
+
+本文主要介绍基于Codec HDI2.0 开发的编解码功能,包括初始化,编解码以及释放等。
+
+
+
+# CODEC HDI 2.0框架介绍
+
+Codec HDI 2.0 驱动框架基于[HDF驱动框架](https://device.harmonyos.com/cn/docs/documentation/guide/driver-hdf-overview-0000001051715456)实现。Codec HDI 2.0 驱动架构组成:
+
+
+
+Codec HDI Interface 2.0(简称HDI2.0)提供基于OpenMax 的标准接口,Media Service 调用这套接口实现硬件编解码能力。HDI 另外提供了实现Callback 机制的接口,Media Service 可以通过HDI 接口创建Callback 信息接收服务端(Codec HDI Callback Remote Service),并且通过SetCallback 方法将对应的客户端代理(Codec HDI Callback Client Proxy)传给OpenMax 实现层,OpenMax 在数据Buffer 处理过程中会通过此代理调用回调方法,告知Media Service 进行对应的数据处理。
+
+
+
+
+# CODEC HDI 2.0开发实例
+
+代码路径:
+
+ drivers\peripheral\codec\test\demo\codec_hdi_decode.cpp(解码Demo,本文以解码为例)
+ drivers\peripheral\codec\test\demo\codec_hdi_encode.cpp(编码Demo)
+
+下面以rk3568为例,介绍codec HDI 2.0开发步骤。
+
+CODEC HDI 2.0开发主要包含如下几个重要步骤:
+
+1. 接口及回调初始化
+2. 组件初始化
+3. 设置编解码参数和配置信息
+4. 申请输入输出Buffer
+5. 编解码
+6. 组件回调处理
+7. 组件释放
+
+
+
+
+## 接口及回调初始化
+
+Codec HDI2.0 接口及回调初始化包括一下主要操作:
+
+
+ //初始化HDI2.0 ComponentManager实例,用于打开OMX组件
+ omxMgr_ = GetCodecComponentManager();
+
+ //初始化回调
+ callback_ = CodecCallbackTypeStubGetInstance();
+ if (!omxMgr_ || !callback_) {
+ FUNC_EXIT_ERR();
+ return false;
+ }
+ //设置回调函数指针
+ callback_->EventHandler = &OMXCore::OnEvent;
+ callback_->EmptyBufferDone = &OMXCore::OnEmptyBufferDone;
+ callback_->FillBufferDone = &OMXCore::OnFillBufferDone;
+
+
+## 组件初始化
+
+组件初始化包括打开组件并获取组件的版本号。
+
+
+ //新建组件实例,组件实例为 client_ 后续接口中需要使用 client_
+ uint32_t err = HDF_SUCCESS;
+ if (codec == codecMime::AVC) {
+ err = omxMgr_->CreateComponent(&client_, "OMX.rk.video_decoder.avc", 0, 0, callback_);
+ } else {
+ err = omxMgr_->CreateComponent(&client_, "OMX.rk.video_decoder.hevc", 0, 0, callback_);
+ }
+
+ //获取组件版本号
+ struct CompVerInfo verInfo;
+ memset(&verInfo, 0, sizeof(verInfo));
+ err = client_->GetComponentVersion(client_, &verInfo);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed to CreateComponent", __func__);
+ return false;
+ }
+
+
+
+## 设置编解码参数和配置信息
+
+codec HDI2.0 编解码参数配置,包括输入输出数据的宽和高,输入数据格式和输出数据格式
+
+
+ //设置输入端口图片的宽高
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ InitParam(param);
+ param.nPortIndex = (uint32_t)PortIndex::kPortIndexInput;
+ auto err = client_->GetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed PortIndex::kPortIndexInput, index is OMX_IndexParamPortDefinition", __func__);
+ return false;
+ }
+ HDF_LOGI("PortIndex::kPortIndexInput: eCompressionFormat = %{public}d, eColorFormat = %{public}d ",
+ param.format.video.eCompressionFormat, param.format.video.eColorFormat);
+ param.format.video.nFrameWidth = width_;
+ param.format.video.nFrameHeight = height_;
+ param.format.video.nStride = width_;
+ param.format.video.nSliceHeight = height_;
+ err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed with PortIndex::kPortIndexInput, index is OMX_IndexParamPortDefinition", __func__);
+ return false;
+ }
+
+
+
+ // 输出宽和高,格式设置
+ InitParam(param);
+ param.nPortIndex = (uint32_t)PortIndex::kPortIndexOutput;
+ err = client_->GetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed with PortIndex::kPortIndexOutput, index is OMX_IndexParamPortDefinition", __func__);
+ return false;
+ }
+ HDF_LOGI("PortIndex::kPortIndexOutput eCompressionFormat = %{public}d, eColorFormat=%{public}d",
+ param.format.video.eCompressionFormat, param.format.video.eColorFormat);
+ param.format.video.nFrameWidth = width_;
+ param.format.video.nFrameHeight = height_;
+ param.format.video.nStride = width_;
+ param.format.video.nSliceHeight = height_;
+ param.format.video.eColorFormat = AV_COLOR_FORMAT; // 输出数据格式设置,YUV420SP
+ err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed with PortIndex::kPortIndexOutput, index is OMX_IndexParamPortDefinition",
+ __func__);
+ return false;
+ }
+
+ // 设置输入数据为H264编码或H265编码
+ OMX_VIDEO_PARAM_PORTFORMATTYPE param;
+ InitParam(param);
+ param.nPortIndex = (uint32_t)PortIndex::kPortIndexInput;
+ auto err = client_->GetParameter(client_, OMX_IndexParamVideoPortFormat, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed with PortIndex::kPortIndexInput", __func__);
+ return false;
+ }
+ HDF_LOGI("set Format PortIndex::kPortIndexInput eCompressionFormat = %{public}d, eColorFormat=%{public}d",
+ param.eCompressionFormat, param.eColorFormat);
+ param.xFramerate = FRAME; // 30fps,Q16 format
+ if (codecMime_ == codecMime::AVC) {
+ param.eCompressionFormat = OMX_VIDEO_CodingAVC; // H264
+ } else {
+ param.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)OMX_VIDEO_CodingHEVC; // H265
+ }
+
+ err = client_->SetParameter(client_, OMX_IndexParamVideoPortFormat, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed with PortIndex::kPortIndexInput", __func__);
+ return false;
+ }
+
+
+## 申请输入输出Buffer
+
+此处讲解输入输出buffer的申请过程,参考codec_hdi_test.cpp 中的UseBuffers 函数,申请了输入和输出buffer,本例中讲解了共享内存的buffer实现,填充了OmxCodecBuffer, 根据返回的bufferID 记录OmxCodecBuffer 与之对应关系,后续直接通过bufferID 操作即可。同时,我们在调用完UseBuffer 之后,需要判断下端口是否可用,如果不是可用状态,需要使当前端口可用。输入输出Buffer 设置完后,端口bufffer申请完成后,需要设置组件状态为OMX_StateIdle,并等待通知结果。
+
+ // 输入端口buffer申请
+ auto ret = UseBufferOnPort(PortIndex::kPortIndexInput);
+ if (!ret) {
+ HDF_LOGE("%{public}s UseBufferOnPort PortIndex::kPortIndexInput error", __func__);
+ return false;
+ }
+
+ // 输出端口buffer申请
+ ret = UseBufferOnPort(PortIndex::kPortIndexOutput);
+ if (!ret) {
+ HDF_LOGE("%{public}s UseBufferOnPort PortIndex::kPortIndexOutput error", __func__);
+ return false;
+ }
+
+ // 发送命令,使组件进入OMX_StateIdle状态
+ HDF_LOGI("...command to IDLE....");
+ auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__);
+
+ return false;
+ }
+ HDF_LOGI("Wait for OMX_StateIdle status");
+ this->WaitForStatusChanged();
+
+UseBufferOnPort 实现如下:
+
+ bool CodecHdiDecode::UseBufferOnPort(enum PortIndex portIndex)
+ {
+ HDF_LOGI("%{public}s enter, portIndex = %{public}d", __func__, portIndex);
+ int bufferSize = 0;
+ int bufferCount = 0;
+ bool bPortEnable = false;
+ // 获取端口buffer参数
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ InitParam(param);
+ param.nPortIndex = (OMX_U32)portIndex;
+ auto err = client_->GetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param));
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed to GetParameter with OMX_IndexParamPortDefinition : portIndex[%{public}d]",
+ __func__, portIndex);
+ return false;
+ }
+
+ bufferSize = param.nBufferSize;
+ bufferCount = param.nBufferCountActual;
+ bPortEnable = param.bEnabled;
+ HDF_LOGI("buffer index [%{public}d], buffer size [%{public}d], "
+ "buffer count [%{public}d], portEnable[%{public}d], err [%{public}d]",
+ portIndex, bufferSize, bufferCount, bPortEnable, err);
+
+ {
+ OMX_PARAM_BUFFERSUPPLIERTYPE param;
+ InitParam(param);
+ param.nPortIndex = (uint32_t)portIndex;
+ auto err = client_->GetParameter(client_, OMX_IndexParamCompBufferSupplier, (int8_t *)¶m, sizeof(param));
+ HDF_LOGI("param.eBufferSupplier[%{public}d] isSupply [%{public}d], err [%{public}d]", param.eBufferSupplier,
+ this->isSupply_, err);
+ }
+
+ // 设置端口buffer
+ UseBufferOnPort(portIndex, bufferCount, bufferSize);
+ // set port enable
+ if (!bPortEnable) {
+ auto err = client_->SendCommand(client_, OMX_CommandPortEnable, (uint32_t)portIndex, NULL, 0);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s SendCommand OMX_CommandPortEnable::PortIndex::kPortIndexInput error", __func__);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool CodecHdiDecode::UseBufferOnPort(enum PortIndex portIndex, int bufferCount, int bufferSize)
+ {
+ for (int i = 0; i < bufferCount; i++) {
+ OmxCodecBuffer *omxBuffer = new OmxCodecBuffer();
+ memset_s(omxBuffer, sizeof(OmxCodecBuffer), 0, sizeof(OmxCodecBuffer));
+ omxBuffer->size = sizeof(OmxCodecBuffer);
+ omxBuffer->version.s.nVersionMajor = 1;
+ omxBuffer->bufferType = BUFFER_TYPE_AVSHARE_MEM_FD;
+ int fd = AshmemCreate(0, bufferSize);
+ shared_ptr sharedMem = make_shared(fd, bufferSize);
+ omxBuffer->bufferLen = FD_SIZE;
+ omxBuffer->buffer = (uint8_t *)(unsigned long)fd;
+ omxBuffer->allocLen = bufferSize;
+ omxBuffer->fenceFd = -1;
+
+ if (portIndex == PortIndex::kPortIndexInput) {
+ omxBuffer->type = READ_ONLY_TYPE; // ReadOnly
+ sharedMem->MapReadAndWriteAshmem();
+ } else {
+ omxBuffer->type = READ_WRITE_TYPE;
+ sharedMem->MapReadOnlyAshmem();
+ }
+ auto err = client_->UseBuffer(client_, (uint32_t)portIndex, omxBuffer);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed to UseBuffer with portIndex[%{public}d]", __func__, portIndex);
+ sharedMem->UnmapAshmem();
+ sharedMem->CloseAshmem();
+ sharedMem = nullptr;
+ return false;
+ }
+ omxBuffer->bufferLen = 0;
+ HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId);
+
+ BufferInfo *bufferInfo = new BufferInfo;
+ bufferInfo->omxBuffer = omxBuffer;
+ bufferInfo->avSharedPtr = sharedMem;
+ bufferInfo->portIndex = portIndex;
+ omxBuffers_.insert(std::make_pair(omxBuffer->bufferId, std::move(bufferInfo)));
+ if (portIndex == PortIndex::kPortIndexInput) {
+ unUsedInBuffers_.push_back(omxBuffer->bufferId);
+ } else {
+ unUsedOutBuffers_.push_back(omxBuffer->bufferId);
+ }
+ int fdret = (int)omxBuffer->buffer;
+ HDF_LOGI("{bufferID = %{public}d, srcfd = %{public}d, retfd = %{public}d}", omxBuffer->bufferId, fd, fdret);
+ }
+
+ return true;
+ }
+
+
+## 编解码
+
+编解码流程比较简单,需要先将组件设置为Executing状态,然后填充输入buffer, 读取输出buffer,进行buffer的轮转。
+
+ // 设置组件进入OMX_StateExecuting状态,开始buffer的轮转
+ HDF_LOGI("...command to OMX_StateExecuting....");
+ auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateExecuting, NULL, 0);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__);
+ return;
+ }
+
+ //设置输出buffer填充
+ for (auto bufferId : unUsedOutBuffers_) {
+ HDF_LOGI("fill bufferid [%{public}d]", bufferId);
+ auto iter = omxBuffers_.find(bufferId);
+ if (iter != omxBuffers_.end()) {
+ BufferInfo *bufferInfo = iter->second;
+ auto err = client_->FillThisBuffer(client_, bufferInfo->pOmxBuffer);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("FillThisBuffer error");
+ FUNC_EXIT_ERR();
+ return;
+ }
+ }
+ }
+
+
+ //填充输入buffer
+ bool bEndOfFile = false;
+ while (!bEndOfFile) {
+ HDF_LOGI(" inputput run");
+ int bufferID = GetFreeBufferId();
+ if (this->exit_) {
+ break;
+ }
+ if (bufferID < 0) {
+ usleep(10000);
+ continue;
+ }
+ auto iter = omxBuffers_.find(bufferID);
+ if (iter == omxBuffers_.end()) {
+ continue;
+ }
+ BufferInfo *bufferInfo = iter->second;
+ void *sharedAddr = (void *)bufferInfo->avSharedPtr->ReadFromAshmem(0, 0);
+ bool bEOS = (size_t)this->ReadOnePacket(fpIn_, (char *)sharedAddr, bufferInfo->omxBuffer->filledLen);
+ HDF_LOGI("read data size is %{public}d", bufferInfo->omxBuffer->filledLen);
+ bufferInfo->omxBuffer->offset = 0;
+ if (bEOS) {
+ bufferInfo->omxBuffer->flag = OMX_BUFFERFLAG_EOS;
+ bEndOfFile = true;
+ }
+ auto err = client_->EmptyThisBuffer(client_, bufferInfo->omxBuffer);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("%{public}s EmptyThisBuffer error", __func__);
+ return;
+ }
+ }
+ // wait
+ while (!this->exit_) {
+ usleep(10000);
+ continue;
+ }
+ // 解码完成后,使组件进入OMX_StateIdle状态
+ client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0);
+
+对rk OMX解码时,不支持数据的分帧,所以需要我进手动分帧,目前简单实现按照开始码0x000001或0x00000001分帧发送到服务端处理。分帧代码如下:
+
+ //文件分帧读取实现
+ bool OMXCore::ReadOnePacket(FILE* fp, char* buf, size_t& nFilled)
+ {
+ //先读取4个字节
+ size_t t = fread(buf, 1, 4, fp);
+ if (t < 4) {
+ //文件读取结束
+ return true;
+ }
+ size_t filled = 0;
+ filled = 4;
+
+ bool bRet = true;
+ while (!feof(fp)) {
+ fread(buf + filled, 1, 1, fp);
+ // HDF_LOGI("enter ReadFile filled= %{public}d", filled);
+ if (buf[filled] == 1) {
+ // check start code
+ if ((buf[filled - 1] == 0) &&
+ (buf[filled - 2] == 0) &&
+ (buf[filled - 3] == 0)) {
+ fseek(fp, -4, SEEK_CUR);
+ //读文件的时候,最后一次未加1,因此减3
+ filled -= 3;
+ bRet = false;
+ break;
+ } else if ((buf[filled - 1] == 0) &&
+ (buf[filled - 2] == 0)) {
+ fseek(fp, -3, SEEK_CUR);
+ filled -= 2;
+ bRet = false;
+ break;
+ }
+ }
+ filled++;
+ }
+ nFilled = filled;
+ return bRet;
+ }
+
+
+## 组件回调处理
+
+codec HDI2.0 提供3中回调函数,EventHandler, EmptyBufferDone 和 FillBufferDone。
+
+-EventHandler: 主要命令完成后的通知,例如:IDLE转为Executing 的命令执行成功通知等。
+-EmptyBufferDone: 输入数据消费完毕,客户端需要重新填入待编解码数据,再次调用EmptyThisBuffer
+-FillBufferDone: 输出数据填充完毕,客户端需要读取已编码/解码数据,再次调用FillThisBuffer
+
+####EmptyBufferDone 示例
+
+ //EmptyBufferDone 回调处理示例
+
+ int32_t OMXCore::OnEmptyBufferDone(struct CodecCallbackType *self, int8_t *pAppData, uint32_t pAppDataLen,
+ const struct OmxCodecBuffer *pBuffer)
+ {
+ FUNC_ENTER();
+ HDF_LOGI("onEmptyBufferDone: pBuffer.bufferID [%{public}d]", pBuffer->bufferId);
+ g_core->OnEmptyBufferDone(pBuffer);
+ FUNC_EXIT();
+ return HDF_SUCCESS;
+ }
+
+
+ int32_t OMXCore::OnEmptyBufferDone(const struct OmxCodecBuffer *pBuffer)
+ {
+ unique_lock ulk(mLockInputBuffers_);
+ unUsedInBuffers_.push_back(pBuffer->bufferId);
+ return HDF_SUCCESS;
+ }
+
+
+
+####FillBufferDone 示例
+
+ //FillBufferDone 回调处理示例
+ int32_t OMXCore::OnFillBufferDone(struct CodecCallbackType *self, int8_t *pAppData, uint32_t pAppDataLen,
+ struct OmxCodecBuffer *pBuffer)
+ {
+ FUNC_ENTER();
+ HDF_LOGI("onFillBufferDone: pBuffer.bufferID [%{public}d]", pBuffer->bufferId);
+ g_core->OnFillBufferDone(pBuffer);
+ FUNC_EXIT();
+ return HDF_SUCCESS;
+ }
+
+
+ int32_t OMXCore::onFillBufferDone(struct OmxCodecBuffer* pBuffer) {
+ //根据bufferID, 找到ptr
+ if (bExit_) {
+ return HDF_SUCCESS;
+ }
+
+ auto iter = omxBuffers_.find(pBuffer->bufferId);
+ if (iter == omxBuffers_.end() || !iter->second) {
+ return HDF_SUCCESS;
+ }
+ //取出输出的数据
+ BufferInfo *pBufferInfo = iter->second;
+ const void *addr = pBufferInfo->avSharedPtr->ReadFromAshmem(pBuffer->filledLen, pBuffer->offset);
+ //(void)addr;
+ //解码数据保存到文件
+ fwrite(addr, 1, pBuffer->filledLen, fpOut_.get());
+ fflush(fpOut_.get());
+ //重置buffer数据
+ pBuffer->offset = 0;
+ pBuffer->filledLen = 0;
+ if (pBuffer->flag == OMX_BUFFERFLAG_EOS) {
+ //结束
+ bExit_ = true;
+ HDF_LOGI("OnFillBufferDone the END coming");
+ return HDF_SUCCESS;
+ }
+ //再次调用FillThisBuffer
+ auto err = client_->FillThisBuffer(client_, pBufferInfo->pOmxBuffer);
+ if (err != HDF_SUCCESS) {
+ HDF_LOGE("FillThisBuffer error");
+ return HDF_SUCCESS;
+ }
+ return HDF_SUCCESS;
+ }
+
+####EventHandler示例
+
+ int32_t CodecHdiDecode::OnEvent(struct CodecCallbackType *self, enum OMX_EVENTTYPE event, struct EventInfo *info)
+ {
+ HDF_LOGI("onEvent: appData[0x%{public}p], eEvent [%{public}d], "
+ "nData1[%{public}d]",
+ info->appData, event, info->data1);
+ switch (event) {
+ case OMX_EventCmdComplete: {
+ OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE)info->data1;
+ if (OMX_CommandStateSet == cmd) {
+ HDF_LOGI("OMX_CommandStateSet reached, status is %{public}d", info->data2);
+ g_core->onStatusChanged();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return HDF_SUCCESS;
+ }
+
+
+## 组件释放
+
+组件释放前,需要将组件状态修改为IDLE,然后开始释放输入输出Buffer, 再讲组件状态修改为OMX_StateLoaded, 最后再调用ComponentDeInit 和 DestoryComponent。
+
+####Buffer释放示例
+
+ // 发送命令,使组件进入OMX_StateLoaded状态
+ client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateLoaded, nullptr, 0);
+
+ // 释放所有申请的buffer
+ auto iter = omxBuffers_.begin();
+ while (iter != omxBuffers_.end()) {
+ BufferInfo *bufferInfo = iter->second;
+ client_->FreeBuffer(client_, (uint32_t)bufferInfo->portIndex, bufferInfo->omxBuffer);
+ delete bufferInfo;
+ iter++;
+ }
+ omxBuffers_.clear();
+ unUsedInBuffers_.clear();
+ unUsedOutBuffers_.clear();
+
+ enum OMX_STATETYPE status;
+ client_->GetState(client_, &status);
+ // buffer释放后,组件即进入OMX_StateLoaded状态
+ if (status != OMX_StateLoaded) {
+ HDF_LOGI("Wait for OMX_StateLoaded status");
+ this->WaitForStatusChanged();
+ } else {
+ HDF_LOGI(" status is %{public}d", status);
+ }
+
+
+####组件实例释放示例
+ //组件实例释放
+ void OMXCore::Release() {
+ omxMgr_->DestoryComponent(client_);
+ client_ = nullptr;
+
+ CodecComponentManagerRelease();
+ }
+
+
+# 总结
+
+以上就是基于Codec HDI2.0 编解码开发过程中,所涉及的所有关键点,重点介绍了 Codec HDI2.0 编解码的过程及相关的示例代码。希望通过本次的文档,您能初步掌握基于Codec HDI2.0 编解码的开发。
\ No newline at end of file