1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Shenzhen Kaihong DID Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "codec_hdi_decode.h" 17094332d3Sopenharmony_ci#include <hdf_base.h> 18094332d3Sopenharmony_ci#include <unistd.h> 19094332d3Sopenharmony_ci#include "codec_component_manager.h" 20094332d3Sopenharmony_ci#include "codec_omx_ext.h" 21094332d3Sopenharmony_ci 22094332d3Sopenharmony_ciusing namespace std; 23094332d3Sopenharmony_ciusing namespace OHOS; 24094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Buffer::V1_0; 25094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_0; 26094332d3Sopenharmony_cinamespace { 27094332d3Sopenharmony_ciconstexpr uint32_t FD_SIZE = sizeof(int); 28094332d3Sopenharmony_ciconstexpr uint32_t FRAME = 30 << 16; 29094332d3Sopenharmony_ciconstexpr uint32_t DENOMINATOR = 2; 30094332d3Sopenharmony_ciconstexpr uint32_t NUMERATOR = 3; 31094332d3Sopenharmony_ciconstexpr uint32_t MAX_WAIT_COUNT = 3; 32094332d3Sopenharmony_ci} // namespace 33094332d3Sopenharmony_ci#define HDF_LOG_TAG codec_omx_hdi_dec 34094332d3Sopenharmony_ciIDisplayBuffer *CodecHdiDecode::buffer_ = nullptr; 35094332d3Sopenharmony_ci 36094332d3Sopenharmony_ci#define AV_COLOR_FORMAT OMX_COLOR_FormatYUV420SemiPlanar 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_cistatic CodecHdiDecode *g_core = nullptr; 39094332d3Sopenharmony_ciCodecHdiDecode::CodecHdiDecode() 40094332d3Sopenharmony_ci{ 41094332d3Sopenharmony_ci client_ = nullptr; 42094332d3Sopenharmony_ci callback_ = nullptr; 43094332d3Sopenharmony_ci omxMgr_ = nullptr; 44094332d3Sopenharmony_ci exit_ = false; 45094332d3Sopenharmony_ci width_ = 0; 46094332d3Sopenharmony_ci height_ = 0; 47094332d3Sopenharmony_ci codecMime_ = CodecMime::AVC; 48094332d3Sopenharmony_ci count_ = 0; 49094332d3Sopenharmony_ci useBufferHandle_ = false; 50094332d3Sopenharmony_ci componentId_ = 0; 51094332d3Sopenharmony_ci reader_ = nullptr; 52094332d3Sopenharmony_ci color_ = ColorFormat::YUV420SP; 53094332d3Sopenharmony_ci omxColorFormat_ = OMX_COLOR_FormatYUV420SemiPlanar; 54094332d3Sopenharmony_ci} 55094332d3Sopenharmony_ci 56094332d3Sopenharmony_ciCodecHdiDecode::~CodecHdiDecode() 57094332d3Sopenharmony_ci{ 58094332d3Sopenharmony_ci if (ioOut_.is_open()) { 59094332d3Sopenharmony_ci ioOut_.close(); 60094332d3Sopenharmony_ci } 61094332d3Sopenharmony_ci if (ioIn_.is_open()) { 62094332d3Sopenharmony_ci ioIn_.close(); 63094332d3Sopenharmony_ci } 64094332d3Sopenharmony_ci} 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_civoid CodecHdiDecode::WaitForStatusChanged() 67094332d3Sopenharmony_ci{ 68094332d3Sopenharmony_ci unique_lock<mutex> autoLock(statusLock_); 69094332d3Sopenharmony_ci statusCondition_.wait(autoLock); 70094332d3Sopenharmony_ci} 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_civoid CodecHdiDecode::OnStatusChanged() 73094332d3Sopenharmony_ci{ 74094332d3Sopenharmony_ci statusCondition_.notify_one(); 75094332d3Sopenharmony_ci} 76094332d3Sopenharmony_ci 77094332d3Sopenharmony_ciint CodecHdiDecode::GetYuvSize() 78094332d3Sopenharmony_ci{ 79094332d3Sopenharmony_ci return width_ * height_ * NUMERATOR / DENOMINATOR; 80094332d3Sopenharmony_ci} 81094332d3Sopenharmony_ci 82094332d3Sopenharmony_cibool CodecHdiDecode::Init(CommandOpt &opt) 83094332d3Sopenharmony_ci{ 84094332d3Sopenharmony_ci this->width_ = opt.width; 85094332d3Sopenharmony_ci this->height_ = opt.height; 86094332d3Sopenharmony_ci this->codecMime_ = opt.codec; 87094332d3Sopenharmony_ci this->stride_ = AlignUp(opt.width); 88094332d3Sopenharmony_ci this->useBufferHandle_ = opt.useBuffer; 89094332d3Sopenharmony_ci color_ = opt.colorForamt; 90094332d3Sopenharmony_ci if (color_ == ColorFormat::RGBA8888) { 91094332d3Sopenharmony_ci omxColorFormat_ = static_cast<OMX_COLOR_FORMATTYPE>(CODEC_COLOR_FORMAT_RGBA8888); 92094332d3Sopenharmony_ci } else if (color_ == ColorFormat::BGRA8888) { 93094332d3Sopenharmony_ci omxColorFormat_ = OMX_COLOR_Format32bitBGRA8888; 94094332d3Sopenharmony_ci } 95094332d3Sopenharmony_ci HDF_LOGI("width[%{public}d], height[%{public}d],stride_[%{public}d],infile[%{public}s],outfile[%{public}s]", width_, 96094332d3Sopenharmony_ci height_, stride_, opt.fileInput.c_str(), opt.fileOutput.c_str()); 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_ci // gralloc init 99094332d3Sopenharmony_ci buffer_ = IDisplayBuffer::Get(); 100094332d3Sopenharmony_ci reader_ = CodecPacketReader::GetPacketReader(opt.codec); 101094332d3Sopenharmony_ci ioIn_.open(opt.fileInput, std::ios_base::binary); 102094332d3Sopenharmony_ci ioOut_.open(opt.fileOutput, std::ios_base::binary | std::ios_base::trunc); 103094332d3Sopenharmony_ci if (!ioOut_.is_open() || !ioIn_.is_open()) { 104094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to open file %{public}s or %{public}s", __func__, opt.fileInput.c_str(), 105094332d3Sopenharmony_ci opt.fileOutput.c_str()); 106094332d3Sopenharmony_ci return false; 107094332d3Sopenharmony_ci } 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ci omxMgr_ = GetCodecComponentManager(); 110094332d3Sopenharmony_ci 111094332d3Sopenharmony_ci callback_ = CodecCallbackTypeGet(nullptr); 112094332d3Sopenharmony_ci if ((omxMgr_ == nullptr) || (callback_ == nullptr)) { 113094332d3Sopenharmony_ci HDF_LOGE("%{public}s omxMgr_ is null or callback_ is null", __func__); 114094332d3Sopenharmony_ci return false; 115094332d3Sopenharmony_ci } 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_ci callback_->EventHandler = &CodecHdiDecode::OnEvent; 118094332d3Sopenharmony_ci callback_->EmptyBufferDone = &CodecHdiDecode::OnEmptyBufferDone; 119094332d3Sopenharmony_ci callback_->FillBufferDone = &CodecHdiDecode::OnFillBufferDone; 120094332d3Sopenharmony_ci int32_t err = GetComponent(); 121094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 122094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to CreateComponent", __func__); 123094332d3Sopenharmony_ci return false; 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci 126094332d3Sopenharmony_ci struct CompVerInfo verInfo; 127094332d3Sopenharmony_ci err = memset_s(&verInfo, sizeof(verInfo), 0, sizeof(verInfo)); 128094332d3Sopenharmony_ci if (err != EOK) { 129094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memset_s verInfo err [%{public}d].", __func__, err); 130094332d3Sopenharmony_ci return false; 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci err = client_->GetComponentVersion(client_, &verInfo); 133094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 134094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to CreateComponent", __func__); 135094332d3Sopenharmony_ci return false; 136094332d3Sopenharmony_ci } 137094332d3Sopenharmony_ci 138094332d3Sopenharmony_ci return true; 139094332d3Sopenharmony_ci} 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ciint32_t CodecHdiDecode::ConfigPortDefine() 142094332d3Sopenharmony_ci{ 143094332d3Sopenharmony_ci // set width and height on input port 144094332d3Sopenharmony_ci OMX_PARAM_PORTDEFINITIONTYPE param; 145094332d3Sopenharmony_ci InitParam(param); 146094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 147094332d3Sopenharmony_ci auto err = 148094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 149094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 150094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed PortIndex::PORT_INDEX_INPUT, index is OMX_IndexParamPortDefinition", __func__); 151094332d3Sopenharmony_ci return err; 152094332d3Sopenharmony_ci } 153094332d3Sopenharmony_ci HDF_LOGI("PortIndex::PORT_INDEX_INPUT: eCompressionFormat = %{public}d, eColorFormat = %{public}d ", 154094332d3Sopenharmony_ci param.format.video.eCompressionFormat, param.format.video.eColorFormat); 155094332d3Sopenharmony_ci param.format.video.nFrameWidth = width_; 156094332d3Sopenharmony_ci param.format.video.nFrameHeight = height_; 157094332d3Sopenharmony_ci param.format.video.nStride = stride_; 158094332d3Sopenharmony_ci param.format.video.nSliceHeight = height_; 159094332d3Sopenharmony_ci err = 160094332d3Sopenharmony_ci client_->SetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 161094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 162094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_INPUT, index is OMX_IndexParamPortDefinition", __func__); 163094332d3Sopenharmony_ci return err; 164094332d3Sopenharmony_ci } 165094332d3Sopenharmony_ci 166094332d3Sopenharmony_ci // set width, height and color format on output port 167094332d3Sopenharmony_ci InitParam(param); 168094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 169094332d3Sopenharmony_ci err = 170094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 171094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 172094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_OUTPUT, index is OMX_IndexParamPortDefinition", 173094332d3Sopenharmony_ci __func__); 174094332d3Sopenharmony_ci return err; 175094332d3Sopenharmony_ci } 176094332d3Sopenharmony_ci HDF_LOGI("PortIndex::PORT_INDEX_OUTPUT eCompressionFormat = %{public}d, eColorFormat=%{public}d", 177094332d3Sopenharmony_ci param.format.video.eCompressionFormat, param.format.video.eColorFormat); 178094332d3Sopenharmony_ci param.format.video.nFrameWidth = width_; 179094332d3Sopenharmony_ci param.format.video.nFrameHeight = height_; 180094332d3Sopenharmony_ci param.format.video.nStride = stride_; 181094332d3Sopenharmony_ci param.format.video.nSliceHeight = height_; 182094332d3Sopenharmony_ci param.format.video.eColorFormat = omxColorFormat_; 183094332d3Sopenharmony_ci err = 184094332d3Sopenharmony_ci client_->SetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 185094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 186094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_OUTPUT, index is OMX_IndexParamPortDefinition", 187094332d3Sopenharmony_ci __func__); 188094332d3Sopenharmony_ci return err; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci return err; 191094332d3Sopenharmony_ci} 192094332d3Sopenharmony_cibool CodecHdiDecode::Configure() 193094332d3Sopenharmony_ci{ 194094332d3Sopenharmony_ci if (ConfigPortDefine() != HDF_SUCCESS) { 195094332d3Sopenharmony_ci return false; 196094332d3Sopenharmony_ci } 197094332d3Sopenharmony_ci 198094332d3Sopenharmony_ci OMX_VIDEO_PARAM_PORTFORMATTYPE param; 199094332d3Sopenharmony_ci InitParam(param); 200094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 201094332d3Sopenharmony_ci auto err = client_->GetParameter(client_, OMX_IndexParamVideoPortFormat, reinterpret_cast<int8_t *>(¶m), 202094332d3Sopenharmony_ci sizeof(param)); 203094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 204094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_INPUT", __func__); 205094332d3Sopenharmony_ci return false; 206094332d3Sopenharmony_ci } 207094332d3Sopenharmony_ci HDF_LOGI("set Format PortIndex::PORT_INDEX_INPUT eCompressionFormat = %{public}d, eColorFormat=%{public}d", 208094332d3Sopenharmony_ci param.eCompressionFormat, param.eColorFormat); 209094332d3Sopenharmony_ci param.xFramerate = FRAME; // 30fps,Q16 format 210094332d3Sopenharmony_ci switch (codecMime_) { 211094332d3Sopenharmony_ci case CodecMime::AVC: 212094332d3Sopenharmony_ci param.eCompressionFormat = OMX_VIDEO_CodingAVC; // H264 213094332d3Sopenharmony_ci break; 214094332d3Sopenharmony_ci case CodecMime::HEVC: 215094332d3Sopenharmony_ci param.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC; // H265 216094332d3Sopenharmony_ci break; 217094332d3Sopenharmony_ci case CodecMime::MPEG4: 218094332d3Sopenharmony_ci param.eCompressionFormat = OMX_VIDEO_CodingMPEG4; // H264 219094332d3Sopenharmony_ci break; 220094332d3Sopenharmony_ci case CodecMime::VP9: 221094332d3Sopenharmony_ci param.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingVP9; // H264 222094332d3Sopenharmony_ci break; 223094332d3Sopenharmony_ci default: 224094332d3Sopenharmony_ci break; 225094332d3Sopenharmony_ci } 226094332d3Sopenharmony_ci 227094332d3Sopenharmony_ci err = client_->SetParameter(client_, OMX_IndexParamVideoPortFormat, reinterpret_cast<int8_t *>(¶m), 228094332d3Sopenharmony_ci sizeof(param)); 229094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 230094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_INPUT", __func__); 231094332d3Sopenharmony_ci return false; 232094332d3Sopenharmony_ci } 233094332d3Sopenharmony_ci 234094332d3Sopenharmony_ci err = CheckAndUseBufferHandle(); 235094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 236094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed with CheckAndUseBufferHandle", __func__); 237094332d3Sopenharmony_ci return false; 238094332d3Sopenharmony_ci } 239094332d3Sopenharmony_ci return true; 240094332d3Sopenharmony_ci} 241094332d3Sopenharmony_ci 242094332d3Sopenharmony_ciint32_t CodecHdiDecode::CheckAndUseBufferHandle() 243094332d3Sopenharmony_ci{ 244094332d3Sopenharmony_ci if (!useBufferHandle_) { 245094332d3Sopenharmony_ci return HDF_SUCCESS; 246094332d3Sopenharmony_ci } 247094332d3Sopenharmony_ci SupportBufferType param; 248094332d3Sopenharmony_ci InitParamInOhos(param); 249094332d3Sopenharmony_ci param.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 250094332d3Sopenharmony_ci 251094332d3Sopenharmony_ci auto err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, reinterpret_cast<int8_t *>(¶m), 252094332d3Sopenharmony_ci sizeof(param)); 253094332d3Sopenharmony_ci HDF_LOGI( 254094332d3Sopenharmony_ci "OMX_GetParameter:OMX_IndexParamSupportBufferType:kPortIndexInput, err [%{public}x], bufferTypes[%{public}d]", 255094332d3Sopenharmony_ci err, param.bufferTypes); 256094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 257094332d3Sopenharmony_ci return err; 258094332d3Sopenharmony_ci } 259094332d3Sopenharmony_ci InitParamInOhos(param); 260094332d3Sopenharmony_ci param.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 261094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, reinterpret_cast<int8_t *>(¶m), 262094332d3Sopenharmony_ci sizeof(param)); 263094332d3Sopenharmony_ci HDF_LOGI( 264094332d3Sopenharmony_ci "OMX_GetParameter:OMX_IndexParamSupportBufferType:kPortIndexOutput, err [%{public}x], bufferTypes[%{public}d]", 265094332d3Sopenharmony_ci err, param.bufferTypes); 266094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 267094332d3Sopenharmony_ci return err; 268094332d3Sopenharmony_ci } 269094332d3Sopenharmony_ci GetBufferHandleUsageParams usage; 270094332d3Sopenharmony_ci InitParamInOhos(usage); 271094332d3Sopenharmony_ci usage.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 272094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamGetBufferHandleUsage, reinterpret_cast<int8_t *>(&usage), 273094332d3Sopenharmony_ci sizeof(usage)); 274094332d3Sopenharmony_ci HDF_LOGI("OMX_GetParameter:GetBufferHandleUsage:kPortIndexOutput, err [%{public}x], usage[%{public}" PRIu64 "]", 275094332d3Sopenharmony_ci err, usage.usage); 276094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 277094332d3Sopenharmony_ci return err; 278094332d3Sopenharmony_ci } 279094332d3Sopenharmony_ci UseBufferType type; 280094332d3Sopenharmony_ci InitParamInOhos(type); 281094332d3Sopenharmony_ci type.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 282094332d3Sopenharmony_ci type.bufferType = CODEC_BUFFER_TYPE_HANDLE; 283094332d3Sopenharmony_ci err = client_->SetParameter(client_, OMX_IndexParamUseBufferType, reinterpret_cast<int8_t *>(&type), sizeof(type)); 284094332d3Sopenharmony_ci HDF_LOGI("OMX_SetParameter:OMX_IndexParamUseBufferType:kPortIndexOutput, err [%{public}x]", err); 285094332d3Sopenharmony_ci return err; 286094332d3Sopenharmony_ci} 287094332d3Sopenharmony_ci 288094332d3Sopenharmony_cibool CodecHdiDecode::UseBuffers() 289094332d3Sopenharmony_ci{ 290094332d3Sopenharmony_ci HDF_LOGI("...command to IDLE...."); 291094332d3Sopenharmony_ci auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0); 292094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 293094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__); 294094332d3Sopenharmony_ci return false; 295094332d3Sopenharmony_ci } 296094332d3Sopenharmony_ci 297094332d3Sopenharmony_ci err = UseBufferOnPort(PortIndex::PORT_INDEX_INPUT); 298094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 299094332d3Sopenharmony_ci HDF_LOGE("%{public}s UseBufferOnPort PortIndex::PORT_INDEX_INPUT error", __func__); 300094332d3Sopenharmony_ci return false; 301094332d3Sopenharmony_ci } 302094332d3Sopenharmony_ci 303094332d3Sopenharmony_ci err = UseBufferOnPort(PortIndex::PORT_INDEX_OUTPUT); 304094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 305094332d3Sopenharmony_ci HDF_LOGE("%{public}s UseBufferOnPort PortIndex::PORT_INDEX_OUTPUT error", __func__); 306094332d3Sopenharmony_ci return false; 307094332d3Sopenharmony_ci } 308094332d3Sopenharmony_ci 309094332d3Sopenharmony_ci HDF_LOGI("Wait for OMX_StateIdle status"); 310094332d3Sopenharmony_ci OMX_STATETYPE status; 311094332d3Sopenharmony_ci err = client_->GetState(client_, &status); 312094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 313094332d3Sopenharmony_ci HDF_LOGE("%{public}s GetState err [%{public}x]", __func__, err); 314094332d3Sopenharmony_ci return false; 315094332d3Sopenharmony_ci } 316094332d3Sopenharmony_ci if (status != OMX_StateIdle) { 317094332d3Sopenharmony_ci HDF_LOGI("Wait for OMX_StateLoaded status"); 318094332d3Sopenharmony_ci this->WaitForStatusChanged(); 319094332d3Sopenharmony_ci } else { 320094332d3Sopenharmony_ci HDF_LOGI(" status is %{public}d", status); 321094332d3Sopenharmony_ci } 322094332d3Sopenharmony_ci 323094332d3Sopenharmony_ci return true; 324094332d3Sopenharmony_ci} 325094332d3Sopenharmony_ci 326094332d3Sopenharmony_ciint32_t CodecHdiDecode::UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize) 327094332d3Sopenharmony_ci{ 328094332d3Sopenharmony_ci if (bufferCount <= 0 || bufferSize <= 0) { 329094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 330094332d3Sopenharmony_ci } 331094332d3Sopenharmony_ci for (int i = 0; i < bufferCount; i++) { 332094332d3Sopenharmony_ci std::shared_ptr<OmxCodecBuffer> omxBuffer = std::make_shared<OmxCodecBuffer>(); 333094332d3Sopenharmony_ci omxBuffer->size = sizeof(OmxCodecBuffer); 334094332d3Sopenharmony_ci omxBuffer->version.s.nVersionMajor = 1; 335094332d3Sopenharmony_ci omxBuffer->bufferType = CODEC_BUFFER_TYPE_AVSHARE_MEM_FD; 336094332d3Sopenharmony_ci int fd = AshmemCreate(0, bufferSize); 337094332d3Sopenharmony_ci shared_ptr<Ashmem> sharedMem = make_shared<Ashmem>(fd, bufferSize); 338094332d3Sopenharmony_ci omxBuffer->bufferLen = FD_SIZE; 339094332d3Sopenharmony_ci omxBuffer->buffer = reinterpret_cast<uint8_t *>(fd); 340094332d3Sopenharmony_ci omxBuffer->allocLen = bufferSize; 341094332d3Sopenharmony_ci omxBuffer->fenceFd = -1; 342094332d3Sopenharmony_ci omxBuffer->pts = 0; 343094332d3Sopenharmony_ci omxBuffer->flag = 0; 344094332d3Sopenharmony_ci 345094332d3Sopenharmony_ci if (portIndex == PortIndex::PORT_INDEX_INPUT) { 346094332d3Sopenharmony_ci omxBuffer->type = READ_ONLY_TYPE; 347094332d3Sopenharmony_ci sharedMem->MapReadAndWriteAshmem(); 348094332d3Sopenharmony_ci } else { 349094332d3Sopenharmony_ci omxBuffer->type = READ_WRITE_TYPE; 350094332d3Sopenharmony_ci sharedMem->MapReadOnlyAshmem(); 351094332d3Sopenharmony_ci } 352094332d3Sopenharmony_ci auto err = client_->UseBuffer(client_, static_cast<uint32_t>(portIndex), omxBuffer.get()); 353094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 354094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to UseBuffer with portIndex[%{public}d]", __func__, portIndex); 355094332d3Sopenharmony_ci sharedMem->UnmapAshmem(); 356094332d3Sopenharmony_ci sharedMem->CloseAshmem(); 357094332d3Sopenharmony_ci sharedMem = nullptr; 358094332d3Sopenharmony_ci return err; 359094332d3Sopenharmony_ci } 360094332d3Sopenharmony_ci omxBuffer->bufferLen = 0; 361094332d3Sopenharmony_ci HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); 362094332d3Sopenharmony_ci 363094332d3Sopenharmony_ci std::shared_ptr<BufferInfo> bufferInfo = std::make_shared<BufferInfo>(); 364094332d3Sopenharmony_ci bufferInfo->omxBuffer = omxBuffer; 365094332d3Sopenharmony_ci bufferInfo->avSharedPtr = sharedMem; 366094332d3Sopenharmony_ci bufferInfo->portIndex = portIndex; 367094332d3Sopenharmony_ci omxBuffers_.emplace(std::make_pair(omxBuffer->bufferId, bufferInfo)); 368094332d3Sopenharmony_ci if (portIndex == PortIndex::PORT_INDEX_INPUT) { 369094332d3Sopenharmony_ci unUsedInBuffers_.push_back(omxBuffer->bufferId); 370094332d3Sopenharmony_ci } else { 371094332d3Sopenharmony_ci unUsedOutBuffers_.push_back(omxBuffer->bufferId); 372094332d3Sopenharmony_ci } 373094332d3Sopenharmony_ci } 374094332d3Sopenharmony_ci 375094332d3Sopenharmony_ci return HDF_SUCCESS; 376094332d3Sopenharmony_ci} 377094332d3Sopenharmony_ci 378094332d3Sopenharmony_ciint32_t CodecHdiDecode::UseBufferOnPort(PortIndex portIndex) 379094332d3Sopenharmony_ci{ 380094332d3Sopenharmony_ci HDF_LOGI("%{public}s enter, portIndex = %{public}d", __func__, portIndex); 381094332d3Sopenharmony_ci 382094332d3Sopenharmony_ci OMX_PARAM_PORTDEFINITIONTYPE param; 383094332d3Sopenharmony_ci InitParam(param); 384094332d3Sopenharmony_ci param.nPortIndex = static_cast<OMX_U32>(portIndex); 385094332d3Sopenharmony_ci auto err = 386094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 387094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 388094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to GetParameter with OMX_IndexParamPortDefinition : portIndex[%{public}d]", 389094332d3Sopenharmony_ci __func__, portIndex); 390094332d3Sopenharmony_ci return err; 391094332d3Sopenharmony_ci } 392094332d3Sopenharmony_ci 393094332d3Sopenharmony_ci int bufferSize = param.nBufferSize; 394094332d3Sopenharmony_ci int bufferCount = param.nBufferCountActual; 395094332d3Sopenharmony_ci bool portEnable = param.bEnabled; 396094332d3Sopenharmony_ci HDF_LOGI("buffer index [%{public}d], buffer size [%{public}d], " 397094332d3Sopenharmony_ci "buffer count [%{public}d], portEnable[%{public}d], err [%{public}d]", 398094332d3Sopenharmony_ci portIndex, bufferSize, bufferCount, portEnable, err); 399094332d3Sopenharmony_ci 400094332d3Sopenharmony_ci { 401094332d3Sopenharmony_ci OMX_PARAM_BUFFERSUPPLIERTYPE param; 402094332d3Sopenharmony_ci InitParam(param); 403094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(portIndex); 404094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamCompBufferSupplier, reinterpret_cast<int8_t *>(¶m), 405094332d3Sopenharmony_ci sizeof(param)); 406094332d3Sopenharmony_ci HDF_LOGI("param.eBufferSupplier[%{public}d] err [%{public}d]", param.eBufferSupplier, err); 407094332d3Sopenharmony_ci } 408094332d3Sopenharmony_ci if (useBufferHandle_ && portIndex == PortIndex::PORT_INDEX_OUTPUT) { 409094332d3Sopenharmony_ci err = UseBufferHandle(bufferCount, bufferSize); 410094332d3Sopenharmony_ci } else { 411094332d3Sopenharmony_ci err = UseBufferOnPort(portIndex, bufferCount, bufferSize); 412094332d3Sopenharmony_ci } 413094332d3Sopenharmony_ci 414094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 415094332d3Sopenharmony_ci HDF_LOGE("%{public}s UseBufferOnPort err[%{public}x]", __func__, err); 416094332d3Sopenharmony_ci return err; 417094332d3Sopenharmony_ci } 418094332d3Sopenharmony_ci // set port enable 419094332d3Sopenharmony_ci if (!portEnable) { 420094332d3Sopenharmony_ci err = client_->SendCommand(client_, OMX_CommandPortEnable, static_cast<uint32_t>(portIndex), NULL, 0); 421094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 422094332d3Sopenharmony_ci HDF_LOGE("%{public}s SendCommand OMX_CommandPortEnable::PortIndex::PORT_INDEX_INPUT error", __func__); 423094332d3Sopenharmony_ci return err; 424094332d3Sopenharmony_ci } 425094332d3Sopenharmony_ci } 426094332d3Sopenharmony_ci return HDF_SUCCESS; 427094332d3Sopenharmony_ci} 428094332d3Sopenharmony_ci 429094332d3Sopenharmony_ciint32_t CodecHdiDecode::UseBufferHandle(int bufferCount, int bufferSize) 430094332d3Sopenharmony_ci{ 431094332d3Sopenharmony_ci if (bufferCount <= 0 || bufferSize <= 0 || buffer_ == nullptr) { 432094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 433094332d3Sopenharmony_ci } 434094332d3Sopenharmony_ci PixelFormat pixForamt = PIXEL_FMT_YCBCR_420_SP; 435094332d3Sopenharmony_ci if (color_ == ColorFormat::RGBA8888) { 436094332d3Sopenharmony_ci pixForamt = PIXEL_FMT_RGBA_8888; 437094332d3Sopenharmony_ci } else if (color_ == ColorFormat::BGRA8888) { 438094332d3Sopenharmony_ci pixForamt = PIXEL_FMT_BGRA_8888; 439094332d3Sopenharmony_ci } 440094332d3Sopenharmony_ci AllocInfo alloc = {.width = this->width_, 441094332d3Sopenharmony_ci .height = this->height_, 442094332d3Sopenharmony_ci .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, 443094332d3Sopenharmony_ci .format = pixForamt}; 444094332d3Sopenharmony_ci 445094332d3Sopenharmony_ci for (int i = 0; i < bufferCount; i++) { 446094332d3Sopenharmony_ci int32_t ret = HDF_SUCCESS; 447094332d3Sopenharmony_ci std::shared_ptr<OmxCodecBuffer> omxBuffer = std::make_shared<OmxCodecBuffer>(); 448094332d3Sopenharmony_ci omxBuffer->size = sizeof(OmxCodecBuffer); 449094332d3Sopenharmony_ci omxBuffer->version.s.nVersionMajor = 1; 450094332d3Sopenharmony_ci omxBuffer->bufferType = CODEC_BUFFER_TYPE_HANDLE; 451094332d3Sopenharmony_ci BufferHandle *bufferHandle = nullptr; 452094332d3Sopenharmony_ci ret = buffer_->AllocMem(alloc, bufferHandle); 453094332d3Sopenharmony_ci HDF_LOGI("%{public}s AlloceMem ret val err[%{public}d]", __func__, ret); 454094332d3Sopenharmony_ci if (DISPLAY_SUCCESS != ret) { 455094332d3Sopenharmony_ci HDF_LOGE("%{public}s AllocMem error", __func__); 456094332d3Sopenharmony_ci return ret; 457094332d3Sopenharmony_ci } 458094332d3Sopenharmony_ci size_t handleSize = 459094332d3Sopenharmony_ci sizeof(BufferHandle) + (sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts)); 460094332d3Sopenharmony_ci omxBuffer->bufferLen = handleSize; 461094332d3Sopenharmony_ci omxBuffer->buffer = reinterpret_cast<uint8_t *>(bufferHandle); 462094332d3Sopenharmony_ci omxBuffer->allocLen = bufferSize; 463094332d3Sopenharmony_ci omxBuffer->fenceFd = -1; // check use -1 first with no window 464094332d3Sopenharmony_ci omxBuffer->pts = 0; 465094332d3Sopenharmony_ci omxBuffer->flag = 0; 466094332d3Sopenharmony_ci auto err = client_->UseBuffer(client_, static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT), omxBuffer.get()); 467094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 468094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to UseBuffer with output port]", __func__); 469094332d3Sopenharmony_ci return err; 470094332d3Sopenharmony_ci } 471094332d3Sopenharmony_ci omxBuffer->bufferLen = 0; 472094332d3Sopenharmony_ci HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); 473094332d3Sopenharmony_ci 474094332d3Sopenharmony_ci std::shared_ptr<BufferInfo> bufferInfo = std::make_shared<BufferInfo>(); 475094332d3Sopenharmony_ci bufferInfo->omxBuffer = omxBuffer; 476094332d3Sopenharmony_ci bufferInfo->setBufferHandle(bufferHandle); 477094332d3Sopenharmony_ci bufferInfo->portIndex = PortIndex::PORT_INDEX_OUTPUT; 478094332d3Sopenharmony_ci omxBuffers_.emplace(std::make_pair(omxBuffer->bufferId, bufferInfo)); 479094332d3Sopenharmony_ci unUsedOutBuffers_.push_back(omxBuffer->bufferId); 480094332d3Sopenharmony_ci } 481094332d3Sopenharmony_ci return HDF_SUCCESS; 482094332d3Sopenharmony_ci} 483094332d3Sopenharmony_ci 484094332d3Sopenharmony_civoid CodecHdiDecode::FreeBuffers() 485094332d3Sopenharmony_ci{ 486094332d3Sopenharmony_ci // command to loaded 487094332d3Sopenharmony_ci (void)client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateLoaded, nullptr, 0); 488094332d3Sopenharmony_ci 489094332d3Sopenharmony_ci // release all the buffers 490094332d3Sopenharmony_ci auto iter = omxBuffers_.begin(); 491094332d3Sopenharmony_ci while (iter != omxBuffers_.end()) { 492094332d3Sopenharmony_ci auto bufferInfo = iter->second; 493094332d3Sopenharmony_ci iter = omxBuffers_.erase(iter); 494094332d3Sopenharmony_ci (void)client_->FreeBuffer(client_, static_cast<uint32_t>(bufferInfo->portIndex), bufferInfo->omxBuffer.get()); 495094332d3Sopenharmony_ci bufferInfo = nullptr; 496094332d3Sopenharmony_ci } 497094332d3Sopenharmony_ci 498094332d3Sopenharmony_ci unUsedInBuffers_.clear(); 499094332d3Sopenharmony_ci unUsedOutBuffers_.clear(); 500094332d3Sopenharmony_ci 501094332d3Sopenharmony_ci // wait loaded 502094332d3Sopenharmony_ci OMX_STATETYPE status = OMX_StateLoaded; 503094332d3Sopenharmony_ci int32_t tryCount = MAX_WAIT_COUNT; 504094332d3Sopenharmony_ci do { 505094332d3Sopenharmony_ci int32_t err = client_->GetState(client_, &status); 506094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 507094332d3Sopenharmony_ci HDF_LOGE("%s GetState error [%{public}x]", __func__, err); 508094332d3Sopenharmony_ci break; 509094332d3Sopenharmony_ci } 510094332d3Sopenharmony_ci if (status != OMX_StateLoaded) { 511094332d3Sopenharmony_ci HDF_LOGI("Wait for OMX_StateLoaded status"); 512094332d3Sopenharmony_ci this->WaitForStatusChanged(); 513094332d3Sopenharmony_ci } 514094332d3Sopenharmony_ci tryCount--; 515094332d3Sopenharmony_ci } while ((status != OMX_StateLoaded) && (tryCount > 0)); 516094332d3Sopenharmony_ci} 517094332d3Sopenharmony_ci 518094332d3Sopenharmony_civoid CodecHdiDecode::Release() 519094332d3Sopenharmony_ci{ 520094332d3Sopenharmony_ci omxMgr_->DestroyComponent(componentId_); 521094332d3Sopenharmony_ci CodecComponentTypeRelease(client_); 522094332d3Sopenharmony_ci client_ = nullptr; 523094332d3Sopenharmony_ci CodecComponentManagerRelease(); 524094332d3Sopenharmony_ci} 525094332d3Sopenharmony_ci 526094332d3Sopenharmony_cibool CodecHdiDecode::FillAllTheBuffer() 527094332d3Sopenharmony_ci{ 528094332d3Sopenharmony_ci for (auto bufferId : unUsedOutBuffers_) { 529094332d3Sopenharmony_ci HDF_LOGI("fill bufferid [%{public}d]", bufferId); 530094332d3Sopenharmony_ci auto iter = omxBuffers_.find(bufferId); 531094332d3Sopenharmony_ci if (iter != omxBuffers_.end()) { 532094332d3Sopenharmony_ci auto bufferInfo = iter->second; 533094332d3Sopenharmony_ci auto buffer = bufferInfo->omxBuffer.get(); 534094332d3Sopenharmony_ci if (bufferInfo->bufferHandle != nullptr) { 535094332d3Sopenharmony_ci buffer->buffer = reinterpret_cast<uint8_t *>(bufferInfo->bufferHandle); 536094332d3Sopenharmony_ci buffer->bufferLen = sizeof(BufferHandle) + sizeof(int32_t) * (bufferInfo->bufferHandle->reserveFds + 537094332d3Sopenharmony_ci bufferInfo->bufferHandle->reserveInts); 538094332d3Sopenharmony_ci } 539094332d3Sopenharmony_ci 540094332d3Sopenharmony_ci auto err = client_->FillThisBuffer(client_, buffer); 541094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 542094332d3Sopenharmony_ci HDF_LOGE("%{public}s FillThisBuffer error", __func__); 543094332d3Sopenharmony_ci return false; 544094332d3Sopenharmony_ci } 545094332d3Sopenharmony_ci } 546094332d3Sopenharmony_ci } 547094332d3Sopenharmony_ci return true; 548094332d3Sopenharmony_ci} 549094332d3Sopenharmony_ci 550094332d3Sopenharmony_ciint CodecHdiDecode::GetFreeBufferId() 551094332d3Sopenharmony_ci{ 552094332d3Sopenharmony_ci int bufferID = -1; 553094332d3Sopenharmony_ci unique_lock<mutex> ulk(lockInputBuffers_); 554094332d3Sopenharmony_ci size_t nSize = this->unUsedInBuffers_.size(); 555094332d3Sopenharmony_ci if (nSize > 0) { 556094332d3Sopenharmony_ci bufferID = unUsedInBuffers_.front(); 557094332d3Sopenharmony_ci unUsedInBuffers_.pop_front(); 558094332d3Sopenharmony_ci } 559094332d3Sopenharmony_ci return bufferID; 560094332d3Sopenharmony_ci} 561094332d3Sopenharmony_ci 562094332d3Sopenharmony_ciint32_t CodecHdiDecode::GetComponent() 563094332d3Sopenharmony_ci{ 564094332d3Sopenharmony_ci int32_t count = omxMgr_->GetComponentNum(); 565094332d3Sopenharmony_ci if (count <= 0) { 566094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetComponentNum ret %{public}d", __func__, count); 567094332d3Sopenharmony_ci return HDF_FAILURE; 568094332d3Sopenharmony_ci } 569094332d3Sopenharmony_ci auto caps = std::make_unique<CodecCompCapability[]>(count); 570094332d3Sopenharmony_ci auto err = omxMgr_->GetComponentCapabilityList(caps.get(), count); 571094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 572094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetComponentCapabilityList ret %{public}d", __func__, err); 573094332d3Sopenharmony_ci return err; 574094332d3Sopenharmony_ci } 575094332d3Sopenharmony_ci std::string compName(""); 576094332d3Sopenharmony_ci for (int32_t i = 0; i < count; i++) { 577094332d3Sopenharmony_ci if (caps[i].type != VIDEO_DECODER) { 578094332d3Sopenharmony_ci continue; 579094332d3Sopenharmony_ci } 580094332d3Sopenharmony_ci if (((caps[i].role == MEDIA_ROLETYPE_VIDEO_AVC) && (codecMime_ == CodecMime::AVC)) || 581094332d3Sopenharmony_ci ((caps[i].role == MEDIA_ROLETYPE_VIDEO_HEVC) && (codecMime_ == CodecMime::HEVC)) || 582094332d3Sopenharmony_ci ((caps[i].role == MEDIA_ROLETYPE_VIDEO_VP9) && (codecMime_ == CodecMime::VP9)) || 583094332d3Sopenharmony_ci ((caps[i].role == MEDIA_ROLETYPE_VIDEO_MPEG4) && (codecMime_ == CodecMime::MPEG4))) { 584094332d3Sopenharmony_ci compName = caps[i].compName; 585094332d3Sopenharmony_ci break; 586094332d3Sopenharmony_ci } 587094332d3Sopenharmony_ci } 588094332d3Sopenharmony_ci if (compName.empty()) { 589094332d3Sopenharmony_ci HDF_LOGE("%{public}s: role is unexpected ", __func__); 590094332d3Sopenharmony_ci return HDF_FAILURE; 591094332d3Sopenharmony_ci } 592094332d3Sopenharmony_ci return omxMgr_->CreateComponent(&client_, &componentId_, compName.data(), reinterpret_cast<int64_t>(this), 593094332d3Sopenharmony_ci callback_); 594094332d3Sopenharmony_ci} 595094332d3Sopenharmony_ci 596094332d3Sopenharmony_civoid CodecHdiDecode::Run() 597094332d3Sopenharmony_ci{ 598094332d3Sopenharmony_ci HDF_LOGI("...command to OMX_StateExecuting...."); 599094332d3Sopenharmony_ci auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateExecuting, NULL, 0); 600094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 601094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__); 602094332d3Sopenharmony_ci return; 603094332d3Sopenharmony_ci } 604094332d3Sopenharmony_ci 605094332d3Sopenharmony_ci if (!FillAllTheBuffer()) { 606094332d3Sopenharmony_ci HDF_LOGE("%{public}s FillAllTheBuffer error", __func__); 607094332d3Sopenharmony_ci return; 608094332d3Sopenharmony_ci } 609094332d3Sopenharmony_ci 610094332d3Sopenharmony_ci auto t1 = std::chrono::system_clock::now(); 611094332d3Sopenharmony_ci bool eosFlag = false; 612094332d3Sopenharmony_ci while (!eosFlag) { 613094332d3Sopenharmony_ci HDF_LOGI(" inputput run"); 614094332d3Sopenharmony_ci int bufferID = GetFreeBufferId(); 615094332d3Sopenharmony_ci if (this->exit_) { 616094332d3Sopenharmony_ci break; 617094332d3Sopenharmony_ci } 618094332d3Sopenharmony_ci if (bufferID < 0) { 619094332d3Sopenharmony_ci usleep(10000); // 10000: sleep time 10ms 620094332d3Sopenharmony_ci continue; 621094332d3Sopenharmony_ci } 622094332d3Sopenharmony_ci auto iter = omxBuffers_.find(bufferID); 623094332d3Sopenharmony_ci if (iter == omxBuffers_.end()) { 624094332d3Sopenharmony_ci continue; 625094332d3Sopenharmony_ci } 626094332d3Sopenharmony_ci auto bufferInfo = iter->second; 627094332d3Sopenharmony_ci const char *sharedAddr = static_cast<const char *>(bufferInfo->avSharedPtr->ReadFromAshmem(0, 0)); 628094332d3Sopenharmony_ci eosFlag = reader_->ReadOnePacket(ioIn_, const_cast<char *>(sharedAddr), bufferInfo->omxBuffer->filledLen); 629094332d3Sopenharmony_ci bufferInfo->omxBuffer->offset = 0; 630094332d3Sopenharmony_ci if (eosFlag) { 631094332d3Sopenharmony_ci bufferInfo->omxBuffer->flag = OMX_BUFFERFLAG_EOS; 632094332d3Sopenharmony_ci } 633094332d3Sopenharmony_ci err = client_->EmptyThisBuffer(client_, bufferInfo->omxBuffer.get()); 634094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 635094332d3Sopenharmony_ci HDF_LOGE("%{public}s EmptyThisBuffer error", __func__); 636094332d3Sopenharmony_ci return; 637094332d3Sopenharmony_ci } 638094332d3Sopenharmony_ci } 639094332d3Sopenharmony_ci // wait 640094332d3Sopenharmony_ci while (!this->exit_) { 641094332d3Sopenharmony_ci usleep(10000); // 10000: sleep time 10ms 642094332d3Sopenharmony_ci } 643094332d3Sopenharmony_ci auto t2 = std::chrono::system_clock::now(); 644094332d3Sopenharmony_ci std::chrono::duration<double> diff = t2 - t1; 645094332d3Sopenharmony_ci HDF_LOGI("decoder costtime %{public}f, count=%{public}d", diff.count(), count_); 646094332d3Sopenharmony_ci // command to IDLE 647094332d3Sopenharmony_ci (void)client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0); 648094332d3Sopenharmony_ci return; 649094332d3Sopenharmony_ci} 650094332d3Sopenharmony_ciint32_t CodecHdiDecode::OnEvent(struct CodecCallbackType *self, OMX_EVENTTYPE event, struct EventInfo *info) 651094332d3Sopenharmony_ci{ 652094332d3Sopenharmony_ci HDF_LOGI("%{public}s: appData[%{public}" PRId64 "] eEvent [%{public}d], nData1[%{public}d]", __func__, 653094332d3Sopenharmony_ci info->appData, event, info->data1); 654094332d3Sopenharmony_ci if (event == OMX_EventCmdComplete) { 655094332d3Sopenharmony_ci OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(info->data1); 656094332d3Sopenharmony_ci if (OMX_CommandStateSet == cmd) { 657094332d3Sopenharmony_ci HDF_LOGI("OMX_CommandStateSet reached, status is %{public}d", info->data2); 658094332d3Sopenharmony_ci g_core->OnStatusChanged(); 659094332d3Sopenharmony_ci } 660094332d3Sopenharmony_ci } 661094332d3Sopenharmony_ci return HDF_SUCCESS; 662094332d3Sopenharmony_ci} 663094332d3Sopenharmony_ci 664094332d3Sopenharmony_ciint32_t CodecHdiDecode::OnEmptyBufferDone(struct CodecCallbackType *self, int64_t appData, 665094332d3Sopenharmony_ci const struct OmxCodecBuffer *buffer) 666094332d3Sopenharmony_ci{ 667094332d3Sopenharmony_ci HDF_LOGI("onEmptyBufferDone: pBuffer.bufferID [%{public}d]", buffer->bufferId); 668094332d3Sopenharmony_ci return g_core->OnEmptyBufferDone(*buffer); 669094332d3Sopenharmony_ci} 670094332d3Sopenharmony_ci 671094332d3Sopenharmony_ciint32_t CodecHdiDecode::OnFillBufferDone(struct CodecCallbackType *self, int64_t appData, 672094332d3Sopenharmony_ci const struct OmxCodecBuffer *buffer) 673094332d3Sopenharmony_ci{ 674094332d3Sopenharmony_ci HDF_LOGI("onFillBufferDone: pBuffer.bufferID [%{public}d]", buffer->bufferId); 675094332d3Sopenharmony_ci return g_core->OnFillBufferDone(*buffer); 676094332d3Sopenharmony_ci} 677094332d3Sopenharmony_ci 678094332d3Sopenharmony_ciint32_t CodecHdiDecode::OnEmptyBufferDone(const struct OmxCodecBuffer &buffer) 679094332d3Sopenharmony_ci{ 680094332d3Sopenharmony_ci unique_lock<mutex> ulk(lockInputBuffers_); 681094332d3Sopenharmony_ci unUsedInBuffers_.push_back(buffer.bufferId); 682094332d3Sopenharmony_ci return HDF_SUCCESS; 683094332d3Sopenharmony_ci} 684094332d3Sopenharmony_ci 685094332d3Sopenharmony_ciint32_t CodecHdiDecode::OnFillBufferDone(const struct OmxCodecBuffer &buffer) 686094332d3Sopenharmony_ci{ 687094332d3Sopenharmony_ci if (exit_) { 688094332d3Sopenharmony_ci return HDF_SUCCESS; 689094332d3Sopenharmony_ci } 690094332d3Sopenharmony_ci 691094332d3Sopenharmony_ci auto iter = omxBuffers_.find(buffer.bufferId); 692094332d3Sopenharmony_ci if ((iter == omxBuffers_.end()) || (iter->second == nullptr)) { 693094332d3Sopenharmony_ci return HDF_SUCCESS; 694094332d3Sopenharmony_ci } 695094332d3Sopenharmony_ci count_++; 696094332d3Sopenharmony_ci // read buffer 697094332d3Sopenharmony_ci auto bufferInfo = iter->second; 698094332d3Sopenharmony_ci if (bufferInfo->avSharedPtr != nullptr) { 699094332d3Sopenharmony_ci void *addr = const_cast<void *>(bufferInfo->avSharedPtr->ReadFromAshmem(buffer.filledLen, buffer.offset)); 700094332d3Sopenharmony_ci ioOut_.write(static_cast<char *>(addr), buffer.filledLen); 701094332d3Sopenharmony_ci } else if (bufferInfo->bufferHandle != nullptr && buffer_ != nullptr) { 702094332d3Sopenharmony_ci buffer_->Mmap(*bufferInfo->bufferHandle); 703094332d3Sopenharmony_ci ioOut_.write(static_cast<char *>(bufferInfo->bufferHandle->virAddr), bufferInfo->bufferHandle->size); 704094332d3Sopenharmony_ci buffer_->Unmap(*bufferInfo->bufferHandle); 705094332d3Sopenharmony_ci } 706094332d3Sopenharmony_ci 707094332d3Sopenharmony_ci ioOut_.flush(); 708094332d3Sopenharmony_ci if (buffer.flag == OMX_BUFFERFLAG_EOS) { 709094332d3Sopenharmony_ci // end 710094332d3Sopenharmony_ci exit_ = true; 711094332d3Sopenharmony_ci HDF_LOGI("OnFillBufferDone the END coming"); 712094332d3Sopenharmony_ci return HDF_SUCCESS; 713094332d3Sopenharmony_ci } 714094332d3Sopenharmony_ci // call fillthisbuffer again 715094332d3Sopenharmony_ci auto err = client_->FillThisBuffer(client_, bufferInfo->omxBuffer.get()); 716094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 717094332d3Sopenharmony_ci HDF_LOGE("%{public}s FillThisBuffer error", __func__); 718094332d3Sopenharmony_ci return HDF_SUCCESS; 719094332d3Sopenharmony_ci } 720094332d3Sopenharmony_ci return HDF_SUCCESS; 721094332d3Sopenharmony_ci} 722094332d3Sopenharmony_ci 723094332d3Sopenharmony_ciint main(int argc, char *argv[]) 724094332d3Sopenharmony_ci{ 725094332d3Sopenharmony_ci CommandOpt opt; 726094332d3Sopenharmony_ci CommandParse parse; 727094332d3Sopenharmony_ci if (!parse.Parse(argc, argv, opt)) { 728094332d3Sopenharmony_ci return HDF_FAILURE; 729094332d3Sopenharmony_ci } 730094332d3Sopenharmony_ci if (g_core == nullptr) { 731094332d3Sopenharmony_ci g_core = new CodecHdiDecode(); 732094332d3Sopenharmony_ci } 733094332d3Sopenharmony_ci // Init width, height, input file 734094332d3Sopenharmony_ci if (!g_core->Init(opt)) { 735094332d3Sopenharmony_ci delete g_core; 736094332d3Sopenharmony_ci g_core = nullptr; 737094332d3Sopenharmony_ci return HDF_FAILURE; 738094332d3Sopenharmony_ci } 739094332d3Sopenharmony_ci 740094332d3Sopenharmony_ci if (!g_core->Configure()) { 741094332d3Sopenharmony_ci delete g_core; 742094332d3Sopenharmony_ci g_core = nullptr; 743094332d3Sopenharmony_ci return HDF_FAILURE; 744094332d3Sopenharmony_ci } 745094332d3Sopenharmony_ci 746094332d3Sopenharmony_ci if (!g_core->UseBuffers()) { 747094332d3Sopenharmony_ci delete g_core; 748094332d3Sopenharmony_ci g_core = nullptr; 749094332d3Sopenharmony_ci return HDF_FAILURE; 750094332d3Sopenharmony_ci } 751094332d3Sopenharmony_ci 752094332d3Sopenharmony_ci g_core->Run(); 753094332d3Sopenharmony_ci g_core->FreeBuffers(); 754094332d3Sopenharmony_ci g_core->Release(); 755094332d3Sopenharmony_ci delete g_core; 756094332d3Sopenharmony_ci g_core = nullptr; 757094332d3Sopenharmony_ci}