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 "v1_0/display_composer_type.h"
24 #include "v1_1/imetadata.h"
25 #include "codec_log_wrapper.h"
26
27 #define AUDIO_CODEC_NAME "OMX.audio"
28
29 namespace OHOS {
30 namespace HDI {
31 namespace Codec {
32 namespace V3_0 {
33
34 std::mutex g_mapperMtx;
35 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> g_mapperService;
36
GetMapperService()37 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> GetMapperService()
38 {
39 std::lock_guard<std::mutex> lk(g_mapperMtx);
40 if (g_mapperService) {
41 return g_mapperService;
42 }
43 g_mapperService = OHOS::HDI::Display::Buffer::V1_0::IMapper::Get(true);
44 if (g_mapperService) {
45 CODEC_LOGI("get IMapper succ");
46 return g_mapperService;
47 }
48 CODEC_LOGE("get IMapper failed");
49 return nullptr;
50 }
51
52 std::mutex g_metaMtx;
53 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> g_metaService;
54
GetMetaService()55 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> GetMetaService()
56 {
57 std::lock_guard<std::mutex> lk(g_metaMtx);
58 if (g_metaService) {
59 return g_metaService;
60 }
61 g_metaService = OHOS::HDI::Display::Buffer::V1_1::IMetadata::Get(true);
62 if (g_metaService) {
63 CODEC_LOGI("get IMetadata succ");
64 return g_metaService;
65 }
66 CODEC_LOGE("get IMetadata failed");
67 return nullptr;
68 }
69
BufferDestructor(BufferHandle* handle)70 void BufferDestructor(BufferHandle* handle)
71 {
72 if (handle == nullptr) {
73 return;
74 }
75 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> mapper = GetMapperService();
76 if (mapper == nullptr) {
77 return;
78 }
79 sptr<NativeBuffer> buffer = new NativeBuffer();
80 buffer->SetBufferHandle(handle, true);
81 mapper->FreeMem(buffer);
82 }
83
ReWrapNativeBuffer(sptr<NativeBuffer>& buffer)84 bool ReWrapNativeBuffer(sptr<NativeBuffer>& buffer)
85 {
86 if (buffer == nullptr) {
87 return true;
88 }
89 BufferHandle* handle = buffer->Move();
90 if (handle == nullptr) {
91 return true;
92 }
93 buffer->SetBufferHandle(handle, true, BufferDestructor);
94 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> meta = GetMetaService();
95 if (meta == nullptr) {
96 return false;
97 }
98 int32_t ret = meta->RegisterBuffer(buffer);
99 if (ret != Display::Composer::V1_0::DISPLAY_SUCCESS &&
100 ret != Display::Composer::V1_0::DISPLAY_NOT_SUPPORT) {
101 CODEC_LOGE("RegisterBuffer failed, ret = %{public}d", ret);
102 return false;
103 }
104 return true;
105 }
106
ReWrapNativeBufferInOmxBuffer(const OmxCodecBuffer &inBuffer)107 bool CodecComponentService::ReWrapNativeBufferInOmxBuffer(const OmxCodecBuffer &inBuffer)
108 {
109 if (!isIPCMode_) {
110 return true;
111 }
112 return ReWrapNativeBuffer(const_cast<OmxCodecBuffer &>(inBuffer).bufferhandle);
113 }
114
CodecComponentService(const std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &node, const std::shared_ptr<OHOS::Codec::Omx::ComponentMgr> mgr, const std::string name)115 CodecComponentService::CodecComponentService(const std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &node,
116 const std::shared_ptr<OHOS::Codec::Omx::ComponentMgr> mgr, const std::string name)
117 {
118 name_ = name;
119 node_ = node;
120 mgr_ = mgr;
121 isIPCMode_ = (HdfRemoteGetCallingPid() == getpid() ? false : true);
122 #ifdef SUPPORT_ROLE
123 SetComponentRole();
124 #endif
125 }
~CodecComponentService()126 CodecComponentService::~CodecComponentService()
127 {
128 if (node_ != nullptr) {
129 node_->ReleaseOMXResource();
130 int32_t ret = node_->CloseHandle();
131 if (ret != HDF_SUCCESS) {
132 CODEC_LOGE("CloseHandle failed, err[%{public}d]", ret);
133 }
134 node_ = nullptr;
135 ReleaseCache();
136 }
137 name_ = "";
138 mgr_ = nullptr;
139 }
140
ReleaseCache()141 void CodecComponentService::ReleaseCache()
142 {
143 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
144 mallopt(M_FLUSH_THREAD_CACHE, 0);
145 #endif
146 }
147
GetComponentVersion(CompVerInfo &verInfo)148 int32_t CodecComponentService::GetComponentVersion(CompVerInfo &verInfo)
149 {
150 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetComponentVersion");
151 return node_->GetComponentVersion(verInfo);
152 }
153
SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t> &cmdData)154 int32_t CodecComponentService::SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t> &cmdData)
155 {
156 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSendCommand");
157 CODEC_LOGI("commandType: [%{public}d], command [%{public}d]", cmd, param);
158 return node_->SendCommand(cmd, param, const_cast<int8_t *>(cmdData.data()));
159 }
160
GetParameter(uint32_t index, const std::vector<int8_t> &inParamStruct, std::vector<int8_t> &outParamStruct)161 int32_t CodecComponentService::GetParameter(uint32_t index, const std::vector<int8_t> &inParamStruct,
162 std::vector<int8_t> &outParamStruct)
163 {
164 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetParameter");
165 CODEC_LOGD("index [%{public}x]", index);
166 outParamStruct = inParamStruct;
167 return node_->GetParameter(static_cast<enum OMX_INDEXTYPE>(index), outParamStruct.data());
168 }
169
SetParameter(uint32_t index, const std::vector<int8_t> ¶mStruct)170 int32_t CodecComponentService::SetParameter(uint32_t index, const std::vector<int8_t> ¶mStruct)
171 {
172 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetParameter");
173 CODEC_LOGD("index [%{public}x]", index);
174 return node_->SetParameter(static_cast<enum OMX_INDEXTYPE>(index), paramStruct.data());
175 }
176
GetConfig(uint32_t index, const std::vector<int8_t> &inCfgStruct, std::vector<int8_t> &outCfgStruct)177 int32_t CodecComponentService::GetConfig(uint32_t index, const std::vector<int8_t> &inCfgStruct,
178 std::vector<int8_t> &outCfgStruct)
179 {
180 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetConfig");
181 CODEC_LOGD("index [%{public}x]", index);
182 outCfgStruct = inCfgStruct;
183 return node_->GetConfig(static_cast<enum OMX_INDEXTYPE>(index), outCfgStruct.data());
184 }
185
SetConfig(uint32_t index, const std::vector<int8_t> &cfgStruct)186 int32_t CodecComponentService::SetConfig(uint32_t index, const std::vector<int8_t> &cfgStruct)
187 {
188 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetConfig");
189 CODEC_LOGD("index [%{public}x]", index);
190 return node_->SetConfig(static_cast<enum OMX_INDEXTYPE>(index), cfgStruct.data());
191 }
192
GetExtensionIndex(const std::string ¶mName, uint32_t &indexType)193 int32_t CodecComponentService::GetExtensionIndex(const std::string ¶mName, uint32_t &indexType)
194 {
195 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetExtensionIndex");
196 CODEC_LOGI("paramName [%{public}s]", paramName.c_str());
197 return node_->GetExtensionIndex(paramName.c_str(), indexType);
198 }
199
GetState(CodecStateType &state)200 int32_t CodecComponentService::GetState(CodecStateType &state)
201 {
202 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetState");
203 return node_->GetState(state);
204 }
205
ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort, const CodecTunnelSetupType &inTunnelSetup, CodecTunnelSetupType &outTunnelSetup)206 int32_t CodecComponentService::ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort,
207 const CodecTunnelSetupType &inTunnelSetup,
208 CodecTunnelSetupType &outTunnelSetup)
209 {
210 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentTunnelRequest");
211 CODEC_LOGI("port [%{public}d]", port);
212 outTunnelSetup = inTunnelSetup;
213 return node_->ComponentTunnelRequest(port, tunneledComp, tunneledPort, outTunnelSetup);
214 }
215
UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer)216 int32_t CodecComponentService::UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer)
217 {
218 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseBuffer");
219 CODEC_LOGD("portIndex: [%{public}d]", portIndex);
220 if (!ReWrapNativeBufferInOmxBuffer(inBuffer)) {
221 return HDF_FAILURE;
222 }
223 outBuffer = const_cast<OmxCodecBuffer &>(inBuffer);
224
225 if (outBuffer.fd >= 0 && isIPCMode_ && outBuffer.bufferType != CODEC_BUFFER_TYPE_AVSHARE_MEM_FD &&
226 outBuffer.bufferType != CODEC_BUFFER_TYPE_DMA_MEM_FD &&
227 name_.find(AUDIO_CODEC_NAME) == std::string::npos) {
228 close(outBuffer.fd);
229 outBuffer.fd = -1;
230 }
231 if (outBuffer.fenceFd >= 0) {
232 close(outBuffer.fenceFd);
233 outBuffer.fenceFd = -1;
234 }
235
236 return node_->UseBuffer(portIndex, outBuffer);
237 }
238
AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer)239 int32_t CodecComponentService::AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
240 OmxCodecBuffer &outBuffer)
241 {
242 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecAllocateBuffer");
243 CODEC_LOGD("portIndex: [%{public}d]", portIndex);
244 outBuffer = inBuffer;
245 return node_->AllocateBuffer(portIndex, outBuffer);
246 }
247
FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer)248 int32_t CodecComponentService::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer)
249 {
250 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFreeBuffer");
251 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
252 CODEC_LOGD("portIndex: [%{public}d], bufferId: [%{public}d]", portIndex, buffer.bufferId);
253 int32_t ret = node_->FreeBuffer(portIndex, buffer);
254 ReleaseCache();
255 if (isIPCMode_ && bufferTemp.fd >= 0) {
256 close(bufferTemp.fd);
257 bufferTemp.fd = -1;
258 }
259
260 return ret;
261 }
262
EmptyThisBuffer(const OmxCodecBuffer &buffer)263 int32_t CodecComponentService::EmptyThisBuffer(const OmxCodecBuffer &buffer)
264 {
265 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecEmptyThisBuffer");
266 if (!ReWrapNativeBufferInOmxBuffer(buffer)) {
267 return HDF_FAILURE;
268 }
269 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
270 int32_t ret = node_->EmptyThisBuffer(bufferTemp);
271 if (isIPCMode_ && bufferTemp.fd >= 0) {
272 close(bufferTemp.fd);
273 bufferTemp.fd = -1;
274 }
275
276 return ret;
277 }
278
FillThisBuffer(const OmxCodecBuffer &buffer)279 int32_t CodecComponentService::FillThisBuffer(const OmxCodecBuffer &buffer)
280 {
281 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFillThisBuffer");
282 if (!ReWrapNativeBufferInOmxBuffer(buffer)) {
283 return HDF_FAILURE;
284 }
285 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
286 int32_t ret = node_->FillThisBuffer(bufferTemp);
287 if (isIPCMode_ && bufferTemp.fd >= 0) {
288 close(bufferTemp.fd);
289 bufferTemp.fd = -1;
290 }
291
292 return ret;
293 }
294
SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData)295 int32_t CodecComponentService::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData)
296 {
297 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetCallbacks");
298 CODEC_LOGI("service impl!");
299 CHECK_AND_RETURN_RET_LOG(callbacks != nullptr, HDF_ERR_INVALID_PARAM, "callbacks is null");
300 return node_->SetCallbacks(callbacks, appData);
301 }
302
ComponentDeInit()303 int32_t CodecComponentService::ComponentDeInit()
304 {
305 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentDeInit");
306 CODEC_LOGI("service impl!");
307 return node_->ComponentDeInit();
308 }
309
UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer, const std::vector<int8_t> &eglImage)310 int32_t CodecComponentService::UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
311 OmxCodecBuffer &outBuffer, const std::vector<int8_t> &eglImage)
312 {
313 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseEglImage");
314 CODEC_LOGI("portIndex [%{public}d]", portIndex);
315 outBuffer = inBuffer;
316 return node_->UseEglImage(outBuffer, portIndex, eglImage.data());
317 }
318
ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index)319 int32_t CodecComponentService::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index)
320 {
321 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentRoleEnum");
322 CODEC_LOGI("index [%{public}d]", index);
323 return node_->ComponentRoleEnum(role, index);
324 }
325
SetComponentRole()326 void CodecComponentService::SetComponentRole()
327 {
328 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetComponentRole");
329 if (name_ == "") {
330 CODEC_LOGE("compName is null");
331 return;
332 }
333 OHOS::Codec::Omx::CodecOMXCore *core;
334 auto err = mgr_->GetCoreOfComponent(core, name_);
335 if (err != HDF_SUCCESS) {
336 CODEC_LOGE("core is null");
337 return;
338 }
339
340 std::vector<std::string> roles;
341 int32_t ret = core->GetRolesOfComponent(name_, roles);
342 if (ret != HDF_SUCCESS) {
343 CODEC_LOGE("GetRoleOfComponent return err [%{public}d]", ret);
344 return;
345 }
346 if (roles.empty()) {
347 CODEC_LOGE("role of component is empty");
348 return;
349 }
350 uint32_t roleIndex = 0;
351 CODEC_LOGI("RoleName = [%{public}s]", roles[roleIndex].c_str());
352
353 OMX_PARAM_COMPONENTROLETYPE role;
354 errno_t res = strncpy_s(reinterpret_cast<char *>(role.cRole), OMX_MAX_STRINGNAME_SIZE,
355 roles[roleIndex].c_str(), roles[roleIndex].length());
356 if (res != EOK) {
357 CODEC_LOGE("strncpy_s return err [%{public}d]", err);
358 return;
359 }
360 role.nSize = sizeof(role);
361 ret = node_->SetParameter(OMX_IndexParamStandardComponentRole, reinterpret_cast<int8_t *>(&role));
362 if (ret != HDF_SUCCESS) {
363 CODEC_LOGE("OMX_IndexParamStandardComponentRole err [%{public}d]", ret);
364 }
365 }
366
SetParameterWithBuffer(uint32_t index, const std::vector<int8_t>& paramStruct, const OmxCodecBuffer& inBuffer)367 int32_t CodecComponentService::SetParameterWithBuffer(uint32_t index, const std::vector<int8_t>& paramStruct,
368 const OmxCodecBuffer& inBuffer)
369 {
370 return node_->SetParameterWithBuffer(index, paramStruct, inBuffer);
371 }
372
GetComponentCompName() const373 const std::string &CodecComponentService::GetComponentCompName() const
374 {
375 return name_;
376 }
377
GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &dumpNode_)378 void CodecComponentService::GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &dumpNode_)
379 {
380 dumpNode_ = node_;
381 }
382
383 } // namespace V3_0
384 } // namespace Codec
385 } // namespace HDI
386 } // namespace OHOS
387