1 /*
2  * Copyright (c) 2022-2023 Shenzhen Kaihong DID Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "codec_component_service.h"
17 #include <hdf_base.h>
18 #include <hdf_remote_service.h>
19 #include <securec.h>
20 #include <malloc.h>
21 #include <unistd.h>
22 #include <hitrace_meter.h>
23 #include "codec_log_wrapper.h"
24 
25 #define AUDIO_CODEC_NAME "OMX.audio"
26 
27 namespace OHOS {
28 namespace HDI {
29 namespace Codec {
30 namespace V3_0 {
31 
32 std::mutex g_mapperMtx;
33 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> g_mapperService;
34 
GetMapperService()35 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> GetMapperService()
36 {
37     std::lock_guard<std::mutex> lk(g_mapperMtx);
38     if (g_mapperService) {
39         return g_mapperService;
40     }
41     g_mapperService = OHOS::HDI::Display::Buffer::V1_0::IMapper::Get(true);
42     if (g_mapperService) {
43         CODEC_LOGI("get IMapper succ");
44         return g_mapperService;
45     }
46     CODEC_LOGE("get IMapper failed");
47     return nullptr;
48 }
49 
CodecComponentService(const std::shared_ptr<OHOS::Codec::Omx::ComponentNode> & node,const std::shared_ptr<OHOS::Codec::Omx::ComponentMgr> mgr,const std::string name)50 CodecComponentService::CodecComponentService(const std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &node,
51     const std::shared_ptr<OHOS::Codec::Omx::ComponentMgr> mgr, const std::string name)
52 {
53     name_ = name;
54     node_ = node;
55     mgr_  = mgr;
56     isIPCMode_ = (HdfRemoteGetCallingPid() == getpid() ? false : true);
57 #ifdef SUPPORT_ROLE
58     SetComponentRole();
59 #endif
60 }
~CodecComponentService()61 CodecComponentService::~CodecComponentService()
62 {
63     if (node_ != nullptr) {
64         node_->ReleaseOMXResource();
65         int32_t ret = node_->CloseHandle();
66         if (ret != HDF_SUCCESS) {
67             CODEC_LOGE("CloseHandle failed, err[%{public}d]", ret);
68         }
69         node_ = nullptr;
70         ReleaseCache();
71     }
72     name_ = "";
73     mgr_ = nullptr;
74 }
75 
ReleaseCache()76 void CodecComponentService::ReleaseCache()
77 {
78 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
79     mallopt(M_FLUSH_THREAD_CACHE, 0);
80 #endif
81 }
82 
GetComponentVersion(CompVerInfo & verInfo)83 int32_t CodecComponentService::GetComponentVersion(CompVerInfo &verInfo)
84 {
85     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetComponentVersion");
86     return node_->GetComponentVersion(verInfo);
87 }
88 
SendCommand(CodecCommandType cmd,uint32_t param,const std::vector<int8_t> & cmdData)89 int32_t CodecComponentService::SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t> &cmdData)
90 {
91     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSendCommand");
92     CODEC_LOGI("commandType: [%{public}d], command [%{public}d]", cmd, param);
93     return node_->SendCommand(cmd, param, const_cast<int8_t *>(cmdData.data()));
94 }
95 
GetParameter(uint32_t index,const std::vector<int8_t> & inParamStruct,std::vector<int8_t> & outParamStruct)96 int32_t CodecComponentService::GetParameter(uint32_t index, const std::vector<int8_t> &inParamStruct,
97                                             std::vector<int8_t> &outParamStruct)
98 {
99     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetParameter");
100     CODEC_LOGD("index [%{public}x]", index);
101     outParamStruct = inParamStruct;
102     return node_->GetParameter(static_cast<enum OMX_INDEXTYPE>(index), outParamStruct.data());
103 }
104 
SetParameter(uint32_t index,const std::vector<int8_t> & paramStruct)105 int32_t CodecComponentService::SetParameter(uint32_t index, const std::vector<int8_t> &paramStruct)
106 {
107     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetParameter");
108     CODEC_LOGD("index [%{public}x]", index);
109     return node_->SetParameter(static_cast<enum OMX_INDEXTYPE>(index), paramStruct.data());
110 }
111 
GetConfig(uint32_t index,const std::vector<int8_t> & inCfgStruct,std::vector<int8_t> & outCfgStruct)112 int32_t CodecComponentService::GetConfig(uint32_t index, const std::vector<int8_t> &inCfgStruct,
113                                          std::vector<int8_t> &outCfgStruct)
114 {
115     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetConfig");
116     CODEC_LOGD("index [%{public}x]", index);
117     outCfgStruct = inCfgStruct;
118     return node_->GetConfig(static_cast<enum OMX_INDEXTYPE>(index), outCfgStruct.data());
119 }
120 
SetConfig(uint32_t index,const std::vector<int8_t> & cfgStruct)121 int32_t CodecComponentService::SetConfig(uint32_t index, const std::vector<int8_t> &cfgStruct)
122 {
123     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetConfig");
124     CODEC_LOGD("index [%{public}x]", index);
125     return node_->SetConfig(static_cast<enum OMX_INDEXTYPE>(index), cfgStruct.data());
126 }
127 
GetExtensionIndex(const std::string & paramName,uint32_t & indexType)128 int32_t CodecComponentService::GetExtensionIndex(const std::string &paramName, uint32_t &indexType)
129 {
130     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetExtensionIndex");
131     CODEC_LOGI("paramName [%{public}s]", paramName.c_str());
132     return node_->GetExtensionIndex(paramName.c_str(), indexType);
133 }
134 
GetState(CodecStateType & state)135 int32_t CodecComponentService::GetState(CodecStateType &state)
136 {
137     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetState");
138     return node_->GetState(state);
139 }
140 
ComponentTunnelRequest(uint32_t port,int32_t tunneledComp,uint32_t tunneledPort,const CodecTunnelSetupType & inTunnelSetup,CodecTunnelSetupType & outTunnelSetup)141 int32_t CodecComponentService::ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort,
142                                                       const CodecTunnelSetupType &inTunnelSetup,
143                                                       CodecTunnelSetupType &outTunnelSetup)
144 {
145     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentTunnelRequest");
146     CODEC_LOGI("port [%{public}d]", port);
147     outTunnelSetup = inTunnelSetup;
148     return node_->ComponentTunnelRequest(port, tunneledComp, tunneledPort, outTunnelSetup);
149 }
150 
UseBuffer(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer)151 int32_t CodecComponentService::UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer)
152 {
153     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseBuffer");
154     CODEC_LOGD("portIndex: [%{public}d]", portIndex);
155     outBuffer = const_cast<OmxCodecBuffer &>(inBuffer);
156 
157     if (outBuffer.fd >= 0 && isIPCMode_ && outBuffer.bufferType != CODEC_BUFFER_TYPE_AVSHARE_MEM_FD &&
158         outBuffer.bufferType != CODEC_BUFFER_TYPE_DMA_MEM_FD &&
159         name_.find(AUDIO_CODEC_NAME) == std::string::npos) {
160         close(outBuffer.fd);
161         outBuffer.fd = -1;
162     }
163     if (outBuffer.fenceFd >= 0) {
164         close(outBuffer.fenceFd);
165         outBuffer.fenceFd = -1;
166     }
167 
168     return node_->UseBuffer(portIndex, outBuffer);
169 }
170 
AllocateBuffer(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer)171 int32_t CodecComponentService::AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
172                                               OmxCodecBuffer &outBuffer)
173 {
174     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecAllocateBuffer");
175     CODEC_LOGD("portIndex: [%{public}d]", portIndex);
176     outBuffer = inBuffer;
177     return node_->AllocateBuffer(portIndex, outBuffer);
178 }
179 
FreeBuffer(uint32_t portIndex,const OmxCodecBuffer & buffer)180 int32_t CodecComponentService::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer)
181 {
182     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFreeBuffer");
183     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
184     CODEC_LOGD("portIndex: [%{public}d], bufferId: [%{public}d]", portIndex, buffer.bufferId);
185     int32_t ret = node_->FreeBuffer(portIndex, buffer);
186     ReleaseCache();
187     if (isIPCMode_ && bufferTemp.fd >= 0) {
188         close(bufferTemp.fd);
189         bufferTemp.fd = -1;
190     }
191 
192     return ret;
193 }
194 
EmptyThisBuffer(const OmxCodecBuffer & buffer)195 int32_t CodecComponentService::EmptyThisBuffer(const OmxCodecBuffer &buffer)
196 {
197     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecEmptyThisBuffer");
198     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
199     int32_t ret = node_->EmptyThisBuffer(bufferTemp);
200     if (isIPCMode_ && bufferTemp.fd >= 0) {
201         close(bufferTemp.fd);
202         bufferTemp.fd = -1;
203     }
204 
205     return ret;
206 }
207 
FillThisBuffer(const OmxCodecBuffer & buffer)208 int32_t CodecComponentService::FillThisBuffer(const OmxCodecBuffer &buffer)
209 {
210     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFillThisBuffer");
211     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
212     int32_t ret = node_->FillThisBuffer(bufferTemp);
213     if (isIPCMode_ && bufferTemp.fd >= 0) {
214         close(bufferTemp.fd);
215         bufferTemp.fd = -1;
216     }
217 
218     return ret;
219 }
220 
SetCallbacks(const sptr<ICodecCallback> & callbacks,int64_t appData)221 int32_t CodecComponentService::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData)
222 {
223     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetCallbacks");
224     CODEC_LOGI("service impl!");
225     CHECK_AND_RETURN_RET_LOG(callbacks != nullptr, HDF_ERR_INVALID_PARAM, "callbacks is null");
226     return node_->SetCallbacks(callbacks, appData);
227 }
228 
ComponentDeInit()229 int32_t CodecComponentService::ComponentDeInit()
230 {
231     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentDeInit");
232     CODEC_LOGI("service impl!");
233     return node_->ComponentDeInit();
234 }
235 
UseEglImage(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer,const std::vector<int8_t> & eglImage)236 int32_t CodecComponentService::UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
237                                            OmxCodecBuffer &outBuffer, const std::vector<int8_t> &eglImage)
238 {
239     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseEglImage");
240     CODEC_LOGI("portIndex [%{public}d]", portIndex);
241     outBuffer = inBuffer;
242     return node_->UseEglImage(outBuffer, portIndex, eglImage.data());
243 }
244 
ComponentRoleEnum(std::vector<uint8_t> & role,uint32_t index)245 int32_t CodecComponentService::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index)
246 {
247     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentRoleEnum");
248     CODEC_LOGI("index [%{public}d]", index);
249     return node_->ComponentRoleEnum(role, index);
250 }
251 
SetComponentRole()252 void CodecComponentService::SetComponentRole()
253 {
254     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetComponentRole");
255     if (name_ == "") {
256         CODEC_LOGE("compName is null");
257         return;
258     }
259     OHOS::Codec::Omx::CodecOMXCore *core;
260     auto err = mgr_->GetCoreOfComponent(core, name_);
261     if (err != HDF_SUCCESS) {
262         CODEC_LOGE("core is null");
263         return;
264     }
265 
266     std::vector<std::string> roles;
267     int32_t ret = core->GetRolesOfComponent(name_, roles);
268     if (ret != HDF_SUCCESS) {
269         CODEC_LOGE("GetRoleOfComponent return err [%{public}d]", ret);
270         return;
271     }
272     uint32_t roleIndex = 0;
273     CODEC_LOGI("RoleName = [%{public}s]", roles[roleIndex].c_str());
274 
275     OMX_PARAM_COMPONENTROLETYPE role;
276     errno_t res = strncpy_s(reinterpret_cast<char *>(role.cRole), OMX_MAX_STRINGNAME_SIZE,
277                             roles[roleIndex].c_str(), roles[roleIndex].length());
278     if (res != EOK) {
279         CODEC_LOGE("strncpy_s return err [%{public}d]", err);
280         return;
281     }
282     role.nSize = sizeof(role);
283     ret = node_->SetParameter(OMX_IndexParamStandardComponentRole, reinterpret_cast<int8_t *>(&role));
284     if (ret != HDF_SUCCESS) {
285         CODEC_LOGE("OMX_IndexParamStandardComponentRole err [%{public}d]", ret);
286     }
287 }
288 
SetParameterWithBuffer(uint32_t index,const std::vector<int8_t> & paramStruct,const OmxCodecBuffer & inBuffer)289 int32_t CodecComponentService::SetParameterWithBuffer(uint32_t index, const std::vector<int8_t>& paramStruct,
290                                                       const OmxCodecBuffer& inBuffer)
291 {
292     return node_->SetParameterWithBuffer(index, paramStruct, inBuffer);
293 }
294 
GetComponentCompName() const295 const std::string &CodecComponentService::GetComponentCompName() const
296 {
297     return name_;
298 }
299 
GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> & dumpNode_)300 void CodecComponentService::GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &dumpNode_)
301 {
302     dumpNode_ = node_;
303 }
304 
305 }  // namespace V3_0
306 }  // namespace Codec
307 }  // namespace HDI
308 }  // namespace OHOS
309