diff --git a/codec/hal/idl_service/BUILD.gn b/codec/hal/idl_service/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4b6dc17f2b281270115a852c036a24184634fa7a --- /dev/null +++ b/codec/hal/idl_service/BUILD.gn @@ -0,0 +1,112 @@ +# Copyright (c) 2022 Shenzhen Kaihong DID Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/ohos.gni") +import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") + +ohos_shared_library("libcodec_component_manager_service_1.0") { + include_dirs = [ + "//drivers/peripheral/codec/hal/buffersequence/", + "//drivers/peripheral/codec/interfaces/include/", + "//third_party/openmax/api/1.1.2", + "include", + ] + sources = [ + "src/codec_component_config.cpp", + "src/codec_component_manager_service.cpp", + "src/codec_component_service.cpp", + "src/codec_dyna_buffer.cpp", + "src/codec_handle_buffer.cpp", + "src/codec_omx_core.cpp", + "src/codec_share_buffer.cpp", + "src/component_mgr.cpp", + "src/component_node.cpp", + "src/icodec_buffer.cpp", + ] + + cflags_cc = [ + "-Wall", + "-Wextra", + "-Werror", + "-Wno-#warnings", + "-Wno-missing-braces", + "-Wno-missing-field-initializers", + ] + + deps = [ + "//drivers/peripheral/codec/hal/buffersequence:libbufferhandle_parcelable", + "//third_party/libdrm:libdrm", + ] + if (is_standard_system) { + external_deps = [ + "drivers_interface_codec:codec_idl_headers", + "graphic_chipsetsdk:buffer_handle", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "utils_base:utils", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_codec" +} + +ohos_shared_library("libcodec_driver") { + include_dirs = [ + "//drivers/peripheral/codec/interfaces/include/", + "//drivers/peripheral/codec/hal/buffersequence", + "include", + ] + + sources = [ "src/codec_component_manager_driver.cpp" ] + + deps = [ ":libcodec_component_manager_service_1.0" ] + + if (is_standard_system) { + external_deps = [ + "drivers_interface_codec:codec_idl_headers", + "drivers_interface_codec:libcodec_stub_1.0", + "graphic_chipsetsdk:buffer_handle", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "utils_base:utils", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_codec" +} + +group("codec_idl_omx_service") { + deps = [ + ":libcodec_component_manager_service_1.0", + ":libcodec_driver", + ] +} diff --git a/codec/hal/idl_service/include/codec_component_config.h b/codec/hal/idl_service/include/codec_component_config.h new file mode 100644 index 0000000000000000000000000000000000000000..760b9b8627031af0252ee092c5a83f9910de0088 --- /dev/null +++ b/codec/hal/idl_service/include/codec_component_config.h @@ -0,0 +1,70 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_CONFIG_H +#include +#include "v1_0/codec_types.h" +#include "device_resource_if.h" +using OHOS::HDI::Codec::V1_0::CodecCompCapability; +namespace OHOS { +namespace Codec { +namespace Omx { +typedef struct { + std::string attrName; + int32_t &value; + uint32_t defaultValue; +} ConfigUintNodeAttr; +typedef struct { + std::string attrName; + std::vector &vec; +} ConfigUintArrayNodeAttr; + +class CodecComponentConfig { +public: + ~CodecComponentConfig() = default; + static CodecComponentConfig *GetInstance(); + void Init(const DeviceResourceNode &node); + int32_t GetComponentNum(int32_t &count); + int32_t GetComponentCapabilityList(std::vector &capList, int32_t count); + +protected: + CodecComponentConfig(); + +private: + int32_t GetGroupCapabilitiesNumber(const std::string &nodeName, int32_t &num); + int32_t GetGroupCapabilities(const std::string &nodeName); + int32_t GetOneCapability(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &childNode, + CodecCompCapability &cap, bool isVideoGroup); + int32_t GetMiscOfCapability(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &childNode, + CodecCompCapability &cap); + int32_t GetUintTableConfig(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &node, + ConfigUintArrayNodeAttr &attr); + int32_t GetMaskedConfig(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &node, + const std::string &attrName, uint32_t &mask); + int32_t GetAudioPortCapability(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &childNode, + CodecCompCapability &cap); + int32_t GetVideoPortCapability(const struct DeviceResourceIface &iface, const struct DeviceResourceNode &childNode, + CodecCompCapability &cap); + +private: + DeviceResourceNode node_; + std::vector capList_; + static CodecComponentConfig config_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#define CODEC_CONFIG_H +#endif // CODEC_CONFIG_H \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_component_manager_service.h b/codec/hal/idl_service/include/codec_component_manager_service.h new file mode 100644 index 0000000000000000000000000000000000000000..5856fec5d1736307016d4f50ed5a75ac682888e8 --- /dev/null +++ b/codec/hal/idl_service/include/codec_component_manager_service.h @@ -0,0 +1,55 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_HDI_CODEC_V1_0_CODECCOMPONENTMANAGERSERVICE_H +#define OHOS_HDI_CODEC_V1_0_CODECCOMPONENTMANAGERSERVICE_H + +#include +#include +#include "device_resource_if.h" +#include "v1_0/icodec_component.h" +#include "v1_0/icodec_component_manager.h" +#include "component_mgr.h" +namespace OHOS { +namespace HDI { +namespace Codec { +namespace V1_0 { +class CodecComponentManagerService : public ICodecComponentManager { +public: + CodecComponentManagerService(); + virtual ~CodecComponentManagerService() = default; + int32_t GetComponentNum(int32_t &count) override; + int32_t GetComponentCapabilityList(std::vector &capList, int32_t count) override; + int32_t CreateComponent(sptr &component, uint32_t &componentId, const std::string &compName, + int64_t appData, const sptr &callbacks) override; + int32_t DestoryComponent(uint32_t componentId) override; + void LoadCapabilityData(const DeviceResourceNode &node); + +private: + uint32_t GetNextComponentId(void); + +private: + std::map> componentMap_; + uint32_t componentId_; + std::mutex mutex_; + DeviceResourceNode resourceNode_; + std::shared_ptr mgr_; +}; +} // namespace V1_0 +} // namespace Codec +} // namespace HDI +} // namespace OHOS + +#endif // OHOS_HDI_CODEC_V1_0_CODECCOMPONENTMANAGERSERVICE_H \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_component_service.h b/codec/hal/idl_service/include/codec_component_service.h new file mode 100644 index 0000000000000000000000000000000000000000..7537a3cb048c4753d5b1180e0973ac899b6c9f37 --- /dev/null +++ b/codec/hal/idl_service/include/codec_component_service.h @@ -0,0 +1,62 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_HDI_CODEC_V1_0_CODECCOMPONENTSERVICE_H +#define OHOS_HDI_CODEC_V1_0_CODECCOMPONENTSERVICE_H + +#include "component_node.h" +#include "v1_0/icodec_component.h" +namespace OHOS { +namespace HDI { +namespace Codec { +namespace V1_0 { +class CodecComponentService : public ICodecComponent { +public: + CodecComponentService(const std::shared_ptr &node) : node_(node) + {} + virtual ~CodecComponentService() = default; + int32_t GetComponentVersion(CompVerInfo &verInfo) override; + int32_t SendCommand(OMX_COMMANDTYPE cmd, uint32_t param, const std::vector &cmdData) override; + int32_t GetParameter(uint32_t index, const std::vector &inParamStruct, + std::vector &outParamStruct) override; + int32_t SetParameter(uint32_t index, const std::vector ¶mStruct) override; + int32_t GetConfig(uint32_t index, const std::vector &inCfgStruct, + std::vector &outCfgStruct) override; + int32_t SetConfig(uint32_t index, const std::vector &cfgStruct) override; + int32_t GetExtensionIndex(const std::string ¶mName, uint32_t &indexType) override; + int32_t GetState(OMX_STATETYPE &state) override; + int32_t ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort, + const OMX_TUNNELSETUPTYPE &inTunnelSetup, + OMX_TUNNELSETUPTYPE &outTunnelSetup) override; + int32_t UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer) override; + int32_t AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer) override; + int32_t FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer) override; + int32_t EmptyThisBuffer(const OmxCodecBuffer &buffer) override; + int32_t FillThisBuffer(const OmxCodecBuffer &buffer) override; + int32_t SetCallbacks(const sptr &callbacks, int64_t appData) override; + int32_t ComponentDeInit() override; + int32_t UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer, + const std::vector &eglImage) override; + int32_t ComponentRoleEnum(std::vector &role, uint32_t index) override; + +private: + std::shared_ptr node_; +}; +} // namespace V1_0 +} // namespace Codec +} // namespace HDI +} // namespace OHOS + +#endif // OHOS_HDI_CODEC_V1_0_CODECCOMPONENTSERVICE_H \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_dyna_buffer.h b/codec/hal/idl_service/include/codec_dyna_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..b33cf8493f079675d0c4494ace273c2f43219852 --- /dev/null +++ b/codec/hal/idl_service/include/codec_dyna_buffer.h @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_DYNA_BUFFER_H +#define CODEC_DYNA_BUFFER_H +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecDynaBuffer : ICodecBuffer { +public: + ~CodecDynaBuffer(); + sptr static Create(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + uint8_t *GetBuffer() override; + +protected: + CodecDynaBuffer(struct OmxCodecBuffer &codecBuffer); + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + +private: + std::shared_ptr dynaBuffer_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif // CODEC_DYNA_BUFFER_H \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_handle_buffer.h b/codec/hal/idl_service/include/codec_handle_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..cc99fe2038bb605dfddc2e70b879de3524604e41 --- /dev/null +++ b/codec/hal/idl_service/include/codec_handle_buffer.h @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_HANDLE_BUFFER_H +#define CODEC_HANDLE_BUFFER_H +#include +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecHandleBuffer : ICodecBuffer { +public: + ~CodecHandleBuffer(); + sptr static Create(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + uint8_t *GetBuffer() override; + +protected: + CodecHandleBuffer(struct OmxCodecBuffer &codecBuffer); + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + +private: + BufferHandle *bufferHandle_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif // CODEC_HANDLE_BUFFER_H \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_log_wrapper.h b/codec/hal/idl_service/include/codec_log_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..e0390ec9c120d3d091d51a29fe03ff30c2329355 --- /dev/null +++ b/codec/hal/idl_service/include/codec_log_wrapper.h @@ -0,0 +1,67 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_LOG_WRAPPER_H +#define CODEC_LOG_WRAPPER_H +#include +namespace OHOS { +#define HDF_LOG_TAG codec_hdi_omx + +#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) +#ifndef CODEC_DEBUG +#define CODEC_LOGE(fmt, ...) HDF_LOGE("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGW(fmt, ...) HDF_LOGW("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGI(fmt, ...) HDF_LOGI("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGD(fmt, ...) HDF_LOGD("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#else +constexpr int32_t MAX_BUFFER_LEN = 256; +static FILE *fp = fopen("/data/codec.log", "rw"); +static void LOG(const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + std::string stdFromat = fmt; + do { + std::size_t pos = stdFormat.find("{public}"); + if (pos == std::string::npos) { + break; + } + stdFormat = stdFormat.erase(pos, strlen("{public}")); + } while (true); + char buf[MAX_BUFFER_LEN] = {0}; + if (vsnprintf_s(buf, sizeof(buf), sizeof(buf), stdFormat.c_str(), va) <= 0) { + va_end(va); + return; + } + va_end(va); + if (fp != nullptr) { + fwrite(buf, strlen(buf), 1, fp); + fflush(fp); + } +} +#define CODEC_LOGE(fmt, ...) LOG("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGW(fmt, ...) LOG("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGI(fmt, ...) LOG("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#define CODEC_LOGD(fmt, ...) LOG("[%{public}s] %{public}s# " fmt, FILENAME, __func__, ##__VA_ARGS__) +#endif +#define CHECK_AND_RETURN_RET_LOG(cond, ret, fmt, ...) \ +do { \ +if (!(cond)) { \ +CODEC_LOGE(fmt, ##__VA_ARGS__); \ +return ret; \ +} \ +} while (0) +} // namespace OHOS +#endif /* CODEC_LOG_WRAPPER_H */ \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_omx_core.h b/codec/hal/idl_service/include/codec_omx_core.h new file mode 100644 index 0000000000000000000000000000000000000000..659643d3f95cfa9c83a1c5f69da2d8551089805f --- /dev/null +++ b/codec/hal/idl_service/include/codec_omx_core.h @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OMX_CODEC_CORE_H +#define OMX_CODEC_CORE_H +#include +#include +#include +#include +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecOMXCore { +public: + typedef OMX_ERRORTYPE (*InitFunc)(); + typedef OMX_ERRORTYPE (*DeinitFunc)(); + typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(OMX_STRING, OMX_U32, OMX_U32); + typedef OMX_ERRORTYPE (*GetHandleFunc)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *); + typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE); + typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(OMX_STRING, OMX_U32 *, OMX_U8 **); + +public: + CodecOMXCore() = default; + ~CodecOMXCore(); + int32_t Init(const std::string &libName); + void DeInit(); + int32_t GetHandle(OMX_HANDLETYPE &handle, std::string &compName, OMX_PTR appData, + const OMX_CALLBACKTYPE &callbacks); + int32_t FreeHandle(OMX_HANDLETYPE handle); + int32_t ComponentNameEnum(std::string &name, uint32_t index); + int32_t GetRolesOfComponent(std::string &name, std::vector &roles); + +private: + void *libHandle_ = nullptr; + InitFunc init_ = nullptr; + DeinitFunc deInit_ = nullptr; + ComponentNameEnumFunc componentNameEnum_ = nullptr; + GetHandleFunc getHandle_ = nullptr; + FreeHandleFunc freeHandle_ = nullptr; + GetRolesOfComponentFunc getRoles_ = nullptr; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif \ No newline at end of file diff --git a/codec/hal/idl_service/include/codec_share_buffer.h b/codec/hal/idl_service/include/codec_share_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..8807e0a32e9d107c861d55dcdd89a9a26e87fc46 --- /dev/null +++ b/codec/hal/idl_service/include/codec_share_buffer.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_SHARE_BUFFER_H +#define CODEC_SHARE_BUFFER_H +#include +#include +#include "icodec_buffer.h" + +namespace OHOS { +namespace Codec { +namespace Omx { +class CodecShareBuffer : ICodecBuffer { +public: + ~CodecShareBuffer(); + OHOS::sptr static Create(struct OmxCodecBuffer &codecBuffer); + OHOS::sptr static Allocate(struct OmxCodecBuffer &codecBuffer); + int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) override; + int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) override; + void SetAshMem(std::shared_ptr shMem); + uint8_t *GetBuffer() override; + +protected: + CodecShareBuffer(struct OmxCodecBuffer &codecBuffer); + bool CheckInvalid(struct OmxCodecBuffer &codecBuffer) override; + +private: + void ReleaseFd(struct OmxCodecBuffer &codecBuffer); + +private: + std::shared_ptr shMem_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif \ No newline at end of file diff --git a/codec/hal/idl_service/include/component_mgr.h b/codec/hal/idl_service/include/component_mgr.h new file mode 100644 index 0000000000000000000000000000000000000000..d79e9d911537a46cea1af1a6af30834a7ee85724 --- /dev/null +++ b/codec/hal/idl_service/include/component_mgr.h @@ -0,0 +1,65 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMPONENT_MGR_H +#define COMPONENT_MGR_H +#include +#include +#include +#include +#include +#include +#include "codec_omx_core.h" +#include "icomponent_mgr.h" +namespace OHOS { +namespace Codec { +namespace Omx { +class ComponentMgr : public IComponentMgr { +public: + using OMXComponent = struct { + OMX_HANDLETYPE handle; + std::shared_ptr core; + }; + +public: + ComponentMgr(); + ~ComponentMgr(); + ComponentMgr(const ComponentMgr &) = delete; + ComponentMgr &operator=(const ComponentMgr &) = delete; + + virtual int32_t CreateComponentInstance(const char *componentName, const OMX_CALLBACKTYPE *callbacks, void *appData, + OMX_COMPONENTTYPE **component); + + virtual int32_t DeleteComponentInstance(OMX_COMPONENTTYPE *component); + + virtual int32_t GetRolesForComponent(const char *componentName, std::vector *roles); + +private: + void AddVendorComponent(); + void AddSoftComponent(); + void AddComponentByLibName(const char *libName); + void CleanComponent(); + +private: + std::vector> cores_; // save all the core + std::map> compoentsCore_; // save the compoentname<--> core + std::vector components_; // save the opened compoents + std::mutex mutex_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/codec/hal/idl_service/include/component_node.h b/codec/hal/idl_service/include/component_node.h new file mode 100644 index 0000000000000000000000000000000000000000..155be134d4c5f82935b04a207d3d9db27b256855 --- /dev/null +++ b/codec/hal/idl_service/include/component_node.h @@ -0,0 +1,87 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef COMPONENT_NODE_H +#define COMPONENT_NODE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include "icodec_buffer.h" +#include "v1_0/icodec_callback.h" +#include "v1_0/icodec_component.h" +#include "component_mgr.h" +using OHOS::HDI::Codec::V1_0::CompVerInfo; +using OHOS::HDI::Codec::V1_0::ICodecCallback; +using OHOS::HDI::Codec::V1_0::OmxCodecBuffer; +namespace OHOS { +namespace Codec { +namespace Omx { +class ComponentNode : NoCopyable { +public: + ComponentNode(const sptr &callbacks, int64_t appData, std::shared_ptr& mgr); + ~ComponentNode(); + int32_t OpenHandle(const std::string& name); + int32_t GetComponentVersion(CompVerInfo &verInfo); + int32_t SendCommand(OHOS::HDI::Codec::V1_0::OMX_COMMANDTYPE cmd, uint32_t param, int8_t *cmdData); + int32_t GetParameter(OMX_INDEXTYPE paramIndex, int8_t *param); + int32_t SetParameter(OMX_INDEXTYPE paramIndex, const int8_t *param); + int32_t GetConfig(OMX_INDEXTYPE index, int8_t *config); + int32_t SetConfig(OMX_INDEXTYPE index, const int8_t *config); + int32_t GetExtensionIndex(const char *parameterName, uint32_t& index); + int32_t GetState(OHOS::HDI::Codec::V1_0::OMX_STATETYPE &state); + int32_t ComponentTunnelRequest(uint32_t port, int32_t omxHandleTypeTunneledComp, uint32_t tunneledPort, + OHOS::HDI::Codec::V1_0::OMX_TUNNELSETUPTYPE &tunnelSetup); + int32_t UseBuffer(uint32_t portIndex, OmxCodecBuffer &buffer); + int32_t AllocateBuffer(uint32_t portIndex, OmxCodecBuffer &buffer); + int32_t FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer); + int32_t EmptyThisBuffer(OmxCodecBuffer &buffer); + int32_t FillThisBuffer(OmxCodecBuffer &buffer); + int32_t SetCallbacks(const sptr &callbacks, int64_t appData); + int32_t UseEglImage(struct OmxCodecBuffer &buffer, uint32_t portIndex, const int8_t *eglImage); + int32_t ComponentRoleEnum(std::vector &role, uint32_t index); + int32_t ComponentDeInit(); + OMX_ERRORTYPE static OnEvent(OMX_HANDLETYPE component, void *appData, OMX_EVENTTYPE event, uint32_t data1, + uint32_t data2, void *eventData); + OMX_ERRORTYPE static OnEmptyBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer); + OMX_ERRORTYPE static OnFillBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer); + +public: + static OMX_CALLBACKTYPE callbacks_; // callbacks + +private: + int32_t OnEvent(OMX_EVENTTYPE event, uint32_t data1, uint32_t data2, void *eventData); + int32_t OnEmptyBufferDone(OMX_BUFFERHEADERTYPE *buffer); + int32_t OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer); + uint32_t GenerateBufferId(); + sptr GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer); + bool GetBufferById(uint32_t bufferId, sptr &codecBuffer, OMX_BUFFERHEADERTYPE *&bufferHdrType); + void ReleaseCodecBuffer(struct OmxCodecBuffer &buffer); +private: + OMX_HANDLETYPE comp_; // Compnent handle + sptr omxCallback_; + int64_t appData_; + std::map> codecBufferMap_; // Key is buffferID + std::map bufferHeaderMap_; // Key is omx buffer header type + uint32_t bufferIdCount_; + std::shared_ptr mgr_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif /* COMPONENT_NODE_H */ \ No newline at end of file diff --git a/codec/hal/idl_service/include/icodec_buffer.h b/codec/hal/idl_service/include/icodec_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..077a375ccbcbda058ae3c3423b14522fbe7e7304 --- /dev/null +++ b/codec/hal/idl_service/include/icodec_buffer.h @@ -0,0 +1,75 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_CODEC_BUFFER_H +#define I_CODEC_BUFFER_H +#include +#include +#include +#include +#include +#include +#include +#include "codec_omx_ext.h" +#include "v1_0/codec_types.h" +using OHOS::HDI::Codec::V1_0::OmxCodecBuffer; +constexpr uint32_t TIME_WAIT_MS = 5; +namespace OHOS { +namespace Codec { +namespace Omx { +struct DynamicBuffer { + int32_t type; + BufferHandle *bufferHandle; + + DynamicBuffer() : type(0), bufferHandle(nullptr) + {} + ~DynamicBuffer() + { + type = 0; + if (bufferHandle != nullptr) { + FreeBufferHandle(bufferHandle); + } + bufferHandle = nullptr; + } +}; +using DynamicBuffer = struct DynamicBuffer; + +class ICodecBuffer : public RefBase { +public: + ICodecBuffer(struct OmxCodecBuffer &codecBuffer); + virtual ~ICodecBuffer(); + sptr static CreateCodeBuffer(struct OmxCodecBuffer &codecBuffer); + sptr static AllocateCodecBuffer(struct OmxCodecBuffer &codecBuffer); + virtual int32_t FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t FreeBuffer(struct OmxCodecBuffer &codecBuffer) = 0; + virtual int32_t EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer); + virtual int32_t FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer); + virtual uint8_t *GetBuffer() = 0; + struct OmxCodecBuffer &GetCodecBuffer(); + void SetBufferId(int32_t bufferId); + +protected: + ICodecBuffer() + {} + virtual bool CheckInvalid(struct OmxCodecBuffer &codecBuffer); + +protected: + struct OmxCodecBuffer codecBuffer_; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS +#endif \ No newline at end of file diff --git a/codec/hal/idl_service/include/icomponent_mgr.h b/codec/hal/idl_service/include/icomponent_mgr.h new file mode 100644 index 0000000000000000000000000000000000000000..1e1921a53390952756cca3503a267fd9aacad4a7 --- /dev/null +++ b/codec/hal/idl_service/include/icomponent_mgr.h @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_COMPONENT_MGR_H +#define I_COMPONENT_MGR_H +#include +#include +#include + +namespace OHOS { +namespace Codec { +namespace Omx { +class IComponentMgr { +public: + IComponentMgr() + {} + virtual ~IComponentMgr() + {} + IComponentMgr(const IComponentMgr &) = delete; + IComponentMgr &operator=(const IComponentMgr &) = delete; + + virtual int32_t CreateComponentInstance(const char *componentName, const OMX_CALLBACKTYPE *callbacks, + void *appData, OMX_COMPONENTTYPE **component) = 0; + + virtual int32_t DeleteComponentInstance(OMX_COMPONENTTYPE *component) = 0; + + virtual int32_t GetRolesForComponent(const char *componentName, std::vector *vRoles) = 0; +}; +} // namespace Omx +} // namespace Codec +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/codec/hal/idl_service/src/codec_component_config.cpp b/codec/hal/idl_service/src/codec_component_config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20821c0e1629be2eacb2459933baf8cbd95889a9 --- /dev/null +++ b/codec/hal/idl_service/src/codec_component_config.cpp @@ -0,0 +1,373 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "codec_component_config.h" +#include +#include +#include "codec_log_wrapper.h" + +constexpr int32_t MASK_NUM_LIMIT = 32; +constexpr char NODE_VIDEO_HARDWARE_ENCODERS[] = "VideoHwEncoders"; +constexpr char NODE_VIDEO_HARDWARE_DECODERS[] = "VideoHwDecoders"; +constexpr char NODE_VIDEO_SOFTWARE_ENCODERS[] = "VideoSwEncoders"; +constexpr char NODE_VIDEO_SOFTWARE_DECODERS[] = "VideoSwDecoders"; +constexpr char NODE_AUDIO_HARDWARE_ENCODERS[] = "AudioHwEncoders"; +constexpr char NODE_AUDIO_HARDWARE_DECODERS[] = "AudioHwDecoders"; +constexpr char NODE_AUDIO_SOFTWARE_ENCODERS[] = "AudioSwEncoders"; +constexpr char NODE_AUDIO_SOFTWARE_DECODERS[] = "AudioSwDecoders"; + +constexpr char CODEC_CONFIG_KEY_ROLE[] = "role"; +constexpr char CODEC_CONFIG_KEY_TYPE[] = "type"; +constexpr char CODEC_CONFIG_KEY_NAME[] = "name"; +constexpr char CODEC_CONFIG_KEY_SUPPORT_PROFILES[] = "supportProfiles"; +constexpr char CODEC_CONFIG_KEY_MAX_INST[] = "maxInst"; +constexpr char CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC[] = "isSoftwareCodec"; +constexpr char CODEC_CONFIG_KEY_PROCESS_MODE_MASK[] = "processModeMask"; +constexpr char CODEC_CONFIG_KEY_CAPS_MASK[] = "capsMask"; +constexpr char CODEC_CONFIG_KEY_MIN_BITRATE[] = "minBitRate"; +constexpr char CODEC_CONFIG_KEY_MAX_BITRATE[] = "maxBitRate"; + +constexpr char CODEC_CONFIG_KEY_MIN_WIDTH[] = "minWidth"; +constexpr char CODEC_CONFIG_KEY_MIN_HEIGHT[] = "minHeight"; +constexpr char CODEC_CONFIG_KEY_MAX_WIDTH[] = "maxWidth"; +constexpr char CODEC_CONFIG_KEY_MAX_HEIGHT[] = "maxHeight"; +constexpr char CODEC_CONFIG_KEY_WIDTH_ALIGNMENT[] = "widthAlignment"; +constexpr char CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT[] = "heightAlignment"; +constexpr char CODEC_CONFIG_KEY_MIN_BLOCK_COUNT[] = "minBlockCount"; +constexpr char CODEC_CONFIG_KEY_MAX_BLOCK_COUNT[] = "maxBlockCount"; +constexpr char CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND[] = "minBlocksPerSecond"; +constexpr char CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND[] = "maxBlocksPerSecond"; +constexpr char CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS[] = "supportPixelFmts"; +constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH[] = "blockSizeWidth"; +constexpr char CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT[] = "blockSizeHeight"; +constexpr char CODEC_CONFIG_KEY_MIN_FRAME_RATE[] = "minFrameRate"; +constexpr char CODEC_CONFIG_KEY_MAX_FRAME_RATE[] = "maxFrameRate"; +constexpr char CODEC_CONFIG_KEY_BITE_RATE_MODE[] = "bitRateMode"; +constexpr char CODEC_CONFIG_KEY_MESURED_FRAME_RATE[] = "measuredFrameRate"; + +constexpr char CODEC_CONFIG_KEY_SAMPLE_FORMATS[] = "sampleFormats"; +constexpr char CODEC_CONFIG_KEY_SAMPLE_RATE[] = "sampleRate"; +constexpr char CODEC_CONFIG_KEY_CHANNEL_LAYOUTS[] = "channelLayouts"; +constexpr char CODEC_CONFIG_KEY_CHANNEL_COUNT[] = "channelCount"; + +using namespace OHOS::HDI::Codec::V1_0; +namespace OHOS { +namespace Codec { +namespace Omx { +CodecComponentConfig CodecComponentConfig::config_; +CodecComponentConfig::CodecComponentConfig() +{} + +void CodecComponentConfig::Init(const DeviceResourceNode &node) +{ + node_ = node; + std::string codecGroupsNodeName[] = {NODE_VIDEO_HARDWARE_ENCODERS, NODE_VIDEO_HARDWARE_DECODERS, + NODE_VIDEO_SOFTWARE_ENCODERS, NODE_VIDEO_SOFTWARE_DECODERS, + NODE_AUDIO_HARDWARE_ENCODERS, NODE_AUDIO_HARDWARE_DECODERS, + NODE_AUDIO_SOFTWARE_ENCODERS, NODE_AUDIO_SOFTWARE_DECODERS}; + int count = sizeof(codecGroupsNodeName) / sizeof(std::string); + for (int index = 0; index < count; index++) { + if (GetGroupCapabilities(codecGroupsNodeName[index]) != HDF_SUCCESS) { + continue; + } + } + CODEC_LOGD("Init Run....capList_.size=%{public}zu", capList_.size()); +} + +CodecComponentConfig *CodecComponentConfig::GetInstance() +{ + return &config_; +} + +int32_t CodecComponentConfig::GetComponentNum(int32_t &count) +{ + count = capList_.size(); + CODEC_LOGD("enter, count = %{public}d", count); + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetComponentCapabilityList(std::vector &capList, int32_t count) +{ + CODEC_LOGD("count[%{public}d], size[%{public}zu]", count, capList_.size()); + if ((size_t)count > capList_.size()) { + CODEC_LOGW("count[%{public}d] is too large", count); + count = capList_.size(); + } + auto first = capList_.begin(); + auto last = capList_.begin() + count; + capList.assign(first, last); + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetGroupCapabilitiesNumber(const std::string &nodeName, int32_t &num) +{ + int32_t result = 0; + + const struct DeviceResourceNode *codecGroupNode = NULL; + struct DeviceResourceNode *childNode = NULL; + struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (iface == NULL) { + CODEC_LOGE("failed, iface NULL!"); + return HDF_FAILURE; + } + + codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str()); + if (codecGroupNode == NULL) { + CODEC_LOGE("failed to get child node %{public}s,!", nodeName.c_str()); + return HDF_FAILURE; + } + DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) + { + result++; + } + num = result; + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetGroupCapabilities(const std::string &nodeName) +{ + bool isVideoGroup = true; + const struct DeviceResourceNode *codecGroupNode = NULL; + struct DeviceResourceNode *childNode = NULL; + struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (iface == NULL) { + CODEC_LOGE(" failed, iface NULL!"); + return HDF_ERR_INVALID_PARAM; + } + + codecGroupNode = iface->GetChildNode(&node_, nodeName.c_str()); + if (codecGroupNode == NULL) { + CODEC_LOGE("failed to get child node: %{public}s!", nodeName.c_str()); + return HDF_FAILURE; + } + + if (nodeName.find("Video") == std::string::npos) { + isVideoGroup = false; + } + + DEV_RES_NODE_FOR_EACH_CHILD_NODE(codecGroupNode, childNode) + { + CodecCompCapability cap; + if (GetOneCapability(*iface, *childNode, cap, isVideoGroup) != HDF_SUCCESS) { + CODEC_LOGE("GetOneCapability failed, role is %{public}d!", cap.role); + } + capList_.push_back(cap); + } + + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetOneCapability(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &childNode, CodecCompCapability &cap, + bool isVideoGroup) +{ + if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_ROLE, (uint32_t *)&cap.role, MEDIA_ROLETYPE_INVALID) != + HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("failed to get mime for: %{public}s! Discarded", childNode.name); + return HDF_FAILURE; + } + + if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_TYPE, (uint32_t *)&cap.type, INVALID_TYPE) != HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + cap.type = INVALID_TYPE; + CODEC_LOGE("failed to get type for: %{public}s! Discarded", childNode.name); + return HDF_FAILURE; + } + + const char *compName = NULL; + if (iface.GetString(&childNode, CODEC_CONFIG_KEY_NAME, &compName, "") != HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("get attr %{public}s err!", CODEC_CONFIG_KEY_NAME); + return HDF_FAILURE; + } + if (compName == NULL || strlen(compName) == 0) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("compName is null or empty!"); + return HDF_FAILURE; + } + cap.compName = compName; + + cap.isSoftwareCodec = iface.GetBool(&childNode, CODEC_CONFIG_KEY_IS_SOFTWARE_CODEC); + + if (GetMiscOfCapability(iface, childNode, cap) != HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("get misc cap err!"); + return HDF_FAILURE; + } + + if (isVideoGroup) { + if (GetVideoPortCapability(iface, childNode, cap) != HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("get video port cap err!"); + return HDF_FAILURE; + } + } else { + if (GetAudioPortCapability(iface, childNode, cap) != HDF_SUCCESS) { + cap.role = MEDIA_ROLETYPE_INVALID; + CODEC_LOGE("get audio port cap err!"); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetMiscOfCapability(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &childNode, CodecCompCapability &cap) +{ + ConfigUintArrayNodeAttr attr = {CODEC_CONFIG_KEY_SUPPORT_PROFILES, cap.supportProfiles}; + if (GetUintTableConfig(iface, childNode, attr) != HDF_SUCCESS) { + CODEC_LOGE("get uint table config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + + if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_INST, (uint32_t *)&cap.maxInst, 0) != HDF_SUCCESS) { + CODEC_LOGE("get uint32 config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_PROCESS_MODE_MASK, (uint32_t &)cap.processModeMask) != + HDF_SUCCESS) { + CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + if (GetMaskedConfig(iface, childNode, CODEC_CONFIG_KEY_CAPS_MASK, (uint32_t &)cap.capsMask) != HDF_SUCCESS) { + CODEC_LOGE("get masked config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MIN_BITRATE, (uint32_t *)&(cap.bitRate.min), 0) != HDF_SUCCESS) { + CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + if (iface.GetUint32(&childNode, CODEC_CONFIG_KEY_MAX_BITRATE, (uint32_t *)&(cap.bitRate.max), 0) != HDF_SUCCESS) { + CODEC_LOGE("get uin32 config [%{public}s] err!", attr.attrName.c_str()); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetUintTableConfig(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &node, ConfigUintArrayNodeAttr &attr) +{ + if (attr.attrName.empty()) { + CODEC_LOGE("failed, invalid attr!"); + return HDF_ERR_INVALID_PARAM; + } + + int32_t count = iface.GetElemNum(&node, attr.attrName.c_str()); + if (count < 0) { + CODEC_LOGE("%{public}s table size: count[%{public}d] < 0!", attr.attrName.c_str(), count); + return HDF_FAILURE; + } + if (count > 0) { + std::unique_ptr array = std::make_unique(count); + iface.GetUint32Array(&node, attr.attrName.c_str(), (uint32_t *)array.get(), count, 0); + attr.vec.assign(array.get(), array.get() + count); + } + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetMaskedConfig(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &node, const std::string &attrName, + uint32_t &mask) +{ + int32_t count = iface.GetElemNum(&node, attrName.c_str()); + + mask = 0; + if (count < 0 || count > MASK_NUM_LIMIT) { + CODEC_LOGE("failed, count %{public}d incorrect!", count); + return HDF_FAILURE; + } + + if (count > 0) { + std::unique_ptr values = std::make_unique(count); + if (values == NULL) { + CODEC_LOGE("failed to allocate mem for %{public}s!", attrName.c_str()); + return HDF_FAILURE; + } + iface.GetUint32Array(&node, attrName.c_str(), values.get(), count, 0); + for (int32_t index = 0; index < count; index++) { + mask |= values[index]; + } + } + + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetVideoPortCapability(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &childNode, + CodecCompCapability &cap) +{ + ConfigUintNodeAttr nodeAttrs[] = { + {CODEC_CONFIG_KEY_MIN_WIDTH, cap.port.video.minSize.width, 0}, + {CODEC_CONFIG_KEY_MIN_HEIGHT, cap.port.video.minSize.height, 0}, + {CODEC_CONFIG_KEY_MAX_WIDTH, cap.port.video.maxSize.width, 0}, + {CODEC_CONFIG_KEY_MAX_HEIGHT, cap.port.video.maxSize.height, 0}, + {CODEC_CONFIG_KEY_WIDTH_ALIGNMENT, cap.port.video.whAlignment.widthAlignment, 0}, + {CODEC_CONFIG_KEY_HEIGHT_ALIGNMENT, cap.port.video.whAlignment.heightAlignment, 0}, + {CODEC_CONFIG_KEY_MIN_BLOCK_COUNT, cap.port.video.blockCount.min, 0}, + {CODEC_CONFIG_KEY_MAX_BLOCK_COUNT, cap.port.video.blockCount.max, 0}, + {CODEC_CONFIG_KEY_MIN_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.min, 0}, + {CODEC_CONFIG_KEY_MAX_BLOCKS_PER_SECOND, cap.port.video.blocksPerSecond.max, 0}, + {CODEC_CONFIG_KEY_BLOCK_SIZE_WIDTH, cap.port.video.blockSize.width, 0}, + {CODEC_CONFIG_KEY_BLOCK_SIZE_HEIGHT, cap.port.video.blockSize.height, 0}, + {CODEC_CONFIG_KEY_MIN_FRAME_RATE, cap.port.video.frameRate.min, 0}, + {CODEC_CONFIG_KEY_MAX_FRAME_RATE, cap.port.video.frameRate.max, 0}}; + + int32_t count = sizeof(nodeAttrs) / sizeof(ConfigUintNodeAttr); + for (int32_t i = 0; i < count; i++) { + if (iface.GetUint32(&childNode, nodeAttrs[i].attrName.c_str(), (uint32_t *)&nodeAttrs[i].value, + nodeAttrs[i].defaultValue) != HDF_SUCCESS) { + CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str()); + return HDF_FAILURE; + } + } + ConfigUintArrayNodeAttr arrayAttrs[] = { + {CODEC_CONFIG_KEY_SUPPORT_PIXEL_FMTS, cap.port.video.supportPixFmts}, + {CODEC_CONFIG_KEY_BITE_RATE_MODE, (std::vector &)cap.port.video.bitRatemode}, + {CODEC_CONFIG_KEY_MESURED_FRAME_RATE, cap.port.video.measuredFrameRate}}; + + count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr); + for (int32_t i = 0; i < count; i++) { + if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) { + CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, nodeAttrs[i].attrName.c_str()); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +int32_t CodecComponentConfig::GetAudioPortCapability(const struct DeviceResourceIface &iface, + const struct DeviceResourceNode &childNode, + CodecCompCapability &cap) +{ + ConfigUintArrayNodeAttr arrayAttrs[] = {{CODEC_CONFIG_KEY_SAMPLE_FORMATS, cap.port.audio.sampleFormats}, + {CODEC_CONFIG_KEY_SAMPLE_RATE, cap.port.audio.sampleRate}, + {CODEC_CONFIG_KEY_CHANNEL_LAYOUTS, cap.port.audio.channelLayouts}, + {CODEC_CONFIG_KEY_CHANNEL_COUNT, cap.port.audio.channelCount}}; + + int32_t count = sizeof(arrayAttrs) / sizeof(ConfigUintArrayNodeAttr); + for (int32_t i = 0; i < count; i++) { + if (GetUintTableConfig(iface, childNode, arrayAttrs[i]) != HDF_SUCCESS) { + CODEC_LOGE("failed to get %{public}s.%{public}s!", childNode.name, arrayAttrs[i].attrName.c_str()); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/codec_component_manager_driver.cpp b/codec/hal/idl_service/src/codec_component_manager_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09e01d36464c32fa595f5518492fb27c185a14fd --- /dev/null +++ b/codec/hal/idl_service/src/codec_component_manager_driver.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "codec_component_config.h" +#include "v1_0/codec_component_manager_stub.h" +using namespace OHOS::HDI::Codec::V1_0; + +struct HdfCodecComponentManagerHost { + struct IDeviceIoService ioService; + OHOS::sptr stub; +}; + +static int32_t CodecComponentManagerDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, + struct HdfSBuf *reply) +{ + auto *hdfCodecComponentManagerHost = + CONTAINER_OF(client->device->service, struct HdfCodecComponentManagerHost, ioService); + + OHOS::MessageParcel *dataParcel = nullptr; + OHOS::MessageParcel *replyParcel = nullptr; + OHOS::MessageOption option; + + if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { + HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { + HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__); + return HDF_ERR_INVALID_PARAM; + } + + return hdfCodecComponentManagerHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option); +} + +static int HdfCodecComponentManagerDriverInit(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("HdfCodecComponentManagerDriverInit enter"); + OHOS::Codec::Omx::CodecComponentConfig::GetInstance()->Init(*deviceObject->property); + return HDF_SUCCESS; +} + +static int HdfCodecComponentManagerDriverBind(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("HdfCodecComponentManagerDriverBind enter"); + + auto *hdfCodecComponentManagerHost = new (std::nothrow) HdfCodecComponentManagerHost; + if (hdfCodecComponentManagerHost == nullptr) { + HDF_LOGE("%{public}s: failed to create create HdfCodecComponentManagerHost object", __func__); + return HDF_FAILURE; + } + + hdfCodecComponentManagerHost->ioService.Dispatch = CodecComponentManagerDriverDispatch; + hdfCodecComponentManagerHost->ioService.Open = NULL; + hdfCodecComponentManagerHost->ioService.Release = NULL; + + auto serviceImpl = ICodecComponentManager::Get(true); + if (serviceImpl == nullptr) { + HDF_LOGE("%{public}s: failed to get of implement service", __func__); + delete hdfCodecComponentManagerHost; + return HDF_FAILURE; + } + + hdfCodecComponentManagerHost->stub = + OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, ICodecComponentManager::GetDescriptor()); + if (hdfCodecComponentManagerHost->stub == nullptr) { + HDF_LOGE("%{public}s: failed to get stub object", __func__); + delete hdfCodecComponentManagerHost; + return HDF_FAILURE; + } + + deviceObject->service = &hdfCodecComponentManagerHost->ioService; + return HDF_SUCCESS; +} + +static void HdfCodecComponentManagerDriverRelease(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("HdfCodecComponentManagerDriverRelease enter"); + if (deviceObject->service == nullptr) { + HDF_LOGE("HdfCodecComponentManagerDriverRelease not initted"); + return; + } + + auto *hdfCodecComponentManagerHost = + CONTAINER_OF(deviceObject->service, struct HdfCodecComponentManagerHost, ioService); + delete hdfCodecComponentManagerHost; +} + +static struct HdfDriverEntry g_codeccomponentmanagerDriverEntry = { + .moduleVersion = 1, + .moduleName = "libcodec_driver.z.so", + .Bind = HdfCodecComponentManagerDriverBind, + .Init = HdfCodecComponentManagerDriverInit, + .Release = HdfCodecComponentManagerDriverRelease, +}; + +#ifndef __cplusplus +extern "C" { +#endif +HDF_INIT(g_codeccomponentmanagerDriverEntry); +#ifndef __cplusplus +} +#endif diff --git a/codec/hal/idl_service/src/codec_component_manager_service.cpp b/codec/hal/idl_service/src/codec_component_manager_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6963466749588352ca9b2f827dd5c187bbcc4fe --- /dev/null +++ b/codec/hal/idl_service/src/codec_component_manager_service.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_component_manager_service.h" +#include +#include "codec_component_config.h" +#include "codec_component_service.h" +#include "codec_log_wrapper.h" +#include "component_node.h" +namespace OHOS { +namespace HDI { +namespace Codec { +namespace V1_0 { +using OHOS::Codec::Omx::ComponentNode; +extern "C" ICodecComponentManager *CodecComponentManagerImplGetInstance(void) +{ + return new (std::nothrow) CodecComponentManagerService(); +} + +CodecComponentManagerService::CodecComponentManagerService() : componentId_(0) +{ + mgr_ = std::make_shared(); +} + +int32_t CodecComponentManagerService::GetComponentNum(int32_t &count) +{ + return OHOS::Codec::Omx::CodecComponentConfig::GetInstance()->GetComponentNum(count); +} + +int32_t CodecComponentManagerService::GetComponentCapabilityList(std::vector &capList, + int32_t count) +{ + return OHOS::Codec::Omx::CodecComponentConfig::GetInstance()->GetComponentCapabilityList(capList, count); +} + +int32_t CodecComponentManagerService::CreateComponent(sptr &component, uint32_t &componentId, + const std::string &compName, int64_t appData, + const sptr &callbacks) +{ + CODEC_LOGD("compName[%{public}s]", compName.c_str()); + std::shared_ptr node = std::make_shared(callbacks, appData, mgr_); + auto err = node->OpenHandle(compName); + if (err != HDF_SUCCESS) { + CODEC_LOGE("OpenHandle faled, err[%{public}d]", err); + node = nullptr; + return err; + } + + sptr codecComponent = new CodecComponentService(node); + std::unique_lock autoLock(mutex_); + componentId = GetNextComponentId(); + componentMap_.emplace(std::make_pair(componentId, codecComponent)); + component = codecComponent; + CODEC_LOGD("componentId[%{public}d]", componentId); + return HDF_SUCCESS; +} + +int32_t CodecComponentManagerService::DestoryComponent(uint32_t componentId) +{ + CODEC_LOGD("componentId[%{public}d]", componentId); + auto iter = componentMap_.find(componentId); + if (iter == componentMap_.end() || iter->second == nullptr) { + CODEC_LOGE(" can not find component service by componentId[%{public}d]", componentId); + return HDF_ERR_INVALID_PARAM; + } + + std::unique_lock autoLock(mutex_); + componentMap_.erase(iter); + return HDF_SUCCESS; +} + +uint32_t CodecComponentManagerService::GetNextComponentId(void) +{ + uint32_t tempId = 0; + do { + tempId = ++componentId_; + } while (componentMap_.find(tempId) != componentMap_.end()); + return tempId; +} + +void CodecComponentManagerService::LoadCapabilityData(const DeviceResourceNode &node) +{ + resourceNode_ = node; +} +} // namespace V1_0 +} // namespace Codec +} // namespace HDI +} // namespace OHOS diff --git a/codec/hal/idl_service/src/codec_component_service.cpp b/codec/hal/idl_service/src/codec_component_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb6329c30c42344f2df4cb866558a4615e726486 --- /dev/null +++ b/codec/hal/idl_service/src/codec_component_service.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_component_service.h" +#include +#include "codec_log_wrapper.h" +namespace OHOS { +namespace HDI { +namespace Codec { +namespace V1_0 { +int32_t CodecComponentService::GetComponentVersion(CompVerInfo &verInfo) +{ + return node_->GetComponentVersion(verInfo); +} + +int32_t CodecComponentService::SendCommand(OMX_COMMANDTYPE cmd, uint32_t param, const std::vector &cmdData) +{ + CODEC_LOGD("cmd [%{public}d]", cmd); + return node_->SendCommand(cmd, param, const_cast(cmdData.data())); +} + +int32_t CodecComponentService::GetParameter(uint32_t index, const std::vector &inParamStruct, + std::vector &outParamStruct) +{ + CODEC_LOGD("index [%{public}d]", index); + outParamStruct = inParamStruct; + return node_->GetParameter(static_cast(index), outParamStruct.data()); +} + +int32_t CodecComponentService::SetParameter(uint32_t index, const std::vector ¶mStruct) +{ + CODEC_LOGD("index [%{public}d]", index); + return node_->SetParameter(static_cast(index), paramStruct.data()); +} + +int32_t CodecComponentService::GetConfig(uint32_t index, const std::vector &inCfgStruct, + std::vector &outCfgStruct) +{ + CODEC_LOGD("index [%{public}d]", index); + outCfgStruct = inCfgStruct; + return node_->GetConfig(static_cast(index), outCfgStruct.data()); +} + +int32_t CodecComponentService::SetConfig(uint32_t index, const std::vector &cfgStruct) +{ + CODEC_LOGD("index [%{public}d]", index); + return node_->SetConfig(static_cast(index), cfgStruct.data()); +} + +int32_t CodecComponentService::GetExtensionIndex(const std::string ¶mName, uint32_t &indexType) +{ + CODEC_LOGD("paramName [%{public}s]", paramName.c_str()); + return node_->GetExtensionIndex(paramName.c_str(), indexType); +} + +int32_t CodecComponentService::GetState(OMX_STATETYPE &state) +{ + return node_->GetState(state); +} + +int32_t CodecComponentService::ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort, + const OMX_TUNNELSETUPTYPE &inTunnelSetup, + OMX_TUNNELSETUPTYPE &outTunnelSetup) +{ + CODEC_LOGD("port [%{public}d]", port); + outTunnelSetup = inTunnelSetup; + return node_->ComponentTunnelRequest(port, tunneledComp, tunneledPort, outTunnelSetup); +} + +int32_t CodecComponentService::UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer) +{ + CODEC_LOGD("portIndex [%{public}d]", portIndex); + outBuffer = inBuffer; + return node_->UseBuffer(portIndex, outBuffer); +} + +int32_t CodecComponentService::AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, + OmxCodecBuffer &outBuffer) +{ + CODEC_LOGD("portIndex [%{public}d]", portIndex); + outBuffer = inBuffer; + return node_->AllocateBuffer(portIndex, outBuffer); +} + +int32_t CodecComponentService::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer) +{ + CODEC_LOGD("portIndex [%{public}d]", portIndex); + return node_->FreeBuffer(portIndex, buffer); +} + +int32_t CodecComponentService::EmptyThisBuffer(const OmxCodecBuffer &buffer) +{ + return node_->EmptyThisBuffer(const_cast(buffer)); +} + +int32_t CodecComponentService::FillThisBuffer(const OmxCodecBuffer &buffer) +{ + return node_->FillThisBuffer(const_cast(buffer)); +} + +int32_t CodecComponentService::SetCallbacks(const sptr &callbacks, int64_t appData) +{ + return node_->SetCallbacks(callbacks, appData); +} + +int32_t CodecComponentService::ComponentDeInit() +{ + return node_->ComponentDeInit(); +} + +int32_t CodecComponentService::UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer, + OmxCodecBuffer &outBuffer, const std::vector &eglImage) +{ + CODEC_LOGD("portIndex [%{public}d]", portIndex); + outBuffer = inBuffer; + return node_->UseEglImage(outBuffer, portIndex, eglImage.data()); +} + +int32_t CodecComponentService::ComponentRoleEnum(std::vector &role, uint32_t index) +{ + CODEC_LOGD("index [%{public}d]", index); + return node_->ComponentRoleEnum(role, index); +} +} // namespace V1_0 +} // namespace Codec +} // namespace HDI +} // namespace OHOS diff --git a/codec/hal/idl_service/src/codec_dyna_buffer.cpp b/codec/hal/idl_service/src/codec_dyna_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc959b38e40da36ab8335a41aa1874afa040548e --- /dev/null +++ b/codec/hal/idl_service/src/codec_dyna_buffer.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "codec_dyna_buffer.h" +#include +#include +#include +#include +#include +#include "v1_0/codec_types.h" +using namespace OHOS::HDI::Codec::V1_0; +namespace OHOS { +namespace Codec { +namespace Omx { +CodecDynaBuffer::CodecDynaBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecDynaBuffer::~CodecDynaBuffer() +{ + if (dynaBuffer_ != nullptr) { + dynaBuffer_ = nullptr; + } +} + +sptr CodecDynaBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + BufferHandle *bufferHandle = nullptr; + if (codecBuffer.bufferhandle) { + bufferHandle = codecBuffer.bufferhandle->Move(); + codecBuffer.bufferhandle = nullptr; + } + CodecDynaBuffer *buffer = new CodecDynaBuffer(codecBuffer); + buffer->dynaBuffer_ = std::make_shared(); + buffer->dynaBuffer_->bufferHandle = bufferHandle; + return sptr(buffer); +} + +int32_t CodecDynaBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s :dyna buffer handle is not supported in FillThisBuffer ", __func__); + (void)codecBuffer; + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecDynaBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s : CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + ResetBuffer(codecBuffer, omxBuffer); + + int fence = codecBuffer.fenceFd; + if (fence >= 0) { + sync_wait(fence, TIME_WAIT_MS); + close(codecBuffer.fenceFd); + codecBuffer.fenceFd = -1; + } + + return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecDynaBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (codecBuffer.bufferhandle != nullptr) { + codecBuffer.bufferhandle = nullptr; + } + if (dynaBuffer_ != nullptr) { + dynaBuffer_ = nullptr; + } + + return HDF_SUCCESS; +} + +int32_t CodecDynaBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::EmptyOmxBufferDone(omxBuffer); +} + +int32_t CodecDynaBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s :dyna buffer handle is not supported in FillThisBuffer ", __func__); + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +uint8_t *CodecDynaBuffer::GetBuffer() +{ + return reinterpret_cast(dynaBuffer_.get()); +} + +bool CodecDynaBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || dynaBuffer_ == nullptr) { + HDF_LOGE("%{public}s :dynaBuffer_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecDynaBuffer::ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + (void)omxBuffer; + if (codecBuffer.bufferhandle == nullptr) { + return; + } + auto bufferHandle = codecBuffer.bufferhandle->Move(); + codecBuffer.bufferhandle = nullptr; + + // if recv new BufferHandle, save it, but do not need to save to omxBuffer + if (dynaBuffer_->bufferHandle != nullptr) { + FreeBufferHandle(dynaBuffer_->bufferHandle); + } + dynaBuffer_->bufferHandle = bufferHandle; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/codec_handle_buffer.cpp b/codec/hal/idl_service/src/codec_handle_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b66e1d2df493bb2158b49c7fa16f92e7b9bcde4f --- /dev/null +++ b/codec/hal/idl_service/src/codec_handle_buffer.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_handle_buffer.h" +#include +#include +#include +#include +#include "v1_0/codec_types.h" +using namespace OHOS::HDI::Codec::V1_0; +namespace OHOS { +namespace Codec { +namespace Omx { +CodecHandleBuffer::CodecHandleBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecHandleBuffer::~CodecHandleBuffer() +{ + if (bufferHandle_ != nullptr) { + FreeBufferHandle(bufferHandle_); + bufferHandle_ = nullptr; + } +} + +sptr CodecHandleBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + if (codecBuffer.bufferhandle == nullptr) { + HDF_LOGE("%{public}s error, bufferHandle is null", __func__); + return nullptr; + } + auto bufferHandle = codecBuffer.bufferhandle->Move(); + codecBuffer.bufferhandle = nullptr; + CodecHandleBuffer *buffer = new CodecHandleBuffer(codecBuffer); + buffer->bufferHandle_ = bufferHandle; + return sptr(buffer); +} + +int32_t CodecHandleBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :CheckInvalid return false or mem has no right to write ", __func__); + return HDF_ERR_INVALID_PARAM; + } + ResetBuffer(codecBuffer, omxBuffer); + + int fenceFd = codecBuffer.fenceFd; + if (fenceFd >= 0) { + sync_wait(fenceFd, TIME_WAIT_MS); + close(codecBuffer.fenceFd); + codecBuffer.fenceFd = -1; + } + return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecHandleBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s : bufferHandle is not support in EmptyThisBuffer", __func__); + (void)codecBuffer; + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecHandleBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + codecBuffer.bufferhandle = nullptr; + if (bufferHandle_ != nullptr) { + FreeBufferHandle(bufferHandle_); + bufferHandle_ = nullptr; + } + + return HDF_SUCCESS; +} + +int32_t CodecHandleBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + HDF_LOGE("%{public}s : bufferHandle is not support in EmptyThisBuffer", __func__); + (void)omxBuffer; + return HDF_ERR_INVALID_PARAM; +} + +int32_t CodecHandleBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::FillOmxBufferDone(omxBuffer); +} + +uint8_t *CodecHandleBuffer::GetBuffer() +{ + return reinterpret_cast(bufferHandle_); +} + +bool CodecHandleBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || bufferHandle_ == nullptr) { + HDF_LOGE("%{public}s :bufferHandle_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecHandleBuffer::ResetBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (codecBuffer.bufferhandle == nullptr) { + return; + } + auto bufferHandle = codecBuffer.bufferhandle->Move(); + codecBuffer.bufferhandle = nullptr; + // if recv new BufferHandle, save it, and save the new bufferhandle to omxbuffer + if (bufferHandle == nullptr) { + return; + } + if (bufferHandle_ != nullptr) { + FreeBufferHandle(bufferHandle_); + } + bufferHandle_ = bufferHandle; + omxBuffer.pBuffer = reinterpret_cast(bufferHandle_); +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/codec_omx_core.cpp b/codec/hal/idl_service/src/codec_omx_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e92c3338df27637f9c2ee5f8adb8cbc8edae7c83 --- /dev/null +++ b/codec/hal/idl_service/src/codec_omx_core.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_omx_core.h" +#include +#include +#include +#include +#include +#include +namespace OHOS { +namespace Codec { +namespace Omx { +CodecOMXCore::~CodecOMXCore() +{ + if (libHandle_ != nullptr) { + dlclose(libHandle_); + } +} +int32_t CodecOMXCore::Init(const std::string &libName) +{ + libHandle_ = dlopen(libName.c_str(), RTLD_LAZY); + if (libHandle_ == NULL) { + HDF_LOGE("%{public}s:failed to dlopen %{public}s.", __func__, libName.c_str()); + return HDF_ERR_INVALID_PARAM; + } + + init_ = (InitFunc)dlsym(libHandle_, "OMX_Init"); + deInit_ = (DeinitFunc)dlsym(libHandle_, "OMX_Deinit"); + getHandle_ = (GetHandleFunc)dlsym(libHandle_, "OMX_GetHandle"); + freeHandle_ = (FreeHandleFunc)dlsym(libHandle_, "OMX_FreeHandle"); + getRoles_ = (GetRolesOfComponentFunc)dlsym(libHandle_, "OMX_GetRolesOfComponent"); + componentNameEnum_ = (ComponentNameEnumFunc)dlsym(libHandle_, "OMX_ComponentNameEnum"); + + if (init_ != NULL) { + (*(init_))(); + } + return HDF_SUCCESS; +} + +void CodecOMXCore::DeInit() +{ + if (deInit_) { + (*deInit_)(); + } +} + +int32_t CodecOMXCore::GetHandle(OMX_HANDLETYPE &handle, std::string &compName, OMX_PTR appData, + const OMX_CALLBACKTYPE &callbacks) +{ + if (getHandle_ == nullptr) { + HDF_LOGE("%{public}s: getHandle is null.", __func__); + return HDF_ERR_INVALID_PARAM; + } + return (*getHandle_)(&handle, const_cast(compName.c_str()), appData, (OMX_CALLBACKTYPE *)&callbacks); +} + +int32_t CodecOMXCore::FreeHandle(OMX_HANDLETYPE handle) +{ + if (freeHandle_ == nullptr) { + HDF_LOGE("%{public}s: freeHandle_ is null.", __func__); + return HDF_ERR_INVALID_PARAM; + } + return (*freeHandle_)(handle); +} + +int32_t CodecOMXCore::ComponentNameEnum(std::string &name, uint32_t index) +{ + if (componentNameEnum_ == nullptr) { + HDF_LOGE("%{public}s: componentNameEnum is null.", __func__); + return HDF_ERR_INVALID_PARAM; + } + char tmpComponentName[OMX_MAX_STRINGNAME_SIZE] = {0}; + uint32_t err = (*(componentNameEnum_))(tmpComponentName, OMX_MAX_STRINGNAME_SIZE, index); + if (err == HDF_SUCCESS) { + name = tmpComponentName; + } + return err; +} +int32_t CodecOMXCore::GetRolesOfComponent(std::string &name, std::vector &roles) +{ + if (getRoles_ == nullptr) { + HDF_LOGE("%{public}s: getRoles is null.", __func__); + return HDF_ERR_INVALID_PARAM; + } + uint32_t roleCount = 0; + uint32_t err = (*getRoles_)(const_cast(name.c_str()), &roleCount, nullptr); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s: getRoles_ return err [%{public}x].", __func__, err); + return err; + } + if (roleCount <= 0) { + return err; + } + + char role[roleCount][OMX_MAX_STRINGNAME_SIZE]; + uint32_t bufferSize = sizeof(char) * (roleCount * OMX_MAX_STRINGNAME_SIZE); + err = memset_s(role, sizeof(role), 0, bufferSize); + if (err != EOK) { + HDF_LOGE("%{public}s: memset_s return err [%{public}x].", __func__, err); + return err; + } + + uint32_t roleLen = roleCount; + err = (*getRoles_)(const_cast(name.c_str()), &roleCount, reinterpret_cast(role)); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s: getRoles_ return err [%{public}x].", __func__, err); + return err; + } + for (uint32_t i = 0; i < roleLen; i++) { + roles.push_back(role[i]); + } + + return err; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/codec_share_buffer.cpp b/codec/hal/idl_service/src/codec_share_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..980c80d84c21c64422dcd85964512b1971ecd0b7 --- /dev/null +++ b/codec/hal/idl_service/src/codec_share_buffer.cpp @@ -0,0 +1,180 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_share_buffer.h" +#include +#include +#include +#include +using namespace OHOS::HDI::Codec::V1_0; +namespace OHOS { +namespace Codec { +namespace Omx { +CodecShareBuffer::CodecShareBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) +{} + +CodecShareBuffer::~CodecShareBuffer() +{ + if (shMem_ != nullptr) { + shMem_->UnmapAshmem(); + shMem_->CloseAshmem(); + shMem_ = nullptr; + } +} + +void CodecShareBuffer::SetAshMem(std::shared_ptr shMem) +{ + shMem_ = shMem; +} + +OHOS::sptr CodecShareBuffer::Create(struct OmxCodecBuffer &codecBuffer) +{ + if (codecBuffer.fd < 0) { + HDF_LOGE("%{public}s error, codecBuffer.fd < 0", __func__); + return nullptr; + } + int size = OHOS::AshmemGetSize(codecBuffer.fd); + std::shared_ptr sharedMem = std::make_shared(codecBuffer.fd, size); + bool mapd = false; + if (codecBuffer.type == READ_WRITE_TYPE) { + mapd = sharedMem->MapReadAndWriteAshmem(); + } else { + mapd = sharedMem->MapReadOnlyAshmem(); + } + if (!mapd) { + HDF_LOGE("%{public}s error, MapReadAndWriteAshmem or MapReadOnlyAshmem return false", __func__); + return nullptr; + } + codecBuffer.fd = -1; + CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); + buffer->SetAshMem(sharedMem); + return OHOS::sptr(buffer); +} + +OHOS::sptr CodecShareBuffer::Allocate(struct OmxCodecBuffer &codecBuffer) +{ + codecBuffer.bufferType = CODEC_BUFFER_TYPE_AVSHARE_MEM_FD; + // create shared memory + int sharedFD = AshmemCreate(nullptr, codecBuffer.allocLen); + + std::shared_ptr sharedMemory = std::make_shared(sharedFD, codecBuffer.allocLen); + codecBuffer.type = READ_WRITE_TYPE; + bool mapd = false; + if (codecBuffer.type == READ_WRITE_TYPE) { + mapd = sharedMemory->MapReadAndWriteAshmem(); + } else { + mapd = sharedMemory->MapReadOnlyAshmem(); + } + if (!mapd) { + HDF_LOGE("%{public}s error, MapReadAndWriteAshmem or MapReadOnlyAshmem return false", __func__); + return nullptr; + } + codecBuffer.offset = 0; + codecBuffer.filledLen = 0; + CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); + codecBuffer.fd = sharedFD; + buffer->SetAshMem(sharedMemory); + return OHOS::sptr(buffer); +} + +int32_t CodecShareBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer) || codecBuffer_.type != READ_WRITE_TYPE) { + HDF_LOGE("%{public}s :CheckInvalid return false or mem has no right to write ", __func__); + return HDF_ERR_INVALID_PARAM; + } + ReleaseFd(codecBuffer); + return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecShareBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ReleaseFd(codecBuffer); + + void *sharedPtr = const_cast(shMem_->ReadFromAshmem(codecBuffer.filledLen, codecBuffer.offset)); + if (!sharedPtr) { + HDF_LOGE("%{public}s error, omxBuffer.length [%{public}d omxBuffer.offset[%{public}d]", __func__, + codecBuffer.filledLen, codecBuffer.offset); + return HDF_ERR_INVALID_PARAM; + } + auto ret = memcpy_s(omxBuffer.pBuffer + codecBuffer.offset, codecBuffer.allocLen - codecBuffer.offset, sharedPtr, + codecBuffer.filledLen); + if (ret != EOK) { + HDF_LOGE("%{public}s error, memcpy_s ret [%{public}d", __func__, ret); + return HDF_ERR_INVALID_PARAM; + } + return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer); +} + +int32_t CodecShareBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + if (!CheckInvalid(codecBuffer)) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return HDF_ERR_INVALID_PARAM; + } + + ReleaseFd(codecBuffer); + + shMem_->UnmapAshmem(); + shMem_->CloseAshmem(); + shMem_ = nullptr; + return HDF_SUCCESS; +} + +uint8_t *CodecShareBuffer::GetBuffer() +{ + return nullptr; +} + +int32_t CodecShareBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + return ICodecBuffer::EmptyOmxBufferDone(omxBuffer); +} + +int32_t CodecShareBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + if (shMem_ == nullptr || !shMem_->WriteToAshmem(omxBuffer.pBuffer, omxBuffer.nFilledLen, omxBuffer.nOffset)) { + HDF_LOGE("%{public}s write to ashmem[%{public}p] fail", __func__, shMem_.get()); + return HDF_ERR_INVALID_PARAM; + } + + return ICodecBuffer::FillOmxBufferDone(omxBuffer); +} + +bool CodecShareBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (!ICodecBuffer::CheckInvalid(codecBuffer) || shMem_ == nullptr) { + HDF_LOGE("%{public}s :shMem_ is null or CheckInvalid return false", __func__); + return false; + } + return true; +} + +void CodecShareBuffer::ReleaseFd(struct OmxCodecBuffer &codecBuffer) +{ + // close the fd, if fd is sent by codecBuffer + if (codecBuffer.fd >= 0) { + close(codecBuffer.fd); + codecBuffer.fd = -1; + } +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/component_mgr.cpp b/codec/hal/idl_service/src/component_mgr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5db39ad1f0515e9baaf87f5c14950c491ba20e2a --- /dev/null +++ b/codec/hal/idl_service/src/component_mgr.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "component_mgr.h" +#include +#include +#include +#include +#include +#include +#define HDF_LOG_TAG codec_hdi_server + +namespace OHOS { +namespace Codec { +namespace Omx { +ComponentMgr::ComponentMgr() +{ + AddVendorComponent(); + AddSoftComponent(); +} + +ComponentMgr::~ComponentMgr() +{ + CleanComponent(); +} + +int32_t ComponentMgr::CreateComponentInstance(const char *componentName, const OMX_CALLBACKTYPE *callbacks, + void *appData, OMX_COMPONENTTYPE **component) +{ + int32_t err = HDF_ERR_INVALID_PARAM; + std::lock_guard lk(mutex_); + + auto iter = compoentsCore_.find(componentName); + if (iter == compoentsCore_.end() || iter->second == nullptr) { + HDF_LOGE("%{public}s: can not find component[%{public}s] in core", __func__, componentName); + return err; + } + auto core = iter->second; + OMX_HANDLETYPE handle = nullptr; + std::string name(componentName); + err = core->GetHandle(handle, name, appData, *callbacks); + if (err == OMX_ErrorNone && handle) { + OMXComponent comp; + comp.core = core; + *component = reinterpret_cast(handle); + comp.handle = handle; + components_.push_back(comp); + } + return err; +} + +int32_t ComponentMgr::DeleteComponentInstance(OMX_COMPONENTTYPE *component) +{ + int32_t err = OMX_ErrorInvalidComponent; + for (size_t i = 0; i < components_.size(); i++) { + if (components_[i].handle == component) { + err = components_[i].core->FreeHandle(components_[i].handle); + components_.erase(components_.begin() + i); + break; + } + } + return err; +} + +int32_t ComponentMgr::GetRolesForComponent(const char *componentName, std::vector *roles) +{ + (void)roles; + (void)componentName; + return OMX_ErrorNone; +} + +void ComponentMgr::AddVendorComponent() +{ + std::string path = HDF_LIBRARY_FULL_PATH("libOMX_Core"); + AddComponentByLibName(path.c_str()); +} + +void ComponentMgr::AddSoftComponent() +{} + +void ComponentMgr::AddComponentByLibName(const char *libName) +{ + auto core = std::make_shared(); + core->Init(libName); + std::lock_guard lk(mutex_); + cores_.emplace_back(core); + std::string name(""); + uint32_t index = 0; + while (HDF_SUCCESS == core->ComponentNameEnum(name, index)) { + ++index; + compoentsCore_.emplace(std::make_pair(name, core)); + } +} + +void ComponentMgr::CleanComponent() +{ + std::lock_guard lk(mutex_); + for (size_t i = 0; i < components_.size(); i++) { + components_[i].core->FreeHandle(components_[i].handle); + } + components_.clear(); + + for (size_t i = 0; i < cores_.size(); i++) { + cores_[i]->DeInit(); + } + cores_.clear(); + + compoentsCore_.clear(); +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/component_node.cpp b/codec/hal/idl_service/src/component_node.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3cb7ddab14cf0a037ef82dadfbb4279c75bfc36e --- /dev/null +++ b/codec/hal/idl_service/src/component_node.cpp @@ -0,0 +1,509 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "component_node.h" +#include +#include +#include +#include "codec_log_wrapper.h" +#include "component_mgr.h" +#include "icodec_buffer.h" + +using OHOS::HDI::Codec::V1_0::EventInfo; +#define FD_SIZE sizeof(int) +constexpr int NAME_LENGTH = 32; +constexpr int ROLE_MAX_LEN = 256; +namespace OHOS { +namespace Codec { +namespace Omx { +OMX_ERRORTYPE ComponentNode::OnEvent(OMX_HANDLETYPE component, void *appData, OMX_EVENTTYPE event, uint32_t data1, + uint32_t data2, void *eventData) +{ + ComponentNode *node = (ComponentNode *)appData; + (void)component; + if (node != nullptr) { + node->OnEvent(event, data1, data2, eventData); + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE ComponentNode::OnEmptyBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer) +{ + ComponentNode *node = (ComponentNode *)appData; + (void)component; + if (node != nullptr) { + node->OnEmptyBufferDone(buffer); + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE ComponentNode::OnFillBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer) +{ + ComponentNode *node = (ComponentNode *)appData; + (void)component; + if (node != nullptr) { + node->OnFillBufferDone(buffer); + } + return OMX_ErrorNone; +} + +OMX_CALLBACKTYPE ComponentNode::callbacks_ = {&ComponentNode::OnEvent, &ComponentNode::OnEmptyBufferDone, + &ComponentNode::OnFillBufferDone}; + +ComponentNode::ComponentNode(const sptr &callbacks, int64_t appData, std::shared_ptr &mgr) +{ + omxCallback_ = callbacks; + appData_ = appData; + comp_ = nullptr; + codecBufferMap_.clear(); + bufferHeaderMap_.clear(); + bufferIdCount_ = 0; + mgr_ = mgr; +} + +ComponentNode::~ComponentNode() +{ + if (omxCallback_ != nullptr) { + omxCallback_ = nullptr; + } + codecBufferMap_.clear(); + bufferHeaderMap_.clear(); + bufferIdCount_ = 0; + if (comp_ != nullptr) { + mgr_->DeleteComponentInstance(static_cast(comp_)); + comp_ = nullptr; + } +} + +int32_t ComponentNode::OpenHandle(const std::string &name) +{ + if (comp_ != nullptr) { + return HDF_SUCCESS; + } + + OMX_COMPONENTTYPE *comp = nullptr; + auto err = mgr_->CreateComponentInstance(name.c_str(), &callbacks_, this, &comp); + if (err != OMX_ErrorNone) { + CODEC_LOGE("CreateComponentInstance err = %{public}x ", err); + return err; + } + this->comp_ = (OMX_HANDLETYPE)comp; + return HDF_SUCCESS; +} + +int32_t ComponentNode::GetComponentVersion(CompVerInfo &verInfo) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + char name[NAME_LENGTH] = {0}; + OMX_UUIDTYPE uuid = {0}; + OMX_VERSIONTYPE compVersion = {.nVersion = 0}; + OMX_VERSIONTYPE sepcVersion = {.nVersion = 0}; + int32_t err = OMX_GetComponentVersion(comp_, name, &compVersion, &sepcVersion, &uuid); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_GetComponentVersion err = %{public}x ", err); + return err; + } + + verInfo.compName = name; + verInfo.compUUID.insert(verInfo.compUUID.end(), uuid, uuid + sizeof(OMX_UUIDTYPE)); + (void)memcpy_s(&verInfo.compVersion, sizeof(verInfo.compVersion), &compVersion, sizeof(sepcVersion)); + (void)memcpy_s(&verInfo.specVersion, sizeof(verInfo.specVersion), &sepcVersion, sizeof(sepcVersion)); + + return err; +} + +int32_t ComponentNode::SendCommand(OHOS::HDI::Codec::V1_0::OMX_COMMANDTYPE cmd, uint32_t param, int8_t *cmdData) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_COMMANDTYPE omxCmd = static_cast(cmd); + auto err = OMX_SendCommand(comp_, omxCmd, param, cmdData); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_SendCommand err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::GetParameter(OMX_INDEXTYPE paramIndex, int8_t *param) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + auto err = OMX_GetParameter(comp_, paramIndex, param); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_GetParameter err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::SetParameter(OMX_INDEXTYPE paramIndex, const int8_t *param) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + auto err = OMX_SetParameter(comp_, paramIndex, const_cast(param)); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_SetParameter err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::GetConfig(OMX_INDEXTYPE index, int8_t *config) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + auto err = OMX_GetConfig(comp_, index, config); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_GetConfig err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::SetConfig(OMX_INDEXTYPE index, const int8_t *config) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + auto err = OMX_SetConfig(comp_, index, const_cast(config)); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_SetConfig err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::GetExtensionIndex(const char *parameterName, uint32_t &index) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_INDEXTYPE indexType = OMX_IndexComponentStartUnused; + auto err = OMX_GetExtensionIndex(comp_, const_cast(parameterName), &indexType); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_GetExtensionIndex ret value[%{public}x]", err); + return err; + } + index = indexType; + return err; +} + +int32_t ComponentNode::GetState(OHOS::HDI::Codec::V1_0::OMX_STATETYPE &state) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_STATETYPE status = OMX_StateInvalid; + auto err = OMX_GetState(comp_, &status); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_GetState ret value[%{public}x]", err); + return err; + } + state = static_cast(status); + return err; +} + +int32_t ComponentNode::ComponentTunnelRequest(uint32_t port, int32_t omxHandleTypeTunneledComp, uint32_t tunneledPort, + OHOS::HDI::Codec::V1_0::OMX_TUNNELSETUPTYPE &tunnelSetup) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_COMPONENTTYPE *comType = static_cast(comp_); + unsigned long tunneledComp = (unsigned long)omxHandleTypeTunneledComp; + auto err = comType->ComponentTunnelRequest(comp_, port, (OMX_HANDLETYPE)tunneledComp, tunneledPort, + reinterpret_cast(&tunnelSetup)); + if (err != OMX_ErrorNone) { + CODEC_LOGE("ComponentTunnelRequest err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::SetCallbacks(const sptr &callbacks, int64_t appData) +{ + this->omxCallback_ = callbacks; + appData_ = appData; + return OMX_ErrorNone; +} + +int32_t ComponentNode::UseEglImage(struct OmxCodecBuffer &buffer, uint32_t portIndex, const int8_t *eglImage) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_BUFFERHEADERTYPE *pBufferHdrType = nullptr; + auto err = OMX_UseEGLImage(comp_, &pBufferHdrType, portIndex, 0, const_cast(eglImage)); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_UseEGLImage error[0x%{public}x]", err); + return err; + } + (void)buffer; + return OMX_ErrorNotImplemented; +} + +int32_t ComponentNode::ComponentRoleEnum(std::vector &role, uint32_t index) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + uint8_t omxRole[ROLE_MAX_LEN] = {0}; + OMX_COMPONENTTYPE *comType = static_cast(comp_); + int32_t err = comType->ComponentRoleEnum(comp_, omxRole, index); + if (err != OMX_ErrorNone) { + CODEC_LOGE("ComponentRoleEnum ret err [0x%{public}x] ", err); + return err; + } + role.insert(role.end(), omxRole, omxRole + strlen((const char *)omxRole)); + return OMX_ErrorNone; +} + +int32_t ComponentNode::ComponentDeInit() +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_COMPONENTTYPE *comType = static_cast(comp_); + auto err = comType->ComponentDeInit(comp_); + if (err != OMX_ErrorNone) { + CODEC_LOGE("ComponentDeInit err = %{public}x ", err); + } + return err; +} + +int32_t ComponentNode::OnEvent(OMX_EVENTTYPE event, uint32_t data1, uint32_t data2, void *eventData) +{ + if (omxCallback_ == nullptr) { + CODEC_LOGE("omxCallback_ is null"); + return OMX_ErrorNone; + } + (void)eventData; + EventInfo info = {.appData = appData_, .data1 = data1, .data2 = data2}; + (void)omxCallback_->EventHandler(static_cast(event), info); + + return OMX_ErrorNone; +} + +int32_t ComponentNode::OnEmptyBufferDone(OMX_BUFFERHEADERTYPE *buffer) +{ + if ((omxCallback_ == nullptr) || (buffer == nullptr)) { + CODEC_LOGE("omxCallback_ or buffer is null"); + return OMX_ErrorNone; + } + sptr codecBuffer = GetBufferInfoByHeader(buffer); + if (codecBuffer == nullptr || codecBuffer->EmptyOmxBufferDone(*buffer) != HDF_SUCCESS) { + CODEC_LOGE("codecBuffer is null or EmptyOmxBufferDone error"); + return OMX_ErrorNone; + } + OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); + (void)omxCallback_->EmptyBufferDone(appData_, codecOmxBuffer); + return OMX_ErrorNone; +} + +int32_t ComponentNode::OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer) +{ + if ((omxCallback_ == nullptr) || (buffer == nullptr)) { + CODEC_LOGE("omxCallback_ or buffer is null"); + return OMX_ErrorNone; + } + + sptr codecBuffer = GetBufferInfoByHeader(buffer); + if (codecBuffer == nullptr || codecBuffer->FillOmxBufferDone(*buffer) != HDF_SUCCESS) { + CODEC_LOGE("codecBuffer is null or EmptyOmxBufferDone error"); + return OMX_ErrorNone; + } + + struct OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); + (void)omxCallback_->FillBufferDone(appData_, codecOmxBuffer); + return OMX_ErrorNone; +} + +int32_t ComponentNode::UseBuffer(uint32_t portIndex, OmxCodecBuffer &buffer) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + if (buffer.fenceFd >= 0) { + close(buffer.fenceFd); + buffer.fenceFd = -1; + } + + int32_t err = OMX_ErrorBadParameter; + sptr codecBuffer = ICodecBuffer::CreateCodeBuffer(buffer); + if (codecBuffer == nullptr) { + CODEC_LOGE("codecBuffer is null"); + return OMX_ErrorInvalidComponent; + } + OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; + if (buffer.bufferType == CODEC_BUFFER_TYPE_AVSHARE_MEM_FD) { + err = OMX_AllocateBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen); + } else { + err = OMX_UseBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen, + codecBuffer->GetBuffer()); + } + + if (err != OMX_ErrorNone) { + CODEC_LOGE("type [%{public}d] OMX_AllocateBuffer or OMX_UseBuffer ret err[%{public}x]", buffer.bufferType, err); + codecBuffer = nullptr; + return err; + } + // for test + buffer.fenceFd = 0; + + uint32_t bufferId = GenerateBufferId(); + buffer.bufferId = bufferId; + codecBuffer->SetBufferId(bufferId); + codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); + bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); + + return err; +} + +int32_t ComponentNode::AllocateBuffer(uint32_t portIndex, OmxCodecBuffer &buffer) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + OMX_BUFFERHEADERTYPE *bufferHdrType = 0; + int32_t err = OMX_AllocateBuffer((OMX_HANDLETYPE)comp_, &bufferHdrType, portIndex, 0, buffer.allocLen); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_AllocateBuffer error, err = %{public}x", err); + return err; + } + + buffer.allocLen = bufferHdrType->nAllocLen; + sptr codecBuffer = ICodecBuffer::AllocateCodecBuffer(buffer); + if (codecBuffer == nullptr) { + CODEC_LOGE("codecBuffer is null"); + (void)OMX_FreeBuffer((OMX_HANDLETYPE)comp_, portIndex, bufferHdrType); + return OMX_ErrorInvalidComponent; + } + + uint32_t bufferId = GenerateBufferId(); + buffer.bufferId = bufferId; + codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); + bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); + return OMX_ErrorNone; +} + +int32_t ComponentNode::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + int32_t err = OMX_ErrorBadParameter; + sptr codecBufer = nullptr; + OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; + if (!GetBufferById(buffer.bufferId, codecBufer, bufferHdrType)) { + CODEC_LOGE(" GetBufferById return false"); + return err; + } + + err = OMX_FreeBuffer((OMX_HANDLETYPE)comp_, portIndex, bufferHdrType); + if (err != OMX_ErrorNone) { + CODEC_LOGE("OMX_FreeBuffer err [%{public}x]", err); + return err; + } + + auto iterOmxBuffer = bufferHeaderMap_.begin(); + while (iterOmxBuffer != bufferHeaderMap_.end()) { + if (iterOmxBuffer->first == bufferHdrType) { + bufferHeaderMap_.erase(iterOmxBuffer); + break; + } + iterOmxBuffer++; + } + + auto iter = codecBufferMap_.find(buffer.bufferId); + if (iter != codecBufferMap_.end()) { + codecBufferMap_.erase(iter); + } + (void)codecBufer->FreeBuffer(const_cast(buffer)); + + return err; +} + +int32_t ComponentNode::EmptyThisBuffer(OmxCodecBuffer &buffer) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + int32_t err = OMX_ErrorBadParameter; + OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; + sptr codecBuffer = nullptr; + if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { + CODEC_LOGE(" GetBufferById return false"); + return err; + } + err = codecBuffer->EmptyOmxBuffer(buffer, *bufferHdrType); + if (err != HDF_SUCCESS) { + CODEC_LOGE("EmptyOmxBuffer err [%{public}d]", err); + return err; + } + + err = OMX_EmptyThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); + return err; +} + +int32_t ComponentNode::FillThisBuffer(OmxCodecBuffer &buffer) +{ + CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); + int32_t err = OMX_ErrorBadParameter; + OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; + sptr codecBuffer = nullptr; + if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { + CODEC_LOGE("GetBufferById return false"); + return err; + } + + err = codecBuffer->FillOmxBuffer(buffer, *bufferHdrType); + if (err != HDF_SUCCESS) { + CODEC_LOGE("FillOmxBuffer err [%{public}d]", err); + return err; + } + + err = OMX_FillThisBuffer((OMX_HANDLETYPE)comp_, bufferHdrType); + return err; +} + +uint32_t ComponentNode::GenerateBufferId() +{ + uint32_t bufferId = 0; + do { + if (++bufferIdCount_ == 0) { + ++bufferIdCount_; + } + bufferId = bufferIdCount_; + } while (codecBufferMap_.find(bufferId) != codecBufferMap_.end()); + return bufferId; +} + +sptr ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer) +{ + if (buffer == nullptr) { + CODEC_LOGE("Buffer is null"); + return nullptr; + } + + auto iterHead = bufferHeaderMap_.find(buffer); + if (iterHead == bufferHeaderMap_.end()) { + CODEC_LOGE("Can not find bufferID by pHeaderType = 0x%{public}p", buffer); + return nullptr; + } + + uint32_t bufferId = iterHead->second; + auto iter = codecBufferMap_.find(bufferId); + if (iter == codecBufferMap_.end()) { + CODEC_LOGE("Can not find bufferInfo by bufferId = %{public}d", bufferId); + return nullptr; + } + return iter->second; +} + +bool ComponentNode::GetBufferById(uint32_t bufferId, sptr &codecBuffer, + OMX_BUFFERHEADERTYPE *&bufferHdrType) +{ + auto iter = codecBufferMap_.find(bufferId); + if ((iter == codecBufferMap_.end()) || (iter->second == nullptr)) { + CODEC_LOGE("Can not find bufferIndo by bufferID [%{public}d]", bufferId); + return false; + } + + auto iterHead = bufferHeaderMap_.begin(); + for (; iterHead != bufferHeaderMap_.end(); iterHead++) { + if (iterHead->second == bufferId) { + break; + } + } + if ((iterHead == bufferHeaderMap_.end()) || (iterHead->first == nullptr)) { + CODEC_LOGE("Can not find bufferHeaderType by bufferID [%{public}d] or iterHead->first is null", bufferId); + return false; + } + bufferHdrType = iterHead->first; + codecBuffer = iter->second; + return true; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file diff --git a/codec/hal/idl_service/src/icodec_buffer.cpp b/codec/hal/idl_service/src/icodec_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a906c1de4147ad69a8c1c9b2531942dc8cf4a070 --- /dev/null +++ b/codec/hal/idl_service/src/icodec_buffer.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd.. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "icodec_buffer.h" +#include +#include +#include "codec_dyna_buffer.h" +#include "codec_handle_buffer.h" +#include "codec_share_buffer.h" +#include "v1_0/codec_types.h" +using namespace OHOS::HDI::Codec::V1_0; +namespace OHOS { +namespace Codec { +namespace Omx { +ICodecBuffer::ICodecBuffer(struct OmxCodecBuffer &codecBuffer) +{ + codecBuffer_ = codecBuffer; +} +ICodecBuffer::~ICodecBuffer() +{} + +sptr ICodecBuffer::CreateCodeBuffer(struct OmxCodecBuffer &codecBuffer) +{ + sptr buffer = nullptr; + switch (codecBuffer.bufferType) { + case CODEC_BUFFER_TYPE_AVSHARE_MEM_FD: + buffer = CodecShareBuffer::Create(codecBuffer); + break; + case CODEC_BUFFER_TYPE_HANDLE: + buffer = CodecHandleBuffer::Create(codecBuffer); + break; + case CODEC_BUFFER_TYPE_DYNAMIC_HANDLE: + buffer = CodecDynaBuffer::Create(codecBuffer); + break; + default: + HDF_LOGE("%s: bufferType[%{public}d] is unexpected", __func__, codecBuffer.bufferType); + break; + } + return buffer; +} + +sptr ICodecBuffer::AllocateCodecBuffer(struct OmxCodecBuffer &codecBuffer) +{ + sptr buffer = nullptr; + switch (codecBuffer.bufferType) { + case CODEC_BUFFER_TYPE_AVSHARE_MEM_FD: + buffer = CodecShareBuffer::Allocate(codecBuffer); + break; + default: + HDF_LOGE("%s: bufferType[%{public}d] is unexpected", __func__, codecBuffer.bufferType); + break; + } + return buffer; +} + +struct OmxCodecBuffer &ICodecBuffer::GetCodecBuffer() +{ + return codecBuffer_; +} + +void ICodecBuffer::SetBufferId(int32_t bufferId) +{ + codecBuffer_.bufferId = bufferId; +} + +bool ICodecBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) +{ + if (codecBuffer_.type != codecBuffer.type) { + HDF_LOGE("%{public}s :input buffer type [%{public}d], but expect type [%{public}d]", __func__, + codecBuffer.bufferType, codecBuffer_.bufferType); + return false; + } + return true; +} + +int32_t ICodecBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + omxBuffer.nOffset = codecBuffer.offset; + omxBuffer.nFilledLen = codecBuffer.filledLen; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) +{ + omxBuffer.nOffset = codecBuffer.offset; + omxBuffer.nFilledLen = codecBuffer.filledLen; + omxBuffer.nFlags = codecBuffer.flag; + omxBuffer.nTimeStamp = codecBuffer.pts; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + codecBuffer_.offset = omxBuffer.nOffset; + codecBuffer_.filledLen = omxBuffer.nFilledLen; + return HDF_SUCCESS; +} + +int32_t ICodecBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) +{ + codecBuffer_.offset = omxBuffer.nOffset; + codecBuffer_.filledLen = omxBuffer.nFilledLen; + codecBuffer_.flag = omxBuffer.nFlags; + codecBuffer_.pts = omxBuffer.nTimeStamp; + return HDF_SUCCESS; +} +} // namespace Omx +} // namespace Codec +} // namespace OHOS \ No newline at end of file