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_encode.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_ci#define HDF_LOG_TAG codec_omx_hdi_enc 27094332d3Sopenharmony_ciIDisplayBuffer *CodecHdiEncode::buffer_ = nullptr; 28094332d3Sopenharmony_ci 29094332d3Sopenharmony_cinamespace { 30094332d3Sopenharmony_ci constexpr int32_t FRAME = 30 << 16; 31094332d3Sopenharmony_ci constexpr int32_t BUFFER_COUNT = 10; 32094332d3Sopenharmony_ci constexpr int32_t BITRATE = 3000000; 33094332d3Sopenharmony_ci constexpr int32_t FD_SIZE = sizeof(int); 34094332d3Sopenharmony_ci constexpr uint32_t MAX_WAIT_COUNT = 3; 35094332d3Sopenharmony_ci} 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_ci#define AV_COLOR_FORMAT (OMX_COLOR_FORMATTYPE) CODEC_COLOR_FORMAT_RGBA8888 38094332d3Sopenharmony_ci 39094332d3Sopenharmony_cistatic CodecHdiEncode *g_core = nullptr; 40094332d3Sopenharmony_ciCodecHdiEncode::CodecHdiEncode() 41094332d3Sopenharmony_ci{ 42094332d3Sopenharmony_ci client_ = nullptr; 43094332d3Sopenharmony_ci callback_ = nullptr; 44094332d3Sopenharmony_ci omxMgr_ = nullptr; 45094332d3Sopenharmony_ci exit_ = false; 46094332d3Sopenharmony_ci useBufferHandle_ = false; 47094332d3Sopenharmony_ci width_ = 0; 48094332d3Sopenharmony_ci height_ = 0; 49094332d3Sopenharmony_ci count_ = 0; 50094332d3Sopenharmony_ci componentId_ = 0; 51094332d3Sopenharmony_ci color_ = ColorFormat::YUV420SP; 52094332d3Sopenharmony_ci codecMime_ = CodecMime::AVC; 53094332d3Sopenharmony_ci omxColorFormat_ = OMX_COLOR_FormatYUV420SemiPlanar; 54094332d3Sopenharmony_ci} 55094332d3Sopenharmony_ci 56094332d3Sopenharmony_ciCodecHdiEncode::~CodecHdiEncode() 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 CodecHdiEncode::WaitForStatusChanged() 67094332d3Sopenharmony_ci{ 68094332d3Sopenharmony_ci unique_lock<mutex> autoLock(statusLock_); 69094332d3Sopenharmony_ci statusCondition_.wait(autoLock); 70094332d3Sopenharmony_ci} 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_civoid CodecHdiEncode::OnStatusChanged() 73094332d3Sopenharmony_ci{ 74094332d3Sopenharmony_ci statusCondition_.notify_one(); 75094332d3Sopenharmony_ci} 76094332d3Sopenharmony_ci 77094332d3Sopenharmony_cibool CodecHdiEncode::ReadOneFrame(char *buf, uint32_t &filledCount) 78094332d3Sopenharmony_ci{ 79094332d3Sopenharmony_ci bool ret = false; 80094332d3Sopenharmony_ci filledCount = ioIn_.read(buf, GetInputBufferSize()).gcount(); 81094332d3Sopenharmony_ci if (ioIn_.eof()) { 82094332d3Sopenharmony_ci ret = true; 83094332d3Sopenharmony_ci } 84094332d3Sopenharmony_ci return ret; 85094332d3Sopenharmony_ci} 86094332d3Sopenharmony_ci 87094332d3Sopenharmony_cibool CodecHdiEncode::Init(CommandOpt &opt) 88094332d3Sopenharmony_ci{ 89094332d3Sopenharmony_ci this->width_ = opt.width; 90094332d3Sopenharmony_ci this->height_ = opt.height; 91094332d3Sopenharmony_ci this->stride_ = AlignUp(width_); 92094332d3Sopenharmony_ci this->useBufferHandle_ = opt.useBuffer; 93094332d3Sopenharmony_ci HDF_LOGI("width[%{public}d], height[%{public}d]", width_, height_); 94094332d3Sopenharmony_ci // gralloc init 95094332d3Sopenharmony_ci codecMime_ = opt.codec; 96094332d3Sopenharmony_ci 97094332d3Sopenharmony_ci buffer_ = IDisplayBuffer::Get(); 98094332d3Sopenharmony_ci color_ = opt.colorForamt; 99094332d3Sopenharmony_ci if (color_ == ColorFormat::RGBA8888) { 100094332d3Sopenharmony_ci omxColorFormat_ = AV_COLOR_FORMAT; 101094332d3Sopenharmony_ci } else if (color_ == ColorFormat::BGRA8888) { 102094332d3Sopenharmony_ci omxColorFormat_ = OMX_COLOR_Format32bitBGRA8888; 103094332d3Sopenharmony_ci } 104094332d3Sopenharmony_ci ioIn_.open(opt.fileInput, std::ios_base::binary); 105094332d3Sopenharmony_ci ioOut_.open(opt.fileOutput, std::ios_base::binary | std::ios_base::trunc); 106094332d3Sopenharmony_ci if (!ioOut_.is_open() || !ioIn_.is_open()) { 107094332d3Sopenharmony_ci HDF_LOGE("%{public}s:failed to open file %{public}s or %{public}s", __func__, opt.fileInput.c_str(), 108094332d3Sopenharmony_ci opt.fileOutput.c_str()); 109094332d3Sopenharmony_ci return false; 110094332d3Sopenharmony_ci } 111094332d3Sopenharmony_ci // Interface init 112094332d3Sopenharmony_ci omxMgr_ = GetCodecComponentManager(); 113094332d3Sopenharmony_ci callback_ = CodecCallbackTypeGet(nullptr); 114094332d3Sopenharmony_ci if ((omxMgr_ == nullptr) || (callback_ == nullptr)) { 115094332d3Sopenharmony_ci HDF_LOGE("%{public}s:omxMgr_ or callback_ is null", __func__); 116094332d3Sopenharmony_ci return false; 117094332d3Sopenharmony_ci } 118094332d3Sopenharmony_ci // set the callback 119094332d3Sopenharmony_ci callback_->EventHandler = &CodecHdiEncode::OnEvent; 120094332d3Sopenharmony_ci callback_->EmptyBufferDone = &CodecHdiEncode::OnEmptyBufferDone; 121094332d3Sopenharmony_ci callback_->FillBufferDone = &CodecHdiEncode::OnFillBufferDone; 122094332d3Sopenharmony_ci 123094332d3Sopenharmony_ci // create a component 124094332d3Sopenharmony_ci auto err = GetComponent(); 125094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 126094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to CreateComponent", __func__); 127094332d3Sopenharmony_ci return false; 128094332d3Sopenharmony_ci } 129094332d3Sopenharmony_ci // get version 130094332d3Sopenharmony_ci struct CompVerInfo verInfo; 131094332d3Sopenharmony_ci (void)memset_s(&verInfo, sizeof(verInfo), 0, sizeof(verInfo)); 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_cibool CodecHdiEncode::Configure() 142094332d3Sopenharmony_ci{ 143094332d3Sopenharmony_ci if (client_ == nullptr) { 144094332d3Sopenharmony_ci return false; 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci // set input width, height and COLOR, set output port width and height 147094332d3Sopenharmony_ci if (ConfigPortDefine() != HDF_SUCCESS) { 148094332d3Sopenharmony_ci HDF_LOGE("%{public}s ConfigPortDefine error", __func__); 149094332d3Sopenharmony_ci return false; 150094332d3Sopenharmony_ci } 151094332d3Sopenharmony_ci if (ConfigBitMode() != HDF_SUCCESS) { 152094332d3Sopenharmony_ci HDF_LOGE("%{public}s ConfigBitMode error", __func__); 153094332d3Sopenharmony_ci return false; 154094332d3Sopenharmony_ci } 155094332d3Sopenharmony_ci if (CheckAndUseBufferHandle() != HDF_SUCCESS) { 156094332d3Sopenharmony_ci HDF_LOGE("%{public}s ConfigUseBufferHandle error", __func__); 157094332d3Sopenharmony_ci return false; 158094332d3Sopenharmony_ci } 159094332d3Sopenharmony_ci 160094332d3Sopenharmony_ci return true; 161094332d3Sopenharmony_ci} 162094332d3Sopenharmony_ci 163094332d3Sopenharmony_ciint32_t CodecHdiEncode::CheckAndUseBufferHandle() 164094332d3Sopenharmony_ci{ 165094332d3Sopenharmony_ci if (!useBufferHandle_) { 166094332d3Sopenharmony_ci return HDF_SUCCESS; 167094332d3Sopenharmony_ci } 168094332d3Sopenharmony_ci 169094332d3Sopenharmony_ci SupportBufferType param; 170094332d3Sopenharmony_ci InitParamInOhos(param); 171094332d3Sopenharmony_ci param.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 172094332d3Sopenharmony_ci 173094332d3Sopenharmony_ci auto err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, reinterpret_cast<int8_t *>(¶m), 174094332d3Sopenharmony_ci sizeof(param)); 175094332d3Sopenharmony_ci HDF_LOGI( 176094332d3Sopenharmony_ci "OMX_GetParameter:OMX_IndexParamSupportBufferType:PORT_INDEX_OUTPUT, err [%{public}x], bufferTypes[%{public}d]", 177094332d3Sopenharmony_ci err, param.bufferTypes); 178094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 179094332d3Sopenharmony_ci return err; 180094332d3Sopenharmony_ci } 181094332d3Sopenharmony_ci InitParamInOhos(param); 182094332d3Sopenharmony_ci param.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 183094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, reinterpret_cast<int8_t *>(¶m), 184094332d3Sopenharmony_ci sizeof(param)); 185094332d3Sopenharmony_ci HDF_LOGI( 186094332d3Sopenharmony_ci "OMX_GetParameter:OMX_IndexParamSupportBufferType:PORT_INDEX_INPUT, err [%{public}x], bufferTypes[%{public}d]", 187094332d3Sopenharmony_ci err, param.bufferTypes); 188094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 189094332d3Sopenharmony_ci return err; 190094332d3Sopenharmony_ci } 191094332d3Sopenharmony_ci GetBufferHandleUsageParams usage; 192094332d3Sopenharmony_ci InitParamInOhos(usage); 193094332d3Sopenharmony_ci usage.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 194094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamGetBufferHandleUsage, reinterpret_cast<int8_t *>(&usage), 195094332d3Sopenharmony_ci sizeof(usage)); 196094332d3Sopenharmony_ci HDF_LOGI("OMX_GetParameter:GetBufferHandleUsage:PORT_INDEX_INPUT, err [%{public}x], usage[%{public}" PRIu64 "]", 197094332d3Sopenharmony_ci err, usage.usage); 198094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 199094332d3Sopenharmony_ci return err; 200094332d3Sopenharmony_ci } 201094332d3Sopenharmony_ci 202094332d3Sopenharmony_ci UseBufferType type; 203094332d3Sopenharmony_ci InitParamInOhos(type); 204094332d3Sopenharmony_ci type.portIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 205094332d3Sopenharmony_ci type.bufferType = CODEC_BUFFER_TYPE_DYNAMIC_HANDLE; 206094332d3Sopenharmony_ci err = client_->SetParameter(client_, OMX_IndexParamUseBufferType, reinterpret_cast<int8_t *>(&type), sizeof(type)); 207094332d3Sopenharmony_ci HDF_LOGI("OMX_SetParameter:OMX_IndexParamUseBufferType:PORT_INDEX_INPUT, err [%{public}x]", err); 208094332d3Sopenharmony_ci return err; 209094332d3Sopenharmony_ci} 210094332d3Sopenharmony_ci 211094332d3Sopenharmony_cibool CodecHdiEncode::UseBuffers() 212094332d3Sopenharmony_ci{ 213094332d3Sopenharmony_ci // command to IDLE 214094332d3Sopenharmony_ci auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0); 215094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 216094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__); 217094332d3Sopenharmony_ci return false; 218094332d3Sopenharmony_ci } 219094332d3Sopenharmony_ci 220094332d3Sopenharmony_ci // use buffer on input port 221094332d3Sopenharmony_ci err = UseBufferOnPort(PortIndex::PORT_INDEX_INPUT); 222094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 223094332d3Sopenharmony_ci HDF_LOGE("%{public}s UseBufferOnPort PORT_INDEX_INPUT error", __func__); 224094332d3Sopenharmony_ci return false; 225094332d3Sopenharmony_ci } 226094332d3Sopenharmony_ci 227094332d3Sopenharmony_ci // use buffer on output port 228094332d3Sopenharmony_ci err = UseBufferOnPort(PortIndex::PORT_INDEX_OUTPUT); 229094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 230094332d3Sopenharmony_ci HDF_LOGE("%{public}s UseBufferOnPort PORT_INDEX_OUTPUT error", __func__); 231094332d3Sopenharmony_ci return false; 232094332d3Sopenharmony_ci } 233094332d3Sopenharmony_ci 234094332d3Sopenharmony_ci if (useBufferHandle_ && CreateBufferHandle() != HDF_SUCCESS) { 235094332d3Sopenharmony_ci HDF_LOGE("%{public}s CreateBufferHandle error", __func__); 236094332d3Sopenharmony_ci return false; 237094332d3Sopenharmony_ci } 238094332d3Sopenharmony_ci 239094332d3Sopenharmony_ci // wait executing state 240094332d3Sopenharmony_ci OMX_STATETYPE status; 241094332d3Sopenharmony_ci err = client_->GetState(client_, &status); 242094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 243094332d3Sopenharmony_ci HDF_LOGE("%{public}s GetState err [%{public}x]", __func__, err); 244094332d3Sopenharmony_ci return false; 245094332d3Sopenharmony_ci } 246094332d3Sopenharmony_ci 247094332d3Sopenharmony_ci // wait loaded 248094332d3Sopenharmony_ci if (status != OMX_StateIdle) { 249094332d3Sopenharmony_ci HDF_LOGI("Wait for OMX_StateLoaded status"); 250094332d3Sopenharmony_ci this->WaitForStatusChanged(); 251094332d3Sopenharmony_ci } else { 252094332d3Sopenharmony_ci HDF_LOGI(" status is %{public}d", status); 253094332d3Sopenharmony_ci } 254094332d3Sopenharmony_ci return true; 255094332d3Sopenharmony_ci} 256094332d3Sopenharmony_ci 257094332d3Sopenharmony_ciint32_t CodecHdiEncode::UseBufferOnPort(PortIndex portIndex) 258094332d3Sopenharmony_ci{ 259094332d3Sopenharmony_ci int bufferSize = 0; 260094332d3Sopenharmony_ci int bufferCount = 0; 261094332d3Sopenharmony_ci bool portEnable = false; 262094332d3Sopenharmony_ci 263094332d3Sopenharmony_ci OMX_PARAM_PORTDEFINITIONTYPE param; 264094332d3Sopenharmony_ci InitParam(param); 265094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(portIndex); 266094332d3Sopenharmony_ci auto err = 267094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 268094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 269094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to GetParameter with OMX_IndexParamPortDefinition : portIndex[%{public}d]", 270094332d3Sopenharmony_ci __func__, portIndex); 271094332d3Sopenharmony_ci return err; 272094332d3Sopenharmony_ci } 273094332d3Sopenharmony_ci bufferSize = param.nBufferSize; 274094332d3Sopenharmony_ci bufferCount = param.nBufferCountActual; 275094332d3Sopenharmony_ci portEnable = param.bEnabled; 276094332d3Sopenharmony_ci { 277094332d3Sopenharmony_ci OMX_PARAM_BUFFERSUPPLIERTYPE param; 278094332d3Sopenharmony_ci InitParam(param); 279094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(portIndex); 280094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamCompBufferSupplier, reinterpret_cast<int8_t *>(¶m), 281094332d3Sopenharmony_ci sizeof(param)); 282094332d3Sopenharmony_ci HDF_LOGI("param.eBufferSupplier[%{public}d] err [%{public}d]", param.eBufferSupplier, err); 283094332d3Sopenharmony_ci } 284094332d3Sopenharmony_ci if (portIndex == PortIndex::PORT_INDEX_INPUT) { 285094332d3Sopenharmony_ci bufferSize = GetInputBufferSize(); 286094332d3Sopenharmony_ci } else if (bufferSize == 0) { 287094332d3Sopenharmony_ci bufferSize = width_ * height_; 288094332d3Sopenharmony_ci HDF_LOGI("bufferSize[%{public}d], width[%{public}d], height[%{public}d]", bufferSize, width_, height_); 289094332d3Sopenharmony_ci } 290094332d3Sopenharmony_ci if (useBufferHandle_ && portIndex == PortIndex::PORT_INDEX_INPUT) { 291094332d3Sopenharmony_ci err = UseDynaBuffer(bufferCount, bufferSize); 292094332d3Sopenharmony_ci } else { 293094332d3Sopenharmony_ci err = UseBufferOnPort(portIndex, bufferCount, bufferSize); 294094332d3Sopenharmony_ci } 295094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 296094332d3Sopenharmony_ci return err; 297094332d3Sopenharmony_ci } 298094332d3Sopenharmony_ci // if port is disable, changed to enable 299094332d3Sopenharmony_ci if (!portEnable) { 300094332d3Sopenharmony_ci err = client_->SendCommand(client_, OMX_CommandPortEnable, static_cast<uint32_t>(portIndex), NULL, 0); 301094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 302094332d3Sopenharmony_ci HDF_LOGE("%{public}s SendCommand OMX_CommandPortEnable::PORT_INDEX_INPUT error", __func__); 303094332d3Sopenharmony_ci return err; 304094332d3Sopenharmony_ci } 305094332d3Sopenharmony_ci } 306094332d3Sopenharmony_ci return HDF_SUCCESS; 307094332d3Sopenharmony_ci} 308094332d3Sopenharmony_ci 309094332d3Sopenharmony_ciint32_t CodecHdiEncode::UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize) 310094332d3Sopenharmony_ci{ 311094332d3Sopenharmony_ci if (bufferCount <= 0 || bufferSize <= 0) { 312094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 313094332d3Sopenharmony_ci } 314094332d3Sopenharmony_ci 315094332d3Sopenharmony_ci for (int i = 0; i < bufferCount; i++) { 316094332d3Sopenharmony_ci auto omxBuffer = std::make_shared<OmxCodecBuffer>(); 317094332d3Sopenharmony_ci omxBuffer->size = sizeof(OmxCodecBuffer); 318094332d3Sopenharmony_ci omxBuffer->version.s.nVersionMajor = 1; 319094332d3Sopenharmony_ci omxBuffer->bufferType = CODEC_BUFFER_TYPE_AVSHARE_MEM_FD; 320094332d3Sopenharmony_ci int fd = AshmemCreate(0, bufferSize); 321094332d3Sopenharmony_ci shared_ptr<Ashmem> spSharedMem = make_shared<Ashmem>(fd, bufferSize); 322094332d3Sopenharmony_ci omxBuffer->bufferLen = FD_SIZE; 323094332d3Sopenharmony_ci omxBuffer->buffer = reinterpret_cast<uint8_t *>(fd); 324094332d3Sopenharmony_ci omxBuffer->allocLen = bufferSize; 325094332d3Sopenharmony_ci omxBuffer->fenceFd = -1; 326094332d3Sopenharmony_ci omxBuffer->pts = 0; 327094332d3Sopenharmony_ci omxBuffer->flag = 0; 328094332d3Sopenharmony_ci if (portIndex == PortIndex::PORT_INDEX_INPUT) { 329094332d3Sopenharmony_ci omxBuffer->type = READ_ONLY_TYPE; 330094332d3Sopenharmony_ci spSharedMem->MapReadAndWriteAshmem(); 331094332d3Sopenharmony_ci } else { 332094332d3Sopenharmony_ci omxBuffer->type = READ_WRITE_TYPE; 333094332d3Sopenharmony_ci spSharedMem->MapReadOnlyAshmem(); 334094332d3Sopenharmony_ci } 335094332d3Sopenharmony_ci auto err = client_->UseBuffer(client_, static_cast<uint32_t>(portIndex), omxBuffer.get()); 336094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 337094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to UseBuffer with portIndex[%{public}d]", __func__, portIndex); 338094332d3Sopenharmony_ci spSharedMem->UnmapAshmem(); 339094332d3Sopenharmony_ci spSharedMem->CloseAshmem(); 340094332d3Sopenharmony_ci spSharedMem = nullptr; 341094332d3Sopenharmony_ci return err; 342094332d3Sopenharmony_ci } 343094332d3Sopenharmony_ci 344094332d3Sopenharmony_ci omxBuffer->bufferLen = 0; 345094332d3Sopenharmony_ci HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); 346094332d3Sopenharmony_ci 347094332d3Sopenharmony_ci auto bufferInfo = std::make_shared<BufferInfo>(); 348094332d3Sopenharmony_ci bufferInfo->omxBuffer = omxBuffer; 349094332d3Sopenharmony_ci bufferInfo->avSharedPtr = spSharedMem; 350094332d3Sopenharmony_ci bufferInfo->portIndex = portIndex; 351094332d3Sopenharmony_ci omxBuffers_.insert(std::make_pair(omxBuffer->bufferId, bufferInfo)); 352094332d3Sopenharmony_ci if (portIndex == PortIndex::PORT_INDEX_INPUT) { 353094332d3Sopenharmony_ci unUsedInBuffers_.push_back(omxBuffer->bufferId); 354094332d3Sopenharmony_ci } else { 355094332d3Sopenharmony_ci unUsedOutBuffers_.push_back(omxBuffer->bufferId); 356094332d3Sopenharmony_ci } 357094332d3Sopenharmony_ci } 358094332d3Sopenharmony_ci return HDF_SUCCESS; 359094332d3Sopenharmony_ci} 360094332d3Sopenharmony_ci 361094332d3Sopenharmony_ciint32_t CodecHdiEncode::UseDynaBuffer(int bufferCount, int bufferSize) 362094332d3Sopenharmony_ci{ 363094332d3Sopenharmony_ci if (bufferCount <= 0 || bufferSize <= 0) { 364094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 365094332d3Sopenharmony_ci } 366094332d3Sopenharmony_ci 367094332d3Sopenharmony_ci for (int i = 0; i < bufferCount; i++) { 368094332d3Sopenharmony_ci auto omxBuffer = std::make_shared<OmxCodecBuffer>(); 369094332d3Sopenharmony_ci omxBuffer->size = sizeof(OmxCodecBuffer); 370094332d3Sopenharmony_ci omxBuffer->version.s.nVersionMajor = 1; 371094332d3Sopenharmony_ci omxBuffer->bufferType = CODEC_BUFFER_TYPE_DYNAMIC_HANDLE; 372094332d3Sopenharmony_ci omxBuffer->bufferLen = 0; 373094332d3Sopenharmony_ci omxBuffer->buffer = nullptr; 374094332d3Sopenharmony_ci omxBuffer->allocLen = bufferSize; 375094332d3Sopenharmony_ci omxBuffer->fenceFd = -1; 376094332d3Sopenharmony_ci omxBuffer->pts = 0; 377094332d3Sopenharmony_ci omxBuffer->flag = 0; 378094332d3Sopenharmony_ci 379094332d3Sopenharmony_ci auto err = client_->UseBuffer(client_, static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT), omxBuffer.get()); 380094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 381094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to UseBuffer with PORT_INDEX_INPUT", __func__); 382094332d3Sopenharmony_ci return err; 383094332d3Sopenharmony_ci } 384094332d3Sopenharmony_ci 385094332d3Sopenharmony_ci omxBuffer->bufferLen = 0; 386094332d3Sopenharmony_ci HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); 387094332d3Sopenharmony_ci 388094332d3Sopenharmony_ci auto bufferInfo = std::make_shared<BufferInfo>(); 389094332d3Sopenharmony_ci bufferInfo->omxBuffer = omxBuffer; 390094332d3Sopenharmony_ci bufferInfo->portIndex = PortIndex::PORT_INDEX_INPUT; 391094332d3Sopenharmony_ci omxBuffers_.insert(std::make_pair(omxBuffer->bufferId, bufferInfo)); 392094332d3Sopenharmony_ci unUsedInBuffers_.push_back(omxBuffer->bufferId); 393094332d3Sopenharmony_ci } 394094332d3Sopenharmony_ci return HDF_SUCCESS; 395094332d3Sopenharmony_ci} 396094332d3Sopenharmony_ci 397094332d3Sopenharmony_civoid CodecHdiEncode::FreeBuffers() 398094332d3Sopenharmony_ci{ 399094332d3Sopenharmony_ci // send command to loaded state 400094332d3Sopenharmony_ci (void)client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateLoaded, nullptr, 0); 401094332d3Sopenharmony_ci 402094332d3Sopenharmony_ci // All the buffer must be released, otherwise the component will wait 403094332d3Sopenharmony_ci auto iter = omxBuffers_.begin(); 404094332d3Sopenharmony_ci while (iter != omxBuffers_.end()) { 405094332d3Sopenharmony_ci auto bufferInfo = iter->second; 406094332d3Sopenharmony_ci (void)client_->FreeBuffer(client_, static_cast<uint32_t>(bufferInfo->portIndex), bufferInfo->omxBuffer.get()); 407094332d3Sopenharmony_ci iter = omxBuffers_.erase(iter); 408094332d3Sopenharmony_ci } 409094332d3Sopenharmony_ci unUsedInBuffers_.clear(); 410094332d3Sopenharmony_ci unUsedOutBuffers_.clear(); 411094332d3Sopenharmony_ci 412094332d3Sopenharmony_ci // wait loaded 413094332d3Sopenharmony_ci OMX_STATETYPE status = OMX_StateLoaded; 414094332d3Sopenharmony_ci int32_t tryCount = MAX_WAIT_COUNT; 415094332d3Sopenharmony_ci do { 416094332d3Sopenharmony_ci int32_t err = client_->GetState(client_, &status); 417094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 418094332d3Sopenharmony_ci HDF_LOGE("%s GetState error [%{public}x]", __func__, err); 419094332d3Sopenharmony_ci break; 420094332d3Sopenharmony_ci } 421094332d3Sopenharmony_ci if (status != OMX_StateLoaded) { 422094332d3Sopenharmony_ci HDF_LOGI("Wait for OMX_StateLoaded status"); 423094332d3Sopenharmony_ci this->WaitForStatusChanged(); 424094332d3Sopenharmony_ci } 425094332d3Sopenharmony_ci tryCount--; 426094332d3Sopenharmony_ci } while ((status != OMX_StateLoaded) && (tryCount > 0)); 427094332d3Sopenharmony_ci} 428094332d3Sopenharmony_ci 429094332d3Sopenharmony_civoid CodecHdiEncode::Release() 430094332d3Sopenharmony_ci{ 431094332d3Sopenharmony_ci omxMgr_->DestroyComponent(componentId_); 432094332d3Sopenharmony_ci CodecComponentTypeRelease(client_); 433094332d3Sopenharmony_ci client_ = nullptr; 434094332d3Sopenharmony_ci CodecComponentManagerRelease(); 435094332d3Sopenharmony_ci} 436094332d3Sopenharmony_ci 437094332d3Sopenharmony_cibool CodecHdiEncode::FillAllTheBuffer() 438094332d3Sopenharmony_ci{ 439094332d3Sopenharmony_ci for (auto bufferId : unUsedOutBuffers_) { 440094332d3Sopenharmony_ci HDF_LOGI("fill bufferid [%{public}d]", bufferId); 441094332d3Sopenharmony_ci auto iter = omxBuffers_.find(bufferId); 442094332d3Sopenharmony_ci if (iter != omxBuffers_.end()) { 443094332d3Sopenharmony_ci auto bufferInfo = iter->second; 444094332d3Sopenharmony_ci auto err = client_->FillThisBuffer(client_, bufferInfo->omxBuffer.get()); 445094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 446094332d3Sopenharmony_ci HDF_LOGE("%{public}s FillThisBuffer error", __func__); 447094332d3Sopenharmony_ci return false; 448094332d3Sopenharmony_ci } 449094332d3Sopenharmony_ci } 450094332d3Sopenharmony_ci } 451094332d3Sopenharmony_ci return true; 452094332d3Sopenharmony_ci} 453094332d3Sopenharmony_ci 454094332d3Sopenharmony_ciint CodecHdiEncode::GetFreeBufferId() 455094332d3Sopenharmony_ci{ 456094332d3Sopenharmony_ci int bufferID = -1; 457094332d3Sopenharmony_ci unique_lock<mutex> ulk(lockInputBuffers_); 458094332d3Sopenharmony_ci size_t nSize = this->unUsedInBuffers_.size(); 459094332d3Sopenharmony_ci if (nSize > 0) { 460094332d3Sopenharmony_ci bufferID = unUsedInBuffers_.front(); 461094332d3Sopenharmony_ci unUsedInBuffers_.pop_front(); 462094332d3Sopenharmony_ci } 463094332d3Sopenharmony_ci return bufferID; 464094332d3Sopenharmony_ci} 465094332d3Sopenharmony_ci 466094332d3Sopenharmony_civoid CodecHdiEncode::Run() 467094332d3Sopenharmony_ci{ 468094332d3Sopenharmony_ci auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateExecuting, NULL, 0); 469094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 470094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__); 471094332d3Sopenharmony_ci return; 472094332d3Sopenharmony_ci } 473094332d3Sopenharmony_ci auto t1 = std::chrono::system_clock::now(); 474094332d3Sopenharmony_ci if (!FillAllTheBuffer()) { 475094332d3Sopenharmony_ci HDF_LOGE("%{public}s FillAllTheBuffer error", __func__); 476094332d3Sopenharmony_ci return; 477094332d3Sopenharmony_ci } 478094332d3Sopenharmony_ci bool endFlag = false; 479094332d3Sopenharmony_ci while (!endFlag) { 480094332d3Sopenharmony_ci int bufferID = GetFreeBufferId(); 481094332d3Sopenharmony_ci if (this->exit_) { 482094332d3Sopenharmony_ci break; 483094332d3Sopenharmony_ci } 484094332d3Sopenharmony_ci if (bufferID < 0) { 485094332d3Sopenharmony_ci usleep(10000); // 10000: sleep time 10ms 486094332d3Sopenharmony_ci continue; 487094332d3Sopenharmony_ci } 488094332d3Sopenharmony_ci auto iter = omxBuffers_.find(bufferID); 489094332d3Sopenharmony_ci if (iter == omxBuffers_.end()) { 490094332d3Sopenharmony_ci continue; 491094332d3Sopenharmony_ci } 492094332d3Sopenharmony_ci auto bufferInfo = iter->second; 493094332d3Sopenharmony_ci if (!FillCodecBuffer(bufferInfo, endFlag)) { 494094332d3Sopenharmony_ci break; 495094332d3Sopenharmony_ci } 496094332d3Sopenharmony_ci err = client_->EmptyThisBuffer(client_, bufferInfo->omxBuffer.get()); 497094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 498094332d3Sopenharmony_ci HDF_LOGE("%{public}s EmptyThisBuffer error", __func__); 499094332d3Sopenharmony_ci return; 500094332d3Sopenharmony_ci } 501094332d3Sopenharmony_ci } 502094332d3Sopenharmony_ci while (!this->exit_) { 503094332d3Sopenharmony_ci usleep(10000); // 10000: sleep time 10ms 504094332d3Sopenharmony_ci } 505094332d3Sopenharmony_ci (void)client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0); 506094332d3Sopenharmony_ci auto t2 = std::chrono::system_clock::now(); 507094332d3Sopenharmony_ci std::chrono::duration<double> diff = t2 - t1; 508094332d3Sopenharmony_ci HDF_LOGI("encoder costtime %{public}f, count=%{public}d", diff.count(), count_); 509094332d3Sopenharmony_ci return; 510094332d3Sopenharmony_ci} 511094332d3Sopenharmony_ci 512094332d3Sopenharmony_cibool CodecHdiEncode::FillCodecBuffer(std::shared_ptr<BufferInfo> bufferInfo, bool &endFlag) 513094332d3Sopenharmony_ci{ 514094332d3Sopenharmony_ci if (buffer_ == nullptr) { 515094332d3Sopenharmony_ci HDF_LOGE("%{public}s buffer_ is null", __func__); 516094332d3Sopenharmony_ci return false; 517094332d3Sopenharmony_ci } 518094332d3Sopenharmony_ci if (useBufferHandle_) { 519094332d3Sopenharmony_ci int bufferHandleId = freeBufferHandles_.front(); 520094332d3Sopenharmony_ci if (bufferHandleId < 0 || bufferHandleId >= BUFFER_COUNT) { 521094332d3Sopenharmony_ci HDF_LOGE("%{public}s bufferHandleId [%{public}d]", __func__, bufferHandleId); 522094332d3Sopenharmony_ci return false; 523094332d3Sopenharmony_ci } 524094332d3Sopenharmony_ci freeBufferHandles_.pop_front(); 525094332d3Sopenharmony_ci bufferInfo->bufferHandleId = bufferHandleId; 526094332d3Sopenharmony_ci BufferHandle *bufferHandle = bufferHandles_[bufferHandleId]; 527094332d3Sopenharmony_ci if (bufferHandle != nullptr) { 528094332d3Sopenharmony_ci buffer_->Mmap(*bufferHandle); 529094332d3Sopenharmony_ci endFlag = 530094332d3Sopenharmony_ci this->ReadOneFrame(reinterpret_cast<char *>(bufferHandle->virAddr), bufferInfo->omxBuffer->filledLen); 531094332d3Sopenharmony_ci bufferInfo->omxBuffer->filledLen = bufferHandle->stride * bufferHandle->height; 532094332d3Sopenharmony_ci buffer_->Unmap(*bufferHandle); 533094332d3Sopenharmony_ci bufferInfo->omxBuffer->buffer = reinterpret_cast<uint8_t *>(bufferHandle); 534094332d3Sopenharmony_ci bufferInfo->omxBuffer->bufferLen = 535094332d3Sopenharmony_ci sizeof(BufferHandle) + sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts); 536094332d3Sopenharmony_ci } 537094332d3Sopenharmony_ci } else { 538094332d3Sopenharmony_ci // read data from ashmem 539094332d3Sopenharmony_ci void *sharedAddr = const_cast<void *>(bufferInfo->avSharedPtr->ReadFromAshmem(0, 0)); 540094332d3Sopenharmony_ci endFlag = this->ReadOneFrame(reinterpret_cast<char *>(sharedAddr), bufferInfo->omxBuffer->filledLen); 541094332d3Sopenharmony_ci } 542094332d3Sopenharmony_ci bufferInfo->omxBuffer->offset = 0; 543094332d3Sopenharmony_ci if (endFlag) { 544094332d3Sopenharmony_ci bufferInfo->omxBuffer->flag = OMX_BUFFERFLAG_EOS; 545094332d3Sopenharmony_ci } 546094332d3Sopenharmony_ci 547094332d3Sopenharmony_ci return true; 548094332d3Sopenharmony_ci} 549094332d3Sopenharmony_ci 550094332d3Sopenharmony_ciint32_t CodecHdiEncode::CreateBufferHandle() 551094332d3Sopenharmony_ci{ 552094332d3Sopenharmony_ci if (buffer_ == nullptr) { 553094332d3Sopenharmony_ci HDF_LOGE("%{public}s buffer_ is null", __func__); 554094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 555094332d3Sopenharmony_ci } 556094332d3Sopenharmony_ci PixelFormat pixForamt = PIXEL_FMT_YCBCR_420_SP; 557094332d3Sopenharmony_ci if (color_ == ColorFormat::RGBA8888) { 558094332d3Sopenharmony_ci pixForamt = PIXEL_FMT_RGBA_8888; 559094332d3Sopenharmony_ci } else if (color_ == ColorFormat::BGRA8888) { 560094332d3Sopenharmony_ci pixForamt = PIXEL_FMT_BGRA_8888; 561094332d3Sopenharmony_ci } 562094332d3Sopenharmony_ci 563094332d3Sopenharmony_ci AllocInfo alloc = {.width = this->stride_, 564094332d3Sopenharmony_ci .height = this->height_, 565094332d3Sopenharmony_ci .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, 566094332d3Sopenharmony_ci .format = pixForamt}; 567094332d3Sopenharmony_ci 568094332d3Sopenharmony_ci int32_t err = HDF_SUCCESS; 569094332d3Sopenharmony_ci for (size_t i = 0; i < BUFFER_COUNT; i++) { 570094332d3Sopenharmony_ci BufferHandle *bufferHandle = nullptr; 571094332d3Sopenharmony_ci err = buffer_->AllocMem(alloc, bufferHandle); 572094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 573094332d3Sopenharmony_ci HDF_LOGE("%{public}s AllocMem fail", __func__); 574094332d3Sopenharmony_ci return err; 575094332d3Sopenharmony_ci } 576094332d3Sopenharmony_ci bufferHandles_.emplace(std::make_pair(i, bufferHandle)); 577094332d3Sopenharmony_ci freeBufferHandles_.push_back(i); 578094332d3Sopenharmony_ci } 579094332d3Sopenharmony_ci return err; 580094332d3Sopenharmony_ci} 581094332d3Sopenharmony_ci 582094332d3Sopenharmony_ciint32_t CodecHdiEncode::OnEvent(struct CodecCallbackType *self, enum OMX_EVENTTYPE event, struct EventInfo *info) 583094332d3Sopenharmony_ci{ 584094332d3Sopenharmony_ci HDF_LOGI("OnEvent: pAppData[%{public} " PRId64 "], eEvent [%{public}d], nData1[%{public}d]", info->appData, event, 585094332d3Sopenharmony_ci info->data1); 586094332d3Sopenharmony_ci if (event == OMX_EventCmdComplete) { 587094332d3Sopenharmony_ci OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(info->data1); 588094332d3Sopenharmony_ci if (OMX_CommandStateSet == cmd) { 589094332d3Sopenharmony_ci HDF_LOGI("OMX_CommandStateSet reached"); 590094332d3Sopenharmony_ci g_core->OnStatusChanged(); 591094332d3Sopenharmony_ci } 592094332d3Sopenharmony_ci } 593094332d3Sopenharmony_ci return HDF_SUCCESS; 594094332d3Sopenharmony_ci} 595094332d3Sopenharmony_ci 596094332d3Sopenharmony_ciint32_t CodecHdiEncode::OnEmptyBufferDone(struct CodecCallbackType *self, int64_t appData, 597094332d3Sopenharmony_ci const struct OmxCodecBuffer *buffer) 598094332d3Sopenharmony_ci{ 599094332d3Sopenharmony_ci HDF_LOGI("OnEmptyBufferDone: pBuffer.bufferID [%{public}d]", buffer->bufferId); 600094332d3Sopenharmony_ci return g_core->OnEmptyBufferDone(*buffer); 601094332d3Sopenharmony_ci} 602094332d3Sopenharmony_ci 603094332d3Sopenharmony_ciint32_t CodecHdiEncode::OnFillBufferDone(struct CodecCallbackType *self, int64_t appData, 604094332d3Sopenharmony_ci const struct OmxCodecBuffer *buffer) 605094332d3Sopenharmony_ci{ 606094332d3Sopenharmony_ci HDF_LOGI("OnFillBufferDone: pBuffer.bufferID [%{public}d]", buffer->bufferId); 607094332d3Sopenharmony_ci return g_core->OnFillBufferDone(*buffer); 608094332d3Sopenharmony_ci} 609094332d3Sopenharmony_ci 610094332d3Sopenharmony_ciuint32_t CodecHdiEncode::GetInputBufferSize() 611094332d3Sopenharmony_ci{ 612094332d3Sopenharmony_ci if (color_ == ColorFormat::YUV420SP) { 613094332d3Sopenharmony_ci return (width_ * height_ * 3 / 2); // 3:byte alignment, 2:byte alignment 614094332d3Sopenharmony_ci } else { 615094332d3Sopenharmony_ci return (width_ * height_ * 4); // 4: byte alignment for RGBA or BGRA 616094332d3Sopenharmony_ci } 617094332d3Sopenharmony_ci} 618094332d3Sopenharmony_ci 619094332d3Sopenharmony_ciint32_t CodecHdiEncode::OnEmptyBufferDone(const struct OmxCodecBuffer &buffer) 620094332d3Sopenharmony_ci{ 621094332d3Sopenharmony_ci unique_lock<mutex> ulk(lockInputBuffers_); 622094332d3Sopenharmony_ci unUsedInBuffers_.push_back(buffer.bufferId); 623094332d3Sopenharmony_ci if (useBufferHandle_) { 624094332d3Sopenharmony_ci auto bufferInfo = omxBuffers_[buffer.bufferId]; 625094332d3Sopenharmony_ci freeBufferHandles_.push_back(bufferInfo->bufferHandleId); 626094332d3Sopenharmony_ci } 627094332d3Sopenharmony_ci 628094332d3Sopenharmony_ci return HDF_SUCCESS; 629094332d3Sopenharmony_ci} 630094332d3Sopenharmony_ci 631094332d3Sopenharmony_ciint32_t CodecHdiEncode::OnFillBufferDone(const struct OmxCodecBuffer &buffer) 632094332d3Sopenharmony_ci{ 633094332d3Sopenharmony_ci if (exit_) { 634094332d3Sopenharmony_ci return HDF_SUCCESS; 635094332d3Sopenharmony_ci } 636094332d3Sopenharmony_ci 637094332d3Sopenharmony_ci auto iter = omxBuffers_.find(buffer.bufferId); 638094332d3Sopenharmony_ci if (iter == omxBuffers_.end() || !iter->second) { 639094332d3Sopenharmony_ci return HDF_SUCCESS; 640094332d3Sopenharmony_ci } 641094332d3Sopenharmony_ci 642094332d3Sopenharmony_ci auto bufferInfo = iter->second; 643094332d3Sopenharmony_ci void *addr = const_cast<void *>(bufferInfo->avSharedPtr->ReadFromAshmem(buffer.filledLen, buffer.offset)); 644094332d3Sopenharmony_ci // save to file 645094332d3Sopenharmony_ci ioOut_.write(static_cast<char *>(addr), buffer.filledLen); 646094332d3Sopenharmony_ci ioOut_.flush(); 647094332d3Sopenharmony_ci count_++; 648094332d3Sopenharmony_ci if ((buffer.flag & static_cast<uint32_t>(OMX_BUFFERFLAG_EOS)) != 0) { 649094332d3Sopenharmony_ci exit_ = true; 650094332d3Sopenharmony_ci HDF_LOGI("OnFillBufferDone the END coming"); 651094332d3Sopenharmony_ci return HDF_SUCCESS; 652094332d3Sopenharmony_ci } 653094332d3Sopenharmony_ci auto err = client_->FillThisBuffer(client_, bufferInfo->omxBuffer.get()); 654094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 655094332d3Sopenharmony_ci HDF_LOGE("FillThisBuffer error"); 656094332d3Sopenharmony_ci return HDF_SUCCESS; 657094332d3Sopenharmony_ci } 658094332d3Sopenharmony_ci return HDF_SUCCESS; 659094332d3Sopenharmony_ci} 660094332d3Sopenharmony_ci 661094332d3Sopenharmony_ciint32_t CodecHdiEncode::ConfigPortDefine() 662094332d3Sopenharmony_ci{ 663094332d3Sopenharmony_ci OMX_PARAM_PORTDEFINITIONTYPE param; 664094332d3Sopenharmony_ci InitParam(param); 665094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_INPUT); 666094332d3Sopenharmony_ci auto err = 667094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 668094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 669094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to GetParameter with PORT_INDEX_INPUT, index is OMX_IndexParamPortDefinition", 670094332d3Sopenharmony_ci __func__); 671094332d3Sopenharmony_ci return err; 672094332d3Sopenharmony_ci } 673094332d3Sopenharmony_ci HDF_LOGI("PORT_INDEX_INPUT: eCompressionFormat = %{public}d, eColorFormat=%{public}d", 674094332d3Sopenharmony_ci param.format.video.eCompressionFormat, param.format.video.eColorFormat); 675094332d3Sopenharmony_ci param.format.video.nFrameWidth = width_; 676094332d3Sopenharmony_ci param.format.video.nFrameHeight = height_; 677094332d3Sopenharmony_ci param.format.video.nStride = stride_; 678094332d3Sopenharmony_ci param.format.video.nSliceHeight = height_; 679094332d3Sopenharmony_ci 680094332d3Sopenharmony_ci param.format.video.eColorFormat = omxColorFormat_; 681094332d3Sopenharmony_ci err = 682094332d3Sopenharmony_ci client_->SetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 683094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 684094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SetParameter with PORT_INDEX_INPUT, index is OMX_IndexParamPortDefinition", 685094332d3Sopenharmony_ci __func__); 686094332d3Sopenharmony_ci return err; 687094332d3Sopenharmony_ci } 688094332d3Sopenharmony_ci 689094332d3Sopenharmony_ci InitParam(param); 690094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 691094332d3Sopenharmony_ci err = 692094332d3Sopenharmony_ci client_->GetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 693094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 694094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to GetParameter with PORT_INDEX_OUTPUT, index is OMX_IndexParamPortDefinition", 695094332d3Sopenharmony_ci __func__); 696094332d3Sopenharmony_ci return err; 697094332d3Sopenharmony_ci } 698094332d3Sopenharmony_ci HDF_LOGI("PORT_INDEX_OUTPUT eCompressionFormat = %{public}d, eColorFormat=%{public}d", 699094332d3Sopenharmony_ci param.format.video.eCompressionFormat, param.format.video.eColorFormat); 700094332d3Sopenharmony_ci param.format.video.nFrameWidth = width_; 701094332d3Sopenharmony_ci param.format.video.nFrameHeight = height_; 702094332d3Sopenharmony_ci param.format.video.nStride = stride_; 703094332d3Sopenharmony_ci param.format.video.nSliceHeight = height_; 704094332d3Sopenharmony_ci err = 705094332d3Sopenharmony_ci client_->SetParameter(client_, OMX_IndexParamPortDefinition, reinterpret_cast<int8_t *>(¶m), sizeof(param)); 706094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 707094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SetParameter with PORT_INDEX_OUTPUT, index is OMX_IndexParamPortDefinition", 708094332d3Sopenharmony_ci __func__); 709094332d3Sopenharmony_ci return err; 710094332d3Sopenharmony_ci } 711094332d3Sopenharmony_ci return HDF_SUCCESS; 712094332d3Sopenharmony_ci} 713094332d3Sopenharmony_ciint32_t CodecHdiEncode::GetComponent() 714094332d3Sopenharmony_ci{ 715094332d3Sopenharmony_ci int32_t count = omxMgr_->GetComponentNum(); 716094332d3Sopenharmony_ci if (count <= 0) { 717094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetComponentNum ret %{public}d", __func__, count); 718094332d3Sopenharmony_ci return HDF_FAILURE; 719094332d3Sopenharmony_ci } 720094332d3Sopenharmony_ci auto caps = std::make_unique<CodecCompCapability[]>(count); 721094332d3Sopenharmony_ci auto err = omxMgr_->GetComponentCapabilityList(caps.get(), count); 722094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 723094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetComponentCapabilityList ret %{public}d", __func__, err); 724094332d3Sopenharmony_ci return err; 725094332d3Sopenharmony_ci } 726094332d3Sopenharmony_ci std::string compName(""); 727094332d3Sopenharmony_ci for (int32_t i = 0; i < count; i++) { 728094332d3Sopenharmony_ci if (caps[i].type != VIDEO_ENCODER) { 729094332d3Sopenharmony_ci continue; 730094332d3Sopenharmony_ci } 731094332d3Sopenharmony_ci if (((caps[i].role == MEDIA_ROLETYPE_VIDEO_AVC) && (codecMime_ == CodecMime::AVC)) || 732094332d3Sopenharmony_ci ((caps[i].role == MEDIA_ROLETYPE_VIDEO_HEVC) && (codecMime_ == CodecMime::HEVC))) { 733094332d3Sopenharmony_ci compName = caps[i].compName; 734094332d3Sopenharmony_ci break; 735094332d3Sopenharmony_ci } 736094332d3Sopenharmony_ci } 737094332d3Sopenharmony_ci if (compName.empty()) { 738094332d3Sopenharmony_ci HDF_LOGE("%{public}s: role is unexpected ", __func__); 739094332d3Sopenharmony_ci return HDF_FAILURE; 740094332d3Sopenharmony_ci } 741094332d3Sopenharmony_ci return omxMgr_->CreateComponent(&client_, &componentId_, compName.data(), reinterpret_cast<int64_t>(this), 742094332d3Sopenharmony_ci callback_); 743094332d3Sopenharmony_ci} 744094332d3Sopenharmony_ci 745094332d3Sopenharmony_ciOMX_VIDEO_CODINGTYPE CodecHdiEncode::GetCompressFormat() 746094332d3Sopenharmony_ci{ 747094332d3Sopenharmony_ci OMX_VIDEO_CODINGTYPE compressFmt = OMX_VIDEO_CodingAVC; 748094332d3Sopenharmony_ci switch (codecMime_) { 749094332d3Sopenharmony_ci case CodecMime::AVC: 750094332d3Sopenharmony_ci compressFmt = OMX_VIDEO_CodingAVC; 751094332d3Sopenharmony_ci break; 752094332d3Sopenharmony_ci case CodecMime::HEVC: 753094332d3Sopenharmony_ci compressFmt = (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingHEVC; 754094332d3Sopenharmony_ci break; 755094332d3Sopenharmony_ci case CodecMime::MPEG4: 756094332d3Sopenharmony_ci compressFmt = OMX_VIDEO_CodingMPEG4; 757094332d3Sopenharmony_ci break; 758094332d3Sopenharmony_ci case CodecMime::VP9: 759094332d3Sopenharmony_ci compressFmt = (OMX_VIDEO_CODINGTYPE)CODEC_OMX_VIDEO_CodingVP9; 760094332d3Sopenharmony_ci break; 761094332d3Sopenharmony_ci default: 762094332d3Sopenharmony_ci break; 763094332d3Sopenharmony_ci } 764094332d3Sopenharmony_ci return compressFmt; 765094332d3Sopenharmony_ci} 766094332d3Sopenharmony_ciint32_t CodecHdiEncode::ConfigBitMode() 767094332d3Sopenharmony_ci{ 768094332d3Sopenharmony_ci OMX_VIDEO_PARAM_PORTFORMATTYPE param; 769094332d3Sopenharmony_ci InitParam(param); 770094332d3Sopenharmony_ci param.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 771094332d3Sopenharmony_ci auto err = client_->GetParameter(client_, OMX_IndexParamVideoPortFormat, reinterpret_cast<int8_t *>(¶m), 772094332d3Sopenharmony_ci sizeof(param)); 773094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 774094332d3Sopenharmony_ci HDF_LOGE("failed to GetParameter with PORT_INDEX_OUTPUT, index is OMX_IndexParamVideoPortFormat"); 775094332d3Sopenharmony_ci return err; 776094332d3Sopenharmony_ci } 777094332d3Sopenharmony_ci HDF_LOGI("set Format PORT_INDEX_INPUT eCompressionFormat = %{public}d, eColorFormat=%{public}d", 778094332d3Sopenharmony_ci param.eCompressionFormat, param.eColorFormat); 779094332d3Sopenharmony_ci param.xFramerate = FRAME; 780094332d3Sopenharmony_ci param.eCompressionFormat = GetCompressFormat(); 781094332d3Sopenharmony_ci err = client_->SetParameter(client_, OMX_IndexParamVideoPortFormat, reinterpret_cast<int8_t *>(¶m), 782094332d3Sopenharmony_ci sizeof(param)); 783094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 784094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SetParameter with PORT_INDEX_INPUT, index is OMX_IndexParamVideoPortFormat", 785094332d3Sopenharmony_ci __func__); 786094332d3Sopenharmony_ci return err; 787094332d3Sopenharmony_ci } 788094332d3Sopenharmony_ci 789094332d3Sopenharmony_ci OMX_VIDEO_PARAM_BITRATETYPE biteType; 790094332d3Sopenharmony_ci InitParam(biteType); 791094332d3Sopenharmony_ci biteType.nPortIndex = static_cast<uint32_t>(PortIndex::PORT_INDEX_OUTPUT); 792094332d3Sopenharmony_ci err = client_->GetParameter(client_, OMX_IndexParamVideoBitrate, reinterpret_cast<int8_t *>(&biteType), 793094332d3Sopenharmony_ci sizeof(biteType)); 794094332d3Sopenharmony_ci if (err != OMX_ErrorNone) { 795094332d3Sopenharmony_ci HDF_LOGE("%{public}s OMX_GetParameter portindex = PORT_INDEX_OUTPUT, err[%{public}d]", __func__, err); 796094332d3Sopenharmony_ci return err; 797094332d3Sopenharmony_ci } 798094332d3Sopenharmony_ci HDF_LOGI("get PORT_INDEX_OUTPUT:OMX_IndexParamVideoBitrate, bit_mode[%{public}d], biterate:[%{publicd}d]", 799094332d3Sopenharmony_ci biteType.eControlRate, biteType.nTargetBitrate); 800094332d3Sopenharmony_ci 801094332d3Sopenharmony_ci biteType.eControlRate = OMX_Video_ControlRateConstant; 802094332d3Sopenharmony_ci biteType.nTargetBitrate = BITRATE; 803094332d3Sopenharmony_ci err = client_->SetParameter(client_, OMX_IndexParamVideoBitrate, reinterpret_cast<int8_t *>(&biteType), 804094332d3Sopenharmony_ci sizeof(biteType)); 805094332d3Sopenharmony_ci if (err != HDF_SUCCESS) { 806094332d3Sopenharmony_ci HDF_LOGE("%{public}s failed to SetParameter with PORT_INDEX_OUTPUT, index is OMX_IndexParamVideoPortFormat", 807094332d3Sopenharmony_ci __func__); 808094332d3Sopenharmony_ci return err; 809094332d3Sopenharmony_ci } 810094332d3Sopenharmony_ci return HDF_SUCCESS; 811094332d3Sopenharmony_ci} 812094332d3Sopenharmony_ci 813094332d3Sopenharmony_ciint main(int argc, char *argv[]) 814094332d3Sopenharmony_ci{ 815094332d3Sopenharmony_ci CommandOpt opt; 816094332d3Sopenharmony_ci CommandParse parse; 817094332d3Sopenharmony_ci if (!parse.Parse(argc, argv, opt)) { 818094332d3Sopenharmony_ci return 0; 819094332d3Sopenharmony_ci } 820094332d3Sopenharmony_ci 821094332d3Sopenharmony_ci if (g_core == nullptr) { 822094332d3Sopenharmony_ci g_core = new CodecHdiEncode(); 823094332d3Sopenharmony_ci } 824094332d3Sopenharmony_ci 825094332d3Sopenharmony_ci if (!g_core->Init(opt)) { 826094332d3Sopenharmony_ci delete g_core; 827094332d3Sopenharmony_ci g_core = nullptr; 828094332d3Sopenharmony_ci return HDF_FAILURE; 829094332d3Sopenharmony_ci } 830094332d3Sopenharmony_ci 831094332d3Sopenharmony_ci if (!g_core->Configure()) { 832094332d3Sopenharmony_ci delete g_core; 833094332d3Sopenharmony_ci g_core = nullptr; 834094332d3Sopenharmony_ci return HDF_FAILURE; 835094332d3Sopenharmony_ci } 836094332d3Sopenharmony_ci 837094332d3Sopenharmony_ci if (!g_core->UseBuffers()) { 838094332d3Sopenharmony_ci delete g_core; 839094332d3Sopenharmony_ci g_core = nullptr; 840094332d3Sopenharmony_ci return HDF_FAILURE; 841094332d3Sopenharmony_ci } 842094332d3Sopenharmony_ci 843094332d3Sopenharmony_ci g_core->Run(); 844094332d3Sopenharmony_ci 845094332d3Sopenharmony_ci g_core->FreeBuffers(); 846094332d3Sopenharmony_ci 847094332d3Sopenharmony_ci g_core->Release(); 848094332d3Sopenharmony_ci delete g_core; 849094332d3Sopenharmony_ci g_core = nullptr; 850094332d3Sopenharmony_ci}