From 1e9376a3616dfa7b1d5b6ce67b0ff3889759a3c1 Mon Sep 17 00:00:00 2001 From: hobbycao Date: Fri, 1 Jul 2022 14:48:32 +0800 Subject: [PATCH] refactor: move distributed camera hdf service to drivers Signed-off-by: hobbycao --- distributed_camera/distributedcamera.gni | 9 +- distributed_camera/hdi_service/BUILD.gn | 141 ++- .../include/dcamera_device/dcamera_device.h | 85 ++ .../dcamera_device/dmetadata_processor.h | 90 ++ .../include/dcamera_host/dcamera_host.h | 80 ++ .../dcamera_provider/dcamera_provider.h | 74 ++ .../dstream_operator/dbuffer_manager.h | 62 ++ .../include/dstream_operator/dcamera_stream.h | 72 ++ .../include/dstream_operator/dimage_buffer.h | 88 ++ .../doffline_stream_operator.h | 40 + .../dstream_operator/dstream_operator.h | 121 +++ .../include/utils/anonymous_string.h | 27 + .../hdi_service/include/utils/constants.h | 147 +++ .../hdi_service/include/utils/dcamera.h | 45 + .../hdi_service/include/utils/dcamera_base.h | 43 + .../hdi_service/include/utils/dh_log.h | 43 + .../include/utils/distributed_hardware_log.h | 38 + .../src/config/dcamera_host_config.cpp | 106 +++ .../src/dcamera_device/dcamera_device.cpp | 472 ++++++++++ .../dcamera_device/dmetadata_processor.cpp | 693 ++++++++++++++ .../src/dcamera_host/dcamera_host.cpp | 234 +++++ .../src/dcamera_provider/dcamera_provider.cpp | 320 +++++++ .../src/dstream_operator/dbuffer_manager.cpp | 160 ++++ .../src/dstream_operator/dcamera_stream.cpp | 370 ++++++++ .../src/dstream_operator/dimage_buffer.cpp | 242 +++++ .../doffline_stream_operator.cpp | 38 + .../src/dstream_operator/dstream_operator.cpp | 871 ++++++++++++++++++ .../src/utils/anonymous_string.cpp | 68 ++ .../hdi_service/src/utils/dcamera.cpp | 199 ++++ .../hdi_service/src/utils/dh_log.cpp | 87 ++ distributed_camera/hdi_service/test/BUILD.gn | 74 ++ .../hdi_service/test/common.cpp | 407 ++++++++ distributed_camera/hdi_service/test/common.h | 183 ++++ .../hdi_service/test/dcamera_hdi_sample.cpp | 95 ++ .../interfaces/hdi_ipc/ipc_data_utils.h | 104 +++ .../device/dcamera_device_callback_proxy.cpp | 88 ++ .../device/dcamera_device_callback_proxy.h | 40 + .../server/device/dcamera_device_stub.cpp | 235 +++++ .../server/device/dcamera_device_stub.h | 44 + .../host/dcamera_host_callback_proxy.cpp | 107 +++ .../server/host/dcamera_host_callback_proxy.h | 41 + .../hdi_ipc/server/host/dcamera_host_stub.cpp | 262 ++++++ .../hdi_ipc/server/host/dcamera_host_stub.h | 69 ++ .../doffline_stream_operator_stub.cpp | 107 +++ .../operator/doffline_stream_operator_stub.h | 39 + .../dstream_operator_callback_proxy.cpp | 162 ++++ .../dstream_operator_callback_proxy.h | 45 + .../server/operator/dstream_operator_stub.cpp | 355 +++++++ .../server/operator/dstream_operator_stub.h | 47 + 49 files changed, 7563 insertions(+), 6 deletions(-) create mode 100644 distributed_camera/hdi_service/include/dcamera_device/dcamera_device.h create mode 100644 distributed_camera/hdi_service/include/dcamera_device/dmetadata_processor.h create mode 100644 distributed_camera/hdi_service/include/dcamera_host/dcamera_host.h create mode 100644 distributed_camera/hdi_service/include/dcamera_provider/dcamera_provider.h create mode 100644 distributed_camera/hdi_service/include/dstream_operator/dbuffer_manager.h create mode 100644 distributed_camera/hdi_service/include/dstream_operator/dcamera_stream.h create mode 100644 distributed_camera/hdi_service/include/dstream_operator/dimage_buffer.h create mode 100644 distributed_camera/hdi_service/include/dstream_operator/doffline_stream_operator.h create mode 100644 distributed_camera/hdi_service/include/dstream_operator/dstream_operator.h create mode 100644 distributed_camera/hdi_service/include/utils/anonymous_string.h create mode 100644 distributed_camera/hdi_service/include/utils/constants.h create mode 100644 distributed_camera/hdi_service/include/utils/dcamera.h create mode 100644 distributed_camera/hdi_service/include/utils/dcamera_base.h create mode 100644 distributed_camera/hdi_service/include/utils/dh_log.h create mode 100644 distributed_camera/hdi_service/include/utils/distributed_hardware_log.h create mode 100644 distributed_camera/hdi_service/src/config/dcamera_host_config.cpp create mode 100644 distributed_camera/hdi_service/src/dcamera_device/dcamera_device.cpp create mode 100644 distributed_camera/hdi_service/src/dcamera_device/dmetadata_processor.cpp create mode 100644 distributed_camera/hdi_service/src/dcamera_host/dcamera_host.cpp create mode 100644 distributed_camera/hdi_service/src/dcamera_provider/dcamera_provider.cpp create mode 100644 distributed_camera/hdi_service/src/dstream_operator/dbuffer_manager.cpp create mode 100644 distributed_camera/hdi_service/src/dstream_operator/dcamera_stream.cpp create mode 100644 distributed_camera/hdi_service/src/dstream_operator/dimage_buffer.cpp create mode 100644 distributed_camera/hdi_service/src/dstream_operator/doffline_stream_operator.cpp create mode 100644 distributed_camera/hdi_service/src/dstream_operator/dstream_operator.cpp create mode 100644 distributed_camera/hdi_service/src/utils/anonymous_string.cpp create mode 100644 distributed_camera/hdi_service/src/utils/dcamera.cpp create mode 100644 distributed_camera/hdi_service/src/utils/dh_log.cpp create mode 100644 distributed_camera/hdi_service/test/BUILD.gn create mode 100644 distributed_camera/hdi_service/test/common.cpp create mode 100644 distributed_camera/hdi_service/test/common.h create mode 100644 distributed_camera/hdi_service/test/dcamera_hdi_sample.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/ipc_data_utils.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp create mode 100644 distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h diff --git a/distributed_camera/distributedcamera.gni b/distributed_camera/distributedcamera.gni index b56debf9fd..61543dab5a 100644 --- a/distributed_camera/distributedcamera.gni +++ b/distributed_camera/distributedcamera.gni @@ -11,7 +11,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -distributedcamera_hdf_path = - "//foundation/distributedhardware/distributed_camera" +distributedcamera_hdf_path = "//drivers/peripheral/distributed_camera" -hdi_service_path = "${distributedcamera_hdf_path}/camera_hdf" +camera_hdf_path = "//drivers/peripheral" + +hdf_framework_path = "//drivers/hdf_core/framework" + +display_hdf_path = "//drivers/peripheral/display" diff --git a/distributed_camera/hdi_service/BUILD.gn b/distributed_camera/hdi_service/BUILD.gn index 49b72e5b87..b7640ac2c9 100644 --- a/distributed_camera/hdi_service/BUILD.gn +++ b/distributed_camera/hdi_service/BUILD.gn @@ -16,9 +16,10 @@ import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni") import("//drivers/peripheral/distributed_camera/distributedcamera.gni") ohos_shared_library("libdistributed_camera_provider_config") { - include_dirs = [ "${hdi_service_path}/hdi_impl/include/dcamera_provider" ] + include_dirs = + [ "${distributedcamera_hdf_path}/hdi_service/include/dcamera_provider" ] sources = [ "./src/config/dcamera_provider_config.cpp" ] - deps = [ "${hdi_service_path}/hdi_impl:distributed_camera_hdf" ] + deps = [ "${distributedcamera_hdf_path}/hdi_service:libdistributed_camera_hdf_service_1.0" ] external_deps = [ "hdf_core:libhdf_host", @@ -34,6 +35,140 @@ ohos_shared_library("libdistributed_camera_provider_config") { part_name = "drivers_peripheral_distributed_camera" } +ohos_shared_library("libdistributed_camera_host_config") { + include_dirs = [ + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/host", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/device", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/operator", + "${distributedcamera_hdf_path}/hdi_service/include/dcamera_host", + "${distributedcamera_hdf_path}/hdi_service/include/dcamera_device", + "${distributedcamera_hdf_path}/hdi_service/include/dstream_operator", + "${distributedcamera_hdf_path}/hdi_service/include/utils", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${camera_hdf_path}/camera/interfaces/include", + "${camera_hdf_path}/camera/interfaces/hdi_ipc", + "${hdf_framework_path}/include/utils", + "${hdf_framework_path}/include/core", + "${hdf_framework_path}/include/osal", + "${hdf_uhdf_path}/include/hdi", + "${hdf_uhdf_path}/osal/include", + "${hdf_uhdf_path}/ipc/include", + "${hdf_uhdf_path}/include/host", + "//drivers/peripheral/camera/interfaces/metadata/include", + "//third_party/jsoncpp/include", + ] + + sources = [ "./src/config/dcamera_host_config.cpp" ] + + deps = [ + "${distributedcamera_hdf_path}/hdi_service:libdistributed_camera_hdf_service_1.0", + "//utils/native/base:utils", + ] + + public_deps = [ "//drivers/interface/distributed_camera/v1_0:libdistributed_camera_provider_stub_1.0" ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "graphic_chipsetsdk:buffer_handle", + "graphic_chipsetsdk:surface", + "hdf_core:libhdf_host", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + ] + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_distributed_camera" +} + +ohos_shared_library("libdistributed_camera_hdf_service_1.0") { + include_dirs = [ + "include/dcamera_device", + "include/dcamera_host", + "include/dcamera_provider", + "include/dstream_operator", + "include/utils", + "../interfaces/hdi_ipc", + "../interfaces/hdi_ipc/server/device", + "../interfaces/hdi_ipc/server/host", + "../interfaces/hdi_ipc/server/operator", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${display_hdf_path}/interfaces/include", + "${hdf_framework_path}/include/utils", + "${hdf_framework_path}/include/core", + "${hdf_framework_path}/include/osal", + "${hdf_uhdf_path}/include/hdi", + "${hdf_uhdf_path}/osal/include", + "${hdf_uhdf_path}/ipc/include", + "${hdf_uhdf_path}/include/host", + "//third_party/jsoncpp/include", + "//drivers/peripheral/camera/interfaces/metadata/include", + "${camera_hdf_path}/camera/interfaces/include", + "${camera_hdf_path}/camera/interfaces/hdi_ipc", + ] + + sources = [ + "../interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp", + "../interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp", + "../interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp", + "../interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp", + "../interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp", + "../interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp", + "../interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp", + "src/dcamera_device/dcamera_device.cpp", + "src/dcamera_device/dmetadata_processor.cpp", + "src/dcamera_host/dcamera_host.cpp", + "src/dcamera_provider/dcamera_provider.cpp", + "src/dstream_operator/dbuffer_manager.cpp", + "src/dstream_operator/dcamera_stream.cpp", + "src/dstream_operator/dimage_buffer.cpp", + "src/dstream_operator/doffline_stream_operator.cpp", + "src/dstream_operator/dstream_operator.cpp", + "src/utils/anonymous_string.cpp", + "src/utils/dcamera.cpp", + "src/utils/dh_log.cpp", + ] + + public_deps = [ "//drivers/interface/distributed_camera/v1_0:libdistributed_camera_provider_stub_1.0" ] + + deps = [ + "//drivers/hdf_core/adapter/uhdf2/ipc:libhdf_ipc_adapter", + "//drivers/peripheral/camera/interfaces/metadata:metadata", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "graphic_chipsetsdk:buffer_handle", + "graphic_chipsetsdk:surface", + "hdf_core:libhdf_utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "utils_base:utils", + ] + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_distributed_camera" +} + group("hdf_distributed_camera_service") { - deps = [ ":libdistributed_camera_provider_config" ] + deps = [ + ":libdistributed_camera_hdf_service_1.0", + ":libdistributed_camera_host_config", + ":libdistributed_camera_provider_config", + ] } diff --git a/distributed_camera/hdi_service/include/dcamera_device/dcamera_device.h b/distributed_camera/hdi_service/include/dcamera_device/dcamera_device.h new file mode 100644 index 0000000000..64e08ee986 --- /dev/null +++ b/distributed_camera/hdi_service/include/dcamera_device/dcamera_device.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CAMERA_DEVICE_H +#define DISTRIBUTED_CAMERA_DEVICE_H + +#include +#include +#include "dcamera_device_stub.h" +#include "dmetadata_processor.h" +#include "dstream_operator.h" +#include "icamera_device_callback.h" +#include "types.h" +#include "v1_0/id_camera_provider_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraDevice : public DCameraDeviceStub { +public: + DCameraDevice(const DHBase &dhBase, const std::string &abilityInfo); + DCameraDevice() = default; + virtual ~DCameraDevice() = default; + DCameraDevice(const DCameraDevice &other) = delete; + DCameraDevice(DCameraDevice &&other) = delete; + DCameraDevice& operator=(const DCameraDevice &other) = delete; + DCameraDevice& operator=(DCameraDevice &&other) = delete; + +public: + CamRetCode GetStreamOperator(const OHOS::sptr &callback, + OHOS::sptr &streamOperator) override; + CamRetCode UpdateSettings(const std::shared_ptr &settings) override; + CamRetCode SetResultMode(const ResultCallbackMode &mode) override; + CamRetCode GetEnabledResults(std::vector &results) override; + CamRetCode EnableResult(const std::vector &results) override; + CamRetCode DisableResult(const std::vector &results) override; + void Close() override; + + CamRetCode OpenDCamera(const OHOS::sptr &callback); + CamRetCode GetDCameraAbility(std::shared_ptr &ability); + DCamRetCode AcquireBuffer(int streamId, DCameraBuffer &buffer); + DCamRetCode ShutterBuffer(int streamId, const DCameraBuffer &buffer); + DCamRetCode OnSettingsResult(const std::shared_ptr &result); + DCamRetCode Notify(const std::shared_ptr &event); + void SetProviderCallback(const OHOS::sptr &callback); + OHOS::sptr GetProviderCallback(); + std::string GetDCameraId(); + bool IsOpened(); + +private: + void Init(const std::string &abilityInfo); + DCamRetCode CreateDStreamOperator(); + std::string GenerateCameraId(const DHBase &dhBase); + void NotifyStartCaptureError(); + void NotifyCameraError(const ErrorType type); + void IsOpenSessFailedState(bool state); +private: + bool isOpened_; + std::string dCameraId_; + DHBase dhBase_; + std::string dCameraAbilityInfo_; + OHOS::sptr dCameraDeviceCallback_; + OHOS::sptr dCameraProviderCallback_; + OHOS::sptr dCameraStreamOperator_; + std::shared_ptr dMetadataProcessor_; + + std::mutex openSesslock_; + std::condition_variable openSessCV_; + bool isOpenSessFailed_ = false; + std::mutex isOpenSessFailedlock_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dcamera_device/dmetadata_processor.h b/distributed_camera/hdi_service/include/dcamera_device/dmetadata_processor.h new file mode 100644 index 0000000000..01fb4e65df --- /dev/null +++ b/distributed_camera/hdi_service/include/dcamera_device/dmetadata_processor.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CAMERA_METADATA_PROCESSOR_H +#define DISTRIBUTED_CAMERA_METADATA_PROCESSOR_H + +#include +#include +#include +#include +#include "constants.h" +#include "dcamera.h" +#include "v1_0/dcamera_types.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +using namespace OHOS::HDI::DistributedCamera::V1_0; +class DMetadataProcessor { +public: + DMetadataProcessor() = default; + ~DMetadataProcessor() = default; + DMetadataProcessor(const DMetadataProcessor &other) = delete; + DMetadataProcessor(DMetadataProcessor &&other) = delete; + DMetadataProcessor& operator=(const DMetadataProcessor &other) = delete; + DMetadataProcessor& operator=(DMetadataProcessor &&other) = delete; + +public: + DCamRetCode InitDCameraAbility(const std::string &abilityInfo); + DCamRetCode GetDCameraAbility(std::shared_ptr &ability); + DCamRetCode SetMetadataResultMode(const ResultCallbackMode &mode); + DCamRetCode GetEnabledMetadataResults(std::vector &results); + DCamRetCode EnableMetadataResult(const std::vector &results); + DCamRetCode DisableMetadataResult(const std::vector &results); + DCamRetCode ResetEnableResults(); + DCamRetCode SaveResultMetadata(std::string resultStr); + void UpdateResultMetadata(const uint64_t &resultTimestamp); + void SetResultCallback(std::function)> &resultCbk); + void PrintDCameraMetadata(const common_metadata_header_t *metadata); + +private: + DCamRetCode InitDCameraDefaultAbilityKeys(const std::string &abilityInfo); + DCamRetCode InitDCameraOutputAbilityKeys(const std::string &abilityInfo); + DCamRetCode AddAbilityEntry(uint32_t tag, const void *data, size_t size); + DCamRetCode UpdateAbilityEntry(uint32_t tag, const void *data, size_t size); + void ConvertToCameraMetadata(common_metadata_header_t *&input, + std::shared_ptr &output); + void ResizeMetadataHeader(common_metadata_header_t *&header, uint32_t itemCapacity, uint32_t dataCapacity); + void UpdateAllResult(const uint64_t &resultTimestamp); + void UpdateOnChanged(const uint64_t &resultTimestamp); + uint32_t GetDataSize(uint32_t type); + void* GetMetadataItemData(const camera_metadata_item_t &item); + std::map> GetDCameraSupportedFormats(const std::string &abilityInfo); + void InitDcameraBaseAbility(); + +private: + std::function)> resultCallback_; + std::shared_ptr dCameraAbility_; + std::string protocolVersion_; + std::string dCameraPosition_; + DCResolution maxPreviewResolution_; + DCResolution maxPhotoResolution_; + ResultCallbackMode metaResultMode_; + std::set allResultSet_; + std::set enabledResultSet_; + std::mutex producerMutex_; + + // The latest result metadata that received from the sink device. + std::shared_ptr latestProducerMetadataResult_; + + // The latest result metadata that replied to the camera service. + std::shared_ptr latestConsumerMetadataResult_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_METADATA_PROCESSOR_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dcamera_host/dcamera_host.h b/distributed_camera/hdi_service/include/dcamera_host/dcamera_host.h new file mode 100644 index 0000000000..af435fe49d --- /dev/null +++ b/distributed_camera/hdi_service/include/dcamera_host/dcamera_host.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_HOST_H +#define DISTRIBUTED_CAMERA_HOST_H + +#include "dcamera.h" +#include "dcamera_base.h" +#include "dcamera_device.h" +#include "icamera_device.h" +#include "icamera_host_callback.h" +#include "icamera_device_callback.h" +#include "v1_0/dcamera_types.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::HDI::DistributedCamera::V1_0; +class DCameraHost { +public: + DCameraHost() = default; + virtual ~DCameraHost() = default; + DCameraHost(const DCameraHost &other) = delete; + DCameraHost(DCameraHost &&other) = delete; + DCameraHost& operator=(const DCameraHost &other) = delete; + DCameraHost& operator=(DCameraHost &&other) = delete; + +public: + static std::shared_ptr GetInstance(); + CamRetCode SetCallback(const OHOS::sptr &callback); + CamRetCode GetCameraIds(std::vector &cameraIds); + CamRetCode GetCameraAbility(const std::string &cameraId, std::shared_ptr &ability); + CamRetCode OpenCamera(const std::string &cameraId, const OHOS::sptr &callback, + OHOS::sptr &pDevice); + CamRetCode SetFlashlight(const std::string &cameraId, bool &isEnable); + + DCamRetCode AddDCameraDevice(const DHBase &dhBase, const std::string &abilityInfo, + const sptr &callback); + DCamRetCode RemoveDCameraDevice(const DHBase &dhBase); + OHOS::sptr GetDCameraDeviceByDHBase(const DHBase &dhBase); + void NotifyDCameraStatus(const DHBase &dhBase, int32_t result); + +private: + bool IsCameraIdInvalid(const std::string &cameraId); + std::string GetCameraIdByDHBase(const DHBase &dhBase); + +private: + class AutoRelease { + public: + AutoRelease() {} + ~AutoRelease() + { + if (DCameraHost::instance_ != nullptr) { + DCameraHost::instance_ = nullptr; + } + } + }; + static AutoRelease autoRelease_; + static std::shared_ptr instance_; + + OHOS::sptr dCameraHostCallback_; + std::map dhBaseHashDCamIdMap_; + std::map> dCameraDeviceMap_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dcamera_provider/dcamera_provider.h b/distributed_camera/hdi_service/include/dcamera_provider/dcamera_provider.h new file mode 100644 index 0000000000..2bb093a8d5 --- /dev/null +++ b/distributed_camera/hdi_service/include/dcamera_provider/dcamera_provider.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_PROVIDER_H +#define DISTRIBUTED_CAMERA_PROVIDER_H + +#include "v1_0/id_camera_provider.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::HDI::DistributedCamera::V1_0; +class DCameraHost; +class DCameraDevice; +class DCameraProvider : public IDCameraProvider { +public: + DCameraProvider() = default; + virtual ~DCameraProvider() = default; + DCameraProvider(const DCameraProvider &other) = delete; + DCameraProvider(DCameraProvider &&other) = delete; + DCameraProvider& operator=(const DCameraProvider &other) = delete; + DCameraProvider& operator=(DCameraProvider &&other) = delete; + +public: + static OHOS::sptr GetInstance(); + int32_t EnableDCameraDevice(const DHBase& dhBase, const std::string& abilityInfo, + const sptr& callbackObj) override; + int32_t DisableDCameraDevice(const DHBase& dhBase) override; + int32_t AcquireBuffer(const DHBase& dhBase, int32_t streamId, DCameraBuffer& buffer) override; + int32_t ShutterBuffer(const DHBase& dhBase, int32_t streamId, const DCameraBuffer& buffer) override; + int32_t OnSettingsResult(const DHBase& dhBase, const DCameraSettings& result) override; + int32_t Notify(const DHBase& dhBase, const DCameraHDFEvent& event) override; + + int32_t OpenSession(const DHBase &dhBase); + int32_t CloseSession(const DHBase &dhBase); + int32_t ConfigureStreams(const DHBase &dhBase, const std::vector &streamInfos); + int32_t ReleaseStreams(const DHBase &dhBase, const std::vector &streamIds); + int32_t StartCapture(const DHBase &dhBase, const std::vector &captureInfos); + int32_t StopCapture(const DHBase &dhBase, const std::vector &streamIds); + int32_t UpdateSettings(const DHBase &dhBase, const std::vector &settings); + +private: + bool IsDhBaseInfoInvalid(const DHBase &dhBase); + sptr GetCallbackBydhBase(const DHBase &dhBase); + OHOS::sptr GetDCameraDevice(const DHBase &dhBase); + +private: + class AutoRelease { + public: + AutoRelease() {} + ~AutoRelease() + { + if (DCameraProvider::instance_ != nullptr) { + DCameraProvider::instance_ = nullptr; + } + } + }; + static AutoRelease autoRelease_; + static OHOS::sptr instance_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dstream_operator/dbuffer_manager.h b/distributed_camera/hdi_service/include/dstream_operator/dbuffer_manager.h new file mode 100644 index 0000000000..f353dec59e --- /dev/null +++ b/distributed_camera/hdi_service/include/dstream_operator/dbuffer_manager.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_BUFFER_MANAGER_H +#define DISTRIBUTED_CAMERA_BUFFER_MANAGER_H + +#include +#include + +#include "constants.h" +#include "dimage_buffer.h" +#include "display_type.h" +#include "surface.h" +#include "surface_buffer.h" + +#include "v1_0/dcamera_types.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::HDI::DistributedCamera::V1_0; +class DBufferManager { +public: + DBufferManager() = default; + virtual ~DBufferManager() = default; + DBufferManager(const DBufferManager &other) = delete; + DBufferManager(DBufferManager &&other) = delete; + DBufferManager& operator=(const DBufferManager &other) = delete; + DBufferManager& operator=(DBufferManager &&other) = delete; + +public: + std::shared_ptr AcquireBuffer(); + RetCode AddBuffer(std::shared_ptr& buffer); + RetCode RemoveBuffer(std::shared_ptr& buffer); + void NotifyStop(bool state); + static RetCode SurfaceBufferToDImageBuffer(const OHOS::sptr &surfaceBuffer, + const std::shared_ptr &buffer); + static RetCode DImageBufferToDCameraBuffer(const std::shared_ptr &imageBuffer, + DCameraBuffer &buffer); + static uint64_t CameraUsageToGrallocUsage(const uint64_t cameraUsage); + static uint32_t PixelFormatToDCameraFormat(const PixelFormat format); + +private: + std::mutex lock_; + std::atomic_bool streamStop_ = false; + std::list> idleList_ = {}; + std::list> busyList_ = {}; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_BUFFER_MANAGER_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dstream_operator/dcamera_stream.h b/distributed_camera/hdi_service/include/dstream_operator/dcamera_stream.h new file mode 100644 index 0000000000..967e95ea84 --- /dev/null +++ b/distributed_camera/hdi_service/include/dstream_operator/dcamera_stream.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_STREAM_H +#define DISTRIBUTED_CAMERA_STREAM_H + +#include "surface.h" +#include "dimage_buffer.h" +#include "dbuffer_manager.h" +#include "v1_0/dcamera_types.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace std; +using namespace OHOS::Camera; +using namespace OHOS::HDI::DistributedCamera::V1_0; +class DCameraStream { +public: + DCameraStream() = default; + ~DCameraStream() = default; + DCameraStream(const DCameraStream &other) = delete; + DCameraStream(DCameraStream &&other) = delete; + DCameraStream &operator=(const DCameraStream &other) = delete; + DCameraStream &operator=(DCameraStream &&other) = delete; + +public: + DCamRetCode InitDCameraStream(const shared_ptr &info); + DCamRetCode GetDCameraStreamInfo(shared_ptr &info); + DCamRetCode SetDCameraBufferQueue(const OHOS::sptr producer); + DCamRetCode ReleaseDCameraBufferQueue(); + DCamRetCode GetDCameraStreamAttribute(shared_ptr &attribute); + DCamRetCode GetDCameraBuffer(DCameraBuffer &buffer); + DCamRetCode ReturnDCameraBuffer(const DCameraBuffer &buffer); + DCamRetCode FlushDCameraBuffer(); + DCamRetCode FinishCommitStream(); + bool HasBufferQueue(); + +private: + DCamRetCode InitDCameraBufferManager(); + DCamRetCode GetNextRequest(); + DCamRetCode CheckRequestParam(); + +private: + int32_t index_ = -1; + int dcStreamId_; + shared_ptr dcStreamInfo_ = nullptr; + shared_ptr dcStreamAttribute_ = nullptr; + shared_ptr dcStreamBufferMgr_ = nullptr; + OHOS::sptr dcStreamProducer_ = nullptr; + map, tuple, int, int>> bufferConfigMap_; + mutex lock_; + condition_variable cv_; + int captureBufferCount_ = 0; + bool isBufferMgrInited_ = false; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_STREAM_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dstream_operator/dimage_buffer.h b/distributed_camera/hdi_service/include/dstream_operator/dimage_buffer.h new file mode 100644 index 0000000000..207e4c440d --- /dev/null +++ b/distributed_camera/hdi_service/include/dstream_operator/dimage_buffer.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CAMERA_IMAGE_BUFFER_H +#define DISTRIBUTED_CAMERA_IMAGE_BUFFER_H + +#include +#include "constants.h" + +namespace OHOS { +namespace DistributedHardware { +class DImageBuffer { +public: + DImageBuffer() = default; + virtual ~DImageBuffer(); + + int32_t GetIndex() const; + uint32_t GetWidth() const; + uint32_t GetHeight() const; + uint32_t GetStride() const; + int32_t GetFormat() const; + uint32_t GetSize() const; + uint64_t GetUsage() const; + uint64_t GetPhyAddress() const; + int32_t GetFileDescriptor() const; + uint64_t GetTimestamp() const; + uint64_t GetFrameNumber() const; + int32_t GetCaptureId() const; + bool GetValidFlag() const; + int32_t GetFenceId() const; + int32_t GetEncodeType() const; + BufferHandle* GetBufferHandle() const; + + void SetIndex(const int32_t index); + void SetWidth(const uint32_t width); + void SetHeight(const uint32_t height); + void SetStride(const uint32_t stride); + void SetFormat(const int32_t format); + void SetSize(const uint32_t size); + void SetUsage(const uint64_t usage); + void SetPhyAddress(const uint64_t addr); + void SetFileDescriptor(const int32_t fd); + void SetTimestamp(const uint64_t timestamp); + void SetFrameNumber(const uint64_t frameNumber); + void SetCaptureId(const int32_t id); + void SetValidFlag(const bool flag); + void SetFenceId(const int32_t fence); + void SetEncodeType(const int32_t type); + void SetBufferHandle(const BufferHandle* bufHandle); + + void Free(); + bool operator==(const DImageBuffer& u); + +private: + int32_t index_ = -1; + uint32_t width_ = 0; + uint32_t height_ = 0; + uint32_t stride_ = 0; + uint32_t format_ = OHOS_CAMERA_FORMAT_INVALID; + uint32_t size_ = 0; + uint64_t usage_ = 0; + uint64_t phyAddr_ = 0; + int32_t fd_ = -1; + uint64_t frameNumber_ = 0; + uint64_t timeStamp_ = 0; + int32_t captureId_ = -1; + bool valid_ = true; + int32_t fenceId_ = -1; + int32_t encodeType_ = 0; + BufferHandle* bufHandle_ = nullptr; + + std::mutex l_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_IMAGE_BUFFER_H diff --git a/distributed_camera/hdi_service/include/dstream_operator/doffline_stream_operator.h b/distributed_camera/hdi_service/include/dstream_operator/doffline_stream_operator.h new file mode 100644 index 0000000000..62c6d624f2 --- /dev/null +++ b/distributed_camera/hdi_service/include/dstream_operator/doffline_stream_operator.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_OFFLINE_STREAM_OPERATOR_H +#define DISTRIBUTED_CAMERA_OFFLINE_STREAM_OPERATOR_H + +#include "doffline_stream_operator_stub.h" +#include "dcamera.h" + +namespace OHOS { +namespace DistributedHardware { +class DOfflineStreamOperator : public DOfflineStreamOperatorStub { +public: + DOfflineStreamOperator() = default; + virtual ~DOfflineStreamOperator() = default; + DOfflineStreamOperator(const DOfflineStreamOperator &other) = delete; + DOfflineStreamOperator(DOfflineStreamOperator &&other) = delete; + DOfflineStreamOperator& operator=(const DOfflineStreamOperator &other) = delete; + DOfflineStreamOperator& operator=(DOfflineStreamOperator &&other) = delete; + +public: + virtual CamRetCode CancelCapture(int captureId) override; + virtual CamRetCode ReleaseStreams(const std::vector& streamIds) override; + virtual CamRetCode Release() override; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_OFFLINE_STREAM_OPERATOR_H \ No newline at end of file diff --git a/distributed_camera/hdi_service/include/dstream_operator/dstream_operator.h b/distributed_camera/hdi_service/include/dstream_operator/dstream_operator.h new file mode 100644 index 0000000000..d4c1d9efd9 --- /dev/null +++ b/distributed_camera/hdi_service/include/dstream_operator/dstream_operator.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CAMERA_STREAM_OPERATOR_H +#define DISTRIBUTED_CAMERA_STREAM_OPERATOR_H + +#include +#include +#include +#include "istream_operator.h" +#include "dstream_operator_stub.h" +#include "dcamera.h" +#include "dmetadata_processor.h" +#include "types.h" +#include "constants.h" +#include "dcamera_stream.h" + +#include "json/json.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace std; +class DCameraProvider; +class DStreamOperator : public DStreamOperatorStub { +public: + explicit DStreamOperator(std::shared_ptr &dMetadataProcessor); + DStreamOperator() = default; + virtual ~DStreamOperator() = default; + DStreamOperator(const DStreamOperator &other) = delete; + DStreamOperator(DStreamOperator &&other) = delete; + DStreamOperator& operator=(const DStreamOperator &other) = delete; + DStreamOperator& operator=(DStreamOperator &&other) = delete; + +public: + CamRetCode IsStreamsSupported(OperationMode mode, + const std::shared_ptr &modeSetting, + const std::vector> &info, + StreamSupportType &type) override; + CamRetCode CreateStreams(const std::vector>& streamInfos) override; + CamRetCode ReleaseStreams(const std::vector& streamIds) override; + CamRetCode CommitStreams(OperationMode mode, + const std::shared_ptr& modeSetting) override; + CamRetCode GetStreamAttributes(std::vector>& attributes) override; + CamRetCode AttachBufferQueue(int streamId, const OHOS::sptr& producer) override; + CamRetCode DetachBufferQueue(int streamId) override; + CamRetCode Capture(int captureId, const std::shared_ptr& captureInfo, bool isStreaming) override; + CamRetCode CancelCapture(int captureId) override; + CamRetCode ChangeToOfflineStream(const std::vector& streamIds, OHOS::sptr& callback, + OHOS::sptr& offlineOperator) override; + + DCamRetCode InitOutputConfigurations(const DHBase &dhBase, const std::string &abilityInfo); + DCamRetCode AcquireBuffer(int streamId, DCameraBuffer &buffer); + DCamRetCode ShutterBuffer(int streamId, const DCameraBuffer &buffer); + DCamRetCode SetCallBack(OHOS::sptr const &callback); + DCamRetCode SetDeviceCallback(function &errorCbk, + function)> &resultCbk); + void Release(); + std::vector GetStreamIds(); + +private: + bool IsCapturing(); + void SetCapturing(bool isCapturing); + DCamRetCode NegotiateSuitableCaptureInfo(const std::shared_ptr& srcCaptureInfo, bool isStreaming); + void ChooseSuitableFormat(std::vector> &streamInfo, + std::shared_ptr &captureInfo); + void ChooseSuitableResolution(std::vector> &streamInfo, + std::shared_ptr &captureInfo); + void ChooseSuitableDataSpace(std::vector> &streamInfo, + std::shared_ptr &captureInfo); + void ChooseSuitableEncodeType(std::vector> &streamInfo, + std::shared_ptr &captureInfo); + void ConvertStreamInfo(std::shared_ptr &srcInfo, std::shared_ptr &dstInfo); + DCEncodeType ConvertDCEncodeType(std::string &srcEncodeType); + std::shared_ptr BuildSuitableCaptureInfo(const shared_ptr& srcCaptureInfo, + std::vector> &srcStreamInfo); + void SnapShotStreamOnCaptureEnded(int32_t captureId, int streamId); + bool HasContinuousCaptureInfo(int captureId); + void ExtractStreamInfo(DCStreamInfo &dstStreamInfo, const std::shared_ptr &srcStreamInfo); + void ExtractCaptureInfo(std::vector &captureInfos); + void ExtractCameraAttr(Json::Value &rootValue, std::set &allFormats, std::vector &photoFormats); + void SetSrcStreamInfo(const std::shared_ptr& srcCaptureInfo, + std::vector>& srcStreamInfo); + +private: + std::shared_ptr dMetadataProcessor_; + OHOS::sptr dcStreamOperatorCallback_; + function errorCallback_; + + DHBase dhBase_; + std::vector dcSupportedCodecType_; + std::map> dcSupportedFormatMap_; + std::map> dcSupportedResolutionMap_; + + std::map> halStreamMap_; + std::map> dcStreamInfoMap_; + std::map> halCaptureInfoMap_; + std::vector> cachedDCaptureInfoList_; + std::map enableShutterCbkMap_; + std::map, int> acceptedBufferNum_; + + std::mutex requestLock_; + bool isCapturing_ = false; + std::mutex isCapturingLock_; + OperationMode currentOperMode_ = OperationMode::NORMAL; + std::shared_ptr latestStreamSetting_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_STREAM_OPERATOR_H diff --git a/distributed_camera/hdi_service/include/utils/anonymous_string.h b/distributed_camera/hdi_service/include/utils/anonymous_string.h new file mode 100644 index 0000000000..8cbfaaaa59 --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/anonymous_string.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device 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_DISTRIBUTED_CAMERA_ANONYMOUS_STRING_H +#define OHOS_DISTRIBUTED_CAMERA_ANONYMOUS_STRING_H + +#include + +namespace OHOS { +namespace DistributedHardware { +std::string GetAnonyString(const std::string &value); +std::string GetAnonyInt32(const int32_t value); +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_ANONYMOUS_STRING_H diff --git a/distributed_camera/hdi_service/include/utils/constants.h b/distributed_camera/hdi_service/include/utils/constants.h new file mode 100644 index 0000000000..b022c0e2fc --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/constants.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CONSTANTS_H +#define DISTRIBUTED_CONSTANTS_H + +#include +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +const uint32_t YUV_WIDTH_RATIO = 3; +const uint32_t YUV_HEIGHT_RATIO = 2; + +const uint32_t DEVID_MAX_LENGTH = 64; +const uint32_t DHID_MAX_LENGTH = 64; + +constexpr size_t DEFAULT_ENTRY_CAPACITY = 100; +constexpr size_t DEFAULT_DATA_CAPACITY = 2000; + +const uint32_t SIZE_FMT_LEN = 2; +const uint32_t MAX_SUPPORT_PREVIEW_WIDTH = 1920; +const uint32_t MAX_SUPPORT_PREVIEW_HEIGHT = 1080; +const uint32_t MAX_SUPPORT_PHOTO_WIDTH = 4096; +const uint32_t MAX_SUPPORT_PHOTO_HEIGHT = 3072; +const std::string STAR_SEPARATOR = "*"; + +const uint32_t MIN_SUPPORT_DEFAULT_FPS = 15; +const uint32_t MAX_SUPPORT_DEFAULT_FPS = 30; + +const int64_t MAX_FRAME_DURATION = 1000000000LL / 10; + +const uint32_t BUFFER_QUEUE_SIZE = 8; + +const uint32_t DEGREE_180 = 180; +const uint32_t DEGREE_240 = 240; + +const uint32_t INGNORE_STR_LEN = 2; + +const uint32_t WAIT_OPEN_TIMEOUT_SEC = 5; + +const std::string ENCODE_TYPE_STR_H264 = "OMX_hisi_video_encoder_avc"; +const std::string ENCODE_TYPE_STR_H265 = "OMX_hisi_video_encoder_hevc"; +const std::string ENCODE_TYPE_STR_JPEG = "jpeg"; +const std::string DH_LOG_TITLE_TAG = "DHFWK"; +constexpr int32_t LOG_MAX_LEN = 4096; + +typedef enum { + OHOS_CAMERA_FORMAT_INVALID = 0, + OHOS_CAMERA_FORMAT_RGBA_8888, + OHOS_CAMERA_FORMAT_YCBCR_420_888, + OHOS_CAMERA_FORMAT_YCRCB_420_SP, + OHOS_CAMERA_FORMAT_JPEG, +} DCameraFormat; + +typedef enum { + DCAMERA_MESSAGE = 0, + DCAMERA_OPERATION = 1, +} DCameraEventType; + +typedef enum { + DCAMERA_EVENT_CHANNEL_DISCONNECTED = 0, + DCAMERA_EVENT_CHANNEL_CONNECTED = 1, + DCAMERA_EVENT_CAMERA_SUCCESS = 2, + + DCAMERA_EVENT_CAMERA_ERROR = -1, + DCAMERA_EVENT_OPEN_CHANNEL_ERROR = -2, + DCAMERA_EVENT_CLOSE_CHANNEL_ERROR = -3, + DCAMERA_EVENT_CONFIG_STREAMS_ERROR = -4, + DCAMERA_EVENT_RELEASE_STREAMS_ERROR = -5, + DCAMERA_EVENT_START_CAPTURE_ERROR = -6, + DCAMERA_EVENT_STOP_CAPTURE_ERROR = -7, + DCAMERA_EVENT_UPDATE_SETTINGS_ERROR = -8, + DCAMERA_EVENT_DEVICE_ERROR = -9, + DCAMERA_EVENT_DEVICE_PREEMPT = -10, + DCAMERA_EVENT_DEVICE_IN_USE = -11, + DCAMERA_EVENT_NO_PERMISSION = -12, +} DCameraEventResult; + +enum DCameraBufferUsage : uint64_t { + CAMERA_USAGE_SW_READ_OFTEN = (1 << 0), + CAMERA_USAGE_SW_WRITE_OFTEN = (1 << 1), + CAMERA_USAGE_MEM_DMA = (1 << 2), +}; + +/* Each virtual camera must include these default resolution. */ +const std::vector> DEFAULT_FMT_VEC { +/* + pair(320, 240), + pair(480, 360), + pair(640, 360), + pair(640, 480), + pair(720, 540), + pair(960, 540), + pair(960, 720), + pair(1280, 720), + pair(1440, 1080), + pair(1920, 1080) +*/ +}; + +using DCSceneType = enum _DCSceneType : int32_t { + PREVIEW = 0, + VIDEO = 1, + PHOTO = 2 +}; + +using RetCode = uint32_t; +enum Ret : uint32_t { + RC_OK = 0, + RC_ERROR, +}; + +struct DCResolution { + int32_t width_; + int32_t height_; + + DCResolution() : width_(0), height_(0) {} + + DCResolution(int32_t width, int32_t height) : width_(width), height_(height) {} + + bool operator ==(const DCResolution others) const + { + return (this->width_ == others.width_) && (this->height_ == others.height_); + } + + bool operator <(const DCResolution others) const + { + return this->width_ < others.width_ || + (this->width_ == others.width_ && this->height_ < others.height_); + } +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CONSTANTS_H diff --git a/distributed_camera/hdi_service/include/utils/dcamera.h b/distributed_camera/hdi_service/include/utils/dcamera.h new file mode 100644 index 0000000000..e38ab8570e --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/dcamera.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 DISTRIBUTED_CAMERA_H +#define DISTRIBUTED_CAMERA_H + +#include +#include "v1_0/dcamera_types.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +using namespace OHOS::HDI::DistributedCamera::V1_0; +using RetCode = uint32_t; +using MetaType = int32_t; +const std::string BASE_64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +CamRetCode MapToExternalRetCode(DCamRetCode retCode); + +DCamRetCode MapToInternalRetCode(CamRetCode retCode); + +uint64_t GetCurrentLocalTimeStamp(); + +void SplitString(const std::string &str, std::vector &tokens, const std::string &delimiters); + +std::string Base64Encode(const unsigned char *toEncode, unsigned int len); + +std::string Base64Decode(const std::string& basicString); + +bool IsBase64(unsigned char c); +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_H diff --git a/distributed_camera/hdi_service/include/utils/dcamera_base.h b/distributed_camera/hdi_service/include/utils/dcamera_base.h new file mode 100644 index 0000000000..5645d54671 --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/dcamera_base.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device 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_DCAMERA_BASE_H +#define OHOS_DCAMERA_BASE_H + +#include + +namespace OHOS { +namespace DistributedHardware { +class DCameraBase { +public: + DCameraBase() = default; + explicit DCameraBase(std::string deviceId, std::string dhId) : deviceId_(deviceId), dhId_(dhId) {} + ~DCameraBase() = default; + + bool operator == (const DCameraBase& index) const + { + return this->deviceId_ == index.deviceId_ && this->dhId_ == index.dhId_; + } + + bool operator < (const DCameraBase& index) const + { + return (this->deviceId_ + this->dhId_) < (index.deviceId_ + index.dhId_); + } + + std::string deviceId_; + std::string dhId_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_BASE_H diff --git a/distributed_camera/hdi_service/include/utils/dh_log.h b/distributed_camera/hdi_service/include/utils/dh_log.h new file mode 100644 index 0000000000..6a8e380145 --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/dh_log.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device 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_DCAMERA_LOG_H +#define OHOS_DCAMERA_LOG_H + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DH_LOG_DEBUG, + DH_LOG_INFO, + DH_LOG_WARN, + DH_LOG_ERROR, +} DHLogLevel; + +void DHLog(DHLogLevel logLevel, const char *fmt, ...); + +#define ULOGD(fmt, ...) DHLog(DH_LOG_DEBUG, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define ULOGI(fmt, ...) DHLog(DH_LOG_INFO, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define ULOGW(fmt, ...) DHLog(DH_LOG_WARN, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define ULOGE(fmt, ...) DHLog(DH_LOG_ERROR, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_LOG_H diff --git a/distributed_camera/hdi_service/include/utils/distributed_hardware_log.h b/distributed_camera/hdi_service/include/utils/distributed_hardware_log.h new file mode 100644 index 0000000000..d7e1c1ee1c --- /dev/null +++ b/distributed_camera/hdi_service/include/utils/distributed_hardware_log.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device 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_DISTRIBUTED_CAMERA_LOG_H +#define OHOS_DISTRIBUTED_CAMERA_LOG_H + +#include + +#include "dh_log.h" + +namespace OHOS { +namespace DistributedHardware { +#define DHLOGD(fmt, ...) DHLog(DH_LOG_DEBUG, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGI(fmt, ...) DHLog(DH_LOG_INFO, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGW(fmt, ...) DHLog(DH_LOG_WARN, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGE(fmt, ...) DHLog(DH_LOG_ERROR, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_LOG_H diff --git a/distributed_camera/hdi_service/src/config/dcamera_host_config.cpp b/distributed_camera/hdi_service/src/config/dcamera_host_config.cpp new file mode 100644 index 0000000000..39f57ae31b --- /dev/null +++ b/distributed_camera/hdi_service/src/config/dcamera_host_config.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_host_stub.h" + +struct HdfDCameraService { + struct IDeviceIoService ioservice; + void *instance; +}; + +static int32_t DCameraServiceDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + HdfDCameraService *service = CONTAINER_OF(client->device->service, HdfDCameraService, ioservice); + if (service == nullptr) { + HDF_LOGE("HdfDCameraService CONTAINER_OF failed!"); + return HDF_FAILURE; + } + return DCHostServiceOnRemoteRequest(service->instance, cmdId, data, reply); +} + +static int HdfDCameraHostDriverInit(struct HdfDeviceObject *deviceObject) +{ + if (deviceObject == nullptr) { + HDF_LOGE("HdfDCameraHostDriverInit:: HdfDeviceObject is NULL !"); + return HDF_FAILURE; + } + + if (!HdfDeviceSetClass(deviceObject, DEVICE_CLASS_CAMERA)) { + HDF_LOGE("HdfDCameraHostDriverInit set camera class failed"); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int HdfDCameraHostDriverBind(HdfDeviceObject *deviceObject) +{ + HDF_LOGI("HdfDCameraHostDriverBind enter!"); + if (deviceObject == nullptr) { + HDF_LOGE("HdfDCameraHostDriverBind: HdfDeviceObject is NULL !"); + return HDF_FAILURE; + } + + HdfDCameraService *service = reinterpret_cast(malloc(sizeof(HdfDCameraService))); + if (service == nullptr) { + HDF_LOGE("HdfDCameraHostDriverBind malloc HdfDCameraService failed!"); + return HDF_FAILURE; + } + + service->ioservice.Dispatch = DCameraServiceDispatch; + service->ioservice.Open = nullptr; + service->ioservice.Release = nullptr; + service->instance = DCameraHostStubInstance(); + + deviceObject->service = &service->ioservice; + return HDF_SUCCESS; +} + +static void HdfDCameraHostDriverRelease(HdfDeviceObject *deviceObject) +{ + if (deviceObject == nullptr || deviceObject->service == nullptr) { + HDF_LOGE("HdfDCameraHostDriverRelease: deviceObject or deviceObject->service is NULL!"); + return; + } + HdfDCameraService *service = CONTAINER_OF(deviceObject->service, HdfDCameraService, ioservice); + if (service == nullptr) { + HDF_LOGE("HdfDCameraHostDriverRelease: service is NULL!"); + return; + } + free(service); +} + +static struct HdfDriverEntry g_dCameraHostDriverEntry = { + .moduleVersion = 1, + .moduleName = "distributed_camera_service", + .Bind = HdfDCameraHostDriverBind, + .Init = HdfDCameraHostDriverInit, + .Release = HdfDCameraHostDriverRelease, +}; + +#ifndef __cplusplus +extern "C" { +#endif // __cplusplus + +HDF_INIT(g_dCameraHostDriverEntry); + +#ifndef __cplusplus +} +#endif // __cplusplus \ No newline at end of file diff --git a/distributed_camera/hdi_service/src/dcamera_device/dcamera_device.cpp b/distributed_camera/hdi_service/src/dcamera_device/dcamera_device.cpp new file mode 100644 index 0000000000..665890007a --- /dev/null +++ b/distributed_camera/hdi_service/src/dcamera_device/dcamera_device.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "dcamera_device.h" + +#include "anonymous_string.h" +#include "constants.h" +#include "dcamera.h" +#include "dcamera_host.h" +#include "dcamera_provider.h" +#include "distributed_hardware_log.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +using ErrorCallback = std::function; +using ResultCallback = std::function)>; +DCameraDevice::DCameraDevice(const DHBase &dhBase, const std::string &abilityInfo) + : isOpened_(false), + dCameraId_(GenerateCameraId(dhBase)), + dhBase_(dhBase), + dCameraAbilityInfo_(abilityInfo), + dCameraDeviceCallback_(nullptr), + dCameraStreamOperator_(nullptr), + dMetadataProcessor_(nullptr) +{ + DHLOGI("DCameraDevice::ctor, instance = %p.", this); + Init(abilityInfo); +} + +void DCameraDevice::Init(const std::string &abilityInfo) +{ + if (dMetadataProcessor_ == nullptr) { + dMetadataProcessor_ = std::make_shared(); + } + dMetadataProcessor_->InitDCameraAbility(abilityInfo); +} + +DCamRetCode DCameraDevice::CreateDStreamOperator() +{ + if (dCameraStreamOperator_ == nullptr) { + dCameraStreamOperator_ = new (std::nothrow) DStreamOperator(dMetadataProcessor_); + if (dCameraStreamOperator_ == nullptr) { + DHLOGE("Create distributed camera stream operator failed."); + return DEVICE_NOT_INIT; + } + } + + DCamRetCode ret = dCameraStreamOperator_->InitOutputConfigurations(dhBase_, dCameraAbilityInfo_); + if (ret != SUCCESS) { + DHLOGE("Init distributed camera stream operator failed, ret=%d.", ret); + return ret; + } + + ErrorCallback onErrorCallback = + [this](ErrorType type, int32_t errorMsg) -> void { + if (dCameraDeviceCallback_) { + DHLOGI("DCameraDevice onErrorCallback type: %u, errorMsg: %d", type, errorMsg); + dCameraDeviceCallback_->OnError(type, errorMsg); + } + }; + ResultCallback onResultCallback = + [this](uint64_t timestamp, const std::shared_ptr &result) -> void { + if (dCameraDeviceCallback_) { + DHLOGI("DCameraDevice onResultCallback timestamp: %llu", timestamp); + dCameraDeviceCallback_->OnResult(timestamp, result); + } + }; + dCameraStreamOperator_->SetDeviceCallback(onErrorCallback, onResultCallback); + + return ret; +} + +CamRetCode DCameraDevice::GetStreamOperator(const OHOS::sptr &callback, + OHOS::sptr &streamOperator) +{ + if (dCameraStreamOperator_ == nullptr) { + DHLOGE("Distributed camera stream operator not init."); + return CamRetCode::DEVICE_ERROR; + } + + if (callback == nullptr) { + DHLOGE("Input callback is null."); + return CamRetCode::INVALID_ARGUMENT; + } + + DCamRetCode ret = dCameraStreamOperator_->SetCallBack(callback); + if (ret != SUCCESS) { + DHLOGE("Set stream operator callback failed, ret=%d.", ret); + return MapToExternalRetCode(ret); + } + + streamOperator = dCameraStreamOperator_; + return CamRetCode::NO_ERROR; +} + +CamRetCode DCameraDevice::UpdateSettings(const std::shared_ptr &settings) +{ + if (settings == nullptr) { + DHLOGE("DCameraDevice::UpdateSettings, input settings is null."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!IsOpened()) { + DHLOGE("DCameraDevice::UpdateSettings, dcamera device %s already closed.", GetAnonyString(dCameraId_).c_str()); + return CamRetCode::CAMERA_CLOSED; + } + + std::string abilityString = Camera::MetadataUtils::EncodeToString(settings); + std::string encodeString = Base64Encode(reinterpret_cast(abilityString.c_str()), + abilityString.length()); + + DCameraSettings dcSetting; + dcSetting.type_ = DCSettingsType::UPDATE_METADATA; + dcSetting.value_ = encodeString; + + std::vector dcSettings; + dcSettings.push_back(dcSetting); + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider instance is null."); + return CamRetCode::DEVICE_ERROR; + } + int32_t ret = provider->UpdateSettings(dhBase_, dcSettings); + + return MapToExternalRetCode(static_cast(ret)); +} + +CamRetCode DCameraDevice::SetResultMode(const ResultCallbackMode &mode) +{ + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return CamRetCode::DEVICE_ERROR; + } + + DCamRetCode ret = dMetadataProcessor_->SetMetadataResultMode(mode); + if (ret != SUCCESS) { + DHLOGE("Set metadata result mode failed, ret=%d.", ret); + } + return MapToExternalRetCode(ret); +} + +CamRetCode DCameraDevice::GetEnabledResults(std::vector &results) +{ + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return CamRetCode::DEVICE_ERROR; + } + + DCamRetCode ret = dMetadataProcessor_->GetEnabledMetadataResults(results); + if (ret != SUCCESS) { + DHLOGE("Get enabled metadata results failed, ret=%d.", ret); + } + return MapToExternalRetCode(ret); +} + +CamRetCode DCameraDevice::EnableResult(const std::vector &results) +{ + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return CamRetCode::DEVICE_ERROR; + } + + DCamRetCode ret = dMetadataProcessor_->EnableMetadataResult(results); + if (ret != SUCCESS) { + DHLOGE("Enable metadata result failed, ret=%d.", ret); + return MapToExternalRetCode(ret); + } + + stringstream sstream; + std::reverse_copy(results.begin(), results.end(), ostream_iterator(sstream, "")); + DCameraSettings dcSetting; + dcSetting.type_ = DCSettingsType::ENABLE_METADATA; + dcSetting.value_ = sstream.str(); + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Enable metadata failed, provider is nullptr."); + return CamRetCode::DEVICE_ERROR; + } + std::vector dcSettings; + dcSettings.push_back(dcSetting); + int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings); + return MapToExternalRetCode(static_cast(retProv)); +} + +CamRetCode DCameraDevice::DisableResult(const std::vector &results) +{ + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return CamRetCode::DEVICE_ERROR; + } + + DCamRetCode ret = dMetadataProcessor_->DisableMetadataResult(results); + if (ret != SUCCESS) { + DHLOGE("Disable metadata result failed, ret=%d.", ret); + return MapToExternalRetCode(ret); + } + + stringstream sstream; + std::reverse_copy(results.begin(), results.end(), ostream_iterator(sstream, "")); + DCameraSettings dcSetting; + dcSetting.type_ = DCSettingsType::DISABLE_METADATA; + dcSetting.value_ = sstream.str(); + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Metadata processor provider is nullptr."); + return CamRetCode::DEVICE_ERROR; + } + std::vector dcSettings; + dcSettings.push_back(dcSetting); + int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings); + return MapToExternalRetCode(static_cast(retProv)); +} + +void DCameraDevice::Close() +{ + DHLOGI("DCameraDevice::Close distributed camera: %s", GetAnonyString(dCameraId_).c_str()); + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) { + std::vector streamIds = dCameraStreamOperator_->GetStreamIds(); + provider->StopCapture(dhBase_, streamIds); + } + if (dCameraStreamOperator_ != nullptr) { + dCameraStreamOperator_->Release(); + dCameraStreamOperator_ = nullptr; + } + if (provider != nullptr) { + provider->CloseSession(dhBase_); + } + if (dMetadataProcessor_ != nullptr) { + dMetadataProcessor_->ResetEnableResults(); + } + dCameraDeviceCallback_ = nullptr; + isOpenSessFailed_ = false; + isOpened_ = false; +} + +CamRetCode DCameraDevice::OpenDCamera(const OHOS::sptr &callback) +{ + if (callback == nullptr) { + DHLOGE("Input callback is null."); + return CamRetCode::INVALID_ARGUMENT; + } + dCameraDeviceCallback_ = callback; + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Get distributed camera provider instance is null."); + return CamRetCode::DEVICE_ERROR; + } + int32_t ret = provider->OpenSession(dhBase_); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Open distributed camera control session failed, ret = %d.", ret); + return MapToExternalRetCode(static_cast(ret)); + } + + unique_lock lock(openSesslock_); + auto st = openSessCV_.wait_for(lock, chrono::seconds(WAIT_OPEN_TIMEOUT_SEC)); + if (st == cv_status::timeout) { + DHLOGE("Wait for distributed camera session open timeout."); + return CamRetCode::DEVICE_ERROR; + } + { + unique_lock lock(isOpenSessFailedlock_); + if (isOpenSessFailed_) { + DHLOGE("Open distributed camera session failed."); + return CamRetCode::DEVICE_ERROR; + } + } + + DCamRetCode retDCode = CreateDStreamOperator(); + if (ret != SUCCESS) { + DHLOGE("Create distributed camera stream operator failed."); + return MapToExternalRetCode(retDCode); + } + isOpened_ = true; + + return MapToExternalRetCode(retDCode); +} + +CamRetCode DCameraDevice::GetDCameraAbility(std::shared_ptr &ability) +{ + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return CamRetCode::DEVICE_ERROR; + } + + DCamRetCode ret = dMetadataProcessor_->GetDCameraAbility(ability); + if (ret != SUCCESS) { + DHLOGE("Get distributed camera ability failed, ret=%d.", ret); + } + return MapToExternalRetCode(ret); +} + +DCamRetCode DCameraDevice::AcquireBuffer(int streamId, DCameraBuffer &buffer) +{ + if (dCameraStreamOperator_ == nullptr) { + DHLOGE("Stream operator not init."); + return DEVICE_NOT_INIT; + } + + DCamRetCode ret = dCameraStreamOperator_->AcquireBuffer(streamId, buffer); + if (ret != SUCCESS) { + DHLOGE("Acquire buffer failed, ret=%d.", ret); + } + return ret; +} + +DCamRetCode DCameraDevice::ShutterBuffer(int streamId, const DCameraBuffer &buffer) +{ + if (dCameraStreamOperator_ == nullptr) { + DHLOGE("Stream operator not init."); + return DEVICE_NOT_INIT; + } + + DCamRetCode ret = dCameraStreamOperator_->ShutterBuffer(streamId, buffer); + if (ret != SUCCESS) { + DHLOGE("Shutter buffer failed, ret=%d.", ret); + } + return ret; +} + +DCamRetCode DCameraDevice::OnSettingsResult(const std::shared_ptr &result) +{ + if (result == nullptr) { + DHLOGE("Input camera settings is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return DCamRetCode::DEVICE_NOT_INIT; + } + + if (result->type_ != DCSettingsType::METADATA_RESULT) { + DHLOGE("Invalid camera setting type = %d.", result->type_); + return DCamRetCode::INVALID_ARGUMENT; + } + if ((result->value_).empty()) { + DHLOGE("Camera settings result is empty."); + return DCamRetCode::INVALID_ARGUMENT; + } + + DCamRetCode ret = dMetadataProcessor_->SaveResultMetadata(result->value_); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Save result metadata failed, ret = %d", ret); + } + return ret; +} + +DCamRetCode DCameraDevice::Notify(const std::shared_ptr &event) +{ + DHLOGI("DCameraDevice::Notify for event type = %d, result = %d, content = %s.", event->type_, event->result_, + event->content_.c_str()); + if ((event->type_ != DCameraEventType::DCAMERA_MESSAGE) && (event->type_ != DCameraEventType::DCAMERA_OPERATION)) { + DHLOGE("Invalid distributed camera event type = %d.", event->type_); + return DCamRetCode::INVALID_ARGUMENT; + } + switch (event->result_) { + case DCameraEventResult::DCAMERA_EVENT_CHANNEL_CONNECTED: { + IsOpenSessFailedState(false); + break; + } + case DCameraEventResult::DCAMERA_EVENT_OPEN_CHANNEL_ERROR: { + IsOpenSessFailedState(true); + break; + } + case DCameraEventResult::DCAMERA_EVENT_CHANNEL_DISCONNECTED: { + NotifyCameraError(ErrorType::DEVICE_DISCONNECT); + break; + } + case DCameraEventResult::DCAMERA_EVENT_CONFIG_STREAMS_ERROR: + case DCameraEventResult::DCAMERA_EVENT_START_CAPTURE_ERROR: { + NotifyStartCaptureError(); + break; + } + case DCameraEventResult::DCAMERA_EVENT_DEVICE_ERROR: { + NotifyCameraError(ErrorType::DRIVER_ERROR); + break; + } + case DCameraEventResult::DCAMERA_EVENT_DEVICE_PREEMPT: { + NotifyCameraError(ErrorType::DEVICE_PREEMPT); + break; + } + case DCameraEventResult::DCAMERA_EVENT_DEVICE_IN_USE: { + NotifyCameraError(ErrorType::DCAMERA_ERROR_DEVICE_IN_USE); + break; + } + case DCameraEventResult::DCAMERA_EVENT_NO_PERMISSION: { + NotifyCameraError(ErrorType::DCAMERA_ERROR_NO_PERMISSION); + break; + } + default: + break; + } + return SUCCESS; +} + +void DCameraDevice::IsOpenSessFailedState(bool state) +{ + { + unique_lock lock(isOpenSessFailedlock_); + isOpenSessFailed_ = state; + } + openSessCV_.notify_one(); +} + +void DCameraDevice::NotifyStartCaptureError() +{ + if (dCameraDeviceCallback_ != nullptr) { + dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0); + } + OHOS::sptr provider = DCameraProvider::GetInstance(); + if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) { + std::vector streamIds = dCameraStreamOperator_->GetStreamIds(); + provider->StopCapture(dhBase_, streamIds); + } + if (dCameraStreamOperator_ != nullptr) { + dCameraStreamOperator_->Release(); + } +} + +void DCameraDevice::NotifyCameraError(const ErrorType type) +{ + if (dCameraDeviceCallback_ != nullptr) { + dCameraDeviceCallback_->OnError(type, 0); + Close(); + } +} + +void DCameraDevice::SetProviderCallback(const OHOS::sptr &callback) +{ + dCameraProviderCallback_ = callback; +} + +OHOS::sptr DCameraDevice::GetProviderCallback() +{ + return dCameraProviderCallback_; +} + +std::string DCameraDevice::GenerateCameraId(const DHBase &dhBase) +{ + return dhBase.deviceId_ + "__" + dhBase.dhId_; +} + +std::string DCameraDevice::GetDCameraId() +{ + return dCameraId_; +} + +bool DCameraDevice::IsOpened() +{ + return isOpened_; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dcamera_device/dmetadata_processor.cpp b/distributed_camera/hdi_service/src/dcamera_device/dmetadata_processor.cpp new file mode 100644 index 0000000000..87df9d8f7b --- /dev/null +++ b/distributed_camera/hdi_service/src/dcamera_device/dmetadata_processor.cpp @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "dmetadata_processor.h" + +#include "dbuffer_manager.h" +#include "dcamera.h" +#include "distributed_hardware_log.h" +#include "json/json.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DCamRetCode DMetadataProcessor::InitDCameraAbility(const std::string &abilityInfo) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) && + rootValue.isObject()) { + if (rootValue.isMember("MetaData") && rootValue["MetaData"].isString()) { + std::string metadataStr = rootValue["MetaData"].asString(); + if (!metadataStr.empty()) { + std::hash h; + DHLOGI("Decode distributed camera metadata from base64, hash: %zu, length: %zu", + h(metadataStr), metadataStr.length()); + std::string decodeString = Base64Decode(metadataStr); + DHLOGI("Decode distributed camera metadata from string, hash: %zu, length: %zu", + h(decodeString), decodeString.length()); + dCameraAbility_ = Camera::MetadataUtils::DecodeFromString(decodeString); + DHLOGI("Decode distributed camera metadata from string success."); + } + } + } + + if (dCameraAbility_ == nullptr) { + DHLOGE("Metadata is null in ability set or failed to decode metadata ability from string."); + dCameraAbility_ = std::make_shared(DEFAULT_ENTRY_CAPACITY, DEFAULT_DATA_CAPACITY); + } + + if (Camera::GetCameraMetadataItemCount(dCameraAbility_->get()) <= 0) { + DCamRetCode ret = InitDCameraDefaultAbilityKeys(abilityInfo); + if (ret != SUCCESS) { + DHLOGE("Init distributed camera defalult abilily keys failed."); + dCameraAbility_ = nullptr; + return ret; + } + } + + DCamRetCode ret = InitDCameraOutputAbilityKeys(abilityInfo); + if (ret != SUCCESS) { + DHLOGE("Init distributed camera output abilily keys failed."); + dCameraAbility_ = nullptr; + return ret; + } + + camera_metadata_item_entry_t* itemEntry = Camera::GetMetadataItems(dCameraAbility_->get()); + uint32_t count = dCameraAbility_->get()->item_count; + for (uint32_t i = 0; i < count; i++, itemEntry++) { + allResultSet_.insert((MetaType)(itemEntry->item)); + } + return SUCCESS; +} + +void DMetadataProcessor::InitDcameraBaseAbility() +{ + const uint8_t cameraType = OHOS_CAMERA_TYPE_LOGICAL; + AddAbilityEntry(OHOS_ABILITY_CAMERA_TYPE, &cameraType, 1); + + const int64_t exposureTime = 0xFFFFFFFFFFFFFFFF; + AddAbilityEntry(OHOS_SENSOR_EXPOSURE_TIME, &exposureTime, 1); + + const float correctionGain = 0.0; + AddAbilityEntry(OHOS_SENSOR_COLOR_CORRECTION_GAINS, &correctionGain, 1); + + const uint8_t faceDetectMode = OHOS_CAMERA_FACE_DETECT_MODE_OFF; + AddAbilityEntry(OHOS_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); + + const uint8_t histogramMode = OHOS_CAMERA_HISTOGRAM_MODE_OFF; + AddAbilityEntry(OHOS_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1); + + const uint8_t aeAntibandingMode = OHOS_CAMERA_AE_ANTIBANDING_MODE_OFF; + AddAbilityEntry(OHOS_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1); + + int32_t aeExposureCompensation = 0xFFFFFFFF; + AddAbilityEntry(OHOS_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExposureCompensation, 1); + + const uint8_t aeLock = OHOS_CAMERA_AE_LOCK_OFF; + AddAbilityEntry(OHOS_CONTROL_AE_LOCK, &aeLock, 1); + + const uint8_t aeMode = OHOS_CAMERA_AE_MODE_OFF; + AddAbilityEntry(OHOS_CONTROL_AE_MODE, &aeMode, 1); + + std::vector fpsRanges; + fpsRanges.push_back(MIN_SUPPORT_DEFAULT_FPS); + fpsRanges.push_back(MAX_SUPPORT_DEFAULT_FPS); + AddAbilityEntry(OHOS_CONTROL_AE_TARGET_FPS_RANGE, fpsRanges.data(), fpsRanges.size()); + + AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), fpsRanges.size()); + + const uint8_t afMode = OHOS_CAMERA_AF_MODE_OFF; + AddAbilityEntry(OHOS_CONTROL_AF_MODE, &afMode, 1); + + const uint8_t awbLock = OHOS_CAMERA_AWB_LOCK_OFF; + AddAbilityEntry(OHOS_CONTROL_AWB_LOCK, &awbLock, 1); + + const uint8_t awbMode = OHOS_CAMERA_AWB_MODE_OFF; + AddAbilityEntry(OHOS_CONTROL_AWB_MODE, &awbMode, 1); + + const uint8_t aeAntibandingModes = OHOS_CAMERA_AE_ANTIBANDING_MODE_AUTO; + AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, &aeAntibandingModes, 1); + + const uint8_t aeAvailableModes = OHOS_CAMERA_AE_MODE_ON; + AddAbilityEntry(OHOS_CONTROL_AE_AVAILABLE_MODES, &aeAvailableModes, 1); + + const int32_t compensationRange[] = { 0, 0 }; + AddAbilityEntry(OHOS_CONTROL_AE_COMPENSATION_RANGE, compensationRange, + (sizeof(compensationRange) / sizeof(compensationRange[0]))); + + const camera_rational_t compensationStep[] = { { 0, 1 } }; + AddAbilityEntry(OHOS_CONTROL_AE_COMPENSATION_STEP, compensationStep, + (sizeof(compensationStep) / sizeof(compensationStep[0]))); + + const uint8_t afAvailableModes[] = { OHOS_CAMERA_AF_MODE_AUTO, OHOS_CAMERA_AF_MODE_OFF }; + AddAbilityEntry(OHOS_CONTROL_AF_AVAILABLE_MODES, afAvailableModes, + (sizeof(afAvailableModes) / sizeof(afAvailableModes[0]))); + + const uint8_t awbAvailableModes = OHOS_CAMERA_AWB_MODE_AUTO; + AddAbilityEntry(OHOS_CONTROL_AWB_AVAILABLE_MODES, &awbAvailableModes, 1); + + const uint8_t deviceExposureMode = OHOS_CAMERA_EXPOSURE_MODE_CONTINUOUS_AUTO; + AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_EXPOSUREMODES, &deviceExposureMode, 1); + + const uint8_t controlExposureMode = OHOS_CAMERA_EXPOSURE_MODE_CONTINUOUS_AUTO; + AddAbilityEntry(OHOS_CONTROL_EXPOSUREMODE, &controlExposureMode, 1); + + const uint8_t deviceFocusModes = OHOS_CAMERA_FOCUS_MODE_AUTO; + AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_FOCUSMODES, &deviceFocusModes, 1); +} + +DCamRetCode DMetadataProcessor::InitDCameraDefaultAbilityKeys(const std::string &abilityInfo) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) && + rootValue.isObject()) { + if (rootValue.isMember("ProtocolVer") && rootValue["ProtocolVer"].isString()) { + protocolVersion_ = rootValue["ProtocolVer"].asString(); + } + if (rootValue.isMember("Position") && rootValue["Position"].isString()) { + dCameraPosition_ = rootValue["Position"].asString(); + } + } + + if (dCameraPosition_ == "BACK") { + const uint8_t position = OHOS_CAMERA_POSITION_BACK; + AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1); + } else if (dCameraPosition_ == "FRONT") { + const uint8_t position = OHOS_CAMERA_POSITION_FRONT; + AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1); + } else { + const uint8_t position = OHOS_CAMERA_POSITION_OTHER; + AddAbilityEntry(OHOS_ABILITY_CAMERA_POSITION, &position, 1); + } + + InitDcameraBaseAbility(); + + const uint8_t controlFocusMode = OHOS_CAMERA_FOCUS_MODE_AUTO; + AddAbilityEntry(OHOS_CONTROL_FOCUSMODE, &controlFocusMode, 1); + + const uint8_t deviceFlashModes = OHOS_CAMERA_FLASH_MODE_AUTO; + AddAbilityEntry(OHOS_ABILITY_DEVICE_AVAILABLE_FLASHMODES, &deviceFlashModes, 1); + + const uint8_t controlFlashMode = OHOS_CAMERA_FLASH_MODE_CLOSE; + AddAbilityEntry(OHOS_CONTROL_FLASHMODE, &controlFlashMode, 1); + + float zoomRatioRange[1] = {1.0}; + AddAbilityEntry(OHOS_ABILITY_ZOOM_RATIO_RANGE, zoomRatioRange, + (sizeof(zoomRatioRange) / sizeof(zoomRatioRange[0]))); + + const float zoomRatio = 1.0; + AddAbilityEntry(OHOS_CONTROL_ZOOM_RATIO, &zoomRatio, 1); + + int32_t activeArraySize[] = { + 0, 0, static_cast(maxPreviewResolution_.width_), static_cast(maxPreviewResolution_.height_) + }; + AddAbilityEntry(OHOS_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize, + (sizeof(activeArraySize) / sizeof(activeArraySize[0]))); + + int32_t pixelArraySize[] = { + static_cast(maxPreviewResolution_.width_), static_cast(maxPreviewResolution_.height_) + }; + AddAbilityEntry(OHOS_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, + (sizeof(pixelArraySize) / sizeof(pixelArraySize[0]))); + + const int32_t jpegThumbnailSizes[] = {0, 0, DEGREE_240, DEGREE_180}; + AddAbilityEntry(OHOS_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes, + (sizeof(jpegThumbnailSizes) / sizeof(jpegThumbnailSizes[0]))); + + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::InitDCameraOutputAbilityKeys(const std::string &abilityInfo) +{ + std::map> supportedFormats = GetDCameraSupportedFormats(abilityInfo); + + std::vector streamConfigurations; + std::map>::iterator iter; + for (iter = supportedFormats.begin(); iter != supportedFormats.end(); ++iter) { + std::vector resolutionList = iter->second; + for (auto resolution : resolutionList) { + DHLOGI("DMetadataProcessor::supported formats: { format=%d, width=%d, height=%d }", iter->first, + resolution.width_, resolution.height_); + streamConfigurations.push_back(iter->first); + streamConfigurations.push_back(resolution.width_); + streamConfigurations.push_back(resolution.height_); + } + } + UpdateAbilityEntry(OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, streamConfigurations.data(), + streamConfigurations.size()); + + UpdateAbilityEntry(OHOS_SENSOR_INFO_MAX_FRAME_DURATION, &MAX_FRAME_DURATION, 1); + + const int32_t jpegMaxSize = maxPhotoResolution_.width_ * maxPhotoResolution_.height_; + UpdateAbilityEntry(OHOS_JPEG_MAX_SIZE, &jpegMaxSize, 1); + + const uint8_t connectionType = OHOS_CAMERA_CONNECTION_TYPE_REMOTE; + UpdateAbilityEntry(OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &connectionType, 1); + + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::AddAbilityEntry(uint32_t tag, const void *data, size_t size) +{ + if (dCameraAbility_ == nullptr) { + DHLOGE("Distributed camera abilily is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + + camera_metadata_item_t item; + int ret = Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item); + if (ret) { + if (!dCameraAbility_->addEntry(tag, data, size)) { + DHLOGE("Add tag %u failed.", tag); + return FAILED; + } + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::UpdateAbilityEntry(uint32_t tag, const void *data, size_t size) +{ + if (dCameraAbility_ == nullptr) { + DHLOGE("Distributed camera abilily is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + + camera_metadata_item_t item; + int ret = Camera::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item); + if (ret) { + if (!dCameraAbility_->addEntry(tag, data, size)) { + DHLOGE("Add tag %u failed.", tag); + return FAILED; + } + } else { + if (!dCameraAbility_->updateEntry(tag, data, size)) { + DHLOGE("Update tag %u failed.", tag); + return FAILED; + } + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::GetDCameraAbility(std::shared_ptr &ability) +{ + ability = dCameraAbility_; + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::SetMetadataResultMode(const ResultCallbackMode &mode) +{ + if (mode < ResultCallbackMode::PER_FRAME || mode > ResultCallbackMode::ON_CHANGED) { + DHLOGE("Invalid result callback mode."); + return DCamRetCode::INVALID_ARGUMENT; + } + metaResultMode_ = mode; + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::GetEnabledMetadataResults(std::vector &results) +{ + auto iter = enabledResultSet_.begin(); + while (iter != enabledResultSet_.end()) { + results.push_back(*iter); + iter++; + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::EnableMetadataResult(const std::vector &results) +{ + if (results.size() == 0) { + DHLOGE("Enable metadata result list is empty."); + return SUCCESS; + } + + for (size_t i = 0; i < results.size(); i++) { + auto iter = allResultSet_.find(results[i]); + if (iter != allResultSet_.end()) { + auto anoIter = enabledResultSet_.find(results[i]); + if (anoIter == enabledResultSet_.end()) { + enabledResultSet_.insert(results[i]); + } + } else { + DHLOGE("Cannot find match metatype."); + return SUCCESS; + } + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::DisableMetadataResult(const std::vector &results) +{ + if (results.size() == 0) { + DHLOGE("Disable metadata result list is empty."); + return SUCCESS; + } + + for (size_t i = 0; i < results.size(); i++) { + auto iter = allResultSet_.find(results[i]); + if (iter != allResultSet_.end()) { + auto anoIter = enabledResultSet_.find(results[i]); + if (anoIter != enabledResultSet_.end()) { + enabledResultSet_.erase(*iter); + } + } else { + DHLOGE("Cannot find match metatype."); + return SUCCESS; + } + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::ResetEnableResults() +{ + if (enabledResultSet_.size() < allResultSet_.size()) { + for (auto result : allResultSet_) { + enabledResultSet_.insert(result); + } + } + return SUCCESS; +} + +void DMetadataProcessor::UpdateResultMetadata(const uint64_t &resultTimestamp) +{ + DHLOGD("DMetadataProcessor::UpdateResultMetadata result callback mode: %d", metaResultMode_); + if (metaResultMode_ != ResultCallbackMode::PER_FRAME) { + return; + } + + std::lock_guard autoLock(producerMutex_); + if (latestProducerMetadataResult_ == nullptr) { + DHLOGD("DMetadataProcessor::UpdateResultMetadata latest producer metadata result is null"); + return; + } + + UpdateAllResult(resultTimestamp); +} + +void DMetadataProcessor::SetResultCallback( + std::function)> &resultCbk) +{ + resultCallback_ = resultCbk; +} + +void DMetadataProcessor::UpdateAllResult(const uint64_t &resultTimestamp) +{ + uint32_t itemCap = Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get()); + uint32_t dataSize = Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get()); + DHLOGD("DMetadataProcessor::UpdateAllResult itemCapacity: %u, dataSize: %u", itemCap, dataSize); + std::shared_ptr result = std::make_shared(itemCap, dataSize); + int32_t ret = Camera::CopyCameraMetadataItems(result->get(), latestProducerMetadataResult_->get()); + if (ret != CAM_META_SUCCESS) { + DHLOGE("DMetadataProcessor::UpdateAllResult copy metadata item failed, ret: %d", ret); + return; + } + resultCallback_(resultTimestamp, result); +} + +void DMetadataProcessor::UpdateOnChanged(const uint64_t &resultTimestamp) +{ + bool needReturn = false; + uint32_t itemCap = Camera::GetCameraMetadataItemCapacity(latestProducerMetadataResult_->get()); + uint32_t dataSize = Camera::GetCameraMetadataDataSize(latestProducerMetadataResult_->get()); + DHLOGD("DMetadataProcessor::UpdateOnChanged itemCapacity: %u, dataSize: %u", itemCap, dataSize); + std::shared_ptr result = std::make_shared(itemCap, dataSize); + DHLOGD("DMetadataProcessor::UpdateOnChanged enabledResultSet size: %d", enabledResultSet_.size()); + for (auto tag : enabledResultSet_) { + DHLOGD("DMetadataProcessor::UpdateOnChanged cameta device metadata tag: %d", tag); + camera_metadata_item_t item; + camera_metadata_item_t anoItem; + int ret1 = Camera::FindCameraMetadataItem(latestProducerMetadataResult_->get(), tag, &item); + int ret2 = Camera::FindCameraMetadataItem(latestConsumerMetadataResult_->get(), tag, &anoItem); + DHLOGD("DMetadataProcessor::UpdateOnChanged find metadata item ret: %d, %d", ret1, ret2); + if (ret1 != CAM_META_SUCCESS) { + continue; + } + + if (ret2 == CAM_META_SUCCESS) { + if ((item.count != anoItem.count) || (item.data_type != anoItem.data_type)) { + needReturn = true; + result->addEntry(tag, GetMetadataItemData(item), item.count); + continue; + } + uint32_t size = GetDataSize(item.data_type); + DHLOGD("DMetadataProcessor::UpdateOnChanged data size: %u", size); + for (uint32_t i = 0; i < (size * static_cast(item.count)); i++) { + if (*(item.data.u8 + i) != *(anoItem.data.u8 + i)) { + needReturn = true; + result->addEntry(tag, GetMetadataItemData(item), item.count); + break; + } + } + } else { + needReturn = true; + result->addEntry(tag, GetMetadataItemData(item), item.count); + continue; + } + } + + if (needReturn) { + resultCallback_(resultTimestamp, result); + } +} + +DCamRetCode DMetadataProcessor::SaveResultMetadata(std::string resultStr) +{ + if (resultStr.empty()) { + DHLOGE("Input result string is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::string metadataStr = Base64Decode(resultStr); + std::lock_guard autoLock(producerMutex_); + latestConsumerMetadataResult_ = latestProducerMetadataResult_; + latestProducerMetadataResult_ = Camera::MetadataUtils::DecodeFromString(metadataStr); + if (latestProducerMetadataResult_ == nullptr) { + DHLOGE("Failed to decode metadata setting from string."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!Camera::GetCameraMetadataItemCount(latestProducerMetadataResult_->get())) { + DHLOGE("Input result metadata item is empty."); + return DCamRetCode::INVALID_ARGUMENT; + } + + DHLOGD("DMetadataProcessor::SaveResultMetadata result callback mode: %d", metaResultMode_); + if (metaResultMode_ != ResultCallbackMode::ON_CHANGED) { + return SUCCESS; + } + + uint64_t resultTimestamp = GetCurrentLocalTimeStamp(); + if (latestConsumerMetadataResult_ == nullptr) { + UpdateAllResult(resultTimestamp); + return SUCCESS; + } + + camera_metadata_item_entry_t* itemEntry = Camera::GetMetadataItems(latestProducerMetadataResult_->get()); + uint32_t count = latestProducerMetadataResult_->get()->item_count; + for (uint32_t i = 0; i < count; i++, itemEntry++) { + enabledResultSet_.insert((MetaType)(itemEntry->item)); + } + UpdateOnChanged(resultTimestamp); + return SUCCESS; +} + +void DMetadataProcessor::ConvertToCameraMetadata(common_metadata_header_t *&input, + std::shared_ptr &output) +{ + auto ret = Camera::CopyCameraMetadataItems(output->get(), input); + if (ret != CAM_META_SUCCESS) { + DHLOGE("Failed to copy the old metadata to new metadata."); + output = nullptr; + } +} + +void DMetadataProcessor::ResizeMetadataHeader(common_metadata_header_t *&header, + uint32_t itemCapacity, uint32_t dataCapacity) +{ + if (header) { + Camera::FreeCameraMetadataBuffer(header); + } + header = Camera::AllocateCameraMetadataBuffer(itemCapacity, dataCapacity); +} + +uint32_t DMetadataProcessor::GetDataSize(uint32_t type) +{ + uint32_t size = 0; + if (type == META_TYPE_BYTE) { + size = sizeof(uint8_t); + } else if (type == META_TYPE_INT32) { + size = sizeof(int32_t); + } else if (type == META_TYPE_UINT32) { + size = sizeof(uint32_t); + } else if (type == META_TYPE_FLOAT) { + size = sizeof(float); + } else if (type == META_TYPE_INT64) { + size = sizeof(int64_t); + } else if (type == META_TYPE_DOUBLE) { + size = sizeof(double); + } else if (type == META_TYPE_RATIONAL) { + size = sizeof(camera_rational_t); + } else { + size = 0; + } + return size; +} + +void* DMetadataProcessor::GetMetadataItemData(const camera_metadata_item_t &item) +{ + switch (item.data_type) { + case META_TYPE_BYTE: { + return item.data.u8; + } + case META_TYPE_INT32: { + return item.data.i32; + } + case META_TYPE_UINT32: { + return item.data.ui32; + } + case META_TYPE_FLOAT: { + return item.data.f; + } + case META_TYPE_INT64: { + return item.data.i64; + } + case META_TYPE_DOUBLE: { + return item.data.d; + } + case META_TYPE_RATIONAL: { + return item.data.r; + } + default: { + DHLOGE("DMetadataProcessor::GetMetadataItemData invalid data type: %u", item.data_type); + return nullptr; + } + } +} + +std::map> DMetadataProcessor::GetDCameraSupportedFormats(const std::string &abilityInfo) +{ + std::map> supportedFormats; + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return supportedFormats; + } + + std::set allFormats; + if (rootValue["OutputFormat"]["Preview"].isArray() && (rootValue["OutputFormat"]["Preview"].size() > 0)) { + uint32_t size = rootValue["OutputFormat"]["Preview"].size(); + for (uint32_t i = 0; i < size; i++) { + allFormats.insert((rootValue["OutputFormat"]["Preview"][i]).asInt()); + } + } + + if (rootValue["OutputFormat"]["Video"].isArray() && (rootValue["OutputFormat"]["Video"].size() > 0)) { + uint32_t size = rootValue["OutputFormat"]["Video"].size(); + for (uint32_t i = 0; i < size; i++) { + allFormats.insert((rootValue["OutputFormat"]["Video"][i]).asInt()); + } + } + + std::vector photoFormats; + if (rootValue["OutputFormat"]["Photo"].isArray() && (rootValue["OutputFormat"]["Photo"].size() > 0)) { + uint32_t size = rootValue["OutputFormat"]["Photo"].size(); + for (uint32_t i = 0; i < size; i++) { + photoFormats.push_back((rootValue["OutputFormat"]["Photo"][i]).asInt()); + allFormats.insert((rootValue["OutputFormat"]["Photo"][i]).asInt()); + } + } + + for (const auto &format : allFormats) { + bool isPhotoFormat = (std::find(photoFormats.begin(), photoFormats.end(), format) != photoFormats.end()); + std::string formatStr = std::to_string(format); + if (rootValue["Resolution"][formatStr].isArray() && rootValue["Resolution"][formatStr].size() > 0) { + std::vector resolutionVec; + uint32_t size = rootValue["Resolution"][formatStr].size(); + for (uint32_t i = 0; i < size; i++) { + std::string resoStr = rootValue["Resolution"][formatStr][i].asString(); + std::vector reso; + SplitString(resoStr, reso, STAR_SEPARATOR); + if (reso.size() != SIZE_FMT_LEN) { + continue; + } + uint32_t width = static_cast(std::stoi(reso[0])); + uint32_t height = static_cast(std::stoi(reso[1])); + if (height == 0 || width == 0 || + (isPhotoFormat && ((width * height) > (MAX_SUPPORT_PHOTO_WIDTH * MAX_SUPPORT_PHOTO_HEIGHT))) || + (!isPhotoFormat && + (width > MAX_SUPPORT_PREVIEW_WIDTH || height > MAX_SUPPORT_PREVIEW_HEIGHT))) { + continue; + } + DCResolution resolution(width, height); + resolutionVec.push_back(resolution); + } + if (!resolutionVec.empty()) { + std::sort(resolutionVec.begin(), resolutionVec.end()); + supportedFormats[format] = resolutionVec; + + if (!isPhotoFormat && (maxPreviewResolution_ < resolutionVec[0])) { + maxPreviewResolution_.width_ = resolutionVec[0].width_; + maxPreviewResolution_.height_ = resolutionVec[0].height_; + } + if (isPhotoFormat && (maxPhotoResolution_ < resolutionVec[0])) { + maxPhotoResolution_.width_ = resolutionVec[0].width_; + maxPhotoResolution_.height_ = resolutionVec[0].height_; + } + } + } + } + return supportedFormats; +} + +void DMetadataProcessor::PrintDCameraMetadata(const common_metadata_header_t *metadata) +{ + if (metadata == nullptr) { + DHLOGE("Failed to print metadata, input metadata is null."); + return; + } + + uint32_t tagCount = Camera::GetCameraMetadataItemCount(metadata); + DHLOGD("DMetadataProcessor::PrintDCameraMetadata, input metadata item count = %d.", tagCount); + for (uint32_t i = 0; i < tagCount; i++) { + camera_metadata_item_t item; + int ret = Camera::GetCameraMetadataItem(metadata, i, &item); + if (ret != 0) { + continue; + } + + const char *name = Camera::GetCameraMetadataItemName(item.item); + if (item.data_type == META_TYPE_BYTE) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint8_t)(item.data.u8[k])); + } + } else if (item.data_type == META_TYPE_INT32) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (int32_t)(item.data.i32[k])); + } + } else if (item.data_type == META_TYPE_UINT32) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, (uint32_t)(item.data.ui32[k])); + } + } else if (item.data_type == META_TYPE_FLOAT) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%f", item.index, name, (float)(item.data.f[k])); + } + } else if (item.data_type == META_TYPE_INT64) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%lld", item.index, name, (long long)(item.data.i64[k])); + } + } else if (item.data_type == META_TYPE_DOUBLE) { + for (size_t k = 0; k < item.count; k++) { + DHLOGI("tag index:%d, name:%s, value:%lf", item.index, name, (double)(item.data.d[k])); + } + } else { + DHLOGI("tag index:%d, name:%s, value:%d", item.index, name, *(item.data.r)); + } + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dcamera_host/dcamera_host.cpp b/distributed_camera/hdi_service/src/dcamera_host/dcamera_host.cpp new file mode 100644 index 0000000000..363acba75c --- /dev/null +++ b/distributed_camera/hdi_service/src/dcamera_host/dcamera_host.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_host.h" +#include "anonymous_string.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +std::shared_ptr DCameraHost::instance_ = nullptr; +DCameraHost::AutoRelease DCameraHost::autoRelease_; + +std::shared_ptr DCameraHost::GetInstance() +{ + if (instance_ == nullptr) { + instance_ = std::make_shared(); + if (instance_ == nullptr) { + DHLOGE("Get distributed camera host instance failed."); + return nullptr; + } + } + return instance_; +} + +CamRetCode DCameraHost::SetCallback(const OHOS::sptr &callback) +{ + if (callback == nullptr) { + DHLOGE("DCameraHost::SetCallback, camera host callback is null."); + return CamRetCode::INVALID_ARGUMENT; + } + dCameraHostCallback_ = callback; + return CamRetCode::NO_ERROR; +} + +CamRetCode DCameraHost::GetCameraIds(std::vector &cameraIds) +{ + auto iter = dhBaseHashDCamIdMap_.begin(); + while (iter != dhBaseHashDCamIdMap_.end()) { + if (!(iter->second).empty()) { + cameraIds.push_back(iter->second); + } + iter++; + } + return CamRetCode::NO_ERROR; +} + +CamRetCode DCameraHost::GetCameraAbility(const std::string &cameraId, + std::shared_ptr &ability) +{ + DHLOGE("DCameraHost::GetCameraAbility for cameraId: %s", GetAnonyString(cameraId).c_str()); + + if (IsCameraIdInvalid(cameraId)) { + DHLOGE("DCameraHost::GetCameraAbility, invalid camera id."); + return CamRetCode::INVALID_ARGUMENT; + } + + auto iter = dCameraDeviceMap_.find(cameraId); + return (iter->second)->GetDCameraAbility(ability); +} + +CamRetCode DCameraHost::OpenCamera(const std::string &cameraId, + const OHOS::sptr &callback, + OHOS::sptr &pDevice) +{ + DHLOGI("DCameraHost::OpenCamera for cameraId: %s", GetAnonyString(cameraId).c_str()); + + if (IsCameraIdInvalid(cameraId) || callback == nullptr) { + DHLOGE("DCameraHost::OpenCamera, open camera id is empty or callback is null."); + return CamRetCode::INVALID_ARGUMENT; + } + + auto iter = dCameraDeviceMap_.find(cameraId); + if (iter == dCameraDeviceMap_.end()) { + DHLOGE("DCameraHost::OpenCamera, dcamera device not found."); + return CamRetCode::INSUFFICIENT_RESOURCES; + } + + OHOS::sptr dcameraDevice = iter->second; + if (dcameraDevice == nullptr) { + DHLOGE("DCameraHost::OpenCamera, dcamera device is null."); + return INSUFFICIENT_RESOURCES; + } + + if (dcameraDevice->IsOpened()) { + DHLOGE("DCameraHost::OpenCamera, dcamera device %s already opened.", GetAnonyString(cameraId).c_str()); + return CamRetCode::CAMERA_BUSY; + } + + CamRetCode ret = dcameraDevice->OpenDCamera(callback); + if (ret != CamRetCode::NO_ERROR) { + DHLOGE("DCameraHost::OpenCamera, open camera failed."); + return ret; + } + pDevice = dcameraDevice; + + DHLOGI("DCameraHost::OpenCamera, open camera %s success.", GetAnonyString(cameraId).c_str()); + return CamRetCode::NO_ERROR; +} + +CamRetCode DCameraHost::SetFlashlight(const std::string &cameraId, bool &isEnable) +{ + (void)cameraId; + (void)isEnable; + DHLOGI("DCameraHost::SetFlashlight, distributed camera not support."); + + return CamRetCode::METHOD_NOT_SUPPORTED; +} + +DCamRetCode DCameraHost::AddDCameraDevice(const DHBase &dhBase, const std::string &abilityInfo, + const sptr &callback) +{ + DHLOGI("DCameraHost::AddDCameraDevice for {devId: %s, dhId: %s}", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + OHOS::sptr dcameraDevice = new (std::nothrow) DCameraDevice(dhBase, abilityInfo); + if (dcameraDevice == nullptr) { + DHLOGE("DCameraHost::AddDCameraDevice, create dcamera device failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::string dCameraId = dcameraDevice->GetDCameraId(); + dCameraDeviceMap_[dCameraId] = dcameraDevice; + DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_); + dhBaseHashDCamIdMap_.emplace(dcameraBase, dCameraId); + dcameraDevice->SetProviderCallback(callback); + + if (dCameraHostCallback_ != nullptr) { + dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD); + } + + DHLOGI("DCameraHost::AddDCameraDevice, create dcamera device success, dCameraId: %s", + GetAnonyString(dCameraId).c_str()); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraHost::RemoveDCameraDevice(const DHBase &dhBase) +{ + DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %s, dhId: %s}", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + std::string dCameraId = GetCameraIdByDHBase(dhBase); + if (dCameraId.empty()) { + DHLOGE("DCameraHost::RemoveDCameraDevice, dhBase not exist."); + return DCamRetCode::INVALID_ARGUMENT; + } + + OHOS::sptr dcameraDevice = GetDCameraDeviceByDHBase(dhBase); + if (dcameraDevice != nullptr) { + if (dcameraDevice->IsOpened()) { + dcameraDevice->Close(); + } + dcameraDevice->SetProviderCallback(nullptr); + } + + DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_); + dhBaseHashDCamIdMap_.erase(dcameraBase); + dCameraDeviceMap_.erase(dCameraId); + + if (dCameraHostCallback_ != nullptr) { + dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV); + } + + DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %s", + GetAnonyString(dCameraId).c_str()); + return DCamRetCode::SUCCESS; +} + +bool DCameraHost::IsCameraIdInvalid(const std::string &cameraId) +{ + if (cameraId.empty()) { + return true; + } + + auto iter = dhBaseHashDCamIdMap_.begin(); + while (iter != dhBaseHashDCamIdMap_.end()) { + if (cameraId == iter->second) { + return false; + } + iter++; + } + return true; +} + +std::string DCameraHost::GetCameraIdByDHBase(const DHBase &dhBase) +{ + DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_); + auto iter = dhBaseHashDCamIdMap_.find(dcameraBase); + if (iter == dhBaseHashDCamIdMap_.end()) { + return ""; + } + return iter->second; +} + +OHOS::sptr DCameraHost::GetDCameraDeviceByDHBase(const DHBase &dhBase) +{ + std::string dCameraId = GetCameraIdByDHBase(dhBase); + if (dCameraId.empty()) { + DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dhBase not exist."); + return nullptr; + } + + auto iter = dCameraDeviceMap_.find(dCameraId); + if (iter == dCameraDeviceMap_.end()) { + DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dcamera device not found."); + return nullptr; + } + return iter->second; +} + +void DCameraHost::NotifyDCameraStatus(const DHBase &dhBase, int32_t result) +{ + std::string dCameraId = GetCameraIdByDHBase(dhBase); + if (dCameraId.empty()) { + DHLOGE("DCameraHost::NotifyDCameraStatus, dhBase not exist."); + return; + } + if (dCameraHostCallback_ != nullptr) { + dCameraHostCallback_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE); + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dcamera_provider/dcamera_provider.cpp b/distributed_camera/hdi_service/src/dcamera_provider/dcamera_provider.cpp new file mode 100644 index 0000000000..4e586ca451 --- /dev/null +++ b/distributed_camera/hdi_service/src/dcamera_provider/dcamera_provider.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_provider.h" +#include "anonymous_string.h" +#include "constants.h" +#include "dcamera_device.h" +#include "dcamera_host.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +OHOS::sptr DCameraProvider::instance_ = nullptr; +DCameraProvider::AutoRelease DCameraProvider::autoRelease_; + +extern "C" IDCameraProvider *HdiImplGetInstance(void) +{ + return static_cast(DCameraProvider::GetInstance().GetRefPtr()); +} + +OHOS::sptr DCameraProvider::GetInstance() +{ + if (instance_ == nullptr) { + instance_ = new DCameraProvider(); + if (instance_ == nullptr) { + DHLOGE("Get distributed camera provider instance failed."); + return nullptr; + } + } + return instance_; +} + +int32_t DCameraProvider::EnableDCameraDevice(const DHBase& dhBase, const std::string& abilityInfo, + const sptr& callbackObj) +{ + DHLOGI("DCameraProvider::EnableDCameraDevice for {devId: %s, dhId: %s, abilityInfo length: %d}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(), abilityInfo.length()); + + if (IsDhBaseInfoInvalid(dhBase)) { + DHLOGE("DCameraProvider::EnableDCameraDevice, devId or dhId is invalid."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (abilityInfo.empty()) { + DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera ability is empty."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (callbackObj == nullptr) { + DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera provider callbackObj is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::shared_ptr dCameraHost = DCameraHost::GetInstance(); + if (dCameraHost == nullptr) { + DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera host is null."); + return DCamRetCode::DEVICE_NOT_INIT; + } + DCamRetCode ret = dCameraHost->AddDCameraDevice(dhBase, abilityInfo, callbackObj); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("DCameraProvider::EnableDCameraDevice failed, ret = %d.", ret); + } + + return ret; +} + +int32_t DCameraProvider::DisableDCameraDevice(const DHBase& dhBase) +{ + DHLOGI("DCameraProvider::DisableDCameraDevice for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + if (IsDhBaseInfoInvalid(dhBase)) { + DHLOGE("DCameraProvider::DisableDCameraDevice, devId or dhId is invalid."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::shared_ptr dCameraHost = DCameraHost::GetInstance(); + if (dCameraHost == nullptr) { + DHLOGE("DCameraProvider::DisableDCameraDevice, dcamera host is null."); + return DCamRetCode::DEVICE_NOT_INIT; + } + DCamRetCode ret = dCameraHost->RemoveDCameraDevice(dhBase); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("DCameraProvider::DisableDCameraDevice failed, ret = %d.", ret); + return ret; + } + + return DCamRetCode::SUCCESS; +} + +int32_t DCameraProvider::AcquireBuffer(const DHBase& dhBase, int32_t streamId, DCameraBuffer& buffer) +{ + DHLOGI("DCameraProvider::AcquireBuffer for {devId: %s, dhId: %s}, streamId: %d.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(), streamId); + + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::AcquireBuffer failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + DCamRetCode ret = device->AcquireBuffer(streamId, buffer); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("DCameraProvider::AcquireBuffer failed, ret = %d.", ret); + return ret; + } + return DCamRetCode::SUCCESS; +} + +int32_t DCameraProvider::ShutterBuffer(const DHBase& dhBase, int32_t streamId, const DCameraBuffer& buffer) +{ + DHLOGD("DCameraProvider::ShutterBuffer for {devId: %s, dhId: %s}, streamId = %d, buffer index = %d.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(), streamId, buffer.index_); + + /* ShutterBuffer don't need buffer handle */ + if (buffer.bufferHandle_ != nullptr) { + FreeBufferHandle(buffer.bufferHandle_->GetBufferHandle()); + } + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::ShutterBuffer failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + return device->ShutterBuffer(streamId, buffer); +} + +int32_t DCameraProvider::OnSettingsResult(const DHBase& dhBase, const DCameraSettings& result) +{ + DHLOGI("DCameraProvider::OnSettingsResult for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::OnSettingsResult failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::shared_ptr dCameraResult = std::make_shared(); + dCameraResult->type_ = result.type_; + dCameraResult->value_ = result.value_; + return device->OnSettingsResult(dCameraResult); +} + +int32_t DCameraProvider::Notify(const DHBase& dhBase, const DCameraHDFEvent& event) +{ + DHLOGI("DCameraProvider::Notify for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::Notify failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::shared_ptr dCameraEvent = std::make_shared(); + dCameraEvent->type_ = event.type_; + dCameraEvent->result_ = event.result_; + dCameraEvent->content_ = event.content_; + return device->Notify(dCameraEvent); +} + +int32_t DCameraProvider::OpenSession(const DHBase &dhBase) +{ + DHLOGI("DCameraProvider::OpenSession for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::OpenSession, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return callback->OpenSession(dhBase); +} + +int32_t DCameraProvider::CloseSession(const DHBase &dhBase) +{ + DHLOGI("DCameraProvider::CloseSession for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::CloseSession, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return callback->CloseSession(dhBase); +} + +int32_t DCameraProvider::ConfigureStreams(const DHBase &dhBase, const std::vector &streamInfos) +{ + DHLOGI("DCameraProvider::ConfigureStreams for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::ConfigStreams, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + for (auto info = streamInfos.begin(); info != streamInfos.end(); info++) { + DHLOGI("ConfigureStreams: id=%d, width=%d, height=%d, format=%d, " + + "type=%d.", info->streamId_, info->width_, info->height_, info->format_, info->type_); + } + return callback->ConfigureStreams(dhBase, streamInfos); +} + +int32_t DCameraProvider::ReleaseStreams(const DHBase &dhBase, const std::vector &streamIds) +{ + DHLOGI("DCameraProvider::ReleaseStreams for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::ReleaseStreams, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::string idString = ""; + for (int id : streamIds) { + idString += (std::to_string(id) + ", "); + } + DHLOGI("ReleaseStreams: ids=[%s].", idString.c_str()); + return callback->ReleaseStreams(dhBase, streamIds); +} + +int32_t DCameraProvider::StartCapture(const DHBase &dhBase, const std::vector &captureInfos) +{ + DHLOGI("DCameraProvider::StartCapture for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::StartCapture, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + for (auto info = captureInfos.begin(); info != captureInfos.end(); info++) { + std::string idString = ""; + for (int id : info->streamIds_) { + idString += (std::to_string(id) + ", "); + } + DHLOGI("DCameraProvider::StartCapture: ids=[%s], width=%d, height=%d, format=%d, type=%d, isCapture=%d.", + (idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str()), + info->width_, info->height_, info->format_, info->type_, info->isCapture_); + } + return callback->StartCapture(dhBase, captureInfos); +} + +int32_t DCameraProvider::StopCapture(const DHBase &dhBase, const std::vector &streamIds) +{ + DHLOGI("DCameraProvider::StopCapture for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::StopCapture, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::string idString = ""; + for (int id : streamIds) { + idString += (std::to_string(id) + ", "); + } + DHLOGI("DCameraProvider::StopCapture: ids=[%s].", + idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str()); + return callback->StopCapture(dhBase, streamIds); +} + +int32_t DCameraProvider::UpdateSettings(const DHBase &dhBase, const std::vector &settings) +{ + DHLOGI("DCameraProvider::UpdateSettings for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::UpdateSettings, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return callback->UpdateSettings(dhBase, settings); +} + +bool DCameraProvider::IsDhBaseInfoInvalid(const DHBase &dhBase) +{ + return dhBase.deviceId_.empty() || (dhBase.deviceId_.size() > DEVID_MAX_LENGTH) || + dhBase.dhId_.empty() || (dhBase.dhId_.size() > DHID_MAX_LENGTH); +} + +sptr DCameraProvider::GetCallbackBydhBase(const DHBase &dhBase) +{ + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::GetCallbackBydhBase failed, dcamera device not found."); + return nullptr; + } + return device->GetProviderCallback(); +} + +OHOS::sptr DCameraProvider::GetDCameraDevice(const DHBase &dhBase) +{ + std::shared_ptr dCameraHost = DCameraHost::GetInstance(); + if (dCameraHost == nullptr) { + DHLOGE("DCameraProvider::GetDCameraDevice, dcamera host is null."); + return nullptr; + } + return dCameraHost->GetDCameraDeviceByDHBase(dhBase); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dstream_operator/dbuffer_manager.cpp b/distributed_camera/hdi_service/src/dstream_operator/dbuffer_manager.cpp new file mode 100644 index 0000000000..ff607b54ce --- /dev/null +++ b/distributed_camera/hdi_service/src/dstream_operator/dbuffer_manager.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "dbuffer_manager.h" +#include +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +std::shared_ptr DBufferManager::AcquireBuffer() +{ + std::unique_lock l(lock_); + + if (!idleList_.empty()) { + auto it = idleList_.begin(); + busyList_.splice(busyList_.begin(), idleList_, it); + DHLOGD("Acquire buffer success, index = %d", (*it)->GetIndex()); + return *it; + } + return nullptr; +} + +RetCode DBufferManager::AddBuffer(std::shared_ptr& buffer) +{ + std::unique_lock l(lock_); + if (idleList_.size() + busyList_.size() >= BUFFER_QUEUE_SIZE) { + DHLOGI("Buffer list is full, cannot add buffer."); + return RC_ERROR; + } + idleList_.emplace_back(buffer); + + return RC_OK; +} + +RetCode DBufferManager::RemoveBuffer(std::shared_ptr& buffer) +{ + std::unique_lock l(lock_); + + auto it = std::find(busyList_.begin(), busyList_.end(), buffer); + if (it == busyList_.end()) { + DHLOGE("Busy list is empty, cannot remove buffer."); + return RC_ERROR; + } + busyList_.erase(it); + + return RC_OK; +} + +void DBufferManager::NotifyStop(bool state) +{ + streamStop_ = state; +} + +RetCode DBufferManager::SurfaceBufferToDImageBuffer(const OHOS::sptr &surfaceBuffer, + const std::shared_ptr &buffer) +{ + if (surfaceBuffer == nullptr) { + DHLOGE("Convert surface buffer failed, surfaceBuffer is null."); + return RC_ERROR; + } + + BufferHandle *bufHandle = surfaceBuffer->GetBufferHandle(); + if (bufHandle == nullptr) { + DHLOGE("Convert surface buffer failed, BufferHandle is null."); + return RC_ERROR; + } + if ((bufHandle->size <= 0) || (bufHandle->width <= 0) || (bufHandle->height <= 0) || (bufHandle->usage <= 0)) { + DHLOGE("Convert surface buffer failed, BufferHandle is invalid."); + return RC_ERROR; + } + + buffer->SetPhyAddress(bufHandle->phyAddr); + buffer->SetFileDescriptor(bufHandle->fd); + buffer->SetStride(bufHandle->stride); + buffer->SetWidth(bufHandle->width); + buffer->SetHeight(bufHandle->height); + buffer->SetFormat(PixelFormatToDCameraFormat(static_cast(bufHandle->format))); + buffer->SetUsage(CameraUsageToGrallocUsage(bufHandle->usage)); + buffer->SetSize(static_cast(bufHandle->size)); + buffer->SetBufferHandle(bufHandle); + + return RC_OK; +} + +uint64_t DBufferManager::CameraUsageToGrallocUsage(const uint64_t cameraUsage) +{ + uint64_t grallocUsage = 0; + uint64_t test = 1; + const uint32_t BYTE = 8; + for (uint32_t i = 0; i < sizeof(cameraUsage) * BYTE; i++) { + switch (cameraUsage & (test << i)) { + case CAMERA_USAGE_SW_READ_OFTEN: + grallocUsage |= HBM_USE_CPU_READ; + break; + case CAMERA_USAGE_SW_WRITE_OFTEN: + grallocUsage |= HBM_USE_CPU_WRITE; + break; + case CAMERA_USAGE_MEM_DMA: + grallocUsage |= HBM_USE_MEM_DMA; + break; + default: + break; + } + } + + return grallocUsage; +} + +uint32_t DBufferManager::PixelFormatToDCameraFormat(const PixelFormat format) +{ + uint32_t cameraFormat = OHOS_CAMERA_FORMAT_INVALID; + switch (format) { + case PIXEL_FMT_RGBA_8888: + cameraFormat = OHOS_CAMERA_FORMAT_RGBA_8888; + break; + case PIXEL_FMT_YCBCR_420_SP: + cameraFormat = OHOS_CAMERA_FORMAT_YCBCR_420_888; + break; + case PIXEL_FMT_YCRCB_420_SP: + cameraFormat = OHOS_CAMERA_FORMAT_YCRCB_420_SP; + break; + default: + cameraFormat = OHOS_CAMERA_FORMAT_INVALID; + break; + } + + return cameraFormat; +} + +RetCode DBufferManager::DImageBufferToDCameraBuffer(const std::shared_ptr &imageBuffer, + DCameraBuffer &buffer) +{ + BufferHandle *bufHandle = imageBuffer->GetBufferHandle(); + if (bufHandle == nullptr) { + DHLOGE("Convert image surface buffer failed, BufferHandle is null."); + return RC_ERROR; + } + if ((bufHandle->size <= 0) || (bufHandle->width <= 0) || (bufHandle->height <= 0) || (bufHandle->usage <= 0)) { + DHLOGE("Convert image surface buffer failed, BufferHandle is invalid."); + return RC_ERROR; + } + buffer.index_ = imageBuffer->GetIndex(); + buffer.size_ = imageBuffer->GetSize(); + buffer.bufferHandle_ = new BufferHandleSequenceable(bufHandle); + return RC_OK; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dstream_operator/dcamera_stream.cpp b/distributed_camera/hdi_service/src/dstream_operator/dcamera_stream.cpp new file mode 100644 index 0000000000..e55710283e --- /dev/null +++ b/distributed_camera/hdi_service/src/dstream_operator/dcamera_stream.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_stream.h" + +#include "constants.h" +#include "dcamera.h" +#include "distributed_hardware_log.h" +#include "securec.h" + +namespace OHOS { +namespace DistributedHardware { +DCamRetCode DCameraStream::InitDCameraStream(const shared_ptr &info) +{ + if ((info->streamId_ < 0) || (info->width_ < 0) || (info->height_ < 0) || + (info->format_ < 0) || (info->datasapce_ < 0)) { + DHLOGE("Stream info is invalid."); + return DCamRetCode::INVALID_ARGUMENT; + } + dcStreamId_ = info->streamId_; + dcStreamInfo_ = std::make_shared(); + dcStreamInfo_->streamId_ = info->streamId_; + dcStreamInfo_->width_ = info->width_; + dcStreamInfo_->height_ = info->height_; + dcStreamInfo_->format_ = info->format_; + dcStreamInfo_->datasapce_ = info->datasapce_; + dcStreamInfo_->intent_ = info->intent_; + dcStreamInfo_->tunneledMode_ = info->tunneledMode_; + dcStreamInfo_->bufferQueue_ = info->bufferQueue_; + dcStreamInfo_->minFrameDuration_ = info->minFrameDuration_; + + if (dcStreamAttribute_ == nullptr) { + dcStreamAttribute_ = std::make_shared(); + if (dcStreamAttribute_ == nullptr) { + return DCamRetCode::FAILED; + } + } + dcStreamAttribute_->streamId_ = dcStreamInfo_->streamId_; + dcStreamAttribute_->width_ = dcStreamInfo_->width_; + dcStreamAttribute_->height_ = dcStreamInfo_->height_; + dcStreamAttribute_->overrideFormat_ = dcStreamInfo_->format_; + dcStreamAttribute_->overrideDatasapce_ = dcStreamInfo_->datasapce_; + dcStreamAttribute_->producerUsage_ = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA; + + dcStreamAttribute_->producerBufferCount_ = BUFFER_QUEUE_SIZE; + dcStreamAttribute_->maxBatchCaptureCount_ = BUFFER_QUEUE_SIZE; + dcStreamAttribute_->maxCaptureCount_ = 1; + + DCamRetCode ret = DCamRetCode::SUCCESS; + if (dcStreamInfo_->bufferQueue_ != nullptr) { + DCamRetCode ret = InitDCameraBufferManager(); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Cannot init buffer manager."); + } + } + return ret; +} + +DCamRetCode DCameraStream::InitDCameraBufferManager() +{ + if (dcStreamInfo_ == nullptr) { + DHLOGE("Distributed camera stream info is invalid."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (dcStreamInfo_->bufferQueue_ != nullptr) { + dcStreamProducer_ = OHOS::Surface::CreateSurfaceAsProducer(dcStreamInfo_->bufferQueue_); + } + if (dcStreamProducer_ == nullptr) { + DHLOGE("Distributed camera stream producer is invalid."); + return DCamRetCode::INVALID_ARGUMENT; + } + dcStreamBufferMgr_ = std::make_shared(); + + DCamRetCode ret = DCamRetCode::SUCCESS; + if (!isBufferMgrInited_) { + ret = FinishCommitStream(); + } + return ret; +} + +DCamRetCode DCameraStream::GetDCameraStreamInfo(shared_ptr &info) +{ + if (!dcStreamInfo_) { + DHLOGE("Distributed camera stream info is not init."); + return DCamRetCode::FAILED; + } + info = dcStreamInfo_; + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::SetDCameraBufferQueue(const OHOS::sptr producer) +{ + if (dcStreamInfo_->bufferQueue_) { + DHLOGE("Stream [%d] has already have bufferQueue.", dcStreamId_); + return DCamRetCode::SUCCESS; + } + + dcStreamInfo_->bufferQueue_ = producer; + DCamRetCode ret = InitDCameraBufferManager(); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Init distributed camera buffer manager failed."); + } + return ret; +} + +DCamRetCode DCameraStream::ReleaseDCameraBufferQueue() +{ + DCamRetCode ret = FlushDCameraBuffer(); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Release distributed camera buffer queue failed."); + return ret; + } + dcStreamInfo_->bufferQueue_ = nullptr; + dcStreamProducer_ = nullptr; + dcStreamBufferMgr_ = nullptr; + + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::GetDCameraStreamAttribute(shared_ptr &attribute) +{ + attribute = dcStreamAttribute_; + if (attribute == nullptr) { + return DCamRetCode::INVALID_ARGUMENT; + } + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::FinishCommitStream() +{ + if (isBufferMgrInited_) { + DHLOGI("Stream already inited."); + return DCamRetCode::SUCCESS; + } + if (dcStreamProducer_ == nullptr) { + DHLOGI("No bufferQueue."); + return DCamRetCode::SUCCESS; + } + dcStreamProducer_->SetQueueSize(BUFFER_QUEUE_SIZE); + isBufferMgrInited_ = true; + + for (uint32_t i = 0; i < BUFFER_QUEUE_SIZE; i++) { + GetNextRequest(); + } + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::CheckRequestParam() +{ + if (!isBufferMgrInited_) { + DHLOGE("BufferManager not be init."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (dcStreamInfo_ == nullptr) { + DHLOGE("Cannot create buffer manager by invalid streaminfo."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (dcStreamProducer_ == nullptr) { + DHLOGE("Cannot create a buffer manager by invalid bufferqueue."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::GetNextRequest() +{ + if (CheckRequestParam() != DCamRetCode::SUCCESS) { + return DCamRetCode::INVALID_ARGUMENT; + } + + OHOS::sptr surfaceBuffer = nullptr; + int32_t fence = -1; + int32_t usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA; + OHOS::BufferRequestConfig config = { + .width = dcStreamInfo_->width_, + .height = dcStreamInfo_->height_, + .strideAlignment = 8, + .format = dcStreamInfo_->format_, + .usage = usage, + .timeout = 0 + }; + + OHOS::SurfaceError surfaceError = dcStreamProducer_->RequestBuffer(surfaceBuffer, fence, config); + if (surfaceError == OHOS::SURFACE_ERROR_NO_BUFFER) { + DHLOGE("No available buffer to request in surface."); + return DCamRetCode::EXCEED_MAX_NUMBER; + } + + if (surfaceError != OHOS::SURFACE_ERROR_OK || surfaceBuffer == nullptr) { + DHLOGE("Get producer buffer failed. [streamId = %d] [sfError = %d]", dcStreamInfo_->streamId_, surfaceError); + return DCamRetCode::EXCEED_MAX_NUMBER; + } + + std::shared_ptr imageBuffer = std::make_shared(); + RetCode ret = DBufferManager::SurfaceBufferToDImageBuffer(surfaceBuffer, imageBuffer); + if (ret != RC_OK) { + DHLOGE("Convert surface buffer to image buffer failed, streamId = %d.", dcStreamInfo_->streamId_); + return DCamRetCode::EXCEED_MAX_NUMBER; + } + + imageBuffer->SetIndex(++index_); + imageBuffer->SetFenceId(fence); + ret = dcStreamBufferMgr_->AddBuffer(imageBuffer); + if (ret != RC_OK) { + DHLOGE("Add buffer to buffer manager failed. [streamId = %d]", dcStreamInfo_->streamId_); + return DCamRetCode::EXCEED_MAX_NUMBER; + } + DHLOGD("Add new image buffer success: index = %d, fence = %d", imageBuffer->GetIndex(), fence); + + auto itr = bufferConfigMap_.find(imageBuffer); + if (itr == bufferConfigMap_.end()) { + auto bufferCfg = std::make_tuple(surfaceBuffer, fence, usage); + bufferConfigMap_.insert(std::make_pair(imageBuffer, bufferCfg)); + } + + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::GetDCameraBuffer(DCameraBuffer &buffer) +{ + DCamRetCode retCode = GetNextRequest(); + if (retCode != DCamRetCode::SUCCESS && retCode != DCamRetCode::EXCEED_MAX_NUMBER) { + DHLOGE("Get next request failed."); + return retCode; + } + + std::shared_ptr imageBuffer = dcStreamBufferMgr_->AcquireBuffer(); + if (imageBuffer == nullptr) { + DHLOGE("Cannot get idle buffer."); + return DCamRetCode::EXCEED_MAX_NUMBER; + } + + RetCode ret = DBufferManager::DImageBufferToDCameraBuffer(imageBuffer, buffer); + if (ret != RC_OK) { + DHLOGE("Convert image buffer to distributed camera buffer failed."); + return DCamRetCode::FAILED; + } + captureBufferCount_++; + + DHLOGD("Get buffer success. address = %p, index = %d, size = %d", buffer.bufferHandle_->GetBufferHandle()->virAddr, + buffer.index_, buffer.size_); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::ReturnDCameraBuffer(const DCameraBuffer &buffer) +{ + shared_ptr imageBuffer = nullptr; + for (auto iter = bufferConfigMap_.begin(); iter != bufferConfigMap_.end(); ++iter) { + if (buffer.index_ == iter->first->GetIndex()) { + imageBuffer = iter->first; + break; + } + } + if (imageBuffer == nullptr) { + DHLOGE("Cannot found image buffer, buffer index = %d.", buffer.index_); + return DCamRetCode::INVALID_ARGUMENT; + } + + RetCode ret = dcStreamBufferMgr_->RemoveBuffer(imageBuffer); + if (ret != RC_OK) { + DHLOGE("Buffer manager remove buffer failed: %d", ret); + } + + auto bufCfg = bufferConfigMap_.find(imageBuffer); + if (bufCfg == bufferConfigMap_.end()) { + DHLOGE("Cannot get bufferConfig."); + return DCamRetCode::INVALID_ARGUMENT; + } + auto surfaceBuffer = std::get<0>(bufCfg->second); + int32_t fence = std::get<1>(bufCfg->second); + OHOS::BufferFlushConfig flushConf = { + .damage = { .x = 0, .y = 0, .w = dcStreamInfo_->width_, .h = dcStreamInfo_->height_ }, + .timestamp = 0 + }; + if (dcStreamProducer_ != nullptr) { + int64_t timeStamp = static_cast(GetCurrentLocalTimeStamp()); + if (dcStreamInfo_->intent_ == StreamIntent::VIDEO) { + int32_t size = (dcStreamInfo_->width_) * (dcStreamInfo_->height_) * YUV_WIDTH_RATIO / YUV_HEIGHT_RATIO; + surfaceBuffer->GetExtraData()->ExtraSet("dataSize", size); + surfaceBuffer->GetExtraData()->ExtraSet("isKeyFrame", (int32_t)0); + surfaceBuffer->GetExtraData()->ExtraSet("timeStamp", timeStamp); + } else if (dcStreamInfo_->intent_ == StreamIntent::STILL_CAPTURE) { + int32_t size = buffer.size_; + surfaceBuffer->GetExtraData()->ExtraSet("dataSize", size); + surfaceBuffer->GetExtraData()->ExtraSet("isKeyFrame", (int32_t)0); + surfaceBuffer->GetExtraData()->ExtraSet("timeStamp", timeStamp); + } + int ret = dcStreamProducer_->FlushBuffer(surfaceBuffer, fence, flushConf); + if (ret != 0) { + DHLOGI("FlushBuffer error: %d", ret); + } + } + bufferConfigMap_.erase(bufCfg); + { + captureBufferCount_--; + cv_.notify_one(); + } + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::FlushDCameraBuffer() +{ + if (dcStreamBufferMgr_ == nullptr || dcStreamProducer_ == nullptr) { + DHLOGE("BufferManager or Producer is null."); + return DCamRetCode::SUCCESS; + } + + if (captureBufferCount_ != 0) { + DHLOGI("StreamId:%d has request that not return, captureBufferCount=%d", + dcStreamInfo_->streamId_, captureBufferCount_); + } + { + std::unique_lock l(lock_); + cv_.wait(l, [this] { return !captureBufferCount_; }); + } + + while (true) { + std::shared_ptr imageBuffer = dcStreamBufferMgr_->AcquireBuffer(); + if (imageBuffer == nullptr) { + auto bufCfg = bufferConfigMap_.find(imageBuffer); + if (bufCfg == bufferConfigMap_.end()) { + DHLOGE("Buffer not in map."); + return DCamRetCode::INVALID_ARGUMENT; + } + auto surfaceBuffer = std::get<0>(bufCfg->second); + int32_t fence = std::get<1>(bufCfg->second); + OHOS::BufferFlushConfig flushConf = { + .damage = { + .x = 0, + .y = 0, + .w = dcStreamInfo_->width_, + .h = dcStreamInfo_->height_ }, + .timestamp = 0 + }; + if (dcStreamProducer_ != nullptr) { + dcStreamProducer_->FlushBuffer(surfaceBuffer, fence, flushConf); + } + bufferConfigMap_.erase(bufCfg); + } else { + break; + } + } + captureBufferCount_ = 0; + index_ = -1; + return DCamRetCode::SUCCESS; +} + +bool DCameraStream::HasBufferQueue() +{ + if (dcStreamProducer_ == nullptr || !isBufferMgrInited_) { + return false; + } + return true; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dstream_operator/dimage_buffer.cpp b/distributed_camera/hdi_service/src/dstream_operator/dimage_buffer.cpp new file mode 100644 index 0000000000..4251c24573 --- /dev/null +++ b/distributed_camera/hdi_service/src/dstream_operator/dimage_buffer.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dimage_buffer.h" +#include + +namespace OHOS { +namespace DistributedHardware { +DImageBuffer::~DImageBuffer() +{ + Free(); +} + +int32_t DImageBuffer::GetIndex() const +{ + return index_; +} + +uint32_t DImageBuffer::GetWidth() const +{ + return width_; +} + +uint32_t DImageBuffer::GetHeight() const +{ + return height_; +} + +uint32_t DImageBuffer::GetStride() const +{ + return stride_; +} + +int32_t DImageBuffer::GetFormat() const +{ + return format_; +} + +uint32_t DImageBuffer::GetSize() const +{ + return size_; +} + +uint64_t DImageBuffer::GetUsage() const +{ + return usage_; +} + +uint64_t DImageBuffer::GetPhyAddress() const +{ + return phyAddr_; +} + +int32_t DImageBuffer::GetFileDescriptor() const +{ + return fd_; +} + +uint64_t DImageBuffer::GetTimestamp() const +{ + return timeStamp_; +} + +uint64_t DImageBuffer::GetFrameNumber() const +{ + return frameNumber_; +} + +int32_t DImageBuffer::GetCaptureId() const +{ + return captureId_; +} + +bool DImageBuffer::GetValidFlag() const +{ + return valid_; +} + +int32_t DImageBuffer::GetFenceId() const +{ + return fenceId_; +} + +int32_t DImageBuffer::GetEncodeType() const +{ + return encodeType_; +} + +BufferHandle* DImageBuffer::GetBufferHandle() const +{ + return bufHandle_; +} + +void DImageBuffer::SetIndex(const int32_t index) +{ + std::lock_guard l(l_); + index_ = index; + return; +} + +void DImageBuffer::SetWidth(const uint32_t width) +{ + std::lock_guard l(l_); + width_ = width; + return; +} + +void DImageBuffer::SetHeight(const uint32_t height) +{ + std::lock_guard l(l_); + height_ = height; + return; +} + +void DImageBuffer::SetStride(const uint32_t stride) +{ + std::lock_guard l(l_); + stride_ = stride; + return; +} + +void DImageBuffer::SetFormat(const int32_t format) +{ + std::lock_guard l(l_); + format_ = format; + return; +} + +void DImageBuffer::SetSize(const uint32_t size) +{ + std::lock_guard l(l_); + size_ = size; + return; +} + +void DImageBuffer::SetUsage(const uint64_t usage) +{ + std::lock_guard l(l_); + usage_ = usage; + return; +} + +void DImageBuffer::SetPhyAddress(const uint64_t addr) +{ + std::lock_guard l(l_); + phyAddr_ = addr; + return; +} + +void DImageBuffer::SetFileDescriptor(const int32_t fd) +{ + std::lock_guard l(l_); + fd_ = fd; + return; +} + +void DImageBuffer::SetTimestamp(const uint64_t timeStamp) +{ + std::lock_guard l(l_); + timeStamp_ = timeStamp; + return; +} + +void DImageBuffer::SetFrameNumber(const uint64_t frameNumber) +{ + std::lock_guard l(l_); + frameNumber_ = frameNumber; + return; +} + +void DImageBuffer::SetCaptureId(const int32_t id) +{ + std::lock_guard l(l_); + captureId_ = id; + return; +} + +void DImageBuffer::SetValidFlag(const bool flag) +{ + std::lock_guard l(l_); + valid_ = flag; + return; +} + +void DImageBuffer::SetFenceId(const int32_t fence) +{ + std::lock_guard l(l_); + fenceId_ = fence; + return; +} + +void DImageBuffer::SetEncodeType(const int32_t type) +{ + std::lock_guard l(l_); + encodeType_ = type; + return; +} + +void DImageBuffer::SetBufferHandle(const BufferHandle* bufHandle) +{ + std::lock_guard l(l_); + bufHandle_ = const_cast(bufHandle); + return; +} + +void DImageBuffer::Free() +{ + index_ = -1; + width_ = 0; + height_ = 0; + stride_ = 0; + format_ = OHOS_CAMERA_FORMAT_INVALID; + size_ = 0; + usage_ = 0; + bufHandle_ = nullptr; + phyAddr_ = 0; + fd_ = -1; + + return; +} + +bool DImageBuffer::operator==(const DImageBuffer& u) +{ + if (u.GetPhyAddress() == 0 || phyAddr_ == 0) { + return u.GetIndex() == index_; + } + return u.GetPhyAddress() == phyAddr_; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dstream_operator/doffline_stream_operator.cpp b/distributed_camera/hdi_service/src/dstream_operator/doffline_stream_operator.cpp new file mode 100644 index 0000000000..fc3c721f81 --- /dev/null +++ b/distributed_camera/hdi_service/src/dstream_operator/doffline_stream_operator.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "doffline_stream_operator.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +CamRetCode DOfflineStreamOperator::CancelCapture(int captureId) +{ + (void)captureId; + return CamRetCode::METHOD_NOT_SUPPORTED; +} + +CamRetCode DOfflineStreamOperator::ReleaseStreams(const std::vector& streamIds) +{ + (void)streamIds; + return CamRetCode::METHOD_NOT_SUPPORTED; +} + +CamRetCode DOfflineStreamOperator::Release() +{ + return CamRetCode::METHOD_NOT_SUPPORTED; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/dstream_operator/dstream_operator.cpp b/distributed_camera/hdi_service/src/dstream_operator/dstream_operator.cpp new file mode 100644 index 0000000000..8f8d63c980 --- /dev/null +++ b/distributed_camera/hdi_service/src/dstream_operator/dstream_operator.cpp @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "dstream_operator.h" +#include "dbuffer_manager.h" +#include "dcamera_provider.h" +#include "dcamera.h" +#include "distributed_hardware_log.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DStreamOperator::DStreamOperator(std::shared_ptr &dMetadataProcessor) + : dMetadataProcessor_(dMetadataProcessor) +{ + DHLOGI("DStreamOperator::ctor, instance = %p", this); +} + +CamRetCode DStreamOperator::IsStreamsSupported(OperationMode mode, + const std::shared_ptr &modeSetting, + const std::vector> &info, + StreamSupportType &type) +{ + (void)mode; + type = Camera::DYNAMIC_SUPPORTED; + + if (modeSetting == nullptr) { + DHLOGE("Input invalid argument: modeSetting:%p.", + modeSetting.get()); + return CamRetCode::INVALID_ARGUMENT; + } + + for (auto it : info) { + int id = it->streamId_; + if (halStreamMap_.find(id) != halStreamMap_.end()) { + DHLOGE("Repeat streamId."); + return CamRetCode::INVALID_ARGUMENT; + } + } + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::CreateStreams(const std::vector>& streamInfos) +{ + DHLOGI("DStreamOperator::CreateStreams, input stream info size=%d.", streamInfos.size()); + if (streamInfos.empty()) { + DHLOGE("DStreamOperator::CreateStreams, input stream info is empty."); + return CamRetCode::INVALID_ARGUMENT; + } + + for (auto info : streamInfos) { + if (halStreamMap_.find(info->streamId_) != halStreamMap_.end()) { + return CamRetCode::INVALID_ARGUMENT; + } + if (!info->tunneledMode_) { + return CamRetCode::METHOD_NOT_SUPPORTED; + } + + std::shared_ptr dcStream = std::make_shared(); + if (!dcStream) { + DHLOGE("Create distributed camera stream failed."); + return CamRetCode::INSUFFICIENT_RESOURCES; + } + DCamRetCode ret = dcStream->InitDCameraStream(info); + if (ret != SUCCESS) { + DHLOGE("Init distributed camera stream failed."); + return CamRetCode::INVALID_ARGUMENT; + } + halStreamMap_[info->streamId_] = dcStream; + + std::shared_ptr dcStreamInfo = std::make_shared(); + ConvertStreamInfo(info, dcStreamInfo); + dcStreamInfoMap_[info->streamId_] = dcStreamInfo; + + DHLOGI("Create stream info: id=%d, width=%d, height=%d, format=%d, intent=%d", info->streamId_, + info->width_, info->height_, info->format_, info->intent_); + } + DHLOGI("DStreamOperator::Create distributed camera streams success."); + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::ReleaseStreams(const std::vector& streamIds) +{ + DHLOGI("DStreamOperator::ReleaseStreams, input stream id list size=%d.", streamIds.size()); + if (IsCapturing()) { + DHLOGE("Can not release streams when capture."); + return CamRetCode::CAMERA_BUSY; + } + + for (int id : streamIds) { + auto iter = halStreamMap_.find(id); + if (iter != halStreamMap_.end()) { + auto stream = iter->second; + DCamRetCode ret = stream->ReleaseDCameraBufferQueue(); + if (ret != SUCCESS) { + DHLOGE("Release distributed camera buffer queue for stream %d failed.", id); + return MapToExternalRetCode(ret); + } else { + DHLOGI("Release distributed camera buffer queue for stream %d success.", id); + } + stream = nullptr; + halStreamMap_.erase(id); + dcStreamInfoMap_.erase(id); + } else { + DHLOGE("Error streamId %d.", id); + return CamRetCode::INVALID_ARGUMENT; + } + } + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + int32_t ret = provider->ReleaseStreams(dhBase_, streamIds); + if (ret != SUCCESS) { + DHLOGE("Release distributed camera streams failed."); + return MapToExternalRetCode(static_cast(ret)); + } + + DHLOGI("DStreamOperator::Release distributed camera streams success."); + return CamRetCode::NO_ERROR; +} + +void DStreamOperator::ExtractStreamInfo(DCStreamInfo &dstStreamInfo, + const std::shared_ptr &srcStreamInfo) +{ + dstStreamInfo.streamId_ = srcStreamInfo->streamId_; + dstStreamInfo.width_ = srcStreamInfo->width_; + dstStreamInfo.height_ = srcStreamInfo->height_; + dstStreamInfo.stride_ = srcStreamInfo->stride_; + dstStreamInfo.format_ = srcStreamInfo->format_; + dstStreamInfo.dataspace_ = srcStreamInfo->dataspace_; + dstStreamInfo.encodeType_ = srcStreamInfo->encodeType_; + dstStreamInfo.type_ = srcStreamInfo->type_; +} + +CamRetCode DStreamOperator::CommitStreams(OperationMode mode, + const std::shared_ptr& modeSetting) +{ + DHLOGI("DStreamOperator::CommitStreams, input operation mode=%d.", mode); + if (IsCapturing()) { + DHLOGE("Can not commit streams when capture."); + return CamRetCode::CAMERA_BUSY; + } + + if (currentOperMode_ != mode) { + currentOperMode_ = mode; + } + if (modeSetting == nullptr || modeSetting.get() == nullptr) { + DHLOGE("Input stream mode setting is invalid."); + } else { + latestStreamSetting_ = modeSetting; + } + + if (dcStreamInfoMap_.size() == 0) { + DHLOGE("No stream to commit."); + return CamRetCode::INVALID_ARGUMENT; + } + std::vector dCameraStreams; + for (auto streamInfo : dcStreamInfoMap_) { + DCStreamInfo stream; + ExtractStreamInfo(stream, streamInfo.second); + dCameraStreams.push_back(stream); + } + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + int32_t ret = provider->ConfigureStreams(dhBase_, dCameraStreams); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Commit distributed camera streams failed."); + return MapToExternalRetCode(static_cast(ret)); + } + + for (size_t i = 0; i < dCameraStreams.size(); i++) { + auto streamInfo = dCameraStreams[i]; + for (auto halStream : halStreamMap_) { + if (streamInfo.streamId_ == halStream.first) { + ret = halStream.second->FinishCommitStream(); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Stream %d cannot init.", streamInfo.streamId_); + return MapToExternalRetCode(static_cast(ret)); + } + } + } + } + DHLOGI("DStreamOperator::Commit distributed camera streams success."); + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::GetStreamAttributes(std::vector>& attributes) +{ + attributes.clear(); + for (auto stream : halStreamMap_) { + std::shared_ptr attribute; + DCamRetCode ret = stream.second->GetDCameraStreamAttribute(attribute); + if (ret != SUCCESS) { + DHLOGE("Get distributed camera stream attribute failed."); + attributes.clear(); + return MapToExternalRetCode(ret); + } + attributes.push_back(attribute); + } + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::AttachBufferQueue(int streamId, const OHOS::sptr& producer) +{ + if (IsCapturing()) { + DHLOGE("Can not attach buffer queue when capture."); + return CamRetCode::CAMERA_BUSY; + } + + auto iter = halStreamMap_.find(streamId); + if (iter != halStreamMap_.end()) { + DCamRetCode ret = iter->second->SetDCameraBufferQueue(producer); + if (ret != SUCCESS) { + DHLOGE("Attach distributed camera buffer queue failed."); + } + return MapToExternalRetCode(ret); + } else { + DHLOGE("Not found stream id %d when attach bubfer queue.", streamId); + return CamRetCode::INVALID_ARGUMENT; + } +} + +CamRetCode DStreamOperator::DetachBufferQueue(int streamId) +{ + if (IsCapturing()) { + DHLOGE("Can not detach buffer queue when capture."); + return CamRetCode::CAMERA_BUSY; + } + + auto iter = halStreamMap_.find(streamId); + if (iter != halStreamMap_.end()) { + DCamRetCode ret = iter->second->ReleaseDCameraBufferQueue(); + if (ret != SUCCESS) { + DHLOGE("Detach distributed camera buffer queue failed."); + } + return MapToExternalRetCode(ret); + } else { + DHLOGE("Not found stream id %d when detach bubfer queue.", streamId); + return CamRetCode::INVALID_ARGUMENT; + } +} + +void DStreamOperator::ExtractCaptureInfo(std::vector &captureInfos) +{ + for (auto &captureInfo : cachedDCaptureInfoList_) { + DCCaptureInfo capture; + capture.streamIds_.assign(captureInfo->streamIds_.begin(), captureInfo->streamIds_.end()); + capture.width_ = captureInfo->width_; + capture.height_ = captureInfo->height_; + capture.stride_ = captureInfo->stride_; + capture.format_ = captureInfo->format_; + capture.dataspace_ = captureInfo->dataspace_; + capture.isCapture_ = captureInfo->isCapture_; + capture.encodeType_ = captureInfo->encodeType_; + capture.type_ = captureInfo->type_; + capture.captureSettings_.assign(captureInfo->captureSettings_.begin(), captureInfo->captureSettings_.end()); + captureInfos.emplace_back(capture); + } +} + +CamRetCode DStreamOperator::Capture(int captureId, const std::shared_ptr& captureInfo, bool isStreaming) +{ + if (captureId < 0 || halCaptureInfoMap_.find(captureId) != halCaptureInfoMap_.end()) { + DHLOGE("Input captureId %d is exist.", captureId); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!captureInfo) { + DHLOGE("Input capture info is null."); + return CamRetCode::INVALID_ARGUMENT; + } + + for (auto &id : captureInfo->streamIds_) { + auto iter = halStreamMap_.find(id); + if (iter == halStreamMap_.end()) { + DHLOGE("Invalid stream id %d", id); + return CamRetCode::INVALID_ARGUMENT; + } + if (!iter->second->HasBufferQueue()) { + DHLOGE("Stream %d has not bufferQueue.", iter->first); + return CamRetCode::INVALID_ARGUMENT; + } + enableShutterCbkMap_[id] = captureInfo->enableShutterCallback_; + DHLOGI("DStreamOperator::Capture info: captureId=%d, streamId=%d, isStreaming=%d", captureId, id, isStreaming); + } + + DCamRetCode ret = NegotiateSuitableCaptureInfo(captureInfo, isStreaming); + if (ret != SUCCESS) { + DHLOGE("Negotiate suitable capture info failed."); + return MapToExternalRetCode(ret); + } + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + std::vector captureInfos; + ExtractCaptureInfo(captureInfos); + int32_t retProv = provider->StartCapture(dhBase_, captureInfos); + if (retProv != SUCCESS) { + DHLOGE("Start distributed camera capture failed."); + return MapToExternalRetCode(static_cast(retProv)); + } + halCaptureInfoMap_[captureId] = captureInfo; + + if (dcStreamOperatorCallback_) { + dcStreamOperatorCallback_->OnCaptureStarted(captureId, captureInfo->streamIds_); + } + SetCapturing(true); + DHLOGI("DStreamOperator::Capture, start distributed camera capture success."); + + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::CancelCapture(int captureId) +{ + DHLOGI("DStreamOperator::CancelCapture, cancel distributed camera capture, captureId=%d.", captureId); + + std::unique_lock lock(requestLock_); + if (captureId < 0 || halCaptureInfoMap_.find(captureId) == halCaptureInfoMap_.end()) { + DHLOGE("Input captureId %d is not exist.", captureId); + return CamRetCode::INVALID_ARGUMENT; + } + + OHOS::sptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + + std::vector streamIds = halCaptureInfoMap_[captureId]->streamIds_; + int32_t ret = provider->StopCapture(dhBase_, streamIds); + if (ret != SUCCESS) { + DHLOGE("Cancel distributed camera capture failed."); + return MapToExternalRetCode(static_cast(ret)); + } + + std::vector> info; + for (auto id : halCaptureInfoMap_[captureId]->streamIds_) { + auto iter = halStreamMap_.find(id); + if (iter != halStreamMap_.end()) { + iter->second->FlushDCameraBuffer(); + } + std::shared_ptr tmp = std::make_shared(); + tmp->frameCount_ = acceptedBufferNum_[std::make_pair(captureId, id)]; + tmp->streamId_ = id; + info.push_back(tmp); + acceptedBufferNum_.erase(std::make_pair(captureId, id)); + } + if (dcStreamOperatorCallback_) { + dcStreamOperatorCallback_->OnCaptureEnded(captureId, info); + } + + halCaptureInfoMap_.erase(captureId); + if (!HasContinuousCaptureInfo(captureId)) { + SetCapturing(false); + cachedDCaptureInfoList_.clear(); + } + DHLOGI("DStreamOperator::CancelCapture success, captureId=%d.", captureId); + return CamRetCode::NO_ERROR; +} + +bool DStreamOperator::HasContinuousCaptureInfo(int captureId) +{ + bool flag = false; + for (auto iter : halCaptureInfoMap_) { + for (auto id : iter.second->streamIds_) { + auto dcStreamInfo = dcStreamInfoMap_.find(id); + if (dcStreamInfo == dcStreamInfoMap_.end()) { + continue; + } + + DHLOGI("DStreamOperator::HasContinuousCaptureInfo, captureId=%d, streamId=%d, streamType=%d", + captureId, id, dcStreamInfo->second->type_); + if (dcStreamInfo->second->type_ == DCStreamType::CONTINUOUS_FRAME) { + DHLOGI("DStreamOperator::HasContinuousCaptureInfo, captureId=%d, stream %d is continuous stream.", + captureId, id); + flag = true; + break; + } + } + } + return flag; +} + +CamRetCode DStreamOperator::ChangeToOfflineStream(const std::vector& streamIds, + OHOS::sptr& callback, OHOS::sptr& offlineOperator) +{ + (void)streamIds; + (void)callback; + offlineOperator = nullptr; + return CamRetCode::METHOD_NOT_SUPPORTED; +} + +void DStreamOperator::ExtractCameraAttr(Json::Value &rootValue, std::set &allFormats, + std::vector &photoFormats) +{ + if (rootValue["CodecType"].isArray()) { + uint32_t size = rootValue["CodecType"].size(); + for (uint32_t i = 0; i < size; i++) { + std::string codeType = (rootValue["CodecType"][i]).asString(); + dcSupportedCodecType_.push_back(ConvertDCEncodeType(codeType)); + } + } + + if (rootValue["OutputFormat"]["Preview"].isArray() && (rootValue["OutputFormat"]["Preview"].size() > 0)) { + std::vector previewFormats; + uint32_t size = rootValue["OutputFormat"]["Preview"].size(); + for (uint32_t i = 0; i < size; i++) { + previewFormats.push_back(rootValue["OutputFormat"]["Preview"][i].asInt()); + allFormats.insert((rootValue["OutputFormat"]["Preview"][i]).asInt()); + } + dcSupportedFormatMap_[DCSceneType::PREVIEW] = previewFormats; + } + + if (rootValue["OutputFormat"]["Video"].isArray() && (rootValue["OutputFormat"]["Video"].size() > 0)) { + std::vector videoFormats; + uint32_t size = rootValue["OutputFormat"]["Video"].size(); + for (uint32_t i = 0; i < size; i++) { + videoFormats.push_back(rootValue["OutputFormat"]["Video"][i].asInt()); + allFormats.insert((rootValue["OutputFormat"]["Video"][i]).asInt()); + } + dcSupportedFormatMap_[DCSceneType::VIDEO] = videoFormats; + } + + if (rootValue["OutputFormat"]["Photo"].isArray() && (rootValue["OutputFormat"]["Photo"].size() > 0)) { + uint32_t size = rootValue["OutputFormat"]["Photo"].size(); + for (uint32_t i = 0; i < size; i++) { + photoFormats.push_back(rootValue["OutputFormat"]["Photo"][i].asInt()); + allFormats.insert((rootValue["OutputFormat"]["Photo"][i]).asInt()); + } + dcSupportedFormatMap_[DCSceneType::PHOTO] = photoFormats; + } +} + +DCamRetCode DStreamOperator::InitOutputConfigurations(const DHBase &dhBase, const std::string &abilityInfo) +{ + dhBase_ = dhBase; + + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(abilityInfo.c_str(), abilityInfo.c_str() + abilityInfo.length(), &rootValue, &errs) || + !rootValue.isObject()) { + DHLOGE("Input ablity info is not json object."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::set allFormats; + std::vector photoFormats; + ExtractCameraAttr(rootValue, allFormats, photoFormats); + + for (const auto &format : allFormats) { + bool isPhotoFormat = count(photoFormats.begin(), photoFormats.end(), format); + std::string formatStr = std::to_string(format); + if (rootValue["Resolution"][formatStr].isArray() && rootValue["Resolution"][formatStr].size() > 0) { + std::vector resolutionVec; + uint32_t size = rootValue["Resolution"][formatStr].size(); + for (uint32_t i = 0; i < size; i++) { + std::string resoStr = rootValue["Resolution"][formatStr][i].asString(); + std::vector reso; + SplitString(resoStr, reso, STAR_SEPARATOR); + if (reso.size() != SIZE_FMT_LEN) { + continue; + } + uint32_t width = static_cast(std::stoi(reso[0])); + uint32_t height = static_cast(std::stoi(reso[1])); + if (height == 0 || width == 0 || + (isPhotoFormat && (width > MAX_SUPPORT_PHOTO_WIDTH || height > MAX_SUPPORT_PHOTO_HEIGHT)) || + (!isPhotoFormat && + (width > MAX_SUPPORT_PREVIEW_WIDTH || height > MAX_SUPPORT_PREVIEW_HEIGHT))) { + continue; + } + DCResolution resolution(width, height); + resolutionVec.push_back(resolution); + } + if (!resolutionVec.empty()) { + std::sort(resolutionVec.begin(), resolutionVec.end()); + dcSupportedResolutionMap_[format] = resolutionVec; + } + } + } + + if (dcSupportedCodecType_.empty() || dcSupportedFormatMap_.empty() || dcSupportedResolutionMap_.empty()) { + DHLOGE("Input ablity info is invalid."); + return DEVICE_NOT_INIT; + } + return SUCCESS; +} + +DCamRetCode DStreamOperator::AcquireBuffer(int streamId, DCameraBuffer &buffer) +{ + std::unique_lock lock(requestLock_); + if (!IsCapturing()) { + DHLOGE("Not in capturing state, can not acquire buffer."); + return DCamRetCode::CAMERA_OFFLINE; + } + + auto iter = halStreamMap_.find(streamId); + if (iter == halStreamMap_.end()) { + DHLOGE("streamId %d is invalid, can not acquire buffer.", streamId); + return DCamRetCode::INVALID_ARGUMENT; + } + + DCamRetCode ret = iter->second->GetDCameraBuffer(buffer); + if (ret == DCamRetCode::EXCEED_MAX_NUMBER) { + DHLOGE("Buffer list is full, cannot get new idle buffer."); + } else if (ret == DCamRetCode::INVALID_ARGUMENT) { + DHLOGE("Get distributed camera buffer failed, invalid buffer parameter."); + } + return ret; +} + +DCamRetCode DStreamOperator::ShutterBuffer(int streamId, const DCameraBuffer &buffer) +{ + DHLOGD("DStreamOperator::ShutterBuffer begin shutter buffer for streamId = %d", streamId); + + int32_t captureId = -1; + for (auto iter = halCaptureInfoMap_.begin(); iter != halCaptureInfoMap_.end(); iter++) { + std::shared_ptr captureInfo = iter->second; + std::vector streamIds = captureInfo->streamIds_; + if (std::find(streamIds.begin(), streamIds.end(), streamId) != streamIds.end()) { + captureId = iter->first; + break; + } + } + if (captureId == -1) { + DHLOGE("ShutterBuffer failed, invalid streamId = %d", streamId); + return DCamRetCode::INVALID_ARGUMENT; + } + + auto iter = halStreamMap_.find(streamId); + if (iter != halStreamMap_.end()) { + DCamRetCode ret = iter->second->ReturnDCameraBuffer(buffer); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Flush distributed camera buffer failed."); + return ret; + } + acceptedBufferNum_[std::make_pair(captureId, streamId)]++; + + SnapShotStreamOnCaptureEnded(captureId, streamId); + } + + uint64_t resultTimestamp = GetCurrentLocalTimeStamp(); + dMetadataProcessor_->UpdateResultMetadata(resultTimestamp); + + auto anIter = enableShutterCbkMap_.find(streamId); + if (anIter->second) { + if (dcStreamOperatorCallback_ == nullptr) { + DHLOGE("DStreamOperator::ShutterBuffer failed, need shutter frame, but stream operator callback is null."); + return DCamRetCode::FAILED; + } + std::vector streamIds; + streamIds.push_back(anIter->first); + dcStreamOperatorCallback_->OnFrameShutter(captureId, streamIds, resultTimestamp); + } + return DCamRetCode::SUCCESS; +} + +DCamRetCode DStreamOperator::SetCallBack(OHOS::sptr const &callback) +{ + dcStreamOperatorCallback_ = callback; + return SUCCESS; +} + +DCamRetCode DStreamOperator::SetDeviceCallback( + std::function &errorCbk, + std::function)> &resultCbk) +{ + errorCallback_ = errorCbk; + dMetadataProcessor_->SetResultCallback(resultCbk); + return SUCCESS; +} + +void DStreamOperator::SnapShotStreamOnCaptureEnded(int32_t captureId, int streamId) +{ + auto dcStreamInfo = dcStreamInfoMap_.find(streamId); + if (dcStreamInfo == dcStreamInfoMap_.end()) { + return; + } + if (dcStreamInfo->second->type_ != DCStreamType::SNAPSHOT_FRAME) { + return; + } + if (dcStreamOperatorCallback_ == nullptr) { + return; + } + std::vector> info; + std::shared_ptr tmp = std::make_shared(); + tmp->frameCount_ = acceptedBufferNum_[std::make_pair(captureId, streamId)]; + tmp->streamId_ = streamId; + info.push_back(tmp); + dcStreamOperatorCallback_->OnCaptureEnded(captureId, info); + DHLOGD("snapshot stream successfully reported captureId = %d streamId = %d.", captureId, streamId); +} + +void DStreamOperator::Release() +{ + DHLOGI("DStreamOperator::Release, begin release stream operator."); + + std::unique_lock lock(requestLock_); + std::vector streamIds; + for (auto iter : halStreamMap_) { + streamIds.push_back(iter.first); + } + ReleaseStreams(streamIds); + if (latestStreamSetting_) { + latestStreamSetting_ = nullptr; + } + SetCapturing(false); + halStreamMap_.clear(); + dcStreamInfoMap_.clear(); + halCaptureInfoMap_.clear(); + enableShutterCbkMap_.clear(); + acceptedBufferNum_.clear(); + cachedDCaptureInfoList_.clear(); + dcStreamOperatorCallback_ = nullptr; +} + +std::vector DStreamOperator::GetStreamIds() +{ + DHLOGI("DStreamOperator::GetStreamIds, begin get stream id."); + std::vector streamIds; + std::string idString = ""; + for (auto iter : halStreamMap_) { + streamIds.push_back(iter.first); + idString += (std::to_string(iter.first) + ", "); + } + DHLOGI("DStreamOperator::GetStreamIds, ids=[%s]", idString.c_str()); + return streamIds; +} + +bool DStreamOperator::IsCapturing() +{ + std::unique_lock lock(isCapturingLock_); + return isCapturing_; +} + +void DStreamOperator::SetCapturing(bool isCapturing) +{ + std::unique_lock lock(isCapturingLock_); + isCapturing_ = isCapturing; +} + +void DStreamOperator::ConvertStreamInfo(std::shared_ptr &srcInfo, std::shared_ptr &dstInfo) +{ + dstInfo->streamId_ = srcInfo->streamId_; + dstInfo->width_ = srcInfo->width_; + dstInfo->stride_ = srcInfo->width_; + dstInfo->height_ = srcInfo->height_; + dstInfo->dataspace_ = srcInfo->datasapce_; + dstInfo->encodeType_ = (DCEncodeType)srcInfo->encodeType_; + + if ((srcInfo->intent_ == STILL_CAPTURE) || (srcInfo->intent_ == POST_VIEW)) { + dstInfo->type_ = DCStreamType::SNAPSHOT_FRAME; + if (dstInfo->encodeType_ == DCEncodeType::ENCODE_TYPE_JPEG) { + dstInfo->format_ = OHOS_CAMERA_FORMAT_JPEG; + } else if (dstInfo->encodeType_ == DCEncodeType::ENCODE_TYPE_NULL) { + dstInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP; + } + } else { + dstInfo->type_ = DCStreamType::CONTINUOUS_FRAME; + dstInfo->format_ = + static_cast(DBufferManager::PixelFormatToDCameraFormat(static_cast(srcInfo->format_))); + } +} + +DCamRetCode DStreamOperator::NegotiateSuitableCaptureInfo(const std::shared_ptr& srcCaptureInfo, + bool isStreaming) +{ + std::vector> srcStreamInfo; + SetSrcStreamInfo(srcCaptureInfo, srcStreamInfo); + if (srcStreamInfo.empty()) { + DHLOGE("Input source stream info vector is empty."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::shared_ptr inputCaptureInfo = BuildSuitableCaptureInfo(srcCaptureInfo, srcStreamInfo); + inputCaptureInfo->type_ = isStreaming ? DCStreamType::CONTINUOUS_FRAME : DCStreamType::SNAPSHOT_FRAME; + inputCaptureInfo->isCapture_ = true; + + std::shared_ptr appendCaptureInfo = nullptr; + if (cachedDCaptureInfoList_.empty()) { + std::vector> appendStreamInfo; + auto iter = dcStreamInfoMap_.begin(); + while (iter != dcStreamInfoMap_.end()) { + if ((isStreaming && (iter->second->type_ == DCStreamType::SNAPSHOT_FRAME)) || + (!isStreaming && (iter->second->type_ == DCStreamType::CONTINUOUS_FRAME))) { + appendStreamInfo.push_back(iter->second); + } + iter++; + } + if (!appendStreamInfo.empty()) { + appendCaptureInfo = BuildSuitableCaptureInfo(srcCaptureInfo, appendStreamInfo); + appendCaptureInfo->type_ = isStreaming ? DCStreamType::SNAPSHOT_FRAME : DCStreamType::CONTINUOUS_FRAME; + appendCaptureInfo->isCapture_ = false; + } + } else { + for (auto cacheCapture : cachedDCaptureInfoList_) { + if ((isStreaming && (cacheCapture->type_ == DCStreamType::SNAPSHOT_FRAME)) || + (!isStreaming && (cacheCapture->type_ == DCStreamType::CONTINUOUS_FRAME))) { + cacheCapture->isCapture_ = false; + appendCaptureInfo = cacheCapture; + break; + } + } + if (isStreaming) { + inputCaptureInfo->isCapture_ = false; + } + } + cachedDCaptureInfoList_.clear(); + cachedDCaptureInfoList_.push_back(inputCaptureInfo); + if (appendCaptureInfo != nullptr) { + cachedDCaptureInfoList_.push_back(appendCaptureInfo); + } + return SUCCESS; +} + +void DStreamOperator::SetSrcStreamInfo(const std::shared_ptr& srcCaptureInfo, + std::vector>& srcStreamInfo) +{ + for (auto &id : srcCaptureInfo->streamIds_) { + auto iter = dcStreamInfoMap_.find(id); + if (iter != dcStreamInfoMap_.end()) { + srcStreamInfo.push_back(iter->second); + } + } +} + +std::shared_ptr DStreamOperator::BuildSuitableCaptureInfo(const shared_ptr& srcCaptureInfo, + std::vector> &srcStreamInfo) +{ + std::shared_ptr captureInfo = std::make_shared(); + + ChooseSuitableFormat(srcStreamInfo, captureInfo); + ChooseSuitableResolution(srcStreamInfo, captureInfo); + ChooseSuitableDataSpace(srcStreamInfo, captureInfo); + ChooseSuitableEncodeType(srcStreamInfo, captureInfo); + + DCameraSettings dcSetting; + dcSetting.type_ = DCSettingsType::UPDATE_METADATA; + std::string settingStr = Camera::MetadataUtils::EncodeToString(srcCaptureInfo->captureSetting_); + dcSetting.value_ = Base64Encode(reinterpret_cast(settingStr.c_str()), settingStr.length()); + + captureInfo->captureSettings_.push_back(dcSetting); + + return captureInfo; +} + +void DStreamOperator::ChooseSuitableFormat(std::vector> &streamInfo, + std::shared_ptr &captureInfo) +{ + for (auto stream : streamInfo) { + if (dcSupportedResolutionMap_.count(stream->format_) > 0) { + captureInfo->format_ = stream->format_; + return; + } + } + if ((streamInfo.at(0))->type_ == DCStreamType::CONTINUOUS_FRAME) { + if (dcSupportedFormatMap_.count(DCSceneType::PREVIEW) > 0) { + captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::PREVIEW].at(0); + } else if (dcSupportedFormatMap_.count(DCSceneType::VIDEO) > 0) { + captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::VIDEO].at(0); + } else { + captureInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP; + } + } else { + if (dcSupportedFormatMap_.count(DCSceneType::PHOTO) > 0) { + captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::PHOTO].at(0); + } else { + if ((streamInfo.at(0))->encodeType_ == DCEncodeType::ENCODE_TYPE_JPEG) { + captureInfo->format_ = OHOS_CAMERA_FORMAT_JPEG; + } else { + captureInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP; + } + } + } +} + +void DStreamOperator::ChooseSuitableResolution(std::vector> &streamInfo, + std::shared_ptr &captureInfo) +{ + if (captureInfo == nullptr) { + DHLOGE("DStreamOperator::ChooseSuitableResolution, captureInfo is null."); + return; + } + std::vector supportedResolutionList = dcSupportedResolutionMap_[captureInfo->format_]; + + DCResolution tempResolution = { 0, 0 }; + for (auto stream : streamInfo) { + for (auto resolution : supportedResolutionList) { + if ((resolution.width_ == stream->width_) && (resolution.height_ == stream->height_)) { + if (tempResolution < resolution) { + tempResolution = resolution; + break; + } + } + } + captureInfo->streamIds_.push_back(stream->streamId_); + } + + if ((tempResolution.width_ == 0) || (tempResolution.height_ == 0)) { + captureInfo->width_ = MAX_SUPPORT_PREVIEW_WIDTH; + captureInfo->height_ = MAX_SUPPORT_PREVIEW_HEIGHT; + } else { + captureInfo->width_ = tempResolution.width_; + captureInfo->height_ = tempResolution.height_; + } +} + +void DStreamOperator::ChooseSuitableDataSpace(std::vector> &streamInfo, + std::shared_ptr &captureInfo) +{ + captureInfo->dataspace_ = (streamInfo.at(0))->dataspace_; +} + +void DStreamOperator::ChooseSuitableEncodeType(std::vector> &streamInfo, + std::shared_ptr &captureInfo) +{ + if ((streamInfo.at(0))->type_ == DCStreamType::CONTINUOUS_FRAME) { + if (count(dcSupportedCodecType_.begin(), dcSupportedCodecType_.end(), DCEncodeType::ENCODE_TYPE_H265)) { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_H265; + } else if (count(dcSupportedCodecType_.begin(), dcSupportedCodecType_.end(), DCEncodeType::ENCODE_TYPE_H264)) { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_H264; + } else { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_NULL; + } + } else { + if ((streamInfo.at(0))->encodeType_ == DCEncodeType::ENCODE_TYPE_JPEG) { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_JPEG; + } else { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_NULL; + } + } +} + +DCEncodeType DStreamOperator::ConvertDCEncodeType(std::string &srcEncodeType) +{ + if (srcEncodeType == ENCODE_TYPE_STR_H264) { + return DCEncodeType::ENCODE_TYPE_H264; + } else if (srcEncodeType == ENCODE_TYPE_STR_H265) { + return DCEncodeType::ENCODE_TYPE_H265; + } else if (srcEncodeType == ENCODE_TYPE_STR_JPEG) { + return DCEncodeType::ENCODE_TYPE_JPEG; + } else { + return DCEncodeType::ENCODE_TYPE_NULL; + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/utils/anonymous_string.cpp b/distributed_camera/hdi_service/src/utils/anonymous_string.cpp new file mode 100644 index 0000000000..b6cfa82d2b --- /dev/null +++ b/distributed_camera/hdi_service/src/utils/anonymous_string.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "anonymous_string.h" + +#include "securec.h" + +namespace OHOS { +namespace DistributedHardware { +std::string GetAnonyString(const std::string &value) +{ + constexpr size_t INT32_SHORT_ID_LENGTH = 20; + constexpr size_t INT32_PLAINTEXT_LENGTH = 4; + constexpr size_t INT32_MIN_ID_LENGTH = 3; + std::string res; + std::string tmpStr("******"); + size_t strLen = value.length(); + if (strLen < INT32_MIN_ID_LENGTH) { + return tmpStr; + } + + if (strLen <= INT32_SHORT_ID_LENGTH) { + res += value[0]; + res += tmpStr; + res += value[strLen - 1]; + } else { + res.append(value, 0, INT32_PLAINTEXT_LENGTH); + res += tmpStr; + res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH); + } + + return res; +} + +std::string GetAnonyInt32(const int32_t value) +{ + constexpr int32_t INT32_STRING_LENGTH = 40; + char tempBuffer[INT32_STRING_LENGTH] = ""; + int32_t secRet = sprintf_s(tempBuffer, INT32_STRING_LENGTH, "%d", value); + if (secRet <= 0) { + std::string nullString(""); + return nullString; + } + size_t length = strlen(tempBuffer); + for (size_t i = 1; i <= length - 1; i++) { + tempBuffer[i] = '*'; + } + if (length == 0x01) { + tempBuffer[0] = '*'; + } + + std::string tempString(tempBuffer); + return tempString; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/utils/dcamera.cpp b/distributed_camera/hdi_service/src/utils/dcamera.cpp new file mode 100644 index 0000000000..b8e31f6dee --- /dev/null +++ b/distributed_camera/hdi_service/src/utils/dcamera.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "dcamera.h" +#include + +namespace OHOS { +namespace DistributedHardware { +const uint32_t OFFSET2 = 2; +const uint32_t OFFSET4 = 4; +const uint32_t OFFSET6 = 6; +const uint8_t PARAM_FC = 0xfc; +const uint8_t PARAM_03 = 0x03; +const uint8_t PARAM_F0 = 0xf0; +const uint8_t PARAM_0F = 0x0f; +const uint8_t PARAM_C0 = 0xc0; +const uint8_t PARAM_3F = 0x3f; +const int INDEX_FIRST = 0; +const int INDEX_SECOND = 1; +const int INDEX_THIRD = 2; +const int INDEX_FORTH = 3; +CamRetCode MapToExternalRetCode(DCamRetCode retCode) +{ + switch (retCode) { + case DCamRetCode::SUCCESS: + return CamRetCode::NO_ERROR; + case DCamRetCode::CAMERA_BUSY: + return CamRetCode::CAMERA_BUSY; + case DCamRetCode::INVALID_ARGUMENT: + return CamRetCode::INVALID_ARGUMENT; + case DCamRetCode::METHOD_NOT_SUPPORTED: + return CamRetCode::METHOD_NOT_SUPPORTED; + case DCamRetCode::CAMERA_OFFLINE: + return CamRetCode::CAMERA_CLOSED; + case DCamRetCode::EXCEED_MAX_NUMBER: + return CamRetCode::INSUFFICIENT_RESOURCES; + case DCamRetCode::FAILED: + return CamRetCode::DEVICE_ERROR; + default: + break; + } + return CamRetCode::DEVICE_ERROR; +} + +DCamRetCode MapToInternalRetCode(CamRetCode retCode) +{ + switch (retCode) { + case CamRetCode::NO_ERROR: + return DCamRetCode::SUCCESS; + case CamRetCode::CAMERA_BUSY: + return DCamRetCode::CAMERA_BUSY; + case CamRetCode::INSUFFICIENT_RESOURCES: + return DCamRetCode::EXCEED_MAX_NUMBER; + case CamRetCode::INVALID_ARGUMENT: + return DCamRetCode::INVALID_ARGUMENT; + case CamRetCode::METHOD_NOT_SUPPORTED: + return DCamRetCode::METHOD_NOT_SUPPORTED; + case CamRetCode::CAMERA_CLOSED: + return DCamRetCode::CAMERA_OFFLINE; + case CamRetCode::DEVICE_ERROR: + return DCamRetCode::FAILED; + default: + break; + } + return DCamRetCode::FAILED; +} + +uint64_t GetCurrentLocalTimeStamp() +{ + std::chrono::time_point tp = + std::chrono::time_point_cast(std::chrono::system_clock::now()); + auto tmp = std::chrono::duration_cast(tp.time_since_epoch()); + return static_cast(tmp.count()); +} + +void SplitString(const std::string &str, std::vector &tokens, const std::string &delimiters) +{ + std::string::size_type lastPos = 0; + std::string::size_type pos = str.find(delimiters); + while (std::string::npos != pos) { + tokens.push_back(str.substr(lastPos, pos - lastPos)); + lastPos = pos + delimiters.size(); + pos = str.find(delimiters, lastPos); + } + if (lastPos != str.length()) { + tokens.push_back(str.substr(lastPos)); + } +} + +std::string Base64Encode(const unsigned char *toEncode, unsigned int len) +{ + std::string ret; + uint32_t i = 0; + unsigned char charArray3[3]; + unsigned char charArray4[4]; + + while (len--) { + charArray3[i++] = *(toEncode++); + if (i == sizeof(charArray3)) { + charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2; + charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) + + ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4); + charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) + + ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6); + charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F; + for (i = 0; i < sizeof(charArray4); i++) { + ret += BASE_64_CHARS[charArray4[i]]; + } + i = 0; + } + } + + if (i) { + uint32_t j = 0; + for (j = i; j < sizeof(charArray3); j++) { + charArray3[j] = '\0'; + } + charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & PARAM_FC) >> OFFSET2; + charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & PARAM_03) << OFFSET4) + + ((charArray3[INDEX_SECOND] & PARAM_F0) >> OFFSET4); + charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & PARAM_0F) << OFFSET2) + + ((charArray3[INDEX_THIRD] & PARAM_C0) >> OFFSET6); + charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & PARAM_3F; + for (j = 0; j < i + 1; j++) { + ret += BASE_64_CHARS[charArray4[j]]; + } + while (i++ < sizeof(charArray3)) { + ret += '='; + } + } + return ret; +} + +std::string Base64Decode(const std::string& basicString) +{ + std::string ret; + uint32_t i = 0; + int index = 0; + int len = static_cast(basicString.size()); + unsigned char charArray3[3]; + unsigned char charArray4[4]; + + while (len-- && (basicString[index] != '=') && IsBase64(basicString[index])) { + charArray4[i++] = basicString[index]; + index++; + if (i == sizeof(charArray4)) { + for (i = 0; i < sizeof(charArray4); i++) { + charArray4[i] = BASE_64_CHARS.find(charArray4[i]); + } + charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) + + ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4); + charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) + + ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2); + charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH]; + for (i = 0; i < sizeof(charArray3); i++) { + ret += charArray3[i]; + } + i = 0; + } + } + + if (i) { + uint32_t j = 0; + for (j = i; j < sizeof(charArray4); j++) { + charArray4[j] = 0; + } + for (j = 0; j < sizeof(charArray4); j++) { + charArray4[j] = BASE_64_CHARS.find(charArray4[j]); + } + charArray3[INDEX_FIRST] = (charArray4[INDEX_FIRST] << OFFSET2) + + ((charArray4[INDEX_SECOND] & 0x30) >> OFFSET4); + charArray3[INDEX_SECOND] = ((charArray4[INDEX_SECOND] & 0xf) << OFFSET4) + + ((charArray4[INDEX_THIRD] & 0x3c) >> OFFSET2); + charArray3[INDEX_THIRD] = ((charArray4[INDEX_THIRD] & 0x3) << OFFSET6) + charArray4[INDEX_FORTH]; + for (j = 0; j < i - 1; j++) { + ret += charArray3[j]; + } + } + return ret; +} + +bool IsBase64(unsigned char c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/src/utils/dh_log.cpp b/distributed_camera/hdi_service/src/utils/dh_log.cpp new file mode 100644 index 0000000000..f2278de4fe --- /dev/null +++ b/distributed_camera/hdi_service/src/utils/dh_log.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "dh_log.h" + +#include "securec.h" + +#include "constants.h" + +#ifdef HI_LOG_ENABLE +#include "hilog/log.h" +#else +#include +#endif + +namespace OHOS { +namespace DistributedHardware { +static void DHLogOut(DHLogLevel logLevel, const char *logBuf) +{ +#ifdef HI_LOG_ENABLE + LogLevel hiLogLevel = LOG_INFO; + switch (logLevel) { + case DH_LOG_DEBUG: + hiLogLevel = LOG_DEBUG; + break; + case DH_LOG_INFO: + hiLogLevel = LOG_INFO; + break; + case DH_LOG_WARN: + hiLogLevel = LOG_WARN; + break; + case DH_LOG_ERROR: + hiLogLevel = LOG_ERROR; + break; + default: + break; + } + (void)HiLogPrint(LOG_CORE, hiLogLevel, LOG_DOMAIN, DH_LOG_TITLE_TAG.c_str(), "%{public}s", logBuf); +#else + switch (logLevel) { + case DH_LOG_DEBUG: + printf("[D]%s\n", logBuf); + break; + case DH_LOG_INFO: + printf("[I]%s\n", logBuf); + break; + case DH_LOG_WARN: + printf("[W]%s\n", logBuf); + break; + case DH_LOG_ERROR: + printf("[E]%s\n", logBuf); + break; + default: + break; + } +#endif +} + +void DHLog(DHLogLevel logLevel, const char *fmt, ...) +{ + char logBuf[LOG_MAX_LEN] = {0}; + va_list arg; + + (void)memset_s(&arg, sizeof(va_list), 0, sizeof(va_list)); + va_start(arg, fmt); + int32_t ret = vsprintf_s(logBuf, sizeof(logBuf), fmt, arg); + va_end(arg); + if (ret < 0) { + DHLogOut(logLevel, "DH log length error."); + return; + } + DHLogOut(logLevel, logBuf); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/test/BUILD.gn b/distributed_camera/hdi_service/test/BUILD.gn new file mode 100644 index 0000000000..66a78a926e --- /dev/null +++ b/distributed_camera/hdi_service/test/BUILD.gn @@ -0,0 +1,74 @@ +# Copyright (c) 2021 Huawei Device 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") +import( + "//foundation/distributedhardware/distributed_camera/distributedcamera.gni") + +ohos_executable("dcamera_hdi_sample") { + install_enable = false + sources = [ + "common.cpp", + "dcamera_hdi_sample.cpp", + ] + + include_dirs = [ + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client/device", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client/host", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client/operator", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/device", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/host", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/operator", + "${distributedcamera_hdf_path}/hdi_service/include/dcamera_device", + "${distributedcamera_hdf_path}/hdi_service/include/dcamera_host", + "${distributedcamera_hdf_path}/hdi_service/include/dcamera_provider", + "${distributedcamera_hdf_path}/hdi_service/include/dstream_operator", + "${distributedcamera_hdf_path}/hdi_service/include/utils", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include/", + "${common_path}/include/constants", + "${fwk_utils_path}/include", + "${fwk_utils_path}/include/log", + "${hdf_framework_path}/include/utils", + "${hdf_uhdf_path}/include/hdi", + "${hdf_uhdf_path}/osal/include", + + "//drivers/peripheral/camera/interfaces/metadata/include", + + "${camera_hdf_path}/camera/interfaces/include", + "${camera_hdf_path}/camera/interfaces/hdi_ipc", + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + "${fwk_common_path}/utils/include", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${fwk_utils_path}:distributedhardwareutils", + "${hdf_uhdf_path}/hdi:libhdi", + "${innerkits_path}/native_cpp/camera_source:distributed_camera_source_sdk", + "//drivers/peripheral/camera/interfaces/metadata:metadata", + ] + + external_deps = [ + "drivers_interface_distributed_camera:libdistributed_camera_provider_proxy_1.0", + "graphic_chipsetsdk:surface", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "samgr_standard:samgr_proxy", + ] + + part_name = "distributed_camera" + subsystem_name = "distributedhardware" +} diff --git a/distributed_camera/hdi_service/test/common.cpp b/distributed_camera/hdi_service/test/common.cpp new file mode 100644 index 0000000000..d99a2a7ac1 --- /dev/null +++ b/distributed_camera/hdi_service/test/common.cpp @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "common.h" + +namespace OHOS { +namespace DistributedHardware { +uint64_t Test::GetCurrentLocalTimeStamp() +{ + std::chrono::time_point tp = + std::chrono::time_point_cast(std::chrono::system_clock::now()); + auto tmp = std::chrono::duration_cast(tp.time_since_epoch()); + return static_cast(tmp.count()); +} + +int32_t Test::SaveYUV(const char* type, const void* buffer, int32_t size) +{ + if (strncmp(type, "preview", strlen(type)) == 0) { + previewBufCnt += 1; + int cycNum = 8; + if (previewBufCnt % cycNum != 0) { + std::cout << "receive preview buffer not save" << std::endl; + return 0; + } + } + char path[PATH_MAX] = {0}; + if (strncmp(type, "preview", strlen(type)) == 0) { + system("mkdir -p /data/dcamera/preview"); + if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/preview/%s_%lld.yuv", + type, GetCurrentLocalTimeStamp()) < 0) { + std::cout << "SaveYUV : preview sprintf_s fail." << std::endl; + return -1; + } + } else { + system("mkdir -p /data/dcamera/capture"); + if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/capture/%s_%lld.jpg", + type, GetCurrentLocalTimeStamp()) < 0) { + std::cout << "SaveYUV : capture sprintf_s fail." << std::endl; + return -1; + } + } + std::cout << "save yuv to file:" << path << std::endl; + + int mode = 00766; + int imgFd = open(path, O_RDWR | O_CREAT, mode); + if (imgFd == -1) { + std::cout << "open file failed, errno = " << strerror(errno) << std::endl; + return -1; + } + + int ret = write(imgFd, buffer, size); + if (ret == -1) { + std::cout << "write file failed, error = " << strerror(errno) << std::endl; + close(imgFd); + return -1; + } + close(imgFd); + return 0; +} + +int32_t Test::SaveVideoFile(const char* type, const void* buffer, int32_t size, int32_t operationMode) +{ + if (operationMode == 0) { + char path[PATH_MAX] = {0}; + system("mkdir -p /data/dcamera/video"); + if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/video/%s_%lld.h265", + type, GetCurrentLocalTimeStamp()) < 0) { + std::cout << "SaveVideoFile : video sprintf_s fail." << std::endl; + return -1; + } + std::cout << "save yuv to file " << std::string(path) << std::endl; + int mode = 00766; + videoFd = open(path, O_RDWR | O_CREAT, mode); + if (videoFd == -1) { + std::cout << "open file failed, errno = " << strerror(errno) << std::endl; + return -1; + } + } else if (operationMode == 1 && videoFd != -1) { + int32_t ret = write(videoFd, buffer, size); + if (ret == -1) { + std::cout << "write file failed, error = " << strerror(errno) << std::endl; + close(videoFd); + return -1; + } + } else { + if (videoFd != -1) { + close(videoFd); + } + } + return 0; +} + +void Test::Init() +{ + if (service == nullptr) { + service = ICameraHost::Get("distributed_camera_service"); + if (service == nullptr) { + std::cout << "==========[test log]ICameraHost get failed."<< std::endl; + return; + } else { + std::cout << "==========[test log]ICameraHost get success."<< std::endl; + } + } + hostCallback = new DCameraHostCallback(); + service->SetCallback(hostCallback); +} + +std::shared_ptr Test::GetCameraAbility() +{ + if (cameraDevice == nullptr) { + rc = service->GetCameraIds(cameraIds); + if (rc != Camera::NO_ERROR) { + std::cout << "==========[test log]GetCameraIds failed." << std::endl; + return ability; + } else { + std::cout << "==========[test log]GetCameraIds success." << std::endl; + } + if (cameraIds.size() == 0) { + std::cout << "==========[test log]camera device list is empty." << std::endl; + return ability; + } + GetCameraMetadata(); + } + return ability; +} + +void Test::GetCameraMetadata() +{ + rc = service->GetCameraAbility(cameraIds.front(), ability); + if (rc != Camera::NO_ERROR) { + std::cout << "==========[test log]GetCameraAbility failed, rc = " << rc << std::endl; + } + common_metadata_header_t* data = ability->get(); + camera_metadata_item_t entry; + int ret = Camera::FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry); + if (ret == 0) { + std::cout << "==========[test log] get OHOS_CONTROL_AE_AVAILABLE_MODES success" << std::endl; + } +} + +void Test::Open() +{ + if (cameraDevice == nullptr) { + service->GetCameraIds(cameraIds); + if (cameraIds.size() == 0) { + std::cout << "==========[test log]camera device list empty." << std::endl; + return; + } + GetCameraMetadata(); + deviceCallback = new DCameraDeviceCallback(); + rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice); + if (rc != Camera::NO_ERROR || cameraDevice == nullptr) { + std::cout << "==========[test log]OpenCamera failed, rc = " << rc << std::endl; + return; + } + std::cout << "==========[test log]OpenCamera success." << std::endl; + } +} + +void Test::Close() +{ + if (cameraDevice != nullptr) { + cameraDevice->Close(); + std::cout << "cameraDevice->Close" << std::endl; + cameraDevice = nullptr; + } + consumerMap_.clear(); + if (hostCallback != nullptr) { + delete hostCallback; + hostCallback = nullptr; + } + if (deviceCallback != nullptr) { + delete deviceCallback; + deviceCallback = nullptr; + } + if (streamOperatorCallback != nullptr) { + delete streamOperatorCallback; + streamOperatorCallback = nullptr; + } +} + +void Test::SetPreviewStreamInfo() +{ + streamInfo_pre->streamId_ = streamId_preview; + streamInfo_pre->width_ = preview_width; + streamInfo_pre->height_ = preview_height; + streamInfo_pre->format_ = preview_format; + streamInfo_pre->datasapce_ = datasapce; + streamInfo_pre->intent_ = PREVIEW; + streamInfo_pre->tunneledMode_ = tunneledMode; + std::shared_ptr consumer_pre = std::make_shared(); + std::cout << "==========[test log]received a preview buffer ... 0" << std::endl; + streamInfo_pre->bufferQueue_ = consumer_pre->CreateProducer([this](void* addr, uint32_t size) { + SaveYUV("preview", addr, size); + }); + streamInfo_pre->bufferQueue_->SetQueueSize(bufferQueueSize); + consumerMap_[intent] = consumer_pre; + streamInfos.push_back(streamInfo_pre); +} + +void Test::SetVideoStreamInfo() +{ + streamInfo_video->streamId_ = streamId_video; + streamInfo_video->width_ = video_width; + streamInfo_video->height_ = video_height; + streamInfo_video->format_ = video_format; + streamInfo_video->datasapce_ = datasapce; + streamInfo_video->intent_ = intent; + streamInfo_video->encodeType_ = OHOS::Camera::ENCODE_TYPE_H265; + streamInfo_video->tunneledMode_ = tunneledMode; + std::shared_ptr consumer_video = std::make_shared(); + std::cout << "==========[test log]received a video buffer ... 1" << std::endl; + SaveVideoFile("video", nullptr, 0, 0); + streamInfo_video->bufferQueue_ = consumer_video->CreateProducer([this](void* addr, uint32_t size) { + SaveVideoFile("video", addr, size, 1); + }); + streamInfo_video->bufferQueue_->SetQueueSize(bufferQueueSize); + consumerMap_[intent] = consumer_video; + streamInfos.push_back(streamInfo_video); +} + +void Test::SetPhotoStreamInfo() +{ + streamInfo_capture->streamId_ = streamId_capture; + streamInfo_capture->width_ = snapshot_width; + streamInfo_capture->height_ = snapshot_height; + streamInfo_capture->format_ = snapshot_format; + streamInfo_capture->datasapce_ = datasapce; + streamInfo_capture->intent_ = intent; + streamInfo_capture->encodeType_ = OHOS::Camera::ENCODE_TYPE_JPEG; + streamInfo_capture->tunneledMode_ = tunneledMode; + std::shared_ptr consumer_capture = std::make_shared(); + std::cout << "==========[test log]received a capture buffer ... 2" << std::endl; + streamInfo_capture->bufferQueue_ = consumer_capture->CreateProducer([this](void* addr, uint32_t size) { + SaveYUV("capture", addr, size); + }); + streamInfo_capture->bufferQueue_->SetQueueSize(bufferQueueSize); + consumerMap_[intent] = consumer_capture; + streamInfos.push_back(streamInfo_capture); +} + +void Test::StartStream(std::vector intents) +{ + streamOperatorCallback = new DStreamOperatorCallback(); + rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]GetStreamOperator success." << std::endl; + } else { + std::cout << "==========[test log]GetStreamOperator fail, rc = " << rc << std::endl; + } + int datasapce = 8; + int tunneledMode = 5; + int bufferQueueSize = 8; + streamInfo_pre = std::make_shared(); + streamInfo_video = std::make_shared(); + streamInfo_capture = std::make_shared(); + for (auto& intent : intents) { + if (intent == 0) { + SetPreviewStreamInfo(); + } else if (intent == 1) { + SetVideoStreamInfo(); + } else { + SetPhotoStreamInfo(); + } + } + + rc = streamOperator->CreateStreams(streamInfos); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]CreateStreams success." << std::endl; + } else { + std::cout << "==========[test log]CreateStreams fail, rc = " << rc << std::endl; + } + rc = streamOperator->CommitStreams(Camera::NORMAL, ability); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]CommitStreams success." << std::endl; + } else { + std::cout << "==========[test log]CommitStreams fail, rc = " << rc << std::endl; + } + unsigned int sleepSeconds = 2; + sleep(sleepSeconds); + std::vector>().swap(streamInfos); +} + +void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming) +{ + captureInfo = std::make_shared(); + captureInfo->streamIds_ = {streamId}; + captureInfo->captureSetting_ = ability; + captureInfo->enableShutterCallback_ = shutterCallback; + rc = streamOperator->Capture(captureId, captureInfo, isStreaming); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]check Capture: Capture success, " << captureId << std::endl; + } else { + std::cout << "==========[test log]check Capture: Capture fail, rc = " << rc << std::endl; + } + unsigned int sleepSeconds = 5; + sleep(sleepSeconds); +} + +void Test::StopStream(std::vector& captureIds, std::vector& streamIds) +{ + if (sizeof(captureIds) > 0) { + for (auto &captureId : captureIds) { + rc = streamOperator->CancelCapture(captureId); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]check Capture: CancelCapture success," << captureId << std::endl; + } else { + std::cout << "==========[test log]check Capture: CancelCapture fail, rc = " << rc; + std::cout << "captureId = " << captureId << std::endl; + } + } + } + int32_t operationMode = 2; + SaveVideoFile("video", nullptr, 0, operationMode); + if (sizeof(streamIds) > 0) { + rc = streamOperator->ReleaseStreams(streamIds); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]check Capture: ReleaseStreams success." << std::endl; + } else { + std::cout << "==========[test log]check Capture: ReleaseStreams fail, rc = " << rc << std::endl; + } + } +} + +void Test::StopOfflineStream(int captureId) +{ + rc = offlineStreamOperator->CancelCapture(captureId); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]check offline: CancelCapture success," << captureId << std::endl; + } else { + std::cout << "==========[test log]check offline: CancelCapture fail, rc = " << rc; + std::cout << "captureId = " << captureId << std::endl; + } + rc = offlineStreamOperator->Release(); + if (rc == Camera::NO_ERROR) { + std::cout << "==========[test log]Check offline stream: offline Release success." << std::endl; + } else { + std::cout << "==========[test log]Check offline stream: offline Release fail, rc = " << rc << std::endl; + } +} + +OHOS::sptr Test::StreamConsumer::CreateProducer(std::function callback) +{ + consumer_ = OHOS::Surface::CreateSurfaceAsConsumer(); + if (consumer_ == nullptr) { + return nullptr; + } + sptr listener = new TestBufferConsumerListener(); + consumer_->RegisterConsumerListener(listener); + auto producer = consumer_->GetProducer(); + std::cout << "create a buffer queue producer:" << producer.GetRefPtr() << std::endl; + if (producer == nullptr) { + return nullptr; + } + callback_ = callback; + consumerThread_ = new std::thread([this] { + int32_t flushFence = 0; + int64_t timestamp = 0; + OHOS::Rect damage; + while (running_) { + OHOS::sptr buffer = nullptr; + consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage); + if (buffer != nullptr) { + void* addr = buffer->GetVirAddr(); + uint32_t size = buffer->GetSize(); + + int32_t gotSize = 0; + int32_t isKey = 0; + int64_t timestamp; + buffer->ExtraGet("dataSize", gotSize); + buffer->ExtraGet("isKeyFrame", isKey); + buffer->ExtraGet("timeStamp", timestamp); + if (gotSize) { + std::cout << "dataSize: " << gotSize << ", isKeyFrame: " + << isKey << " timeStamp:" << timestamp << endl; + } + + callback_(addr, size); + consumer_->ReleaseBuffer(buffer, -1); + shotCount_--; + if (shotCount_ == 0) { + std::unique_lock l(l_); + cv_.notify_one(); + } + } + if (!running_) { + break; + } + std::this_thread::sleep_for(1ms); + } + }); + return producer; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/hdi_service/test/common.h b/distributed_camera/hdi_service/test/common.h new file mode 100644 index 0000000000..1fed4e4709 --- /dev/null +++ b/distributed_camera/hdi_service/test/common.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2022 Huawei Device 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 DISTRIBUTED_CAMERA_TEST_COMMON_H +#define DISTRIBUTED_CAMERA_TEST_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camera_metadata_info.h" +#include "display_type.h" +#include "distributed_hardware_log.h" +#include "drivers/peripheral/camera/interfaces/include/types.h" +#include "icamera_device.h" +#include "icamera_host.h" +#include "idistributed_hardware_source.h" +#include "ioffline_stream_operator.h" +#include "iservice_registry.h" +#include "istream_operator.h" +#include "securec.h" +#include "surface.h" + +#include "constants.h" +#include "dcamera.h" +#include "dcamera_device_callback.h" +#include "dcamera_host.h" +#include "dcamera_host_callback.h" +#include "dcamera_host_proxy.h" +#include "dstream_operator_callback.h" +#include "v1_0/dcamera_types.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::HDI::DistributedCamera::V1_0; +class Test { +public: + void Init(); + void Open(); + void Close(); + std::shared_ptr GetCameraAbility(); + uint64_t GetCurrentLocalTimeStamp(); + int32_t SaveYUV(const char* type, const void* buffer, int32_t size); + int32_t SaveVideoFile(const char* type, const void* buffer, int32_t size, int32_t operationMode); + void StartStream(std::vector intents); + void StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming); + void StopStream(std::vector& captureIds, std::vector& streamIds); + void StopOfflineStream(int captureId); + void GetCameraMetadata(); + + void SetPreviewStreamInfo(); + void SetVideoStreamInfo(); + void SetPhotoStreamInfo(); + + OHOS::sptr streamOperatorCallback = nullptr; + OHOS::sptr hostCallback = nullptr; + OHOS::sptr deviceCallback = nullptr; + OHOS::sptr streamOperator = nullptr; + OHOS::sptr offlineStreamOperator = nullptr; + OHOS::sptr offlineStreamOperatorCallback = nullptr; + std::shared_ptr captureInfo = nullptr; + std::vector> streamInfos; + std::shared_ptr streamInfo = nullptr; + std::shared_ptr streamInfo2 = nullptr; + std::shared_ptr streamInfo_pre = nullptr; + std::shared_ptr streamInfo_video = nullptr; + std::shared_ptr streamInfo_capture = nullptr; + std::vector cameraIds; + int streamId_preview = 1000; + int streamId_preview_double = 1001; + int streamId_capture = 1010; + int streamId_video = 1020; + int captureId_preview = 2000; + int captureId_preview_double = 2001; + int captureId_capture = 2010; + int captureId_video = 2020; + int preview_format = PIXEL_FMT_YCRCB_420_SP; + int video_format = PIXEL_FMT_YCRCB_420_SP; + int snapshot_format = PIXEL_FMT_YCRCB_420_SP; + int preview_width = 1920; + int preview_height = 1080; + int snapshot_width = 4160; + int snapshot_height = 3120; + int video_width = 1920; + int video_height = 1080; + std::vector captureIds; + std::vector streamIds; + std::vector intents; + OHOS::Camera::CamRetCode rc; + OHOS::sptr service = nullptr; + std::shared_ptr ability = nullptr; + OHOS::sptr cameraDevice = nullptr; + bool status; + int previewBufCnt = 0; + int32_t videoFd = -1; + class StreamConsumer; + std::map> consumerMap_ = {}; + + class TestBufferConsumerListener : public IBufferConsumerListener { + public: + TestBufferConsumerListener() {} + ~TestBufferConsumerListener() {} + void OnBufferAvailable() {} + }; + + class StreamConsumer { + public: + OHOS::sptr CreateProducer(std::function callback); + void TakeSnapshot() + { + shotCount_++; + } + void WaitSnapshotEnd() + { + std::cout << "ready to wait" << std::endl; + std::unique_lock l(l_); + cv_.wait(l, [this]() { return shotCount_ == 0; }); + } + ~StreamConsumer() + { + running_ = false; + if (consumerThread_ != nullptr) { + consumerThread_->join(); + delete consumerThread_; + } + } + + public: + std::atomic shotCount_ = 0; + std::mutex l_; + std::condition_variable cv_; + bool running_ = true; + OHOS::sptr consumer_ = nullptr; + std::thread* consumerThread_ = nullptr; + std::function callback_ = nullptr; + }; +}; + +class DCameraMockRegisterCallback : public RegisterCallback { +public: + virtual ~DCameraMockRegisterCallback() = default; + int32_t OnRegisterResult(const std::string &devId, const std::string &dhId, int32_t status, + const std::string &data) + { + cout << "Register devId: " << devId << " dhId: " << dhId << " status:" << status << endl; + return 0; + } +}; + +class DCameraMockUnRegisterCallback : public UnregisterCallback { +public: + virtual ~DCameraMockUnRegisterCallback() = default; + int32_t OnUnregisterResult(const std::string &devId, const std::string &dhId, int32_t status, + const std::string &data) + { + cout << "UnRegister devId: " << devId << " dhId: " << dhId << " status:" << status << endl; + return 0; + } +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_TEST_COMMON_H diff --git a/distributed_camera/hdi_service/test/dcamera_hdi_sample.cpp b/distributed_camera/hdi_service/test/dcamera_hdi_sample.cpp new file mode 100644 index 0000000000..5f14c958dd --- /dev/null +++ b/distributed_camera/hdi_service/test/dcamera_hdi_sample.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "common.h" +#include "dcamera_source_handler.h" + +using namespace std; +using namespace OHOS::DistributedHardware; + +static const std::string TEST_DEV_ID = "11111111111111111111111111111111"; +static const std::string TEST_CAM_ID = "camera_0"; +static const std::string TEST_ATTR = R"({"CodecType": ["avenc_mpeg4"], + "OutputFormat": {"Photo":[4], "Preview":[2, 3], "Video":[2, 3]}, + "Position": "BACK", + "ProtocolVer": "1.0", + "MetaData": "", + "Resolution": { + "2": ["1920*1080", "1504*720", "1440*1080", "1280*960", "1280*720", "1232*768", "1152*720", "960*720", "960*544", + "880*720", "720*720", "720*480", "640*480", "352*288", "320*240"], + "3": ["1920*1080", "1504*720", "1440*1080", "1280*960", "1280*720", "1232*768", "1152*720", "960*720", "960*544", + "880*720", "720*720", "720*480", "640*480", "352*288", "320*240"], + "4": ["3840*2160", "3264*2448", "3264*1840", "2304*1728", "2048*1536", "1920*1440", "1920*1080", "1744*1088", + "1280*720", "1232*768", "1152*720", "640*480", "320*240"]}})"; + +int main() +{ + cout << "distributed camera hdf start" << endl; + + IDistributedHardwareSource *sourceSA = GetSourceHardwareHandler(); + EnableParam param; + param.version = "1.0"; + param.attrs = TEST_ATTR; + std::shared_ptr regCb = + std::make_shared(); + int32_t ret = sourceSA->InitSource("1.0"); + cout << "Init Source " << ret << endl; + ret = sourceSA->RegisterDistributedHardware(TEST_DEV_ID, TEST_CAM_ID, param, regCb); + unsigned int sleepSeconds = 2; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait register end: " << ret << endl; + + std::shared_ptr test = std::make_shared(); + test->Init(); + test->Open(); + sleepSeconds = 1; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait open camera end." << endl; + + std::cout << "==========[test log]Preview stream, 640*480, expected success." << std::endl; + // 启动流 + test->intents = {OHOS::Camera::PREVIEW}; + test->StartStream(test->intents); + sleepSeconds = 1; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait start stream end." << endl; + + // 获取预览图 + test->StartCapture(test->streamId_preview, test->captureId_preview, false, true); + // 释放流 + test->captureIds = {test->captureId_preview}; + test->streamIds = {test->streamId_preview}; + sleepSeconds = 1; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait start capture end." << endl; + + test->StopStream(test->captureIds, test->streamIds); + sleepSeconds = 1; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait stop stream end." << endl; + + test->Close(); + sleepSeconds = 1; + sleep(sleepSeconds); + cout << "sleep" << sleepSeconds << "second wait close end." << endl; + + std::shared_ptr unRegCb = + std::make_shared(); + ret = sourceSA->UnregisterDistributedHardware(TEST_DEV_ID, TEST_CAM_ID, unRegCb); + cout << "distributed camera hdf end ret: " << ret << endl; + + return 0; +} \ No newline at end of file diff --git a/distributed_camera/interfaces/hdi_ipc/ipc_data_utils.h b/distributed_camera/interfaces/hdi_ipc/ipc_data_utils.h new file mode 100644 index 0000000000..9fc2412250 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/ipc_data_utils.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Huawei Device 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 HDI_IPC_DATA_UTILS_H +#define HDI_IPC_DATA_UTILS_H + +#include +#include +#include +#include +#include +#include +#include "camera_metadata_info.h" +#include "v1_0/dcamera_types.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::HDI::DistributedCamera::V1_0; +class IpcDataUtils { +static const uint32_t RATIONAL_TYPE_STEP = 2; +public: + static bool EncodeStreamInfo(const std::shared_ptr &pInfo, MessageParcel &parcel) + { + bool bRet = true; + bRet = (bRet && parcel.WriteInt32(static_cast(pInfo->streamId_))); + bRet = (bRet && parcel.WriteInt32(static_cast(pInfo->width_))); + bRet = (bRet && parcel.WriteInt32(static_cast(pInfo->height_))); + bRet = (bRet && parcel.WriteInt32(static_cast(pInfo->format_))); + bRet = (bRet && parcel.WriteInt32(pInfo->intent_)); + bRet = (bRet && parcel.WriteBool(pInfo->tunneledMode_)); + bool bufferQueueFlag = (pInfo->bufferQueue_ != nullptr) ? true : false; + bRet = (bRet && parcel.WriteBool(bufferQueueFlag)); + if (bufferQueueFlag) { + bRet = (bRet && parcel.WriteRemoteObject(pInfo->bufferQueue_->AsObject())); + } + bRet = (bRet && parcel.WriteInt32(static_cast(pInfo->minFrameDuration_))); + bRet = (bRet && parcel.WriteInt32(pInfo->encodeType_)); + return bRet; + } + + static void DecodeStreamInfo(MessageParcel &parcel, std::shared_ptr &pInfo) + { + pInfo->streamId_ = static_cast(parcel.ReadInt32()); + pInfo->width_ = static_cast(parcel.ReadInt32()); + pInfo->height_ = static_cast(parcel.ReadInt32()); + pInfo->format_ = static_cast(parcel.ReadInt32()); + pInfo->intent_ = static_cast(parcel.ReadInt32()); + pInfo->tunneledMode_ = parcel.ReadBool(); + bool bufferQueueFlag = parcel.ReadBool(); + if (bufferQueueFlag) { + sptr remoteBufferProducer = parcel.ReadRemoteObject(); + pInfo->bufferQueue_ = OHOS::iface_cast(remoteBufferProducer); + } + pInfo->minFrameDuration_ = static_cast(parcel.ReadInt32()); + pInfo->encodeType_ = static_cast(parcel.ReadInt32()); + } + + static bool EncodeDCameraSettings(const std::shared_ptr &pSettings, MessageParcel &parcel) + { + bool bRet = true; + bRet = (bRet && parcel.WriteInt32(pSettings->type_)); + bRet = (bRet && parcel.WriteString(pSettings->value_)); + return bRet; + } + + static void DecodeDCameraSettings(MessageParcel &parcel, std::shared_ptr &pSettings) + { + pSettings->type_ = (DCSettingsType)(parcel.ReadInt32()); + pSettings->value_ = parcel.ReadString(); + } + + static bool EncodeDCameraHDFEvent(const std::shared_ptr &pEvent, MessageParcel &parcel) + { + bool bRet = true; + bRet = (bRet && parcel.WriteInt32(pEvent->type_)); + bRet = (bRet && parcel.WriteInt32(pEvent->result_)); + bRet = (bRet && parcel.WriteString(pEvent->content_)); + return bRet; + } + + static void DecodeDCameraHDFEvent(MessageParcel &parcel, std::shared_ptr &pEvent) + { + pEvent->type_ = parcel.ReadInt32(); + pEvent->result_ = parcel.ReadInt32(); + pEvent->content_ = parcel.ReadString(); + } +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // HDI_IPC_DATA_UTILS_H diff --git a/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp new file mode 100644 index 0000000000..8a47104d5d --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_device_callback_proxy.h" + +#include +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +void DCameraDeviceCallbackProxy::OnError(ErrorType type, int32_t errorMsg) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteUint32(type)) { + DHLOGE("Write error type failed."); + return; + } + + if (!data.WriteInt32(errorMsg)) { + DHLOGE("Write error message failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_CALLBACK_ON_ERROR, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} + +void DCameraDeviceCallbackProxy::OnResult(uint64_t timestamp, + const std::shared_ptr &result) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (result == nullptr) { + return; + } + + if (!data.WriteUint64(timestamp)) { + DHLOGE("Write timestamp failed."); + return; + } + + if (!Camera::MetadataUtils::EncodeCameraMetadata(result, data)) { + DHLOGE("Write metadata failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_CALLBACK_ON_RESULT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return; + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h new file mode 100644 index 0000000000..505feda0c2 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_DEVICE_CALLBACK_PROXY_H +#define DISTRIBUTED_CAMERA_DEVICE_CALLBACK_PROXY_H + +#include "iremote_proxy.h" +#include "icamera_device_callback.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraDeviceCallbackProxy : public IRemoteProxy { +public: + explicit DCameraDeviceCallbackProxy(const sptr &impl) + : IRemoteProxy(impl) {} + + virtual ~DCameraDeviceCallbackProxy() = default; + + virtual void OnError(ErrorType type, int32_t errorMsg) override; + virtual void OnResult(uint64_t timestamp, const std::shared_ptr &result) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_CALLBACK_PROXY_H diff --git a/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp new file mode 100644 index 0000000000..9315851a81 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_device_stub.h" + +#include +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" +#include "istream_operator.h" +#include "istream_operator_callback.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraDeviceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_CAMERA_DEVICE_GET_STREAM_OPERATOR: { + ret = DCDeviceStubGetStreamOperator(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_UPDATE_SETTINGS: { + ret = DCDeviceStubUpdateSettings(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_SET_RESULT_MODE: { + ret = DCDeviceStubSetResultMode(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_GET_ENABLED_RESULTS: { + ret = DCDeviceStubGetEnabledReuslts(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_ENABLE_RESULT: { + ret = DCDeviceStubEnableResult(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_DISABLE_RESULT: { + ret = DCDeviceStubDisableResult(data, reply, option); + break; + } + case CMD_CAMERA_DEVICE_CLOSE: { + ret = DCDeviceStubClose(data, reply, option); + break; + } + default: { + ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return ret; +} + +int32_t DCameraDeviceStub::DCDeviceStubGetStreamOperator(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubGetStreamOperator entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + sptr spStreamOperatorCallback = nullptr; + bool flag = data.ReadBool(); + if (flag) { + sptr remoteObj = data.ReadRemoteObject(); + spStreamOperatorCallback = OHOS::iface_cast(remoteObj); + if (spStreamOperatorCallback == nullptr) { + DHLOGE("Read operator callback failed."); + return HDF_FAILURE; + } + } + + OHOS::sptr streamOperator = nullptr; + CamRetCode ret = GetStreamOperator(spStreamOperatorCallback, streamOperator); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Get stream operator failed."); + return HDF_FAILURE; + } + + bool nullFlag = (streamOperator != nullptr); + if (!reply.WriteBool(nullFlag)) { + DHLOGE("Write stream operator flag failed."); + return HDF_FAILURE; + } + + if (nullFlag && !reply.WriteRemoteObject(streamOperator->AsObject())) { + DHLOGE("Write stream operator failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubUpdateSettings(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubUpdateSettings entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr metadata = nullptr; + Camera::MetadataUtils::DecodeCameraMetadata(data, metadata); + + CamRetCode ret = UpdateSettings(metadata); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Get stream operator failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubSetResultMode(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubSetResultMode entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + ResultCallbackMode mode = static_cast(data.ReadInt32()); + CamRetCode ret = SetResultMode(mode); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubGetEnabledReuslts(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubGetEnabledReuslts entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + std::vector results; + CamRetCode ret = GetEnabledResults(results); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (!reply.WriteInt32Vector(results)) { + DHLOGE("Write results failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubEnableResult(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubEnableResult entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + std::vector results; + if (!data.ReadInt32Vector(&results)) { + DHLOGE("Read results failed."); + return HDF_FAILURE; + } + + CamRetCode ret = EnableResult(results); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (!reply.WriteInt32Vector(results)) { + DHLOGE("Write results failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubDisableResult(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubDisableResult entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + std::vector results; + if (!data.ReadInt32Vector(&results)) { + DHLOGE("Read results failed."); + return HDF_FAILURE; + } + + CamRetCode ret = DisableResult(results); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (!reply.WriteInt32Vector(results)) { + DHLOGE("Write results failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraDeviceStub::DCDeviceStubClose(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + DHLOGI("DCameraDeviceStub::DCDeviceStubClose entry."); + if (data.ReadInterfaceToken() != DCameraDeviceStub::GetDescriptor()) { + DHLOGE("Invalid token."); + return HDF_FAILURE; + } + + Close(); + return HDF_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.h b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.h new file mode 100644 index 0000000000..ab4fa7f848 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/device/dcamera_device_stub.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_DEVICE_SERVER_STUB_H +#define DISTRIBUTED_CAMERA_DEVICE_SERVER_STUB_H + +#include +#include +#include +#include "icamera_device.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraDeviceStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option) override; + +private: + int32_t DCDeviceStubGetStreamOperator(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubUpdateSettings(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubSetResultMode(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubGetEnabledReuslts(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubEnableResult(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubDisableResult(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCDeviceStubClose(MessageParcel& data, MessageParcel& reply, MessageOption& option); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_SERVER_STUB_H \ No newline at end of file diff --git a/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp new file mode 100644 index 0000000000..8c74fe68b0 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_host_callback_proxy.h" + +#include +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DCameraHostCallbackProxy::OnCameraStatus(const std::string &cameraId, CameraStatus status) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return; + } + + if (!data.WriteInt32(status)) { + DHLOGE("Write status failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_CALLBACK_ON_STATUS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} + +void DCameraHostCallbackProxy::OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return; + } + + if (!data.WriteInt32(status)) { + DHLOGE("Write status failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_CALLBACK_ON_FLASHLIGHT_STATUS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} + +void DCameraHostCallbackProxy::OnCameraEvent(const std::string &cameraId, CameraEvent event) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return; + } + + if (!data.WriteInt32(event)) { + DHLOGE("Write event failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_CALLBACK_ON_CAMERA_EVENT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h new file mode 100644 index 0000000000..4b3267c2a8 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_HOST_CALLBACK_PROXY_H +#define DISTRIBUTED_CAMERA_HOST_CALLBACK_PROXY_H + +#include "iremote_proxy.h" +#include "icamera_host_callback.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraHostCallbackProxy : public IRemoteProxy { +public: + explicit DCameraHostCallbackProxy(const sptr &impl) + : IRemoteProxy(impl) {} + + virtual ~DCameraHostCallbackProxy() = default; + + virtual void OnCameraStatus(const std::string &cameraId, CameraStatus status); + virtual void OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status); + virtual void OnCameraEvent(const std::string &cameraId, CameraEvent event); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_CALLBACK_PROXY_H diff --git a/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp new file mode 100644 index 0000000000..e756636865 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dcamera_host_stub.h" + +#include +#include +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" +#include "icamera_device.h" +#include "icamera_host_callback.h" +#include "ipc_data_utils.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraHostStub::DCameraHostStub() +{ +} + +int32_t DCameraHostStub::Init() +{ + dcameraHost_ = DCameraHost::GetInstance(); + if (dcameraHost_ == nullptr) { + DHLOGE("Distributed camera host service start failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::DCHostStubSetCallback(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraHostStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + bool flag = data.ReadBool(); + sptr hostCallback = nullptr; + if (flag) { + sptr remoteObj = data.ReadRemoteObject(); + hostCallback = OHOS::iface_cast(remoteObj); + } + CamRetCode ret = dcameraHost_->SetCallback(hostCallback); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::DCHostStubGetCameraIds(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraHostStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + if (dcameraHost_ == nullptr) { + return HDF_FAILURE; + } + + std::vector cameraIds; + CamRetCode ret = dcameraHost_->GetCameraIds(cameraIds); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (ret == CamRetCode::NO_ERROR) { + if (!reply.WriteStringVector(cameraIds)) { + DHLOGE("Write cameraIds failed."); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::DCHostStubGetCameraAbility(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraHostStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + const std::string cameraId = data.ReadString(); + if (cameraId.empty()) { + DHLOGE("Read input param is empty."); + return HDF_ERR_INVALID_PARAM; + } + + std::shared_ptr ability = nullptr; + CamRetCode ret = dcameraHost_->GetCameraAbility(cameraId, ability); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (ret == CamRetCode::NO_ERROR) { + bool bRet = Camera::MetadataUtils::EncodeCameraMetadata(ability, reply); + if (!bRet) { + DHLOGE("Write ability failed."); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::DCHostStubOpenCamera(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraHostStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + const std::string cameraId = data.ReadString(); + if (cameraId.empty()) { + DHLOGE("Read input param is empty."); + return HDF_ERR_INVALID_PARAM; + } + + bool flag = data.ReadBool(); + OHOS::sptr deviceCallback = nullptr; + if (flag) { + OHOS::sptr remoteCallback = data.ReadRemoteObject(); + deviceCallback = OHOS::iface_cast(remoteCallback); + } + + OHOS::sptr cameraDevice = nullptr; + CamRetCode ret = dcameraHost_->OpenCamera(cameraId, deviceCallback, cameraDevice); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Get stream operator failed."); + return HDF_FAILURE; + } + + if (ret == CamRetCode::NO_ERROR) { + bool deviceFlag = (cameraDevice != nullptr); + if (!reply.WriteBool(deviceFlag)) { + DHLOGE("Write camera device flag failed."); + return HDF_FAILURE; + } + + if (deviceFlag && !reply.WriteRemoteObject(cameraDevice->AsObject())) { + DHLOGE("Write camera device failed."); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::DCHostStubSetFlashlight(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraHostStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + if (dcameraHost_ == nullptr) { + DHLOGE("Camera host is null."); + return HDF_FAILURE; + } + + std::string cameraId = data.ReadString(); + bool isEnable = data.ReadBool(); + CamRetCode ret = dcameraHost_->SetFlashlight(cameraId, isEnable); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraHostStub::OnRemoteRequest(int cmdId, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + switch (cmdId) { + case CMD_CAMERA_HOST_SET_CALLBACK: { + return DCHostStubSetCallback(data, reply, option); + } + case CMD_CAMERA_HOST_GET_CAMERAID: { + return DCHostStubGetCameraIds(data, reply, option); + } + case CMD_CAMERA_HOST_GET_CAMERA_ABILITY: { + return DCHostStubGetCameraAbility(data, reply, option); + } + case CMD_CAMERA_HOST_OPEN_CAMERA: { + return DCHostStubOpenCamera(data, reply, option); + } + case CMD_CAMERA_HOST_SET_FLASH_LIGHT: { + return DCHostStubSetFlashlight(data, reply, option); + } + default: { + DHLOGE("Not support cmd %d.", cmdId); + return HDF_ERR_INVALID_PARAM; + } + } + return HDF_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS + +void *DCameraHostStubInstance() +{ + OHOS::DistributedHardware::DCameraHostStub *stub = new (std::nothrow) OHOS::DistributedHardware::DCameraHostStub(); + if (stub == nullptr) { + HDF_LOGE("%{public}s: camera host stub create failed.", __func__); + return nullptr; + } + + int32_t ret = stub->Init(); + if (ret != HDF_SUCCESS) { + delete stub; + stub = nullptr; + return nullptr; + } + return reinterpret_cast(stub); +} + +void DestroyDCameraHostStub(void *stubObj) +{ + delete reinterpret_cast(stubObj); +} + +int32_t DCHostServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + if (stub == nullptr) { + HDF_LOGE("%{public}s:stub is null", __func__); + return HDF_FAILURE; + } + + OHOS::DistributedHardware::DCameraHostStub *dcameraHostStub = + reinterpret_cast(stub); + OHOS::MessageParcel *dataParcel = nullptr; + OHOS::MessageParcel *replyParcel = nullptr; + + if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { + HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__); + return HDF_ERR_INVALID_PARAM; + } + + if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { + HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__); + return HDF_ERR_INVALID_PARAM; + } + + OHOS::MessageOption option; + return dcameraHostStub->OnRemoteRequest(cmdId, *dataParcel, *replyParcel, option); +} diff --git a/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.h b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.h new file mode 100644 index 0000000000..465c0a4ada --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/host/dcamera_host_stub.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_CAMERA_HOST_SERVER_STUB_H +#define DISTRIBUTED_CAMERA_HOST_SERVER_STUB_H + +#include +#include +#include +#include +#include "dcamera_host.h" +#include "icamera_device_callback.h" +#include "icamera_host_callback.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +enum { + CMD_CAMERA_HOST_SET_CALLBACK = 0, + CMD_CAMERA_HOST_GET_CAMERAID, + CMD_CAMERA_HOST_GET_CAMERA_ABILITY, + CMD_CAMERA_HOST_OPEN_CAMERA, + CMD_CAMERA_HOST_SET_FLASH_LIGHT, +}; + +class DCameraHostStub { +public: + DCameraHostStub(); + virtual ~DCameraHostStub() {} + int32_t Init(); + int32_t OnRemoteRequest(int cmdId, MessageParcel& data, MessageParcel& reply, MessageOption& option); + +private: + int32_t DCHostStubSetCallback(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCHostStubGetCameraIds(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCHostStubGetCameraAbility(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCHostStubOpenCamera(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCHostStubSetFlashlight(MessageParcel& data, MessageParcel& reply, MessageOption& option); + static inline const std::u16string metaDescriptor_ = u"HDI.Camera.V1_0.Host"; + static inline const std::u16string &GetDescriptor() + { + return metaDescriptor_; + } + +private: + std::shared_ptr dcameraHost_ = nullptr; +}; +} // namespace DistributedHardware +} // namespace OHOS + +void* DCameraHostStubInstance(); + +void DestroyDCameraHostStub(void* stubObj); + +int32_t DCHostServiceOnRemoteRequest(void* stub, int cmdId, struct HdfSBuf* data, struct HdfSBuf* reply); + +#endif // DISTRIBUTED_CAMERA_HOST_SERVER_STUB_H \ No newline at end of file diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp b/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp new file mode 100644 index 0000000000..1f9530936e --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "doffline_stream_operator_stub.h" + +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DOfflineStreamOperatorStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_OFFLINE_STREAM_OPERATOR_CANCEL_CAPTURE: { + ret = DOfflineStreamOperatorStubCancelCapture(data, reply, option); + break; + } + case CMD_OFFLINE_STREAM_OPERATOR_RELEASE_STREAMS: { + ret = DOfflineStreamOperatorStubReleaseStreams(data, reply, option); + break; + } + case CMD_OFFLINE_STREAM_OPERATOR_RELEASE: { + ret = DOfflineStreamOperatorStubRelease(data, reply, option); + break; + } + default: { + ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return ret; +} + +int32_t DOfflineStreamOperatorStub::DOfflineStreamOperatorStubCancelCapture(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DOfflineStreamOperatorStub::DOfflineStreamOperatorStubCancelCapture entry."); + if (data.ReadInterfaceToken() != DOfflineStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + CamRetCode ret = CancelCapture(captureId); + if (reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DOfflineStreamOperatorStub::DOfflineStreamOperatorStubReleaseStreams(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DOfflineStreamOperatorStub::DOfflineStreamOperatorStubReleaseStreams entry."); + if (data.ReadInterfaceToken() != DOfflineStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + + CamRetCode ret = ReleaseStreams(streamIds); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DOfflineStreamOperatorStub::DOfflineStreamOperatorStubRelease(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DOfflineStreamOperatorStub::DOfflineStreamOperatorStubRelease entry."); + if (data.ReadInterfaceToken() != DOfflineStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + CamRetCode ret = Release(); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h b/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h new file mode 100644 index 0000000000..5f5ad7f741 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_OFFLINE_STREAM_OPERATOR_SERVER_STUB_H +#define DISTRIBUTED_OFFLINE_STREAM_OPERATOR_SERVER_STUB_H + +#include +#include +#include +#include "ioffline_stream_operator.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DOfflineStreamOperatorStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + int32_t DOfflineStreamOperatorStubCancelCapture(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DOfflineStreamOperatorStubReleaseStreams(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DOfflineStreamOperatorStubRelease(MessageParcel &data, MessageParcel &reply, MessageOption &option); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_OFFLINE_STREAM_OPERATOR_SERVER_STUB_H \ No newline at end of file diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp new file mode 100644 index 0000000000..5438957192 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dstream_operator_callback_proxy.h" + +#include +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DStreamOperatorCallbackProxy::OnCaptureStarted(int32_t captureId, const std::vector &streamId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteInt32(captureId)) { + DHLOGE("Write captureId failed."); + return; + } + + if (!data.WriteInt32Vector(streamId)) { + DHLOGE("Write streamIds failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_STARTED, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} + +void DStreamOperatorCallbackProxy::OnCaptureEnded(int32_t captureId, + const std::vector> &info) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteInt32(captureId)) { + DHLOGE("Write captureId failed."); + return; + } + + size_t size = info.size(); + if (!data.WriteInt32(static_cast(size))) { + DHLOGE("Write info size failed."); + return; + } + for (size_t i = 0; i < size; i++) { + auto captureEndInfo = info.at(i); + bool bRet = data.WriteBuffer((void *)captureEndInfo.get(), sizeof(CaptureEndedInfo)); + if (!bRet) { + DHLOGE("Write info index = %zu failed.", i); + return; + } + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_ENDED, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return; + } +} + +void DStreamOperatorCallbackProxy::OnCaptureError(int32_t captureId, + const std::vector> &info) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteInt32(captureId)) { + DHLOGE("Write captureId failed."); + return; + } + + size_t size = info.size(); + if (!data.WriteInt32(static_cast(size))) { + DHLOGE("Write info size failed."); + return; + } + for (size_t i = 0; i < size; i++) { + auto captureErrorInfo = info.at(i); + bool bRet = data.WriteBuffer((void *)captureErrorInfo.get(), sizeof(CaptureErrorInfo)); + if (!bRet) { + DHLOGE("Write info index = %zu failed.", i); + return; + } + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_ERROR, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return; + } +} + +void DStreamOperatorCallbackProxy::OnFrameShutter(int32_t captureId, + const std::vector &streamId, uint64_t timestamp) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return; + } + + if (!data.WriteInt32(captureId)) { + DHLOGE("Write captureId failed."); + return; + } + + if (!data.WriteInt32Vector(streamId)) { + DHLOGE("Write streamId failed."); + return; + } + + if (!data.WriteUint64(timestamp)) { + DHLOGE("Write streamId failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CALLBACK_ON_FRAME_SHUTTER, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h new file mode 100644 index 0000000000..2c8e169aef --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_STREAM_OPERATOR_CALLBACK_PROXY_H +#define DISTRIBUTED_STREAM_OPERATOR_CALLBACK_PROXY_H + +#include "iremote_proxy.h" +#include "istream_operator_callback.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DStreamOperatorCallbackProxy : public IRemoteProxy { +public: + explicit DStreamOperatorCallbackProxy(const sptr &impl) + : IRemoteProxy(impl) {} + + virtual ~DStreamOperatorCallbackProxy() = default; + + virtual void OnCaptureStarted(int32_t captureId, const std::vector &streamId) override; + virtual void OnCaptureEnded(int32_t captureId, + const std::vector> &info) override; + virtual void OnCaptureError(int32_t captureId, + const std::vector> &info) override; + virtual void OnFrameShutter(int32_t captureId, + const std::vector &streamId, uint64_t timestamp) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_CALLBACK_PROXY_H \ No newline at end of file diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp new file mode 100644 index 0000000000..c3aa1f5ad7 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "dstream_operator_stub.h" + +#include + +#include "cmd_common.h" +#include "distributed_hardware_log.h" +#include "ioffline_stream_operator.h" +#include "ipc_data_utils.h" +#include "istream_operator_callback.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DStreamOperatorStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_STREAM_OPERATOR_IS_STREAMS_SUPPORTED: { + ret = DStreamOperatorStubIsStreamsSupported(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CREATE_STREAMS: { + ret = DStreamOperatorStubCreateStreams(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_RELEASE_STREAMS: { + ret = DStreamOperatorStubReleaseStreams(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_COMMIT_STREAMS: { + ret = DStreamOperatorStubCommitStreams(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_GET_STREAM_ATTRIBUTES: { + ret = DStreamOperatorStubGetStreamAttributes(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_ATTACH_BUFFER_QUEUE: { + ret = DStreamOperatorStubAttachBufferQueue(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_DETACH_BUFFER_QUEUE: { + ret = DStreamOperatorStubDetachBufferQueue(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CAPTURE: { + ret = DStreamOperatorStubCapture(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CANCEL_CAPTURE: { + ret = DStreamOperatorStubCancelCapture(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CHANGE_TO_OFFLINE_STREAM: { + ret = DStreamOperatorStubChangeToOfflineStream(data, reply, option); + break; + } + default: { + ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return ret; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubIsStreamsSupported(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubIsStreamsSupported entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + OperationMode operationMode = static_cast(data.ReadInt32()); + + std::shared_ptr metadata = nullptr; + bool nullFlag = data.ReadBool(); + if (nullFlag) { + Camera::MetadataUtils::DecodeCameraMetadata(data, metadata); + } + + int32_t count = data.ReadInt32(); + std::vector> streamInfos; + for (int i = 0; i < count; i++) { + std::shared_ptr streamInfo = std::make_shared(); + IpcDataUtils::DecodeStreamInfo(data, streamInfo); + streamInfos.push_back(streamInfo); + } + + StreamSupportType streamSupportType; + CamRetCode ret = IsStreamsSupported(operationMode, metadata, streamInfos, streamSupportType); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + if (!reply.WriteInt32(static_cast(streamSupportType))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubCreateStreams(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubCreateStreams entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int32_t count = data.ReadInt32(); + std::vector> streamInfos; + for (int i = 0; i < count; i++) { + std::shared_ptr streamInfo = std::make_shared(); + IpcDataUtils::DecodeStreamInfo(data, streamInfo); + streamInfos.push_back(streamInfo); + } + + CamRetCode ret = CreateStreams(streamInfos); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubReleaseStreams(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubReleaseStreams entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + + CamRetCode ret = ReleaseStreams(streamIds); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubCommitStreams(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubCommitStreams entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + OperationMode mode = static_cast(data.ReadInt32()); + + std::shared_ptr metadata = nullptr; + Camera::MetadataUtils::DecodeCameraMetadata(data, metadata); + + CamRetCode ret = CommitStreams(mode, metadata); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubGetStreamAttributes(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubGetStreamAttributes entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::vector> attributes; + CamRetCode ret = GetStreamAttributes(attributes); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + + size_t count = attributes.size(); + if (!reply.WriteInt32(static_cast(count))) { + DHLOGE("Write attributes count failed."); + return HDF_FAILURE; + } + + for (size_t i = 0; i < count; i++) { + if (!reply.WriteBuffer((void *)(attributes[i].get()), sizeof(StreamAttribute))) { + DHLOGE("Write attribute failed. index = %d.", i); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubAttachBufferQueue(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubAttachBufferQueue entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int32_t streamId = data.ReadInt32(); + sptr remoteObj = data.ReadRemoteObject(); + const sptr bufferProducer = OHOS::iface_cast(remoteObj); + + CamRetCode ret = AttachBufferQueue(streamId, bufferProducer); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubDetachBufferQueue( + MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubDetachBufferQueue entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int32_t streamId = data.ReadInt32(); + CamRetCode ret = DetachBufferQueue(streamId); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubCapture(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubCapture entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int captureId = static_cast(data.ReadInt32()); + + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Write streamIds failed."); + return HDF_FAILURE; + } + + std::shared_ptr metadata = nullptr; + Camera::MetadataUtils::DecodeCameraMetadata(data, metadata); + + bool enableShutterCallback = data.ReadBool(); + std::shared_ptr pInfo = std::make_shared(); + pInfo->streamIds_ = streamIds; + pInfo->captureSetting_ = metadata; + pInfo->enableShutterCallback_ = enableShutterCallback; + + bool isStreaming = data.ReadBool(); + + CamRetCode ret = Capture(captureId, pInfo, isStreaming); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubCancelCapture(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubCancelCapture entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + CamRetCode ret = CancelCapture(captureId); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DStreamOperatorStub::DStreamOperatorStubChangeToOfflineStream(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorStub::DStreamOperatorStubChangeToOfflineStream entry."); + if (data.ReadInterfaceToken() != DStreamOperatorStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + + sptr remoteObj = data.ReadRemoteObject(); + sptr spStreamOperatorCallback = OHOS::iface_cast(remoteObj); + if (spStreamOperatorCallback == nullptr) { + DHLOGE("Read operator callback failed."); + return HDF_FAILURE; + } + + OHOS::sptr offlineOperator = nullptr; + CamRetCode ret = ChangeToOfflineStream(streamIds, spStreamOperatorCallback, offlineOperator); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("write retcode failed."); + return HDF_FAILURE; + } + + if (offlineOperator == nullptr) { + DHLOGE("Change to offline stream failed, offlineOperator is null."); + return HDF_FAILURE; + } + + if (!reply.WriteRemoteObject(offlineOperator->AsObject())) { + DHLOGE("Write offline stream operator failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h new file mode 100644 index 0000000000..f8bd5b72c7 --- /dev/null +++ b/distributed_camera/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device 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 DISTRIBUTED_STREAM_OPERATOR_SERVER_STUB_H +#define DISTRIBUTED_STREAM_OPERATOR_SERVER_STUB_H + +#include +#include +#include +#include "iremote_stub.h" +#include "istream_operator.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DStreamOperatorStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; + +private: + int32_t DStreamOperatorStubIsStreamsSupported(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubCreateStreams(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubReleaseStreams(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubCommitStreams(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubGetStreamAttributes(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubAttachBufferQueue(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubDetachBufferQueue(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubCapture(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubCancelCapture(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DStreamOperatorStubChangeToOfflineStream(MessageParcel &data, MessageParcel &reply, MessageOption &option); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_SERVER_STUB_H \ No newline at end of file -- Gitee