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 *>(&param),
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 *>(&param),
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 *>(&param), 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 *>(&param),
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 *>(&param), 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 *>(&param), 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 *>(&param), 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 *>(&param), 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 *>(&param),
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 *>(&param),
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}