• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (inParamStruct.empty() || (inParamStruct.size() < sizeof(uint32_t))) {
167         CODEC_LOGE("GetParamStruct is Invalid");
168         return HDF_ERR_INVALID_PARAM;
169     }
170     uint32_t currentSize = *(reinterpret_cast<const uint32_t*>(inParamStruct.data()));
171     if (inParamStruct.size() != currentSize) {
172         CODEC_LOGE("Invalid GetParams");
173         return HDF_ERR_INVALID_PARAM;
174     }
175     outParamStruct = inParamStruct;
176     return node_->GetParameter(static_cast<enum OMX_INDEXTYPE>(index), outParamStruct.data());
177 }
178 
SetParameter(uint32_t index,const std::vector<int8_t> & paramStruct)179 int32_t CodecComponentService::SetParameter(uint32_t index, const std::vector<int8_t> &paramStruct)
180 {
181     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetParameter");
182     CODEC_LOGD("index [%{public}x]", index);
183     if (paramStruct.empty() || (paramStruct.size() < sizeof(uint32_t))) {
184         CODEC_LOGE("SetParamStruct is Invalid");
185         return HDF_ERR_INVALID_PARAM;
186     }
187     uint32_t currentSize = *(reinterpret_cast<const uint32_t*>(paramStruct.data()));
188     if (paramStruct.size() != currentSize) {
189         CODEC_LOGE("Invalid SetParams");
190         return HDF_ERR_INVALID_PARAM;
191     }
192     return node_->SetParameter(static_cast<enum OMX_INDEXTYPE>(index), paramStruct.data());
193 }
194 
GetConfig(uint32_t index,const std::vector<int8_t> & inCfgStruct,std::vector<int8_t> & outCfgStruct)195 int32_t CodecComponentService::GetConfig(uint32_t index, const std::vector<int8_t> &inCfgStruct,
196                                          std::vector<int8_t> &outCfgStruct)
197 {
198     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetConfig");
199     CODEC_LOGD("index [%{public}x]", index);
200     if (inCfgStruct.empty() || (inCfgStruct.size() < sizeof(uint32_t))) {
201         CODEC_LOGE("GetCfgStruct is Invalid");
202         return HDF_ERR_INVALID_PARAM;
203     }
204     uint32_t currentSize = *(reinterpret_cast<const uint32_t*>(inCfgStruct.data()));
205     if (inCfgStruct.size() != currentSize) {
206         CODEC_LOGE("Invalid GetConfig");
207         return HDF_ERR_INVALID_PARAM;
208     }
209     outCfgStruct = inCfgStruct;
210     return node_->GetConfig(static_cast<enum OMX_INDEXTYPE>(index), outCfgStruct.data());
211 }
212 
SetConfig(uint32_t index,const std::vector<int8_t> & cfgStruct)213 int32_t CodecComponentService::SetConfig(uint32_t index, const std::vector<int8_t> &cfgStruct)
214 {
215     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetConfig");
216     CODEC_LOGD("index [%{public}x]", index);
217     if (cfgStruct.empty() || ((cfgStruct.size() < sizeof(uint32_t)))) {
218         CODEC_LOGE("SetCfgStruct is Invalid");
219         return HDF_ERR_INVALID_PARAM;
220     }
221     uint32_t currentSize = *(reinterpret_cast<const uint32_t*>(cfgStruct.data()));
222     if (cfgStruct.size() != currentSize) {
223         CODEC_LOGE("Invalid SetConfig");
224         return HDF_ERR_INVALID_PARAM;
225     }
226     return node_->SetConfig(static_cast<enum OMX_INDEXTYPE>(index), cfgStruct.data());
227 }
228 
GetExtensionIndex(const std::string & paramName,uint32_t & indexType)229 int32_t CodecComponentService::GetExtensionIndex(const std::string &paramName, uint32_t &indexType)
230 {
231     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetExtensionIndex");
232     CODEC_LOGI("paramName [%{public}s]", paramName.c_str());
233     return node_->GetExtensionIndex(paramName.c_str(), indexType);
234 }
235 
GetState(CodecStateType & state)236 int32_t CodecComponentService::GetState(CodecStateType &state)
237 {
238     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetState");
239     return node_->GetState(state);
240 }
241 
ComponentTunnelRequest(uint32_t port,int32_t tunneledComp,uint32_t tunneledPort,const CodecTunnelSetupType & inTunnelSetup,CodecTunnelSetupType & outTunnelSetup)242 int32_t CodecComponentService::ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort,
243                                                       const CodecTunnelSetupType &inTunnelSetup,
244                                                       CodecTunnelSetupType &outTunnelSetup)
245 {
246     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentTunnelRequest");
247     CODEC_LOGI("port [%{public}d]", port);
248     outTunnelSetup = inTunnelSetup;
249     return node_->ComponentTunnelRequest(port, tunneledComp, tunneledPort, outTunnelSetup);
250 }
251 
UseBuffer(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer)252 int32_t CodecComponentService::UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer)
253 {
254     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseBuffer");
255     CODEC_LOGD("portIndex: [%{public}d]", portIndex);
256     if (!ReWrapNativeBufferInOmxBuffer(inBuffer)) {
257         return HDF_FAILURE;
258     }
259     outBuffer = const_cast<OmxCodecBuffer &>(inBuffer);
260 
261     if (outBuffer.fd >= 0 && isIPCMode_ && outBuffer.bufferType != CODEC_BUFFER_TYPE_AVSHARE_MEM_FD &&
262         outBuffer.bufferType != CODEC_BUFFER_TYPE_DMA_MEM_FD &&
263         name_.find(AUDIO_CODEC_NAME) == std::string::npos) {
264         close(outBuffer.fd);
265         outBuffer.fd = -1;
266     }
267     if (outBuffer.fenceFd >= 0) {
268         close(outBuffer.fenceFd);
269         outBuffer.fenceFd = -1;
270     }
271 
272     return node_->UseBuffer(portIndex, outBuffer);
273 }
274 
AllocateBuffer(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer)275 int32_t CodecComponentService::AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
276                                               OmxCodecBuffer &outBuffer)
277 {
278     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecAllocateBuffer");
279     CODEC_LOGD("portIndex: [%{public}d]", portIndex);
280     outBuffer = inBuffer;
281     return node_->AllocateBuffer(portIndex, outBuffer);
282 }
283 
FreeBuffer(uint32_t portIndex,const OmxCodecBuffer & buffer)284 int32_t CodecComponentService::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer)
285 {
286     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFreeBuffer");
287     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
288     CODEC_LOGD("portIndex: [%{public}d], bufferId: [%{public}d]", portIndex, buffer.bufferId);
289     int32_t ret = node_->FreeBuffer(portIndex, buffer);
290     ReleaseCache();
291     if (isIPCMode_ && bufferTemp.fd >= 0) {
292         close(bufferTemp.fd);
293         bufferTemp.fd = -1;
294     }
295 
296     return ret;
297 }
298 
EmptyThisBuffer(const OmxCodecBuffer & buffer)299 int32_t CodecComponentService::EmptyThisBuffer(const OmxCodecBuffer &buffer)
300 {
301     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecEmptyThisBuffer");
302     if (!ReWrapNativeBufferInOmxBuffer(buffer)) {
303         return HDF_FAILURE;
304     }
305     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
306     int32_t ret = node_->EmptyThisBuffer(bufferTemp);
307     if (isIPCMode_ && bufferTemp.fd >= 0) {
308         close(bufferTemp.fd);
309         bufferTemp.fd = -1;
310     }
311 
312     return ret;
313 }
314 
FillThisBuffer(const OmxCodecBuffer & buffer)315 int32_t CodecComponentService::FillThisBuffer(const OmxCodecBuffer &buffer)
316 {
317     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFillThisBuffer");
318     if (!ReWrapNativeBufferInOmxBuffer(buffer)) {
319         return HDF_FAILURE;
320     }
321     OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer);
322     int32_t ret = node_->FillThisBuffer(bufferTemp);
323     if (isIPCMode_ && bufferTemp.fd >= 0) {
324         close(bufferTemp.fd);
325         bufferTemp.fd = -1;
326     }
327 
328     return ret;
329 }
330 
SetCallbacks(const sptr<ICodecCallback> & callbacks,int64_t appData)331 int32_t CodecComponentService::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData)
332 {
333     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetCallbacks");
334     CODEC_LOGI("service impl!");
335     CHECK_AND_RETURN_RET_LOG(callbacks != nullptr, HDF_ERR_INVALID_PARAM, "callbacks is null");
336     return node_->SetCallbacks(callbacks, appData);
337 }
338 
ComponentDeInit()339 int32_t CodecComponentService::ComponentDeInit()
340 {
341     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentDeInit");
342     CODEC_LOGI("service impl!");
343     return node_->ComponentDeInit();
344 }
345 
UseEglImage(uint32_t portIndex,const OmxCodecBuffer & inBuffer,OmxCodecBuffer & outBuffer,const std::vector<int8_t> & eglImage)346 int32_t CodecComponentService::UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer,
347                                            OmxCodecBuffer &outBuffer, const std::vector<int8_t> &eglImage)
348 {
349     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseEglImage");
350     CODEC_LOGI("portIndex [%{public}d]", portIndex);
351     outBuffer = inBuffer;
352     return node_->UseEglImage(outBuffer, portIndex, eglImage.data());
353 }
354 
ComponentRoleEnum(std::vector<uint8_t> & role,uint32_t index)355 int32_t CodecComponentService::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index)
356 {
357     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentRoleEnum");
358     CODEC_LOGI("index [%{public}d]", index);
359     return node_->ComponentRoleEnum(role, index);
360 }
361 
SetComponentRole()362 void CodecComponentService::SetComponentRole()
363 {
364     HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetComponentRole");
365     if (name_ == "") {
366         CODEC_LOGE("compName is null");
367         return;
368     }
369     OHOS::Codec::Omx::CodecOMXCore *core;
370     auto err = mgr_->GetCoreOfComponent(core, name_);
371     if (err != HDF_SUCCESS) {
372         CODEC_LOGE("core is null");
373         return;
374     }
375 
376     std::vector<std::string> roles;
377     int32_t ret = core->GetRolesOfComponent(name_, roles);
378     if (ret != HDF_SUCCESS) {
379         CODEC_LOGE("GetRoleOfComponent return err [%{public}d]", ret);
380         return;
381     }
382     if (roles.empty()) {
383         CODEC_LOGE("role of component is empty");
384         return;
385     }
386     uint32_t roleIndex = 0;
387     CODEC_LOGI("RoleName = [%{public}s]", roles[roleIndex].c_str());
388 
389     OMX_PARAM_COMPONENTROLETYPE role;
390     errno_t res = strncpy_s(reinterpret_cast<char *>(role.cRole), OMX_MAX_STRINGNAME_SIZE,
391                             roles[roleIndex].c_str(), roles[roleIndex].length());
392     if (res != EOK) {
393         CODEC_LOGE("strncpy_s return err [%{public}d]", err);
394         return;
395     }
396     role.nSize = sizeof(role);
397     ret = node_->SetParameter(OMX_IndexParamStandardComponentRole, reinterpret_cast<int8_t *>(&role));
398     if (ret != HDF_SUCCESS) {
399         CODEC_LOGE("OMX_IndexParamStandardComponentRole err [%{public}d]", ret);
400     }
401 }
402 
SetParameterWithBuffer(uint32_t index,const std::vector<int8_t> & paramStruct,const OmxCodecBuffer & inBuffer)403 int32_t CodecComponentService::SetParameterWithBuffer(uint32_t index, const std::vector<int8_t>& paramStruct,
404                                                       const OmxCodecBuffer& inBuffer)
405 {
406     return node_->SetParameterWithBuffer(index, paramStruct, inBuffer);
407 }
408 
GetComponentCompName() const409 const std::string &CodecComponentService::GetComponentCompName() const
410 {
411     return name_;
412 }
413 
GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> & dumpNode_)414 void CodecComponentService::GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &dumpNode_)
415 {
416     dumpNode_ = node_;
417 }
418 
419 }  // namespace V3_0
420 }  // namespace Codec
421 }  // namespace HDI
422 }  // namespace OHOS
423