From b7c6311bef3be5b3eae192458103e9d4a8c6f7c9 Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Wed, 9 Mar 2022 11:17:24 +0800 Subject: [PATCH 1/4] commit distributed camera code Signed-off-by: hwzhangchuang --- LICENSE | 178 +++++ OAT.xml | 65 ++ README.en.md | 36 - README.md | 39 - README_ZH.md | 70 ++ bundle.json | 96 +++ camera_hdf/hdi_impl/BUILD.gn | 108 +++ .../include/dcamera_device/dcamera_device.h | 84 ++ .../dcamera_device/dmetadata_processor.h | 81 ++ .../include/dcamera_host/dcamera_host.h | 77 ++ .../dcamera_provider/dcamera_provider.h | 79 ++ .../dstream_operator/dbuffer_manager.h | 58 ++ .../include/dstream_operator/dcamera_steam.h | 69 ++ .../include/dstream_operator/dimage_buffer.h | 89 +++ .../doffline_stream_operator.h | 41 + .../dstream_operator/dstream_operator.h | 113 +++ camera_hdf/hdi_impl/include/utils/constants.h | 113 +++ camera_hdf/hdi_impl/include/utils/dcamera.h | 38 + .../src/dcamera_device/dcamera_device.cpp | 446 +++++++++++ .../dcamera_device/dmetadata_processor.cpp | 608 ++++++++++++++ .../src/dcamera_host/dcamera_host.cpp | 232 ++++++ .../src/dcamera_provider/dcamera_provider.cpp | 306 +++++++ .../src/dstream_operator/dbuffer_manager.cpp | 162 ++++ .../src/dstream_operator/dcamera_steam.cpp | 363 +++++++++ .../src/dstream_operator/dimage_buffer.cpp | 242 ++++++ .../doffline_stream_operator.cpp | 38 + .../src/dstream_operator/dstream_operator.cpp | 753 ++++++++++++++++++ camera_hdf/hdi_impl/src/utils/dcamera.cpp | 89 +++ camera_hdf/hdi_impl/test/BUILD.gn | 83 ++ camera_hdf/hdi_impl/test/common.cpp | 383 +++++++++ camera_hdf/hdi_impl/test/common.h | 178 +++++ .../hdi_impl/test/dcamera_hdi_sample.cpp | 95 +++ camera_hdf/interfaces/hdi_ipc/client/BUILD.gn | 81 ++ .../client/device/dcamera_device_callback.cpp | 31 + .../client/device/dcamera_device_callback.h | 35 + .../device/dcamera_device_callback_stub.cpp | 62 ++ .../device/dcamera_device_callback_stub.h | 36 + .../client/device/dcamera_device_proxy.cpp | 205 +++++ .../client/device/dcamera_device_proxy.h | 53 ++ .../client/host/dcamera_host_callback.cpp | 36 + .../client/host/dcamera_host_callback.h | 36 + .../host/dcamera_host_callback_stub.cpp | 71 ++ .../client/host/dcamera_host_callback_stub.h | 36 + .../client/host/dcamera_host_proxy.cpp | 206 +++++ .../hdi_ipc/client/host/dcamera_host_proxy.h | 50 ++ .../doffline_stream_operator_proxy.cpp | 91 +++ .../operator/doffline_stream_operator_proxy.h | 44 + .../operator/dstream_operator_callback.cpp | 44 + .../operator/dstream_operator_callback.h | 40 + .../dstream_operator_callback_stub.cpp | 148 ++++ .../operator/dstream_operator_callback_stub.h | 41 + .../operator/dstream_operator_proxy.cpp | 384 +++++++++ .../client/operator/dstream_operator_proxy.h | 65 ++ .../provider/dcamera_provider_callback.cpp | 67 ++ .../provider/dcamera_provider_callback.h | 43 + .../dcamera_provider_callback_stub.cpp | 255 ++++++ .../provider/dcamera_provider_callback_stub.h | 44 + .../provider/dcamera_provider_proxy.cpp | 315 ++++++++ .../client/provider/dcamera_provider_proxy.h | 59 ++ .../interfaces/hdi_ipc/config/host/BUILD.gn | 73 ++ .../config/host/dcamera_host_config.cpp | 92 +++ .../hdi_ipc/config/provider/BUILD.gn | 68 ++ .../provider/dcamera_provider_config.cpp | 93 +++ .../interfaces/hdi_ipc/ipc_data_utils.h | 102 +++ .../device/dcamera_device_callback_proxy.cpp | 85 ++ .../device/dcamera_device_callback_proxy.h | 40 + .../server/device/dcamera_device_stub.cpp | 232 ++++++ .../server/device/dcamera_device_stub.h | 44 + .../host/dcamera_host_callback_proxy.cpp | 104 +++ .../server/host/dcamera_host_callback_proxy.h | 41 + .../hdi_ipc/server/host/dcamera_host_stub.cpp | 260 ++++++ .../hdi_ipc/server/host/dcamera_host_stub.h | 69 ++ .../doffline_stream_operator_stub.cpp | 104 +++ .../operator/doffline_stream_operator_stub.h | 39 + .../dstream_operator_callback_proxy.cpp | 159 ++++ .../dstream_operator_callback_proxy.h | 45 ++ .../server/operator/dstream_operator_stub.cpp | 352 ++++++++ .../server/operator/dstream_operator_stub.h | 47 ++ .../dcamera_provider_callback_proxy.cpp | 267 +++++++ .../dcamera_provider_callback_proxy.h | 48 ++ .../server/provider/dcamera_provider_stub.cpp | 296 +++++++ .../server/provider/dcamera_provider_stub.h | 60 ++ .../include/idistributed_camera_provider.h | 164 ++++ .../idistributed_camera_provider_callback.h | 161 ++++ camera_hdf/interfaces/include/types.h | 307 +++++++ common/BUILD.gn | 56 ++ .../constants/distributed_camera_constants.h | 117 +++ .../constants/distributed_camera_errno.h | 39 + common/include/utils/data_buffer.h | 60 ++ common/include/utils/dcamera_index.h | 43 + common/include/utils/dcamera_utils_tools.h | 35 + common/src/utils/data_buffer.cpp | 119 +++ common/src/utils/dcamera_utils_tools.cpp | 157 ++++ distributedcamera.gni | 44 + figures/distributedcamera_arch.png | Bin 0 -> 99835 bytes .../native_cpp/camera_sink/BUILD.gn | 60 ++ .../include/dcamera_sink_handler.h | 46 ++ .../include/dcamera_sink_handler_ipc.h | 53 ++ .../include/distributed_camera_sink_proxy.h | 50 ++ .../include/idistributed_camera_sink.h | 52 ++ .../camera_sink/src/dcamera_sink_handler.cpp | 92 +++ .../src/dcamera_sink_handler_ipc.cpp | 159 ++++ .../src/distributed_camera_sink_proxy.cpp | 248 ++++++ .../native_cpp/camera_source/BUILD.gn | 63 ++ .../callback/dcamera_source_callback.h | 46 ++ .../callback/dcamera_source_callback_stub.h | 41 + .../callback/idcamera_source_callback.h | 39 + .../include/dcamera_source_handler.h | 61 ++ .../include/dcamera_source_handler_ipc.h | 53 ++ .../include/distributed_camera_source_proxy.h | 50 ++ .../include/idistributed_camera_source.h | 48 ++ .../src/callback/dcamera_source_callback.cpp | 90 +++ .../callback/dcamera_source_callback_stub.cpp | 82 ++ .../src/dcamera_source_handler.cpp | 126 +++ .../src/dcamera_source_handler_ipc.cpp | 159 ++++ .../src/distributed_camera_source_proxy.cpp | 160 ++++ sa_profile/4803.xml | 27 + sa_profile/4804.xml | 27 + sa_profile/BUILD.gn | 23 + .../base/include/dcamera_capture_info_cmd.h | 54 ++ .../base/include/dcamera_channel_info_cmd.h | 57 ++ .../base/include/dcamera_event_cmd.h | 44 + .../base/include/dcamera_info_cmd.h | 48 ++ .../include/dcamera_metadata_setting_cmd.h | 36 + .../base/include/dcamera_open_info_cmd.h | 46 ++ .../base/include/dcamera_protocol.h | 37 + .../base/include/icamera_controller.h | 45 ++ .../base/src/dcamera_capture_info_cmd.cpp | 170 ++++ .../base/src/dcamera_channel_info_cmd.cpp | 108 +++ .../base/src/dcamera_event_cmd.cpp | 95 +++ .../base/src/dcamera_info_cmd.cpp | 83 ++ .../base/src/dcamera_metadata_setting_cmd.cpp | 93 +++ .../base/src/dcamera_open_info_cmd.cpp | 82 ++ .../cameraservice/base/test/unittest/BUILD.gn | 19 + .../unittest/common/dcameraprotocol/BUILD.gn | 75 ++ .../dcameraprotocol/dcamera_protocol_test.cpp | 198 +++++ .../cameraoperator/client/BUILD.gn | 85 ++ .../include/callback/dcamera_input_callback.h | 35 + .../callback/dcamera_manager_callback.h | 31 + .../include/callback/dcamera_photo_callback.h | 38 + .../callback/dcamera_preview_callback.h | 37 + .../callback/dcamera_session_callback.h | 35 + .../include/callback/dcamera_video_callback.h | 37 + .../client/include/dcamera_client.h | 77 ++ .../client/include/icamera_operator.h | 64 ++ .../listener/dcamera_photo_surface_listener.h | 36 + .../listener/dcamera_video_surface_listener.h | 36 + .../src/callback/dcamera_input_callback.cpp | 41 + .../src/callback/dcamera_manager_callback.cpp | 36 + .../src/callback/dcamera_photo_callback.cpp | 56 ++ .../src/callback/dcamera_preview_callback.cpp | 51 ++ .../src/callback/dcamera_session_callback.cpp | 41 + .../src/callback/dcamera_video_callback.cpp | 51 ++ .../client/src/dcamera_client.cpp | 437 ++++++++++ .../dcamera_photo_surface_listener.cpp | 70 ++ .../dcamera_video_surface_listener.cpp | 75 ++ .../client/test/unittest/BUILD.gn | 19 + .../unittest/common/cameraoperator/BUILD.gn | 90 +++ .../cameraoperator/dcamera_client_test.cpp | 269 +++++++ .../cameraoperator/handler/BUILD.gn | 77 ++ .../handler/include/dcamera_handler.h | 73 ++ .../handler/src/dcamera_handler.cpp | 256 ++++++ .../handler/test/unittest/BUILD.gn | 19 + .../unittest/common/dcamerahandler/BUILD.gn | 87 ++ .../dcamerahandler/dcamera_handler_test.cpp | 90 +++ services/cameraservice/sinkservice/BUILD.gn | 128 +++ .../distributed_camera_sink_service.h | 59 ++ .../distributed_camera_sink_stub.h | 48 ++ .../dcamera_sink_controller_state_callback.h | 38 + .../dcamera_sink_output_result_callback.h | 38 + .../dcamera_sink_access_control.h | 35 + .../dcamera_sink_controller.h | 84 ++ .../dcamera_sink_data_process.h | 61 ++ .../distributedcameramgr/dcamera_sink_dev.h | 51 ++ .../dcamera_sink_output.h | 60 ++ .../dcamera_sink_service_ipc.h | 54 ++ .../eventbus/dcamera_frame_trigger_event.h | 36 + .../eventbus/dcamera_photo_output_event.h | 38 + .../dcamera_post_authorization_event.h | 38 + .../eventbus/dcamera_video_output_event.h | 38 + .../interface/icamera_sink_access_control.h | 36 + .../interface/icamera_sink_data_process.h | 38 + .../interface/icamera_sink_output.h | 42 + ...dcamera_sink_controller_channel_listener.h | 39 + .../dcamera_sink_data_process_listener.h | 38 + .../dcamera_sink_output_channel_listener.h | 40 + .../distributed_camera_sink_service.cpp | 256 ++++++ .../distributed_camera_sink_stub.cpp | 141 ++++ ...dcamera_sink_controller_state_callback.cpp | 47 ++ .../dcamera_sink_output_result_callback.cpp | 47 ++ .../dcamera_sink_access_control.cpp | 48 ++ .../dcamera_sink_controller.cpp | 442 ++++++++++ .../dcamera_sink_data_process.cpp | 185 +++++ .../distributedcameramgr/dcamera_sink_dev.cpp | 160 ++++ .../dcamera_sink_output.cpp | 234 ++++++ .../dcamera_sink_service_ipc.cpp | 191 +++++ .../eventbus/dcamera_frame_trigger_event.cpp | 34 + .../eventbus/dcamera_photo_output_event.cpp | 34 + .../dcamera_post_authorization_event.cpp | 34 + .../eventbus/dcamera_video_output_event.cpp | 34 + ...amera_sink_controller_channel_listener.cpp | 57 ++ .../dcamera_sink_data_process_listener.cpp | 47 ++ .../dcamera_sink_output_channel_listener.cpp | 57 ++ .../sinkservice/test/unittest/BUILD.gn | 20 + .../common/distributedcamera/BUILD.gn | 61 ++ .../distributed_camera_sink_service_test.cpp | 204 +++++ .../common/distributedcameramgr/BUILD.gn | 86 ++ .../dcamera_sink_access_control_test.cpp | 108 +++ .../dcamera_sink_controller_test.cpp | 356 +++++++++ .../dcamera_sink_data_process_test.cpp | 198 +++++ .../dcamera_sink_dev_test.cpp | 215 +++++ .../dcamera_sink_output_test.cpp | 240 ++++++ .../mock_camera_channel.h | 63 ++ .../mock_camera_operator.h | 82 ++ .../mock_data_process_pipeline.h | 56 ++ .../mock_dcamera_sink_controller.h | 78 ++ .../mock_dcamera_sink_data_process.h | 78 ++ .../mock_dcamera_sink_output.h | 63 ++ services/cameraservice/sourceservice/BUILD.gn | 115 +++ .../dcamera_service_state_listener.h | 39 + .../dcamera_source_callback_proxy.h | 44 + .../distributed_camera_source_service.h | 68 ++ .../distributed_camera_source_stub.h | 45 ++ .../distributedcameramgr/dcamera_source_dev.h | 93 +++ .../dcamera_source_event.h | 124 +++ .../dcamera_source_service_ipc.h | 54 ++ .../dcamera_source_controller.h | 70 ++ ...amera_source_controller_channel_listener.h | 39 + .../dcameradata/dcamera_source_data_process.h | 50 ++ .../dcameradata/dcamera_source_input.h | 65 ++ .../dcamera_source_input_channel_listener.h | 41 + .../dcameradata/dcamera_stream_data_process.h | 67 ++ ...ra_stream_data_process_pipeline_listener.h | 40 + .../dcamera_stream_data_process_producer.h | 67 ++ .../dcamera_provider_callback_impl.h | 47 ++ .../dcamerainterface/icamera_input.h | 40 + .../icamera_source_data_process.h | 67 ++ .../dcamerainterface/icamera_state_listener.h | 34 + .../dcamera_source_capture_state.h | 52 ++ .../dcamera_source_config_stream_state.h | 55 ++ .../dcamerastate/dcamera_source_init_state.h | 46 ++ .../dcamera_source_opened_state.h | 52 ++ .../dcamera_source_regist_state.h | 49 ++ .../dcamerastate/dcamera_source_state.h | 43 + .../dcamera_source_state_factory.h | 31 + .../dcamera_source_state_machine.h | 37 + .../dcamera_service_state_listener.cpp | 92 +++ .../dcamera_source_callback_proxy.cpp | 78 ++ .../distributed_camera_source_service.cpp | 198 +++++ .../distributed_camera_source_stub.cpp | 135 ++++ .../dcamera_source_dev.cpp | 538 +++++++++++++ .../dcamera_source_event.cpp | 106 +++ .../dcamera_source_service_ipc.cpp | 191 +++++ .../dcamera_source_controller.cpp | 472 +++++++++++ ...era_source_controller_channel_listener.cpp | 67 ++ .../dcamera_source_data_process.cpp | 165 ++++ .../dcameradata/dcamera_source_input.cpp | 377 +++++++++ .../dcamera_source_input_channel_listener.cpp | 67 ++ .../dcamera_stream_data_process.cpp | 229 ++++++ ..._stream_data_process_pipeline_listener.cpp | 55 ++ .../dcamera_stream_data_process_producer.cpp | 235 ++++++ .../dcamera_provider_callback_impl.cpp | 181 +++++ .../dcamera_source_capture_state.cpp | 217 +++++ .../dcamera_source_config_stream_state.cpp | 258 ++++++ .../dcamera_source_init_state.cpp | 80 ++ .../dcamera_source_opened_state.cpp | 188 +++++ .../dcamera_source_regist_state.cpp | 117 +++ .../dcamera_source_state_factory.cpp | 65 ++ .../dcamera_source_state_machine.cpp | 63 ++ .../sourceservice/test/unittest/BUILD.gn | 19 + .../common/distributedcameramgr/BUILD.gn | 93 +++ .../dcamera_source_state_machine_test.cpp | 355 +++++++++ .../mock_dcamera_source_dev.h | 84 ++ services/channel/BUILD.gn | 62 ++ .../include/dcamera_channel_sink_impl.h | 46 ++ .../include/dcamera_channel_source_impl.h | 46 ++ .../channel/include/dcamera_softbus_adapter.h | 86 ++ .../channel/include/dcamera_softbus_session.h | 120 +++ services/channel/include/icamera_channel.h | 44 + .../include/icamera_channel_listener.h | 43 + .../channel/src/dcamera_channel_sink_impl.cpp | 126 +++ .../src/dcamera_channel_source_impl.cpp | 145 ++++ .../channel/src/dcamera_softbus_adapter.cpp | 488 ++++++++++++ .../channel/src/dcamera_softbus_session.cpp | 451 +++++++++++ services/data_process/BUILD.gn | 81 ++ .../include/eventbus/dcamera_codec_event.h | 90 +++ .../include/eventbus/dcamera_pipeline_event.h | 101 +++ .../interfaces/data_process_listener.h | 38 + .../interfaces/idata_process_pipeline.h | 40 + .../include/pipeline/abstract_data_process.h | 44 + .../include/pipeline/dcamera_pipeline_sink.h | 72 ++ .../pipeline/dcamera_pipeline_source.h | 76 ++ .../convert_nv12_to_nv21.h | 48 ++ .../fpscontroller/fps_controller_process.h | 79 ++ .../multimedia_codec/decode_data_process.h | 145 ++++ .../multimedia_codec/decode_video_callback.h | 45 ++ .../multimedia_codec/encode_data_process.h | 123 +++ .../multimedia_codec/encode_video_callback.h | 45 ++ .../include/utils/image_common_type.h | 78 ++ .../src/pipeline/abstract_data_process.cpp | 37 + .../src/pipeline/dcamera_pipeline_sink.cpp | 176 ++++ .../src/pipeline/dcamera_pipeline_source.cpp | 209 +++++ .../convert_nv12_to_nv21.cpp | 364 +++++++++ .../fpscontroller/fps_controller_process.cpp | 331 ++++++++ .../multimedia_codec/decode_data_process.cpp | 701 ++++++++++++++++ .../decode_video_callback.cpp | 67 ++ .../multimedia_codec/encode_data_process.cpp | 499 ++++++++++++ .../encode_video_callback.cpp | 66 ++ .../src/utils/image_common_type.cpp | 66 ++ 309 files changed, 34003 insertions(+), 75 deletions(-) create mode 100644 LICENSE create mode 100644 OAT.xml delete mode 100644 README.en.md delete mode 100644 README.md create mode 100644 README_ZH.md create mode 100644 bundle.json create mode 100644 camera_hdf/hdi_impl/BUILD.gn create mode 100644 camera_hdf/hdi_impl/include/dcamera_device/dcamera_device.h create mode 100644 camera_hdf/hdi_impl/include/dcamera_device/dmetadata_processor.h create mode 100644 camera_hdf/hdi_impl/include/dcamera_host/dcamera_host.h create mode 100644 camera_hdf/hdi_impl/include/dcamera_provider/dcamera_provider.h create mode 100644 camera_hdf/hdi_impl/include/dstream_operator/dbuffer_manager.h create mode 100644 camera_hdf/hdi_impl/include/dstream_operator/dcamera_steam.h create mode 100644 camera_hdf/hdi_impl/include/dstream_operator/dimage_buffer.h create mode 100644 camera_hdf/hdi_impl/include/dstream_operator/doffline_stream_operator.h create mode 100644 camera_hdf/hdi_impl/include/dstream_operator/dstream_operator.h create mode 100644 camera_hdf/hdi_impl/include/utils/constants.h create mode 100644 camera_hdf/hdi_impl/include/utils/dcamera.h create mode 100644 camera_hdf/hdi_impl/src/dcamera_device/dcamera_device.cpp create mode 100644 camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp create mode 100644 camera_hdf/hdi_impl/src/dcamera_host/dcamera_host.cpp create mode 100644 camera_hdf/hdi_impl/src/dcamera_provider/dcamera_provider.cpp create mode 100644 camera_hdf/hdi_impl/src/dstream_operator/dbuffer_manager.cpp create mode 100644 camera_hdf/hdi_impl/src/dstream_operator/dcamera_steam.cpp create mode 100644 camera_hdf/hdi_impl/src/dstream_operator/dimage_buffer.cpp create mode 100644 camera_hdf/hdi_impl/src/dstream_operator/doffline_stream_operator.cpp create mode 100644 camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp create mode 100644 camera_hdf/hdi_impl/src/utils/dcamera.cpp create mode 100644 camera_hdf/hdi_impl/test/BUILD.gn create mode 100644 camera_hdf/hdi_impl/test/common.cpp create mode 100644 camera_hdf/hdi_impl/test/common.h create mode 100644 camera_hdf/hdi_impl/test/dcamera_hdi_sample.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/BUILD.gn create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/config/host/BUILD.gn create mode 100644 camera_hdf/interfaces/hdi_ipc/config/host/dcamera_host_config.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/config/provider/BUILD.gn create mode 100644 camera_hdf/interfaces/hdi_ipc/config/provider/dcamera_provider_config.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/ipc_data_utils.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.h create mode 100644 camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp create mode 100644 camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.h create mode 100644 camera_hdf/interfaces/include/idistributed_camera_provider.h create mode 100644 camera_hdf/interfaces/include/idistributed_camera_provider_callback.h create mode 100644 camera_hdf/interfaces/include/types.h create mode 100644 common/BUILD.gn create mode 100644 common/include/constants/distributed_camera_constants.h create mode 100644 common/include/constants/distributed_camera_errno.h create mode 100644 common/include/utils/data_buffer.h create mode 100644 common/include/utils/dcamera_index.h create mode 100644 common/include/utils/dcamera_utils_tools.h create mode 100644 common/src/utils/data_buffer.cpp create mode 100644 common/src/utils/dcamera_utils_tools.cpp create mode 100644 distributedcamera.gni create mode 100644 figures/distributedcamera_arch.png create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/BUILD.gn create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/include/dcamera_sink_handler.h create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/include/dcamera_sink_handler_ipc.h create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/include/distributed_camera_sink_proxy.h create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/include/idistributed_camera_sink.h create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler_ipc.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_sink/src/distributed_camera_sink_proxy.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_source/BUILD.gn create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback_stub.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/callback/idcamera_source_callback.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler_ipc.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/distributed_camera_source_proxy.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/include/idistributed_camera_source.h create mode 100644 interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback_stub.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler_ipc.cpp create mode 100644 interfaces/inner_kits/native_cpp/camera_source/src/distributed_camera_source_proxy.cpp create mode 100644 sa_profile/4803.xml create mode 100644 sa_profile/4804.xml create mode 100644 sa_profile/BUILD.gn create mode 100644 services/cameraservice/base/include/dcamera_capture_info_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_channel_info_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_event_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_info_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_metadata_setting_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_open_info_cmd.h create mode 100644 services/cameraservice/base/include/dcamera_protocol.h create mode 100644 services/cameraservice/base/include/icamera_controller.h create mode 100644 services/cameraservice/base/src/dcamera_capture_info_cmd.cpp create mode 100644 services/cameraservice/base/src/dcamera_channel_info_cmd.cpp create mode 100644 services/cameraservice/base/src/dcamera_event_cmd.cpp create mode 100644 services/cameraservice/base/src/dcamera_info_cmd.cpp create mode 100644 services/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp create mode 100644 services/cameraservice/base/src/dcamera_open_info_cmd.cpp create mode 100644 services/cameraservice/base/test/unittest/BUILD.gn create mode 100644 services/cameraservice/base/test/unittest/common/dcameraprotocol/BUILD.gn create mode 100644 services/cameraservice/base/test/unittest/common/dcameraprotocol/dcamera_protocol_test.cpp create mode 100644 services/cameraservice/cameraoperator/client/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_input_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_manager_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_photo_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_preview_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_session_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/callback/dcamera_video_callback.h create mode 100644 services/cameraservice/cameraoperator/client/include/dcamera_client.h create mode 100644 services/cameraservice/cameraoperator/client/include/icamera_operator.h create mode 100644 services/cameraservice/cameraoperator/client/include/listener/dcamera_photo_surface_listener.h create mode 100644 services/cameraservice/cameraoperator/client/include/listener/dcamera_video_surface_listener.h create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_input_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_manager_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_photo_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_preview_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_session_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/callback/dcamera_video_callback.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/dcamera_client.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/listener/dcamera_photo_surface_listener.cpp create mode 100644 services/cameraservice/cameraoperator/client/src/listener/dcamera_video_surface_listener.cpp create mode 100644 services/cameraservice/cameraoperator/client/test/unittest/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/dcamera_client_test.cpp create mode 100644 services/cameraservice/cameraoperator/handler/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/handler/include/dcamera_handler.h create mode 100644 services/cameraservice/cameraoperator/handler/src/dcamera_handler.cpp create mode 100644 services/cameraservice/cameraoperator/handler/test/unittest/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/BUILD.gn create mode 100644 services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/dcamera_handler_test.cpp create mode 100644 services/cameraservice/sinkservice/BUILD.gn create mode 100644 services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_service.h create mode 100644 services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_stub.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_controller_state_callback.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_output_result_callback.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_access_control.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_data_process.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_dev.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_output.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_service_ipc.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_frame_trigger_event.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_photo_output_event.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_post_authorization_event.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_video_output_event.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_access_control.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_data_process.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_output.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_data_process_listener.h create mode 100644 services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_output_channel_listener.h create mode 100644 services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_service.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_stub.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_controller_state_callback.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_output_result_callback.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_access_control.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_data_process.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_dev.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_output.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_service_ipc.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_frame_trigger_event.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_photo_output_event.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_post_authorization_event.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_video_output_event.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_data_process_listener.cpp create mode 100644 services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_output_channel_listener.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/BUILD.gn create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcamera/BUILD.gn create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcamera/distributed_camera_sink_service_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/BUILD.gn create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_access_control_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_data_process_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_dev_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_channel.h create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_data_process_pipeline.h create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_controller.h create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_data_process.h create mode 100644 services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_output.h create mode 100644 services/cameraservice/sourceservice/BUILD.gn create mode 100644 services/cameraservice/sourceservice/include/distributedcamera/dcamera_service_state_listener.h create mode 100644 services/cameraservice/sourceservice/include/distributedcamera/dcamera_source_callback_proxy.h create mode 100644 services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_service.h create mode 100644 services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_stub.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_dev.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_event.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_service_ipc.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_data_process.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_input.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_source_data_process.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_state_listener.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_capture_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_init_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_opened_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_regist_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_factory.h create mode 100644 services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_machine.h create mode 100644 services/cameraservice/sourceservice/src/distributedcamera/dcamera_service_state_listener.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcamera/dcamera_source_callback_proxy.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_service.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_stub.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_event.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_service_ipc.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_data_process.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_capture_state.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_init_state.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_opened_state.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_regist_state.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_factory.cpp create mode 100644 services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_machine.cpp create mode 100644 services/cameraservice/sourceservice/test/unittest/BUILD.gn create mode 100644 services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/BUILD.gn create mode 100644 services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_state_machine_test.cpp create mode 100644 services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/mock_dcamera_source_dev.h create mode 100644 services/channel/BUILD.gn create mode 100644 services/channel/include/dcamera_channel_sink_impl.h create mode 100644 services/channel/include/dcamera_channel_source_impl.h create mode 100644 services/channel/include/dcamera_softbus_adapter.h create mode 100644 services/channel/include/dcamera_softbus_session.h create mode 100644 services/channel/include/icamera_channel.h create mode 100644 services/channel/include/icamera_channel_listener.h create mode 100644 services/channel/src/dcamera_channel_sink_impl.cpp create mode 100644 services/channel/src/dcamera_channel_source_impl.cpp create mode 100644 services/channel/src/dcamera_softbus_adapter.cpp create mode 100644 services/channel/src/dcamera_softbus_session.cpp create mode 100644 services/data_process/BUILD.gn create mode 100644 services/data_process/include/eventbus/dcamera_codec_event.h create mode 100644 services/data_process/include/eventbus/dcamera_pipeline_event.h create mode 100644 services/data_process/include/interfaces/data_process_listener.h create mode 100644 services/data_process/include/interfaces/idata_process_pipeline.h create mode 100644 services/data_process/include/pipeline/abstract_data_process.h create mode 100644 services/data_process/include/pipeline/dcamera_pipeline_sink.h create mode 100644 services/data_process/include/pipeline/dcamera_pipeline_source.h create mode 100644 services/data_process/include/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.h create mode 100644 services/data_process/include/pipeline_node/fpscontroller/fps_controller_process.h create mode 100644 services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h create mode 100644 services/data_process/include/pipeline_node/multimedia_codec/decode_video_callback.h create mode 100644 services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h create mode 100644 services/data_process/include/pipeline_node/multimedia_codec/encode_video_callback.h create mode 100644 services/data_process/include/utils/image_common_type.h create mode 100644 services/data_process/src/pipeline/abstract_data_process.cpp create mode 100644 services/data_process/src/pipeline/dcamera_pipeline_sink.cpp create mode 100644 services/data_process/src/pipeline/dcamera_pipeline_source.cpp create mode 100644 services/data_process/src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp create mode 100644 services/data_process/src/pipeline_node/fpscontroller/fps_controller_process.cpp create mode 100644 services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp create mode 100644 services/data_process/src/pipeline_node/multimedia_codec/decode_video_callback.cpp create mode 100644 services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp create mode 100644 services/data_process/src/pipeline_node/multimedia_codec/encode_video_callback.cpp create mode 100644 services/data_process/src/utils/image_common_type.cpp diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..e454a525 --- /dev/null +++ b/LICENSE @@ -0,0 +1,178 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 00000000..c18b31e0 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 702c1b79..00000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# distributed_camera - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 9e662c7b..00000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# distributed_camera - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 00000000..39f17d5b --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,70 @@ +# **分布式相机组件** + +## **简介** + +分布式相机是多个设备的相机同时协同使用的能力。分布式相机组件是为分布式硬件子系统提供这一能力的组件。本组件不直接对接应用,只向分布式硬件框架子系统提供C++接口。应用可以通过相机框架的接口使用分布式相机组件操作其他设备的Camera,使用方式与本地相机一致。 + +其系统架构图如下图所示: + +![](figures/distributedcamera_arch.png) + +**分布式相机接口(DistributedCameraSDK)**:为分布式硬件管理框架提供超级终端虚拟Camera使能/去使能能力,以及相机状态。 + +**分布式相机主控端生命周期管理(DistributedCameraSourceMgr)**:通过状态机管理主控端Camera状态,负责主控端相关对象的创建销毁,以及两端的参数协商。 + +**分布式相机被控端生命周期管理(DistributedCameraSinkMgr)**:管理被控端Camera状态,负责被控端相关对象的创建销毁,以及两端的参数协商。 + +**通道模块(Channel)**:通过软总线连接主控端与被控端,接收发送主控端的相机指令或被控端的图像信息。 + +**数据处理器(DataProcess)**:对相机框架返回的图像数据做处理(编解码、色彩空间转换、分辨率缩放、帧率调整,角度调整等)。 + +**分布式相机客户端(CameraClient)**:被控端调用多媒体接口查询操作本地相机(查询相机数量及相关信息;打开、关闭、获取流等操作)。 + +**虚拟相机HDF层实现(VirtualCameraHdf)**:在HDF层建立的虚拟Camera硬件,能够被多媒体框架发现和加载,像使用本地的Camera一样被使用 + +## **目录** + +``` +/foundation/distributedhardware/distributedcamera +├── camera_hdf # 分布式相机HAL功能 +├── common # 分布式相机公共模块 +├── interfaces # 分布式相机对外接口模块 +├── sa_profile # 分布式相机SA配置模块 +├── services # 服务模块 +│ └── cameraservice # 相机服务模块 +│ ├── base # 分布式相机两端公共部分 +│ ├── cameraoperator # 分布式相机相机操作模块 +│ ├── sinkservice # 分布式相机被控端服务模块 +│ └── sourceservice # 分布式相机主控端服务模块 +│ ├── channel # 分布式相机通道模块 +│ └── data_process # 分布式相机数据处理模块 +``` + +## **约束** +**语言限制**:C++语言。 +**组网环境**:必须确保设备在同一个局域网中。 +**操作系统限制**:OpenHarmony操作系统。 + +## **说明** +### **概念说明** +#### 主控端(source):控制端,通过调用分布式相机能力,使用被控端的摄像头进行预览、拍照、录像等功能。 +#### 被控端(sink):被控制端,通过分布式相机接收主控端的命令,使用本地摄像头为主控端提供图像数据。 +#### Metadata:又叫元数据,是用于控制相机各种属性的参数。 + +### **接口说明** +分布式相机组件实现分布式硬件管理框架提供的接口,分布式硬件管理框架统一调用接口实现虚拟硬件驱动注册等功能。 + +### **业务流程说明** +#### **1. 设备开机启动** +系统拉起分布式相机的SA服务,Source侧被初始化,相关模块被初始化。 + +#### **2. 设备组网上线** +设备上线后,分布式硬件管理框架同步到上线设备的相机硬件信息并使能,使能成功后在系统中会新增分布式相机驱动并通知到相机框架,相机框架统一管理本地相机和分布式相机驱动;上层应用通过相机框架接口可以查询到分布式相机,并按照和本地相机相同的接口使用分布式相机。 + +#### **3. 设备下线** +设备下线后,分布式硬件管理框架去使能下线设备的相机硬件,本地移除分布式相机驱动并通知到相机框架,此时下线设备的分布式相机不可用。 + +## **涉及仓** +**** +**分布式相机** +[distributed_camera](https://gitee.com/openharmony/distributed_camera) \ No newline at end of file diff --git a/bundle.json b/bundle.json new file mode 100644 index 00000000..dfcb1b63 --- /dev/null +++ b/bundle.json @@ -0,0 +1,96 @@ +{ + "name":"@ohos/distributed_camera", + "description":"distributed hardware camera", + "version":"3.1", + "author":{}, + "repository":"https://gitee.com/openharmony/distributed_camera", + "license":"Apache License 2.0", + "publishAs":"code-segment", + "segment":{ + "destPath":"foundation/distributedhardware/distributedcamera/" + }, + "dirs":{}, + "scripts":{}, + "component":{ + "name":"distributed_camera", + "subsystem":"distributedhardware", + "syscap":[ + "SystemCapability.distributedhardware.distributed_camera" + ], + "features":[], + "adapted_system_type":[ + "standard" + ], + "rom":"2000k", + "ram":"6M", + "deps":{ + "components":[ + "appexecfwk_standard", + "eventhandler", + "hiviewdfx_hilog_native", + "ipc", + "safwk", + "samgr_standard", + "dsoftbus_standard", + "utils_base", + "graphic_standard", + "distributed_hardware_fwk", + "multimedia_camera_standard", + "multimedia_media_standard", + "hdf", + "hidl_adapter" + ], + "third_party":[ + "jsoncpp", + "googletest" + ] + }, + "build":{ + "sub_component":[ + "//foundation/distributedhardware/distributedcamera/common:distributed_camera_utils", + "//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_sink:distributed_camera_sink_sdk", + "//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_source:distributed_camera_source_sdk", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/cameraoperator/client:distributed_camera_client", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/cameraoperator/handler:distributed_camera_handler", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/sinkservice:distributed_camera_sink", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/sourceservice:distributed_camera_source", + "//foundation/distributedhardware/distributedcamera/services/data_process:distributed_camera_data_process", + "//foundation/distributedhardware/distributedcamera/sa_profile:dcamera_sa_profile", + "//foundation/distributedhardware/distributedcamera/services/channel:distributed_camera_channel", + "//foundation/distributedhardware/distributedcamera/camera_hdf/interfaces/hdi_ipc/config/host:distributed_camera_host_config", + "//foundation/distributedhardware/distributedcamera/camera_hdf/interfaces/hdi_ipc/config/provider:distributed_camera_provider_config", + "//foundation/distributedhardware/distributedcamera/camera_hdf/interfaces/hdi_ipc/client:distributed_camera_hdf_client", + "//foundation/distributedhardware/distributedcamera/camera_hdf/hdi_impl:distributed_camera_hdf" + ], + "inner_kits":[ + { + "type":"so", + "name":"//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_sink:distributed_camera_sink_sdk", + "header":{ + "header_base":"//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_sink/include", + "header_files":[ + "idistributed_camera_sink.h" + ] + } + }, + { + "type":"so", + "name":"//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_source:distributed_camera_source_sdk", + "header":{ + "header_base":"//foundation/distributedhardware/distributedcamera/interfaces/inner_kits/native_cpp/camera_source/include", + "header_files":[ + "idistributed_camera_source.h" + ] + } + } + ], + "test":[ + "//foundation/distributedhardware/distributedcamera/services/cameraservice/cameraoperator/client/test/unittest:camera_client_test", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/cameraoperator/handler/test/unittest:camera_handler_test", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/sinkservice/test/unittest:sink_service_test", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/sourceservice/test/unittest:source_service_test", + "//foundation/distributedhardware/distributedcamera/services/cameraservice/base/test/unittest:services_base_test" + ] + } + } +} \ No newline at end of file diff --git a/camera_hdf/hdi_impl/BUILD.gn b/camera_hdf/hdi_impl/BUILD.gn new file mode 100644 index 00000000..9e152f18 --- /dev/null +++ b/camera_hdf/hdi_impl/BUILD.gn @@ -0,0 +1,108 @@ +# 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/adapter/uhdf2/uhdf.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_hdf") { + include_dirs = [ + "include/dcamera_device", + "include/dcamera_host", + "include/dcamera_provider", + "include/dstream_operator", + "include/utils", + "../interfaces/include", + "../interfaces/hdi_ipc", + "../interfaces/hdi_ipc/server/device", + "../interfaces/hdi_ipc/server/host", + "../interfaces/hdi_ipc/server/operator", + "../interfaces/hdi_ipc/server/provider", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${common_path}/include/utils", + "${common_path}/include/constants", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include/", + "${fwk_utils_path}/include", + "${fwk_utils_path}/include/log", + "${camera_hdf_path}/camera/interfaces/include", + "${camera_hdf_path}/gralloc/src/adapter", + "${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", + + #producer + "//foundation/graphic/standard/frameworks/surface/include", + "//foundation/graphic/standard/interfaces/kits/surface", + "//foundation/graphic/standard/utils/include", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/multimedia/camera_standard/frameworks/native/metadata/include", + ] + + 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", + "../interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.cpp", + "../interfaces/hdi_ipc/server/provider/dcamera_provider_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/doffline_stream_operator.cpp", + "src/dstream_operator/dstream_operator.cpp", + "src/dstream_operator/dbuffer_manager.cpp", + "src/dstream_operator/dimage_buffer.cpp", + "src/dstream_operator/dcamera_steam.cpp", + "src/utils/dcamera.cpp" + ] + + deps = [ + "//utils/native/base:utils", + "${common_path}:distributed_camera_utils", + "${fwk_utils_path}:distributedhardwareutils", + "//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/graphic/standard/frameworks/surface:surface", + "//drivers/peripheral/display/hal:hdi_display_gralloc", + "//foundation/multimedia/camera_standard/frameworks/native/metadata:metadata", + "//third_party/jsoncpp:jsoncpp", + "${camera_hdf_path}/gralloc/src/adapter:libgralloc_adapter", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} diff --git a/camera_hdf/hdi_impl/include/dcamera_device/dcamera_device.h b/camera_hdf/hdi_impl/include/dcamera_device/dcamera_device.h new file mode 100644 index 00000000..9a42c19f --- /dev/null +++ b/camera_hdf/hdi_impl/include/dcamera_device/dcamera_device.h @@ -0,0 +1,84 @@ +/* + * 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_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 "idistributed_camera_provider_callback.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraDevice : public DCameraDeviceStub { +public: + DCameraDevice(const std::shared_ptr &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, std::shared_ptr &buffer); + DCamRetCode ShutterBuffer(int streamId, const std::shared_ptr &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 std::shared_ptr &dhBase); + +private: + bool isOpened_; + std::string dCameraId_; + std::shared_ptr 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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_DEVICE_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dcamera_device/dmetadata_processor.h b/camera_hdf/hdi_impl/include/dcamera_device/dmetadata_processor.h new file mode 100644 index 00000000..e5102398 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dcamera_device/dmetadata_processor.h @@ -0,0 +1,81 @@ +/* + * 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_METADATA_PROCESSOR_H +#define DISTRIBUTED_CAMERA_METADATA_PROCESSOR_H + +#include +#include +#include +#include "constants.h" +#include "dcamera.h" +#include +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +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); + DCamRetCode UpdateResultMetadata(bool &needReturn, std::shared_ptr &result); + 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); + uint32_t GetDataSize(uint32_t type); + std::map> GetDCameraSupportedFormats(const std::string &abilityInfo); + +private: + std::shared_ptr dCameraAbility_; + std::string protocolVersion_; + std::string dCameraPosition_; + DCResolution maxPreviewResolution_; + DCResolution maxPhotoResolution_; + ResultCallbackMode metaResultMode_; + std::set allResultSet_; + std::set enabledResultSet_; + + // The latest result metadata that received from the sink device. + common_metadata_header_t *latestProducerResultMetadata_; + + // The latest result metadata that replied to the camera service. + common_metadata_header_t *latestConsumerResultMetadata_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_METADATA_PROCESSOR_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dcamera_host/dcamera_host.h b/camera_hdf/hdi_impl/include/dcamera_host/dcamera_host.h new file mode 100644 index 00000000..603ad354 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dcamera_host/dcamera_host.h @@ -0,0 +1,77 @@ +/* + * 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_device.h" +#include "icamera_device.h" +#include "icamera_host_callback.h" +#include "icamera_device_callback.h" +#include +#include + +namespace OHOS { +namespace DistributedHardware { +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 std::shared_ptr &dhBase, const std::string &abilityInfo, + const sptr &callback); + DCamRetCode RemoveDCameraDevice(const std::shared_ptr &dhBase); + OHOS::sptr GetDCameraDeviceByDHBase(const std::shared_ptr &dhBase); + void NotifyDCameraStatus(const std::shared_ptr &dhBase, int32_t result); + +private: + bool IsCameraIdInvalid(const std::string &cameraId); + std::string GetCameraIdByDHBase(const std::shared_ptr &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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dcamera_provider/dcamera_provider.h b/camera_hdf/hdi_impl/include/dcamera_provider/dcamera_provider.h new file mode 100644 index 00000000..24fe1d21 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dcamera_provider/dcamera_provider.h @@ -0,0 +1,79 @@ +/* + * 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 "dcamera.h" +#include "idistributed_camera_provider_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraHost; +class DCameraDevice; +class DCameraProvider { +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 std::shared_ptr GetInstance(); + DCamRetCode EnableDCameraDevice(const std::shared_ptr &dhBase, const std::string &abilitySet, + const sptr &callback); + DCamRetCode DisableDCameraDevice(const std::shared_ptr &dhBase); + DCamRetCode AcquireBuffer(const std::shared_ptr &dhBase, int streamId, + std::shared_ptr &buffer); + DCamRetCode ShutterBuffer(const std::shared_ptr &dhBase, int streamId, + const std::shared_ptr &buffer); + DCamRetCode OnSettingsResult(const std::shared_ptr &dhBase, const std::shared_ptr &result); + DCamRetCode Notify(const std::shared_ptr &dhBase, const std::shared_ptr &event); + + DCamRetCode OpenSession(const std::shared_ptr &dhBase); + DCamRetCode CloseSession(const std::shared_ptr &dhBase); + DCamRetCode ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos); + DCamRetCode ReleaseStreams(const std::shared_ptr &dhBase, const std::vector &streamIds); + DCamRetCode StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos); + DCamRetCode StopCapture(const std::shared_ptr &dhBase); + DCamRetCode UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings); + +private: + bool IsDhBaseInfoInvalid(const std::shared_ptr &dhBase); + sptr GetCallbackBydhBase(const std::shared_ptr &dhBase); + OHOS::sptr GetDCameraDevice(const std::shared_ptr &dhBase); + +private: + class AutoRelease { + public: + AutoRelease() {}; + ~AutoRelease() + { + if (DCameraProvider::instance_ != nullptr) { + DCameraProvider::instance_ = nullptr; + } + }; + }; + static AutoRelease autoRelease_; + static std::shared_ptr instance_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dstream_operator/dbuffer_manager.h b/camera_hdf/hdi_impl/include/dstream_operator/dbuffer_manager.h new file mode 100644 index 00000000..a07d671d --- /dev/null +++ b/camera_hdf/hdi_impl/include/dstream_operator/dbuffer_manager.h @@ -0,0 +1,58 @@ +/* + * 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 "display_type.h" +#include +#include "dimage_buffer.h" +#include "surface.h" + +namespace OHOS { +namespace DistributedHardware { +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, + std::shared_ptr &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_ = {}; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_BUFFER_MANAGER_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dstream_operator/dcamera_steam.h b/camera_hdf/hdi_impl/include/dstream_operator/dcamera_steam.h new file mode 100644 index 00000000..703ae264 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dstream_operator/dcamera_steam.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_STREAM_H +#define DISTRIBUTED_CAMERA_STREAM_H + +#include "surface.h" +#include "dimage_buffer.h" +#include "dbuffer_manager.h" +#include +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace std; +using namespace OHOS::Camera; +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(shared_ptr &buffer); + DCamRetCode ReturnDCameraBuffer(const shared_ptr &buffer); + DCamRetCode FlushDCameraBuffer(); + DCamRetCode FinishCommitStream(); + bool HasBufferQueue(); + +private: + DCamRetCode InitDCameraBufferManager(); + DCamRetCode GetNextRequest(); + +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; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_STREAM_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dstream_operator/dimage_buffer.h b/camera_hdf/hdi_impl/include/dstream_operator/dimage_buffer.h new file mode 100644 index 00000000..00cd31c1 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dstream_operator/dimage_buffer.h @@ -0,0 +1,89 @@ +/* + * 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_IMAGE_BUFFER_H +#define DISTRIBUTED_CAMERA_IMAGE_BUFFER_H + +#include +#include "constants.h" +#include "distributed_camera_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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_IMAGE_BUFFER_H diff --git a/camera_hdf/hdi_impl/include/dstream_operator/doffline_stream_operator.h b/camera_hdf/hdi_impl/include/dstream_operator/doffline_stream_operator.h new file mode 100644 index 00000000..6dde3f15 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dstream_operator/doffline_stream_operator.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_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; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_OFFLINE_STREAM_OPERATOR_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/dstream_operator/dstream_operator.h b/camera_hdf/hdi_impl/include/dstream_operator/dstream_operator.h new file mode 100644 index 00000000..3885d503 --- /dev/null +++ b/camera_hdf/hdi_impl/include/dstream_operator/dstream_operator.h @@ -0,0 +1,113 @@ +/* + * 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_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_steam.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace std; +class DCameraProvider; +class DStreamOperator : public DStreamOperatorStub { +public: + 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 std::shared_ptr &dhBase, const std::string &abilityInfo); + DCamRetCode AcquireBuffer(int streamId, std::shared_ptr &buffer); + DCamRetCode ShutterBuffer(int streamId, const std::shared_ptr &buffer); + DCamRetCode SetCallBack(OHOS::sptr const &callback); + DCamRetCode SetDeviceCallback(function &errorCbk, + function)> &resultCbk); + void Release(); + +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); + +private: + std::shared_ptr dMetadataProcessor_; + OHOS::sptr dcStreamOperatorCallback_; + function errorCallback_; + function)> resultCallback_; + + std::shared_ptr 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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_STREAM_OPERATOR_H diff --git a/camera_hdf/hdi_impl/include/utils/constants.h b/camera_hdf/hdi_impl/include/utils/constants.h new file mode 100644 index 00000000..a9a07b88 --- /dev/null +++ b/camera_hdf/hdi_impl/include/utils/constants.h @@ -0,0 +1,113 @@ +/* + * 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_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"; + +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_); + } +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CONSTANTS_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/include/utils/dcamera.h b/camera_hdf/hdi_impl/include/utils/dcamera.h new file mode 100644 index 00000000..768db551 --- /dev/null +++ b/camera_hdf/hdi_impl/include/utils/dcamera.h @@ -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. + */ + +#ifndef DISTRIBUTED_CAMERA_H +#define DISTRIBUTED_CAMERA_H + +#include +#include + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +using RetCode = uint32_t; +using MetaType = int32_t; + +CamRetCode MapToExternalRetCode(DCamRetCode retCode); + +DCamRetCode MapToInternalRetCode(CamRetCode retCode); + +uint64_t GetCurrentLocalTimeStamp(); + +void SplitString(const std::string &str, std::vector &tokens, const std::string &delimiters); +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_H \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dcamera_device/dcamera_device.cpp b/camera_hdf/hdi_impl/src/dcamera_device/dcamera_device.cpp new file mode 100644 index 00000000..7d602127 --- /dev/null +++ b/camera_hdf/hdi_impl/src/dcamera_device/dcamera_device.cpp @@ -0,0 +1,446 @@ +/* + * 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.h" +#include +#include +#include +#include "dcamera_host.h" +#include "dcamera_provider.h" +#include "dcamera_utils_tools.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 std::shared_ptr &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_) { + dCameraDeviceCallback_->OnError(type, errorMsg); + } + }; + ResultCallback onResultCallback = + [this](uint64_t timestamp, const std::shared_ptr &result) -> void { + if (dCameraDeviceCallback_) { + 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.", dCameraId_.c_str()); + return CamRetCode::CAMERA_CLOSED; + } + + std::shared_ptr dcSetting = std::make_shared(); + + dcSetting->type_ = DCSettingsType::UPDATE_METADATA; + std::string abilityStr = CameraStandard::MetadataUtils::EncodeToString(settings); + dcSetting->value_ = Base64Encode(reinterpret_cast(abilityStr.c_str()), abilityStr.length()); + + std::vector> dcSettings; + dcSettings.push_back(dcSetting); + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider instance is null."); + return CamRetCode::DEVICE_ERROR; + } + DCamRetCode ret = provider->UpdateSettings(dhBase_, dcSettings); + + return MapToExternalRetCode(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, "")); + std::shared_ptr dcSetting = std::make_shared(); + dcSetting->type_ = DCSettingsType::ENABLE_METADATA; + dcSetting->value_ = sstream.str(); + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider != nullptr) { + std::vector> dcSettings; + dcSettings.push_back(dcSetting); + ret = provider->UpdateSettings(dhBase_, dcSettings); + } + return MapToExternalRetCode(ret); +} + +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, "")); + std::shared_ptr dcSetting = std::make_shared(); + dcSetting->type_ = DCSettingsType::DISABLE_METADATA; + dcSetting->value_ = sstream.str(); + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider != nullptr) { + std::vector> dcSettings; + dcSettings.push_back(dcSetting); + ret = provider->UpdateSettings(dhBase_, dcSettings); + } + return MapToExternalRetCode(ret); +} + +void DCameraDevice::Close() +{ + DHLOGI("DCameraDevice::Close distributed camera: %s", dCameraId_.c_str()); + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider != nullptr) { + provider->StopCapture(dhBase_); + } + 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; + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Get distributed camera provider instance is null."); + return CamRetCode::DEVICE_ERROR; + } + DCamRetCode ret = provider->OpenSession(dhBase_); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Open distributed camera control session failed, ret = %d.", ret); + return MapToExternalRetCode(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; + } + } + + ret = CreateDStreamOperator(); + if (ret != SUCCESS) { + DHLOGE("Create distributed camera stream operator failed."); + return MapToExternalRetCode(ret); + } + isOpened_ = true; + + return MapToExternalRetCode(ret); +} + +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, std::shared_ptr &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 std::shared_ptr &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 INVALID_ARGUMENT; + } + + if (dMetadataProcessor_ == nullptr) { + DHLOGE("Metadata processor not init."); + return DEVICE_NOT_INIT; + } + + if (result->type_ != DCSettingsType::METADATA_RESULT) { + DHLOGE("Invalid camera setting type = %d.", result->type_); + return INVALID_ARGUMENT; + } + if ((result->value_).empty()) { + DHLOGE("Camera settings result is empty."); + return INVALID_ARGUMENT; + } + + DCamRetCode ret = dMetadataProcessor_->SaveResultMetadata(result->value_); + if (ret != 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 INVALID_ARGUMENT; + } + switch (event->result_) { + case DCameraEventResult::DCAMERA_EVENT_CHANNEL_CONNECTED: { + { + unique_lock lock(isOpenSessFailedlock_); + isOpenSessFailed_ = false; + } + openSessCV_.notify_one(); + break; + } + case DCameraEventResult::DCAMERA_EVENT_OPEN_CHANNEL_ERROR: { + { + unique_lock lock(isOpenSessFailedlock_); + isOpenSessFailed_ = true; + } + openSessCV_.notify_one(); + break; + } + case DCameraEventResult::DCAMERA_EVENT_CHANNEL_DISCONNECTED: { + if (dCameraDeviceCallback_ != nullptr) { + dCameraDeviceCallback_->OnError(ErrorType::FATAL_ERROR, 0); + Close(); + } + break; + } + case DCameraEventResult::DCAMERA_EVENT_CONFIG_STREAMS_ERROR: + case DCameraEventResult::DCAMERA_EVENT_START_CAPTURE_ERROR: { + if (dCameraDeviceCallback_ != nullptr) { + dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0); + } + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider != nullptr) { + provider->StopCapture(dhBase_); + } + if (dCameraStreamOperator_ != nullptr) { + dCameraStreamOperator_->Release(); + } + break; + } + case DCameraEventResult::DCAMERA_EVENT_CAMERA_ERROR: { + std::shared_ptr dCameraHost = DCameraHost::GetInstance(); + if (dCameraHost != nullptr) { + dCameraHost->NotifyDCameraStatus(dhBase_, event->result_); + } + if (dCameraDeviceCallback_ != nullptr) { + dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0); + Close(); + } + break; + } + default: + break; + } + return SUCCESS; +} + +void DCameraDevice::SetProviderCallback(const OHOS::sptr &callback) +{ + dCameraProviderCallback_ = callback; +} + +OHOS::sptr DCameraDevice::GetProviderCallback() +{ + return dCameraProviderCallback_; +} + +std::string DCameraDevice::GenerateCameraId(const std::shared_ptr &dhBase) +{ + return dhBase->deviceId_ + "__" + dhBase->dhId_; +} + +std::string DCameraDevice::GetDCameraId() +{ + return dCameraId_; +} + +bool DCameraDevice::IsOpened() +{ + return isOpened_; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp b/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp new file mode 100644 index 00000000..2b53f17f --- /dev/null +++ b/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp @@ -0,0 +1,608 @@ +/* + * 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 "dmetadata_processor.h" +#include "dbuffer_manager.h" +#include "dcamera_utils_tools.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()) { + dCameraAbility_ = CameraStandard::MetadataUtils::DecodeFromString(Base64Decode(metadataStr)); + 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 (CameraStandard::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 = CameraStandard::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; +} + +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); + } + + 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); + + 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 INVALID_ARGUMENT; + } + + camera_metadata_item_t item; + int ret = CameraStandard::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item); + if (ret) { + if (!dCameraAbility_->addEntry(tag, data, size)) { + DHLOGE("Add tag %d 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 INVALID_ARGUMENT; + } + + camera_metadata_item_t item; + int ret = CameraStandard::FindCameraMetadataItem(dCameraAbility_->get(), tag, &item); + if (ret) { + if (!dCameraAbility_->addEntry(tag, data, size)) { + DHLOGE("Add tag %d failed.", tag); + return FAILED; + } + } else { + if (!dCameraAbility_->updateEntry(tag, data, size)) { + DHLOGE("Update tag %d 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 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; +} + +DCamRetCode DMetadataProcessor::UpdateResultMetadata(bool &needReturn, + std::shared_ptr &result) +{ + if (latestProducerResultMetadata_ == nullptr) { + needReturn = false; + return SUCCESS; + } + + uint32_t itemCapacity = CameraStandard::GetCameraMetadataItemCapacity(latestProducerResultMetadata_); + uint32_t dataCapacity = CameraStandard::GetCameraMetadataDataSize(latestProducerResultMetadata_); + + if (metaResultMode_ == ResultCallbackMode::PER_FRAME) { + ResizeMetadataHeader(latestConsumerResultMetadata_, itemCapacity, dataCapacity); + CameraStandard::CopyCameraMetadataItems(latestConsumerResultMetadata_, latestProducerResultMetadata_); + ConvertToCameraMetadata(latestConsumerResultMetadata_, result); + needReturn = true; + return SUCCESS; + } else { + for (auto tag : enabledResultSet_) { + camera_metadata_item_t item; + camera_metadata_item_t anoItem; + int ret1 = CameraStandard::FindCameraMetadataItem(latestProducerResultMetadata_, tag, &item); + int ret2 = CameraStandard::FindCameraMetadataItem(latestConsumerResultMetadata_, tag, &anoItem); + if (ret1 == 0 && ret2 == 0) { + if (item.count != anoItem.count || item.data_type != anoItem.data_type) { + ResizeMetadataHeader(latestConsumerResultMetadata_, itemCapacity, dataCapacity); + CameraStandard::CopyCameraMetadataItems(latestConsumerResultMetadata_, + latestProducerResultMetadata_); + ConvertToCameraMetadata(latestConsumerResultMetadata_, result); + needReturn = true; + return SUCCESS; + } else { + uint32_t size = GetDataSize(item.data_type); + for (uint32_t i = 0; i < (size * static_cast(item.count)); i++) { + if (*(item.data.u8 + i) != *(anoItem.data.u8 + i)) { + ResizeMetadataHeader(latestConsumerResultMetadata_, itemCapacity, dataCapacity); + CameraStandard::CopyCameraMetadataItems(latestConsumerResultMetadata_, + latestProducerResultMetadata_); + ConvertToCameraMetadata(latestConsumerResultMetadata_, result); + needReturn = true; + return SUCCESS; + } + } + ResizeMetadataHeader(latestConsumerResultMetadata_, itemCapacity, dataCapacity); + CameraStandard::CopyCameraMetadataItems(latestConsumerResultMetadata_, + latestProducerResultMetadata_); + needReturn = false; + } + } else if (ret1 == 0 || ret2 == 0) { + ResizeMetadataHeader(latestConsumerResultMetadata_, itemCapacity, dataCapacity); + CameraStandard::CopyCameraMetadataItems(latestConsumerResultMetadata_, latestProducerResultMetadata_); + ConvertToCameraMetadata(latestConsumerResultMetadata_, result); + needReturn = true; + return SUCCESS; + } + } + } + return SUCCESS; +} + +DCamRetCode DMetadataProcessor::SaveResultMetadata(std::string resultStr) +{ + if (resultStr.empty()) { + DHLOGE("Input result string is null."); + return INVALID_ARGUMENT; + } + + latestProducerResultMetadata_ = CameraStandard::MetadataUtils::DecodeFromString(resultStr)->get(); + if (latestProducerResultMetadata_ == nullptr) { + DHLOGE("Failed to decode metadata setting from string."); + return INVALID_ARGUMENT; + } + + if (!CameraStandard::GetCameraMetadataItemCount(latestProducerResultMetadata_)) { + DHLOGE("Input result metadata item is empty."); + return INVALID_ARGUMENT; + } + + return SUCCESS; +} + +void DMetadataProcessor::ConvertToCameraMetadata(common_metadata_header_t *&input, + std::shared_ptr &output) +{ + auto ret = CameraStandard::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) { + header = nullptr; + } + header = CameraStandard::AllocateCameraMetadataBuffer(itemCapacity, dataCapacity); +} + +uint32_t DMetadataProcessor::GetDataSize(uint32_t type) +{ + int32_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; +} + +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::atoi(reso[0].c_str())); + uint32_t height = static_cast(std::atoi(reso[1].c_str())); + 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()); + 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 = CameraStandard::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 = CameraStandard::GetCameraMetadataItem(metadata, i, &item); + if (ret != 0) { + continue; + } + + const char *name = CameraStandard::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)); + } + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dcamera_host/dcamera_host.cpp b/camera_hdf/hdi_impl/src/dcamera_host/dcamera_host.cpp new file mode 100644 index 00000000..dfc23c9a --- /dev/null +++ b/camera_hdf/hdi_impl/src/dcamera_host/dcamera_host.cpp @@ -0,0 +1,232 @@ +/* + * 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", 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", 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.", 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.", 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 std::shared_ptr &dhBase, const std::string &abilityInfo, + const sptr &callback) +{ + DHLOGI("DCameraHost::AddDCameraDevice for {devId: %s, dhId: %s}", + GetAnonyString(dhBase->deviceId_).c_str(), 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; + DHBase dhBaseKey(dhBase->deviceId_, dhBase->dhId_); + dhBaseHashDCamIdMap_.emplace(dhBaseKey, dCameraId); + dcameraDevice->SetProviderCallback(callback); + + if (dCameraHostCallback_ != nullptr) { + dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD); + } + + DHLOGI("DCameraHost::AddDCameraDevice, create dcamera device success, dCameraId: %s", dCameraId.c_str()); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraHost::RemoveDCameraDevice(const std::shared_ptr &dhBase) +{ + DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %s, dhId: %s}", + GetAnonyString(dhBase->deviceId_).c_str(), 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); + } + + DHBase dhBaseKey(dhBase->deviceId_, dhBase->dhId_); + dhBaseHashDCamIdMap_.erase(dhBaseKey); + dCameraDeviceMap_.erase(dCameraId); + + if (dCameraHostCallback_ != nullptr) { + dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV); + } + + DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %s", 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 std::shared_ptr &dhBase) +{ + DHBase dhBaseKey(dhBase->deviceId_, dhBase->dhId_); + auto iter = dhBaseHashDCamIdMap_.find(dhBaseKey); + if (iter == dhBaseHashDCamIdMap_.end()) { + return ""; + } + return iter->second; +} + +OHOS::sptr DCameraHost::GetDCameraDeviceByDHBase(const std::shared_ptr &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 std::shared_ptr &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); + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dcamera_provider/dcamera_provider.cpp b/camera_hdf/hdi_impl/src/dcamera_provider/dcamera_provider.cpp new file mode 100644 index 00000000..009d6fe8 --- /dev/null +++ b/camera_hdf/hdi_impl/src/dcamera_provider/dcamera_provider.cpp @@ -0,0 +1,306 @@ +/* + * 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 { +std::shared_ptr DCameraProvider::instance_ = nullptr; +DCameraProvider::AutoRelease DCameraProvider::autoRelease_; + +std::shared_ptr DCameraProvider::GetInstance() +{ + if (instance_ == nullptr) { + instance_ = std::make_shared(); + if (instance_ == nullptr) { + DHLOGE("Get distributed camera provider instance failed."); + return nullptr; + } + } + return instance_; +} + +DCamRetCode DCameraProvider::EnableDCameraDevice(const std::shared_ptr &dhBase, + const std::string &abilityInfo, const sptr &callback) +{ + DHLOGI("DCameraProvider::EnableDCameraDevice for {devId: %s, dhId: %s, abilityInfo length: %d}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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 (callback == nullptr) { + DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera provider callback 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, callback); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("DCameraProvider::EnableDCameraDevice failed, ret = %d.", ret); + } + + return ret; +} + +DCamRetCode DCameraProvider::DisableDCameraDevice(const std::shared_ptr &dhBase) +{ + DHLOGI("DCameraProvider::DisableDCameraDevice for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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; +} + +DCamRetCode DCameraProvider::AcquireBuffer(const std::shared_ptr &dhBase, int streamId, + std::shared_ptr &buffer) +{ + DHLOGI("DCameraProvider::AcquireBuffer for {devId: %s, dhId: %s}, streamId: %d.", + GetAnonyString(dhBase->deviceId_).c_str(), 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; + } + + return device->AcquireBuffer(streamId, buffer); +} + +DCamRetCode DCameraProvider::ShutterBuffer(const std::shared_ptr &dhBase, int streamId, + const std::shared_ptr &buffer) +{ + if (buffer == nullptr) { + DHLOGE("DCameraProvider::ShutterBuffer, input distributed camera buffer is null."); + return DCamRetCode::INVALID_ARGUMENT; + } + DHLOGI("DCameraProvider::ShutterBuffer for {devId: %s, dhId: %s}, streamId = %d, buffer index = %d.", + GetAnonyString(dhBase->deviceId_).c_str(), dhBase->dhId_.c_str(), streamId, buffer->index_); + + 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); +} + +DCamRetCode DCameraProvider::OnSettingsResult(const std::shared_ptr &dhBase, + const std::shared_ptr &result) +{ + DHLOGI("DCameraProvider::OnSettingsResult for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), dhBase->dhId_.c_str()); + + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::OnSettingsResult failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return device->OnSettingsResult(result); +} + +DCamRetCode DCameraProvider::Notify(const std::shared_ptr &dhBase, + const std::shared_ptr &event) +{ + DHLOGI("DCameraProvider::Notify for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), dhBase->dhId_.c_str()); + + OHOS::sptr device = GetDCameraDevice(dhBase); + if (device == nullptr) { + DHLOGE("DCameraProvider::Notify failed, dcamera device not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return device->Notify(event); +} + +DCamRetCode DCameraProvider::OpenSession(const std::shared_ptr &dhBase) +{ + DHLOGI("DCameraProvider::OpenSession for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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); +} + +DCamRetCode DCameraProvider::CloseSession(const std::shared_ptr &dhBase) +{ + DHLOGI("DCameraProvider::CloseSession for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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); +} + +DCamRetCode DCameraProvider::ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos) +{ + DHLOGI("DCameraProvider::ConfigureStreams for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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) { + 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); +} + +DCamRetCode DCameraProvider::ReleaseStreams(const std::shared_ptr &dhBase, + const std::vector &streamIds) +{ + DHLOGI("DCameraProvider::ReleaseStreams for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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); +} + +DCamRetCode DCameraProvider::StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos) +{ + DHLOGI("DCameraProvider::StartCapture for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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) { + std::string idString = ""; + for (int id : info->streamIds_) { + idString += (std::to_string(id) + ", "); + } + DHLOGI("StartCapture: ids=[%s], width=%d, height=%d, format=%d, type=%d.", + (idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str()), + info->width_, info->height_, info->format_, info->type_); + } + return callback->StartCapture(dhBase, captureInfos); +} + +DCamRetCode DCameraProvider::StopCapture(const std::shared_ptr &dhBase) +{ + DHLOGI("DCameraProvider::StopCapture for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), dhBase->dhId_.c_str()); + + sptr callback = GetCallbackBydhBase(dhBase); + if (callback == nullptr) { + DHLOGE("DCameraProvider::StopCapture, dcamera provider callback not found."); + return DCamRetCode::INVALID_ARGUMENT; + } + + return callback->StopCapture(dhBase); +} + +DCamRetCode DCameraProvider::UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings) +{ + DHLOGI("DCameraProvider::UpdateSettings for {devId: %s, dhId: %s}.", + GetAnonyString(dhBase->deviceId_).c_str(), 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 std::shared_ptr &dhBase) +{ + return dhBase->deviceId_.empty() || (dhBase->deviceId_.size() > DEVID_MAX_LENGTH) || + dhBase->dhId_.empty() || (dhBase->dhId_.size() > DHID_MAX_LENGTH); +} + +sptr DCameraProvider::GetCallbackBydhBase(const std::shared_ptr &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 std::shared_ptr &dhBase) +{ + std::shared_ptr dCameraHost = DCameraHost::GetInstance(); + if (dCameraHost == nullptr) { + DHLOGE("DCameraProvider::GetDCameraDevice, dcamera host is null."); + return nullptr; + } + return dCameraHost->GetDCameraDeviceByDHBase(dhBase); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dstream_operator/dbuffer_manager.cpp b/camera_hdf/hdi_impl/src/dstream_operator/dbuffer_manager.cpp new file mode 100644 index 00000000..4514863b --- /dev/null +++ b/camera_hdf/hdi_impl/src/dstream_operator/dbuffer_manager.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 "dbuffer_manager.h" +#include +#include "distributed_camera_constants.h" +#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); + DHLOGI("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, + std::shared_ptr &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_ = bufHandle; + + return RC_OK; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dstream_operator/dcamera_steam.cpp b/camera_hdf/hdi_impl/src/dstream_operator/dcamera_steam.cpp new file mode 100644 index 00000000..06ac97e9 --- /dev/null +++ b/camera_hdf/hdi_impl/src/dstream_operator/dcamera_steam.cpp @@ -0,0 +1,363 @@ +/* + * 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_steam.h" +#include +#include +#include "constants.h" +#include "dcamera.h" +#include "distributed_hardware_log.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::GetNextRequest() +{ + if (isBufferMgrInited_ == false) { + 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; + } + + 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 availiable 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(); + auto surface = OHOS::SurfaceBufferImpl::FromBase(surfaceBuffer); + RetCode ret = DBufferManager::SurfaceBufferToDImageBuffer(surface, 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; + } + DHLOGI("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(shared_ptr &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_++; + + DHLOGI("Get buffer success. address = %p, index = %d, size = %d", buffer->bufferHandle_->virAddr, + buffer->index_, buffer->size_); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraStream::ReturnDCameraBuffer(const shared_ptr &buffer) +{ + if (buffer == nullptr) { + DHLOGE("result buffer is null. [streamId = %d]", dcStreamInfo_->streamId_); + return DCamRetCode::INVALID_ARGUMENT; + } + + shared_ptr imageBuffer = nullptr; + map, tuple, int, int>>::iterator iter; + for (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 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) { + if (dcStreamInfo_->intent_ == StreamIntent::VIDEO) { + int32_t size = (dcStreamInfo_->width_) * (dcStreamInfo_->height_) * YUV_WIDTH_RATIO / YUV_HEIGHT_RATIO; + int64_t timeStamp = static_cast(GetCurrentLocalTimeStamp()); + surfaceBuffer->ExtraSet("dataSize", size); + surfaceBuffer->ExtraSet("isKeyFrame", (int32_t)0); + surfaceBuffer->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_ == false) { + return false; + } + return true; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dstream_operator/dimage_buffer.cpp b/camera_hdf/hdi_impl/src/dstream_operator/dimage_buffer.cpp new file mode 100644 index 00000000..7380342a --- /dev/null +++ b/camera_hdf/hdi_impl/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_; +} +} // end namespace DistributedHardware +} // end namespace OHOS diff --git a/camera_hdf/hdi_impl/src/dstream_operator/doffline_stream_operator.cpp b/camera_hdf/hdi_impl/src/dstream_operator/doffline_stream_operator.cpp new file mode 100644 index 00000000..8bcd9d70 --- /dev/null +++ b/camera_hdf/hdi_impl/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; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp b/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp new file mode 100644 index 00000000..7b6823ad --- /dev/null +++ b/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp @@ -0,0 +1,753 @@ +/* + * 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.h" +#include "dbuffer_manager.h" +#include "dcamera_provider.h" +#include "dcamera_utils_tools.h" +#include "distributed_hardware_log.h" +#include "json/json.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; + (void)type; + + 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::METHOD_NOT_SUPPORTED; +} + +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_ != true) { + 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 { + DHLOGE("Release distributed camera buffer queue for stream %d successs.", id); + } + stream = nullptr; + halStreamMap_.erase(id); + dcStreamInfoMap_.erase(id); + } else { + DHLOGE("Error streamId %d.", id); + return CamRetCode::INVALID_ARGUMENT; + } + } + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + DCamRetCode ret = provider->ReleaseStreams(dhBase_, streamIds); + if (ret != SUCCESS) { + DHLOGE("Release distributed camera streams failed."); + return MapToExternalRetCode(ret); + } + + DHLOGI("DStreamOperator::Release distributed camera streams success."); + return CamRetCode::NO_ERROR; +} + +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_) { + dCameraStreams.push_back(streamInfo.second); + } + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + DCamRetCode ret = provider->ConfigureStreams(dhBase_, dCameraStreams); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Commit distributed camera streams failed."); + return MapToExternalRetCode(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(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; + } +} + +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_) { + if (halStreamMap_.find(id) == halStreamMap_.end()) { + DHLOGE("Invalid stream id %d", id); + return CamRetCode::INVALID_ARGUMENT; + } + auto iter = halStreamMap_.find(id); + 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); + } + + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + ret = provider->StartCapture(dhBase_, cachedDCaptureInfoList_); + if (ret != SUCCESS) { + DHLOGE("Start distributed camera capture failed."); + return MapToExternalRetCode(ret); + } + 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 exist.", captureId); + return CamRetCode::INVALID_ARGUMENT; + } + + SetCapturing(false); + std::shared_ptr provider = DCameraProvider::GetInstance(); + if (provider == nullptr) { + DHLOGE("Distributed camera provider not init."); + return CamRetCode::DEVICE_ERROR; + } + DCamRetCode ret = provider->StopCapture(dhBase_); + if (ret != SUCCESS) { + DHLOGE("Cancel distributed camera capture failed."); + return MapToExternalRetCode(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); + } + cachedDCaptureInfoList_.clear(); + halCaptureInfoMap_.erase(captureId); + + return CamRetCode::NO_ERROR; +} + +CamRetCode DStreamOperator::ChangeToOfflineStream(const std::vector& streamIds, + OHOS::sptr& callback, OHOS::sptr& offlineOperator) +{ + (void)streamIds; + (void)callback; + offlineOperator = nullptr; + return CamRetCode::METHOD_NOT_SUPPORTED; +} + +DCamRetCode DStreamOperator::InitOutputConfigurations(const std::shared_ptr &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 INVALID_ARGUMENT; + } + + 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)); + } + } + + std::set allFormats; + 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; + } + + 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()); + } + dcSupportedFormatMap_[DCSceneType::PHOTO] = 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::atoi(reso[0].c_str())); + uint32_t height = static_cast(std::atoi(reso[1].c_str())); + 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, std::shared_ptr &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 std::shared_ptr &buffer) +{ + DHLOGI("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 falied, 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)]++; + } + + uint64_t resultTimestamp = GetCurrentLocalTimeStamp(); + bool needReturn = false; + std::shared_ptr result = nullptr; + DCamRetCode ret = dMetadataProcessor_->UpdateResultMetadata(needReturn, result); + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Cannot handle result metadata."); + return ret; + } + if (needReturn) { + resultCallback_(resultTimestamp, result); + } + + 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; + resultCallback_ = resultCbk; + return SUCCESS; +} + +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; +} + +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->encodeType_ == ENCODE_TYPE_JPEG)) { + dstInfo->type_ = DCStreamType::SNAPSHOT_FRAME; + dstInfo->format_ = OHOS_CAMERA_FORMAT_JPEG; + } 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; + for (auto &id : srcCaptureInfo->streamIds_) { + auto iter = dcStreamInfoMap_.find(id); + if (iter != dcStreamInfoMap_.end()) { + srcStreamInfo.push_back(iter->second); + } + } + if (srcStreamInfo.empty()) { + DHLOGE("Input source stream info vector is empty."); + return 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; + } + } + } + cachedDCaptureInfoList_.clear(); + cachedDCaptureInfoList_.push_back(inputCaptureInfo); + if (appendCaptureInfo != nullptr) { + cachedDCaptureInfoList_.push_back(appendCaptureInfo); + } + return SUCCESS; +} + +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); + + std::shared_ptr dcSetting = std::make_shared(); + dcSetting->type_ = DCSettingsType::UPDATE_METADATA; + std::string settingStr = CameraStandard::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 { + captureInfo->format_ = OHOS_CAMERA_FORMAT_JPEG; + } + } +} + +void DStreamOperator::ChooseSuitableResolution(std::vector> &streamInfo, + std::shared_ptr &captureInfo) +{ + 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 { + captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_JPEG; + } +} + +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; + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/src/utils/dcamera.cpp b/camera_hdf/hdi_impl/src/utils/dcamera.cpp new file mode 100644 index 00000000..1a836826 --- /dev/null +++ b/camera_hdf/hdi_impl/src/utils/dcamera.cpp @@ -0,0 +1,89 @@ +/* + * 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.h" +#include + +namespace OHOS { +namespace DistributedHardware { +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)); + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/test/BUILD.gn b/camera_hdf/hdi_impl/test/BUILD.gn new file mode 100644 index 00000000..04c5bca3 --- /dev/null +++ b/camera_hdf/hdi_impl/test/BUILD.gn @@ -0,0 +1,83 @@ +# 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/adapter/uhdf2/uhdf.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_executable("dcamera_hdi_sample") { + install_enable = false + sources = [ + "dcamera_hdi_sample.cpp", + "common.cpp" + ] + cflags = [ "-Wall" ] + cflags_cc = cflags + include_dirs = [ + "${distributedcamera_hdf_path}/interfaces/include", + "${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/client/provider", + "${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}/interfaces/hdi_ipc/server/provider", + "${distributedcamera_hdf_path}/hdi_impl/include/dcamera_device", + "${distributedcamera_hdf_path}/hdi_impl/include/dcamera_host", + "${distributedcamera_hdf_path}/hdi_impl/include/dcamera_provider", + "${distributedcamera_hdf_path}/hdi_impl/include/dstream_operator", + "${distributedcamera_hdf_path}/hdi_impl/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", + "${camera_hdf_path}/camera/interfaces/include", + "${hdf_framework_path}/include/utils", + "${hdf_uhdf_path}/include/hdi", + "${hdf_uhdf_path}/osal/include", + + #producer + "//foundation/graphic/standard/frameworks/surface/include", + "//foundation/graphic/standard/interfaces/kits/surface", + "//foundation/graphic/standard/utils/include", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/multimedia/camera_standard/frameworks/native/metadata/include", + + "${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", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client:distributed_camera_hdf_client", + "${hdf_uhdf_path}/hdi:libhdi", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/graphic/standard/frameworks/surface:surface", + "//drivers/peripheral/display/hal:hdi_display_gralloc", + "//foundation/multimedia/camera_standard/frameworks/native/metadata:metadata", + "${innerkits_path}/native_cpp/camera_source:distributed_camera_source_sdk", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "samgr_standard:samgr_proxy", + ] + + part_name = "distributed_camera" + subsystem_name = "distributedhardware" +} \ No newline at end of file diff --git a/camera_hdf/hdi_impl/test/common.cpp b/camera_hdf/hdi_impl/test/common.cpp new file mode 100644 index 00000000..178d893b --- /dev/null +++ b/camera_hdf/hdi_impl/test/common.cpp @@ -0,0 +1,383 @@ +/* + * 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"); + sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/preview/%s_%lld.yuv", + type, GetCurrentLocalTimeStamp()); + } else { + system("mkdir -p /data/dcamera/capture"); + sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/capture/%s_%lld.jpg", + type, GetCurrentLocalTimeStamp()); + } + 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"); + sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/video/%s_%lld.h265", + type, GetCurrentLocalTimeStamp()); + 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 = CameraStandard::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::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) { + 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_ = intent; + 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); + } else if (intent == 1) { + 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); + } else { + 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); + } + } + + 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_ == true) { + 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_ == false) { + break; + } + std::this_thread::sleep_for(1ms); + } + }); + return producer; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/hdi_impl/test/common.h b/camera_hdf/hdi_impl/test/common.h new file mode 100644 index 00000000..5a247638 --- /dev/null +++ b/camera_hdf/hdi_impl/test/common.h @@ -0,0 +1,178 @@ +/* + * 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 + +#include "camera_metadata_info.h" +#include "display_type.h" +#include "distributed_hardware_log.h" +#include "drivers/peripheral/adapter/camera/interfaces/include/types.h" +#include "foundation/distributedhardware/distributedcamera/camera_hdf/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" + +namespace OHOS { +namespace DistributedHardware { +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(); + + 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; + } +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif diff --git a/camera_hdf/hdi_impl/test/dcamera_hdi_sample.cpp b/camera_hdf/hdi_impl/test/dcamera_hdi_sample.cpp new file mode 100644 index 00000000..5c460db0 --- /dev/null +++ b/camera_hdf/hdi_impl/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; + +const std::string TEST_DEV_ID = "11111111111111111111111111111111"; +const std::string TEST_CAM_ID = "camera_0"; +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/camera_hdf/interfaces/hdi_ipc/client/BUILD.gn b/camera_hdf/interfaces/hdi_ipc/client/BUILD.gn new file mode 100644 index 00000000..7353b562 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/BUILD.gn @@ -0,0 +1,81 @@ +# 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/adapter/uhdf2/uhdf.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_hdf_client") { + include_dirs = [ + "../", + "../../include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include/", + "${fwk_utils_path}/include", + "${fwk_utils_path}/include/log", + "${camera_hdf_path}/camera/interfaces/include", + "${hdf_framework_path}/include/utils", + "${hdf_uhdf_path}/include/hdi", + "${hdf_uhdf_path}/osal/include", + "//drivers/peripheral/base", + + #producer + "//foundation/graphic/standard/frameworks/surface/include", + "//foundation/graphic/standard/interfaces/kits/surface", + "//foundation/graphic/standard/utils/include", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/multimedia/camera_standard/frameworks/native/metadata/include", + ] + + sources = [ + "device/dcamera_device_callback_stub.cpp", + "device/dcamera_device_callback.cpp", + "device/dcamera_device_proxy.cpp", + "host/dcamera_host_callback_stub.cpp", + "host/dcamera_host_callback.cpp", + "host/dcamera_host_proxy.cpp", + "operator/doffline_stream_operator_proxy.cpp", + "operator/dstream_operator_callback_stub.cpp", + "operator/dstream_operator_callback.cpp", + "operator/dstream_operator_proxy.cpp", + "provider/dcamera_provider_callback_stub.cpp", + "provider/dcamera_provider_callback.cpp", + "provider/dcamera_provider_proxy.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${hdf_uhdf_path}/hdi:libhdi", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + "//foundation/graphic/standard/frameworks/surface:surface", + "//drivers/peripheral/display/hal:hdi_display_gralloc", + "//foundation/multimedia/camera_standard/frameworks/native/metadata:metadata", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "distributedhardware" + part_name = "distributed_camera" +} diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.cpp b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.cpp new file mode 100644 index 00000000..935a83ed --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.cpp @@ -0,0 +1,31 @@ +/* + * 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.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DCameraDeviceCallback::OnError(ErrorType type, int32_t errorMsg) +{ + DHLOGW("DCameraDeviceCallback::OnError enter."); +} + +void DCameraDeviceCallback::OnResult(uint64_t timestamp, const std::shared_ptr &result) +{ + DHLOGW("DCameraDeviceCallback::OnResult enter."); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.h b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.h new file mode 100644 index 00000000..ec4081c9 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback.h @@ -0,0 +1,35 @@ +/* + * 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_H +#define DISTRIBUTED_CAMERA_DEVICE_CALLBACK_H + +#include "dcamera_device_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraDeviceCallback : public DCameraDeviceCallbackStub { +public: + DCameraDeviceCallback() = default; + virtual ~DCameraDeviceCallback() = default; + +public: + virtual void OnError(ErrorType type, int32_t errorMsg) override; + virtual void OnResult(uint64_t timestamp, const std::shared_ptr &result) override; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_CALLBACK_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.cpp b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.cpp new file mode 100644 index 00000000..6e86fd0d --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.cpp @@ -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. + */ + +#include "dcamera_device_callback_stub.h" +#include "dcamera_device_callback.h" +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" +#include "metadata_utils.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraDeviceCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + switch (code) { + case CMD_CAMERA_DEVICE_CALLBACK_ON_ERROR: { + if (data.ReadInterfaceToken() != DCameraDeviceCallbackStub::GetDescriptor()) { + DHLOGI("DCameraDeviceCallbackStub::OnError token failed."); + return HDF_FAILURE; + } + + ErrorType type = static_cast(data.ReadUint32()); + int32_t errorMsg = data.ReadInt32(); + DHLOGI("DCameraDeviceCallbackStub::OnError entry."); + OnError(type, errorMsg); + break; + } + case CMD_CAMERA_DEVICE_CALLBACK_ON_RESULT: { + if (data.ReadInterfaceToken() != DCameraDeviceCallbackStub::GetDescriptor()) { + DHLOGI("DCameraDeviceCallbackStub::OnResult token failed."); + return HDF_FAILURE; + } + + uint64_t timestamp = data.ReadUint64(); + std::shared_ptr result = nullptr; + CameraStandard::MetadataUtils::DecodeCameraMetadata(data, result); + DHLOGI("DCameraDeviceCallbackStub::OnResult entry."); + OnResult(timestamp, result); + break; + } + default: { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return 0; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.h b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.h new file mode 100644 index 00000000..50312699 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_callback_stub.h @@ -0,0 +1,36 @@ +/* + * 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_CLIENT_STUB_H +#define DISTRIBUTED_CAMERA_DEVICE_CALLBACK_CLIENT_STUB_H + +#include "icamera_device_callback.h" +#include "iremote_stub.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraDeviceCallbackStub : public IRemoteStub { +public: + virtual ~DCameraDeviceCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_CALLBACK_CLIENT_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.cpp new file mode 100644 index 00000000..badfd01f --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.cpp @@ -0,0 +1,205 @@ +/* + * 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_proxy.h" +#include +#include +#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 { +CamRetCode DCameraDeviceProxy::GetStreamOperator( + const OHOS::sptr &callback, + OHOS::sptr &streamOperator) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool nullFlag = (callback != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write stream operator callback flag failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (nullFlag && !data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Write stream operator object failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_GET_STREAM_OPERATOR, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + bool flag = reply.ReadBool(); + if (flag) { + sptr remoteStreamOperator = reply.ReadRemoteObject(); + streamOperator = OHOS::iface_cast(remoteStreamOperator); + } + return retCode; +} + +CamRetCode DCameraDeviceProxy::UpdateSettings(const std::shared_ptr &settings) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool bRet = CameraStandard::MetadataUtils::EncodeCameraMetadata(settings, data); + if (!bRet) { + DHLOGE("Write update settings metadata failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_UPDATE_SETTINGS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DCameraDeviceProxy::SetResultMode(const ResultCallbackMode &mode) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(mode))) { + DHLOGE("Write result callback mode failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_SET_RESULT_MODE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DCameraDeviceProxy::GetEnabledResults(std::vector &results) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_GET_ENABLED_RESULTS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + if (!reply.ReadInt32Vector(&results)) { + DHLOGE("Read results failed."); + return CamRetCode::INVALID_ARGUMENT; + } + return retCode; +} + +CamRetCode DCameraDeviceProxy::EnableResult(const std::vector &results) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32Vector(results)) { + DHLOGE("Write results failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_ENABLE_RESULT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DCameraDeviceProxy::DisableResult(const std::vector &results) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32Vector(results)) { + DHLOGE("Write results failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_DISABLE_RESULT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +void DCameraDeviceProxy::Close() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraDeviceProxy::GetDescriptor())) { + DHLOGE("Write stream operator descriptor failed."); + return; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_DEVICE_REMOTE_CLOSE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.h b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.h new file mode 100644 index 00000000..985f2c03 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/device/dcamera_device_proxy.h @@ -0,0 +1,53 @@ +/* + * 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_CLIENT_PROXY_H +#define DISTRIBUTED_CAMERA_DEVICE_CLIENT_PROXY_H + +#include "iremote_proxy.h" +#include "icamera_device.h" +#include "istream_operator_callback.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraDeviceProxy : public IRemoteProxy { +public: + explicit DCameraDeviceProxy(const sptr &impl) : IRemoteProxy(impl) {} + virtual ~DCameraDeviceProxy() = default; + + virtual CamRetCode GetStreamOperator(const OHOS::sptr &callback, + OHOS::sptr &streamOperator) override; + virtual CamRetCode UpdateSettings(const std::shared_ptr &settings) override; + virtual CamRetCode SetResultMode(const ResultCallbackMode &mode) override; + virtual CamRetCode GetEnabledResults(std::vector &results) override; + virtual CamRetCode EnableResult(const std::vector &results) override; + virtual CamRetCode DisableResult(const std::vector &results) override; + virtual void Close() override; + +private: + static constexpr int CMD_CAMERA_DEVICE_REMOTE_GET_STREAM_OPERATOR = 0; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_UPDATE_SERTTINGS = 1; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_SET_RESULT_MODE = 2; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_GET_ENABLED_RESULTS = 3; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_ENABLE_RESULT = 4; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_DISABLE_RESULT = 5; + static constexpr int CMD_CAMERA_DEVICE_REMOTE_CLOSE = 6; + + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_CLIENT_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.cpp b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.cpp new file mode 100644 index 00000000..b85c50c6 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.cpp @@ -0,0 +1,36 @@ +/* + * 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.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DCameraHostCallback::OnCameraStatus(const std::string &cameraId, CameraStatus status) +{ + DHLOGW("DCameraHostCallback::OnCameraStatus enter."); +} + +void DCameraHostCallback::OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status) +{ + DHLOGW("DCameraHostCallback::OnFlashlightStatus enter."); +} + +void DCameraHostCallback::OnCameraEvent(const std::string &cameraId, CameraEvent event) +{ + DHLOGW("DCameraHostCallback::OnCameraEvent enter."); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.h b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.h new file mode 100644 index 00000000..5bf37cf6 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback.h @@ -0,0 +1,36 @@ +/* + * 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_H +#define DISTRIBUTED_CAMERA_HOST_CALLBACK_H + +#include "dcamera_host_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraHostCallback : public DCameraHostCallbackStub { +public: + DCameraHostCallback() = default; + virtual ~DCameraHostCallback() = default; + +public: + virtual void OnCameraStatus(const std::string &cameraId, CameraStatus status) override; + virtual void OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status) override; + virtual void OnCameraEvent(const std::string &cameraId, CameraEvent event) override; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_CALLBACK_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.cpp b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.cpp new file mode 100644 index 00000000..36e27e2c --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.cpp @@ -0,0 +1,71 @@ +/* + * 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_stub.h" +#include "dcamera_host_callback.h" +#include "distributed_hardware_log.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraHostCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + switch (code) { + case CMD_CAMERA_HOST_CALLBACK_ON_STATUS: { + DHLOGI("DCameraHostCallbackStub::OnCameraStatus entry."); + if (data.ReadInterfaceToken() != DCameraHostCallbackStub::GetDescriptor()) { + DHLOGI("DCameraDeviceCallbackStub::OnCameraStatus token failed."); + return HDF_FAILURE; + } + + std::string cameraId = data.ReadString(); + CameraStatus status = static_cast(data.ReadInt32()); + OnCameraStatus(cameraId, status); + break; + } + case CMD_CAMERA_HOST_CALLBACK_ON_FLASHLIGHT_STATUS: { + DHLOGI("DCameraHostCallbackStub::OnFlashlightStatus entry."); + if (data.ReadInterfaceToken() != DCameraHostCallbackStub::GetDescriptor()) { + DHLOGI("DCameraDeviceCallbackStub::OnFlashlightStatus token failed."); + return HDF_FAILURE; + } + + std::string cameraId = data.ReadString(); + FlashlightStatus status = static_cast(data.ReadInt32()); + OnFlashlightStatus(cameraId, status); + break; + } + case CMD_CAMERA_HOST_CALLBACK_ON_CAMERA_EVENT: { + DHLOGI("DCameraHostCallbackStub::OnCameraEvent entry."); + if (data.ReadInterfaceToken() != DCameraHostCallbackStub::GetDescriptor()) { + DHLOGI("DCameraDeviceCallbackStub::OnCameraEvent token failed."); + return HDF_FAILURE; + } + + std::string cameraId = data.ReadString(); + CameraEvent event = static_cast(data.ReadInt32()); + OnCameraEvent(cameraId, event); + break; + } + default: { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return 0; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.h b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.h new file mode 100644 index 00000000..232a3f31 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_callback_stub.h @@ -0,0 +1,36 @@ +/* + * 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_CLIENT_STUB_H +#define DISTRIBUTED_CAMERA_HOST_CALLBACK_CLIENT_STUB_H + +#include "icamera_host_callback.h" +#include "iremote_stub.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraHostCallbackStub : public IRemoteStub { +public: + virtual ~DCameraHostCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_CALLBACK_CLIENT_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.cpp new file mode 100644 index 00000000..9565f39e --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.cpp @@ -0,0 +1,206 @@ +/* + * 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_proxy.h" +#include +#include +#include "distributed_hardware_log.h" +#include "icamera_device.h" +#include "icamera_device_callback.h" +#include "icamera_host_callback.h" +#include "ipc_data_utils.h" +#include "metadata_utils.h" + +OHOS::sptr OHOS::Camera::ICameraHost::Get(const char *serviceName) +{ + using namespace OHOS::HDI::ServiceManager::V1_0; + OHOS::sptr serviceMgr = IServiceManager::Get(); + if (serviceMgr == nullptr) { + HDF_LOGE("%{public}s: IServiceManager failed!", __func__); + return nullptr; + } + + OHOS::sptr remote = serviceMgr->GetService(serviceName); + if (remote == nullptr) { + HDF_LOGE("%{public}s: get %{public}s failed!", __func__, serviceName); + return nullptr; + } + + return iface_cast(remote); +} + +namespace OHOS { +namespace DistributedHardware { +CamRetCode DCameraHostProxy::SetCallback(const OHOS::sptr &callback) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostProxy::GetDescriptor())) { + DHLOGE("Write remote token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool callbackFlag = (callback != nullptr); + if (!data.WriteBool(callbackFlag)) { + DHLOGE("Set callback flag failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (callbackFlag && !data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Write remote callback object failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_SET_CALLBACK, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DCameraHostProxy::GetCameraIds(std::vector &cameraIds) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostProxy::GetDescriptor())) { + DHLOGE("Write remote token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_GET_CAMERAID, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + if (retCode == CamRetCode::NO_ERROR && !reply.ReadStringVector(&cameraIds)) { + DHLOGE("Read camera ids failed."); + return CamRetCode::INVALID_ARGUMENT; + } + return retCode; +} + +CamRetCode DCameraHostProxy::GetCameraAbility(const std::string &cameraId, + std::shared_ptr &ability) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostProxy::GetDescriptor())) { + DHLOGE("Write remote token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_GET_CAMERA_ABILITY, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + if (retCode == CamRetCode::NO_ERROR) { + CameraStandard::MetadataUtils::DecodeCameraMetadata(reply, ability); + } + return retCode; +} + +CamRetCode DCameraHostProxy::OpenCamera(const std::string &cameraId, + const OHOS::sptr &callback, OHOS::sptr &pDevice) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostProxy::GetDescriptor())) { + DHLOGE("Write remote token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool callbackFlag = (callback != nullptr); + if (!data.WriteBool(callbackFlag)) { + DHLOGE("Write camera callback flag failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (callbackFlag && !data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Write camera device callback failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_OPEN_CAMERA, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + bool flag = reply.ReadBool(); + if (flag) { + sptr remoteCameraDevice = reply.ReadRemoteObject(); + if (remoteCameraDevice == nullptr) { + DHLOGE("Read remote camera device is null."); + } + pDevice = OHOS::iface_cast(remoteCameraDevice); + } + return retCode; +} + +CamRetCode DCameraHostProxy::SetFlashlight(const std::string &cameraId, bool &isEnable) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraHostProxy::GetDescriptor())) { + DHLOGE("Write remote token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(cameraId)) { + DHLOGE("Write cameraId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteBool(isEnable)) { + DHLOGE("Write isEnable failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_CAMERA_HOST_REMOTE_SET_FLASH_LIGHT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.h b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.h new file mode 100644 index 00000000..e851ae0f --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/host/dcamera_host_proxy.h @@ -0,0 +1,50 @@ +/* + * 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_CLIENT_PROXY_H +#define DISTRIBUTED_CAMERA_HOST_CLIENT_PROXY_H + +#include "iremote_proxy.h" +#include "icamera_host.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DCameraHostProxy : public IRemoteProxy { +public: + explicit DCameraHostProxy(const sptr &impl) : IRemoteProxy(impl) {} + virtual ~DCameraHostProxy() {} + + virtual CamRetCode SetCallback(const OHOS::sptr &callback) override; + virtual CamRetCode GetCameraIds(std::vector &cameraIds) override; + virtual CamRetCode GetCameraAbility(const std::string &cameraId, + std::shared_ptr &ability) override; + virtual CamRetCode OpenCamera(const std::string &cameraId, + const OHOS::sptr &callback, + OHOS::sptr &pDevice) override; + virtual CamRetCode SetFlashlight(const std::string &cameraId, bool &isEnable) override; + +private: + static constexpr int CMD_CAMERA_HOST_REMOTE_SET_CALLBACK = 0; + static constexpr int CMD_CAMERA_HOST_REMOTE_GET_CAMERAID = 1; + static constexpr int CMD_CAMERA_HOST_REMOTE_GET_CAMERA_ABILITY = 2; + static constexpr int CMD_CAMERA_HOST_REMOTE_OPEN_CAMERA = 3; + static constexpr int CMD_CAMERA_HOST_REMOTE_SET_FLASH_LIGHT = 4; + + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_CLIENT_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.cpp new file mode 100644 index 00000000..5500c5d0 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.cpp @@ -0,0 +1,91 @@ +/* + * 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_proxy.h" +#include +#include +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +CamRetCode DOfflineStreamOperatorProxy::CancelCapture(int captureId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DOfflineStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(captureId))) { + DHLOGE("Write captureId object failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_OFFLINE_STREAM_OPERATOR_CANCEL_CAPTURE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DOfflineStreamOperatorProxy::ReleaseStreams(const std::vector &streamIds) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DOfflineStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + std::vector pxyStreamIds = streamIds; + if (!data.WriteInt32Vector(pxyStreamIds)) { + DHLOGE("Write streamIds object failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_OFFLINE_STREAM_OPERATOR_RELEASE_STREAMS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DOfflineStreamOperatorProxy::Release() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DOfflineStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_OFFLINE_STREAM_OPERATOR_RELEASE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.h b/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.h new file mode 100644 index 00000000..6984eb8d --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/doffline_stream_operator_proxy.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_OFFLINE_STREAM_OPERATOR_CLIENT_PROXY_H +#define DISTRIBUTED_OFFLINE_STREAM_OPERATOR_CLIENT_PROXY_H + +#include "iremote_proxy.h" +#include "ioffline_stream_operator.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DOfflineStreamOperatorProxy : public IRemoteProxy { +public: + explicit DOfflineStreamOperatorProxy(const sptr& impl) + : IRemoteProxy(impl) {} + virtual ~DOfflineStreamOperatorProxy() {} + + virtual CamRetCode CancelCapture(int captureId) override; + virtual CamRetCode ReleaseStreams(const std::vector& streamIds) override; + virtual CamRetCode Release() override; + +private: + static constexpr int CMD_OFFLINE_STREAM_OPERATOR_CANCEL_CAPTURE = 0; + static constexpr int CMD_OFFLINE_STREAM_OPERATOR_RELEASE_STREAMS = 1; + static constexpr int CMD_OFFLINE_STREAM_OPERATOR_RELEASE = 2; + + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_OFFLINE_STREAM_OPERATOR_CLIENT_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.cpp new file mode 100644 index 00000000..5bc0d758 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.cpp @@ -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. + */ + +#include "dstream_operator_callback.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DStreamOperatorCallback::OnCaptureStarted(int32_t captureId, const std::vector &streamId) +{ + DHLOGW("DStreamOperatorCallback::OnCaptureStarted enter."); +} + +void DStreamOperatorCallback::OnCaptureEnded(int32_t captureId, + const std::vector> &info) +{ + DHLOGW("DStreamOperatorCallback::OnCaptureEnded enter."); +} + +void DStreamOperatorCallback::OnCaptureError(int32_t captureId, + const std::vector> &info) +{ + DHLOGW("DStreamOperatorCallback::OnCaptureError enter."); +} + +void DStreamOperatorCallback::OnFrameShutter(int32_t captureId, const std::vector &streamId, + uint64_t timestamp) +{ + DHLOGW("DStreamOperatorCallback::OnFrameShutter enter."); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.h b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.h new file mode 100644 index 00000000..7c4145a2 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback.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_STREAM_OPERATOR_CALLBACK_H +#define DISTRIBUTED_STREAM_OPERATOR_CALLBACK_H + +#include "dstream_operator_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DStreamOperatorCallback : public DStreamOperatorCallbackStub { +public: + DStreamOperatorCallback() = default; + virtual ~DStreamOperatorCallback() = default; + +public: + 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; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_CALLBACK_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.cpp new file mode 100644 index 00000000..3c22c28b --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.cpp @@ -0,0 +1,148 @@ +/* + * 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_stub.h" +#include +#include +#include "distributed_hardware_log.h" +#include "dstream_operator_callback.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DStreamOperatorCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_STARTED: { + ret = OnCaptureStartedStub(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_ENDED: { + ret = OnCaptureEndedStub(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CALLBACK_ON_CAPTURE_ERROR: { + ret = OnCaptureErrorStub(data, reply, option); + break; + } + case CMD_STREAM_OPERATOR_CALLBACK_ON_FRAME_SHUTTER: { + ret = OnFrameShutterStub(data, reply, option); + break; + } + default: { + ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return ret; +} + +int32_t DStreamOperatorCallbackStub::OnCaptureStartedStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorCallbackStub::OnCaptureStartedStub entry."); + if (data.ReadInterfaceToken() != DStreamOperatorCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("OnCaptureStarted read streamIds failed."); + return HDF_FAILURE; + } + OnCaptureStarted(captureId, streamIds); + return HDF_SUCCESS; +} + +int32_t DStreamOperatorCallbackStub::OnCaptureEndedStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorCallbackStub::OnCaptureEndedStub entry."); + if (data.ReadInterfaceToken() != DStreamOperatorCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + int32_t count = data.ReadInt32(); + std::vector> info; + for (int32_t i = 0; i < count; i++) { + const CaptureEndedInfo *pInfo = reinterpret_cast( + data.ReadBuffer(sizeof(CaptureEndedInfo))); + if (pInfo == nullptr) { + DHLOGE("Read ended info failed."); + return HDF_FAILURE; + } + std::shared_ptr captureEndedInfo = std::make_shared(); + captureEndedInfo->streamId_ = pInfo->streamId_; + captureEndedInfo->frameCount_ = pInfo->frameCount_; + info.push_back(captureEndedInfo); + } + OnCaptureEnded(captureId, info); + return HDF_SUCCESS; +} + +int32_t DStreamOperatorCallbackStub::OnCaptureErrorStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorCallbackStub::OnCaptureErrorStub entry."); + if (data.ReadInterfaceToken() != DStreamOperatorCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + int32_t count = data.ReadInt32(); + std::vector> info; + for (int32_t i = 0; i < count; i++) { + const CaptureErrorInfo *pInfo = reinterpret_cast( + data.ReadBuffer(sizeof(CaptureErrorInfo))); + if (pInfo == nullptr) { + DHLOGE("Read error info failed."); + return HDF_FAILURE; + } + std::shared_ptr captureErrorInfo = std::make_shared(); + captureErrorInfo->streamId_ = pInfo->streamId_; + captureErrorInfo->error_ = pInfo->error_; + info.push_back(captureErrorInfo); + } + + OnCaptureError(captureId, info); + return HDF_SUCCESS; +} + +int32_t DStreamOperatorCallbackStub::OnFrameShutterStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DStreamOperatorCallbackStub::OnFrameShutterStub entry."); + if (data.ReadInterfaceToken() != DStreamOperatorCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + int32_t captureId = data.ReadInt32(); + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + uint64_t timestamp = data.ReadUint64(); + OnFrameShutter(captureId, streamIds, timestamp); + return HDF_SUCCESS; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.h b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.h new file mode 100644 index 00000000..095132be --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_callback_stub.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_STREAM_OPERATOR_CALLBACK_CLIENT_STUB_H +#define DISTRIBUTED_STREAM_OPERATOR_CALLBACK_CLIENT_STUB_H + +#include "iremote_stub.h" +#include "istream_operator_callback.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DStreamOperatorCallbackStub : public IRemoteStub { +public: + virtual ~DStreamOperatorCallbackStub() = default; + +private: + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; + int32_t OnCaptureStartedStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t OnCaptureEndedStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t OnCaptureErrorStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t OnFrameShutterStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_CALLBACK_CLIENT_STUB_H diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp new file mode 100644 index 00000000..5915a125 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp @@ -0,0 +1,384 @@ +/* + * 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_proxy.h" +#include +#include +#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 { +CamRetCode DStreamOperatorProxy::IsStreamsSupported(OperationMode mode, + const std::shared_ptr &modeSetting, + const std::vector> &info, + StreamSupportType &type) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(mode)) { + DHLOGE("Write operation mode failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool nullFlag = (modeSetting != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write mode null flag failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (nullFlag && !CameraStandard::MetadataUtils::EncodeCameraMetadata(modeSetting, data)) { + DHLOGE("Write metadata failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + nullFlag = info.size(); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write streaminfo null flag failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + size_t count = info.size(); + if (!data.WriteInt32(static_cast(count))) { + HDF_LOGE("%s: write info count failed", __func__); + return CamRetCode::INVALID_ARGUMENT; + } + + for (size_t i = 0; i < count; i++) { + std::shared_ptr streamInfo = info.at(i); + bool ret = IpcDataUtils::EncodeStreamInfo(streamInfo, data); + if (!ret) { + HDF_LOGE("%s: write streamInfo failed. index = %zu", __func__, i); + return CamRetCode::INVALID_ARGUMENT; + } + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_IS_STREAMS_SUPPORTED, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + type = static_cast(reply.ReadInt32()); + return retCode; +} + +CamRetCode DStreamOperatorProxy::CreateStreams(const std::vector> &streamInfos) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + size_t count = streamInfos.size(); + if (!data.WriteInt32(static_cast(count))) { + DHLOGE("Write streamInfos count failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool bRet = true; + for (size_t i = 0; i < count; i++) { + std::shared_ptr streamInfo = streamInfos.at(i); + bRet = IpcDataUtils::EncodeStreamInfo(streamInfo, data); + if (!bRet) { + DHLOGE("Write streamInfo failed. index = %d", i); + return CamRetCode::INVALID_ARGUMENT; + } + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CREATE_STREAMS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::ReleaseStreams(const std::vector &streamIds) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + std::vector pxyStreamIds = streamIds; + if (!data.WriteInt32Vector(pxyStreamIds)) { + DHLOGE("Write streamIds failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_RELEASE_STREAMS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::CommitStreams(OperationMode mode, + const std::shared_ptr &modeSetting) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(mode)) { + DHLOGE("Write operation mode failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool bRet = CameraStandard::MetadataUtils::EncodeCameraMetadata(modeSetting, data); + if (!bRet) { + DHLOGE("Write metadata failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_COMMIT_STREAMS, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::GetStreamAttributes(std::vector> &attributes) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_GET_STREAM_ATTRIBUTES, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t retCode = reply.ReadInt32(); + int32_t count = reply.ReadInt32(); + for (int i = 0; i < count; i++) { + const uint8_t *buffer = data.ReadBuffer(sizeof(StreamAttribute)); + std::shared_ptr attribute = std::shared_ptr( + reinterpret_cast( + const_cast(buffer))); + attributes.push_back(attribute); + } + return static_cast(retCode); +} + +CamRetCode DStreamOperatorProxy::AttachBufferQueue(int streamId, const OHOS::sptr &producer) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (producer == nullptr) { + DHLOGE("Input producer is NULL."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(streamId))) { + DHLOGE("Write streamId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteRemoteObject(producer->AsObject())) { + DHLOGE("Write buffer producer failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_ATTACH_BUFFER_QUEUE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::DetachBufferQueue(int streamId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(streamId))) { + DHLOGE("Write streamId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_DETACH_BUFFER_QUEUE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::Capture(int captureId, + const std::shared_ptr &info, bool isStreaming) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (info == nullptr) { + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(captureId))) { + DHLOGE("Write captureId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + std::vector pxyStreamIds = info->streamIds_; + if (!data.WriteInt32Vector(pxyStreamIds)) { + DHLOGE("Write streamIds failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + bool bRet = CameraStandard::MetadataUtils::EncodeCameraMetadata(info->captureSetting_, data); + if (!bRet) { + DHLOGE("Write metadata failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteBool(info->enableShutterCallback_)) { + DHLOGE("Write enableShutterCallback_ failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteBool(isStreaming)) { + DHLOGE("Write isStreaming failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CAPTURE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::CancelCapture(int captureId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(captureId))) { + DHLOGE("Write captureId failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest( + CMD_STREAM_OPERATOR_CANCEL_CAPTURE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +CamRetCode DStreamOperatorProxy::ChangeToOfflineStream( + const std::vector &streamIds, + OHOS::sptr &callback, + OHOS::sptr &offlineOperator) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DStreamOperatorProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (callback == nullptr) { + return CamRetCode::INVALID_ARGUMENT; + } + + std::vector pxyStreamIds = streamIds; + if (!data.WriteInt32Vector(pxyStreamIds)) { + DHLOGE("Write streamIds failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Write offline stream operator callback failed."); + return CamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_STREAM_OPERATOR_CHANGE_TO_OFFLINE_STREAM, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code = %d.", ret); + return CamRetCode::INVALID_ARGUMENT; + } + + CamRetCode retCode = static_cast(reply.ReadInt32()); + sptr remoteObj = reply.ReadRemoteObject(); + offlineOperator = OHOS::iface_cast(remoteObj); + return retCode; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.h b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.h new file mode 100644 index 00000000..340b6cac --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.h @@ -0,0 +1,65 @@ +/* + * 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_CLIENT_PROXY_H +#define DISTRIBUTED_STREAM_OPERATOR_CLIENT_PROXY_H + +#include "iremote_proxy.h" +#include "istream_operator.h" + +namespace OHOS { +namespace DistributedHardware { +using namespace OHOS::Camera; +class DStreamOperatorProxy : public IRemoteProxy { +public: + explicit DStreamOperatorProxy(const sptr &impl) : IRemoteProxy(impl) {} + virtual ~DStreamOperatorProxy() = default; + + virtual CamRetCode IsStreamsSupported(OperationMode mode, + const std::shared_ptr &modeSetting, + const std::vector> &info, + StreamSupportType &type) override; + virtual CamRetCode CreateStreams(const std::vector> &streamInfos) override; + virtual CamRetCode ReleaseStreams(const std::vector &streamIds) override; + virtual CamRetCode CommitStreams(OperationMode mode, + const std::shared_ptr &modeSetting) override; + virtual CamRetCode GetStreamAttributes(std::vector> &attributes) override; + virtual CamRetCode AttachBufferQueue(int streamId, + const OHOS::sptr &producer) override; + virtual CamRetCode DetachBufferQueue(int streamId) override; + virtual CamRetCode Capture(int captureId, + const std::shared_ptr &info, bool isStreaming) override; + virtual CamRetCode CancelCapture(int captureId) override; + virtual CamRetCode ChangeToOfflineStream(const std::vector &streamIds, + OHOS::sptr &callback, + OHOS::sptr &offlineOperator) override; + +private: + static constexpr int CMD_STREAM_OPERATOR_IS_STREAMS_SUPPORTED = 0; + static constexpr int CMD_STREAM_OPERATOR_CREATE_STREAMS = 1; + static constexpr int CMD_STREAM_OPERATOR_RELEASE_STREAMS = 2; + static constexpr int CMD_STREAM_OPERATOR_COMMIT_STREAMS = 3; + static constexpr int CMD_STREAM_OPERATOR_GET_STREAM_ATTRIBUTES = 4; + static constexpr int CMD_STREAM_OPERATOR_ATTACH_BUFFER_QUEUE = 5; + static constexpr int CMD_STREAM_OPERATOR_DETACH_BUFFER_QUEUE = 6; + static constexpr int CMD_STREAM_OPERATOR_CAPTURE = 7; + static constexpr int CMD_STREAM_OPERATOR_CANCEL_CAPTURE = 8; + static constexpr int CMD_STREAM_OPERATOR_CHANGE_TO_OFFLINE_STREAM = 9; + + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_CLIENT_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.cpp b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.cpp new file mode 100644 index 00000000..9d7683da --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.cpp @@ -0,0 +1,67 @@ +/* + * 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_callback.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCamRetCode DCameraProviderCallback::OpenSession(const std::shared_ptr &dhBase) +{ + DHLOGW("DCameraProviderCallback::OpenSession enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::CloseSession(const std::shared_ptr &dhBase) +{ + DHLOGW("DCameraProviderCallback::CloseSession enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos) +{ + DHLOGW("DCameraProviderCallback::ConfigureStreams enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::ReleaseStreams(const std::shared_ptr &dhBase, + const std::vector &streamIds) +{ + DHLOGW("DCameraProviderCallback::ReleaseStreams enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos) +{ + DHLOGW("DCameraProviderCallback::StartCapture enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::StopCapture(const std::shared_ptr &dhBase) +{ + DHLOGW("DCameraProviderCallback::StopCapture enter."); + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderCallback::UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings) +{ + DHLOGW("DCameraProviderCallback::UpdateSettings enter."); + return DCamRetCode::SUCCESS; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.h b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.h new file mode 100644 index 00000000..d2fc22cb --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback.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 DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H +#define DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H + +#include "dcamera_provider_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraProviderCallback : public DCameraProviderCallbackStub { +public: + DCameraProviderCallback() = default; + virtual ~DCameraProviderCallback() = default; + +public: + virtual DCamRetCode OpenSession(const std::shared_ptr &dhBase) override; + virtual DCamRetCode CloseSession(const std::shared_ptr &dhBase) override; + virtual DCamRetCode ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos) override; + virtual DCamRetCode ReleaseStreams(const std::shared_ptr &dhBase, + const std::vector &streamIds) override; + virtual DCamRetCode StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos) override; + virtual DCamRetCode StopCapture(const std::shared_ptr &dhBase) override; + virtual DCamRetCode UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings) override; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.cpp b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.cpp new file mode 100644 index 00000000..f8145fe1 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.cpp @@ -0,0 +1,255 @@ +/* + * 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_callback_stub.h" +#include +#include "dcamera_provider_callback.h" +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraProviderCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_OPEN_SESSION: { + ret = DCProviderOpenSessionStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CLOSE_SESSION: { + ret = DCProviderCloseSessionStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CONFIGURE_STREAMS: { + ret = DCProviderConfigureStreamsStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_RELEASE_STREAMS: { + ret = DCProviderReleaseStreamsStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_START_CAPTURE: { + ret = DCProviderStartCaptureStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_STOP_CAPTURE: { + ret = DCProviderStopCaptureStub(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_UPDATE_SETTINGS: { + ret = DCProviderUpdateSettingsStub(data, reply, option); + break; + } + default: { + ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return ret; +} + +int32_t DCameraProviderCallbackStub::DCProviderOpenSessionStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + DCamRetCode ret = OpenSession(dhBase); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderCloseSessionStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + DCamRetCode ret = CloseSession(dhBase); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderConfigureStreamsStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + int32_t count = data.ReadInt32(); + std::vector> streamInfos; + for (int32_t i = 0; i < count; i++) { + const DCStreamInfo *pInfo = reinterpret_cast( + data.ReadBuffer(sizeof(DCStreamInfo))); + if (pInfo == nullptr) { + DHLOGE("Read distributed camera stream info failed."); + return HDF_FAILURE; + } + std::shared_ptr streamInfo = std::make_shared(); + streamInfo->streamId_ = pInfo->streamId_; + streamInfo->width_ = pInfo->width_; + streamInfo->height_ = pInfo->height_; + streamInfo->stride_ = pInfo->stride_; + streamInfo->format_ = pInfo->format_; + streamInfo->dataspace_ = pInfo->dataspace_; + streamInfo->encodeType_ = pInfo->encodeType_; + streamInfo->type_ = pInfo->type_; + streamInfos.push_back(streamInfo); + } + + DCamRetCode ret = ConfigureStreams(dhBase, streamInfos); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderReleaseStreamsStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + + DCamRetCode ret = ReleaseStreams(dhBase, streamIds); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderStartCaptureStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + int32_t count = data.ReadInt32(); + std::vector> captureInfos; + for (int32_t i = 0; i < count; i++) { + std::shared_ptr captureInfo = std::make_shared(); + std::vector streamIds; + if (!data.ReadInt32Vector(&streamIds)) { + DHLOGE("Read streamIds failed."); + return HDF_FAILURE; + } + captureInfo->streamIds_ = streamIds; + captureInfo->width_ = static_cast(data.ReadInt32()); + captureInfo->height_ = static_cast(data.ReadInt32()); + captureInfo->stride_ = static_cast(data.ReadInt32()); + captureInfo->format_ = static_cast(data.ReadInt32()); + captureInfo->dataspace_ = static_cast(data.ReadInt32()); + captureInfo->isCapture_ = data.ReadBool(); + captureInfo->encodeType_ = static_cast(data.ReadInt32()); + captureInfo->type_ = static_cast(data.ReadInt32()); + + int32_t settingsSize = data.ReadInt32(); + std::vector> capSettings; + for (int32_t k = 0; k < settingsSize; k++) { + std::shared_ptr metadata = std::make_shared(); + IpcDataUtils::DecodeDCameraSettings(data, metadata); + capSettings.push_back(metadata); + } + captureInfo->captureSettings_ = capSettings; + captureInfos.push_back(captureInfo); + } + + DCamRetCode ret = StartCapture(dhBase, captureInfos); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderStopCaptureStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + DCamRetCode ret = StopCapture(dhBase); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderCallbackStub::DCProviderUpdateSettingsStub(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != DCameraProviderCallbackStub::GetDescriptor()) { + DHLOGE("OnCaptureStarted invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + int32_t count = data.ReadInt32(); + std::vector> settings; + for (int32_t i = 0; i < count; i++) { + std::shared_ptr metadata = std::make_shared(); + IpcDataUtils::DecodeDCameraSettings(data, metadata); + settings.push_back(metadata); + } + + DCamRetCode ret = UpdateSettings(dhBase, settings); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.h b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_stub.h new file mode 100644 index 00000000..48f2fa51 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_callback_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_PROVIDER_CALLBACK_CLIENT_STUB_H +#define DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CLIENT_STUB_H + +#include "idistributed_camera_provider_callback.h" +#include "iremote_stub.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraProviderCallbackStub : public IRemoteStub { +public: + virtual ~DCameraProviderCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; + +private: + int32_t DCProviderOpenSessionStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderCloseSessionStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderConfigureStreamsStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderReleaseStreamsStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderStartCaptureStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderStopCaptureStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DCProviderUpdateSettingsStub(MessageParcel &data, MessageParcel &reply, MessageOption &option); +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CLIENT_STUB_H diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.cpp new file mode 100644 index 00000000..6b67de6a --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.cpp @@ -0,0 +1,315 @@ +/* + * 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_proxy.h" +#include +#include +#include +#include +#include +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" +#include "iservmgr_hdi.h" + +namespace OHOS { +namespace DistributedHardware { +const std::string DC_PROVIDER_HDI_SERVER_NAME = "distributed_camera_provider_service"; + +sptr IDCameraProvider::Get() +{ + using namespace OHOS::HDI::ServiceManager::V1_0; + OHOS::sptr serviceMgr = IServiceManager::Get(); + if (serviceMgr == nullptr) { + DHLOGE("Get IServiceManager failed."); + return nullptr; + } + + OHOS::sptr remote = serviceMgr->GetService(DC_PROVIDER_HDI_SERVER_NAME.c_str()); + if (remote == nullptr) { + DHLOGE("GetService failed! serviceName = %s", DC_PROVIDER_HDI_SERVER_NAME.c_str()); + return nullptr; + } + + return iface_cast(remote); +} + +DCamRetCode DCameraProviderProxy::EnableDCameraDevice(const std::shared_ptr &dhBase, + const std::string &abilityInfo, const sptr &callback) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_) || !data.WriteString(abilityInfo)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + bool nullFlag = (callback != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write distributed camera provider callback null flag failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (nullFlag && !data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Set callback write remote obj failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_ENABLE_DEVICE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d", ret); + return DCamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderProxy::DisableDCameraDevice(const std::shared_ptr &dhBase) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_DISABLE_DEVICE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return DCamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderProxy::AcquireBuffer(const std::shared_ptr &dhBase, int streamId, + std::shared_ptr &buffer) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteInt32(static_cast(streamId))) { + DHLOGE("Write streamId failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_ACQUIRE_BUFFER, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return DCamRetCode::INVALID_ARGUMENT; + } + int32_t retCode = reply.ReadInt32(); + if (retCode != DCamRetCode::SUCCESS) { + DHLOGE("Acquire avaliable buffer from stub failed."); + return static_cast(retCode); + } + + buffer = std::make_shared(); + buffer->index_ = reply.ReadInt32(); + buffer->size_ = reply.ReadInt32(); + + BufferHandle* retHandle = ReadBufferHandle(reply); + if (retHandle == nullptr) { + DHLOGE("Read retrun buffer handle failed."); + FreeBufferHandle(buffer->bufferHandle_); + return DCamRetCode::INVALID_ARGUMENT; + } + retHandle->virAddr = DCameraMemoryMap(retHandle); + buffer->bufferHandle_ = retHandle; + + return DCamRetCode::SUCCESS; +} + +DCamRetCode DCameraProviderProxy::ShutterBuffer(const std::shared_ptr &dhBase, int streamId, + const std::shared_ptr &buffer) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + DCamRetCode ret = DCamRetCode::SUCCESS; + do { + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + ret = DCamRetCode::INVALID_ARGUMENT; + break; + } + + if (!data.WriteInt32(static_cast(streamId))) { + DHLOGE("Write streamId failed."); + ret = DCamRetCode::INVALID_ARGUMENT; + break; + } + + bool nullFlag = (buffer != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write distributed camera buffer null flag failed."); + ret = DCamRetCode::INVALID_ARGUMENT; + break; + } + + if (!data.WriteInt32(buffer->index_) || !data.WriteInt32(buffer->size_)) { + DHLOGE("write buffer index and size parameter failed."); + ret = DCamRetCode::INVALID_ARGUMENT; + break; + } + + int32_t retCode = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_SHUTTER_BUFFER, data, reply, option); + if (retCode != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", retCode); + ret = DCamRetCode::FAILED; + } + } while (0); + + DCameraMemoryUnmap(buffer->bufferHandle_); + if (ret != DCamRetCode::SUCCESS) { + return ret; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderProxy::OnSettingsResult(const std::shared_ptr &dhBase, + const std::shared_ptr &result) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + bool nullFlag = (result != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write distributed camera settings null flag failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (nullFlag && !IpcDataUtils::EncodeDCameraSettings(result, data)) { + DHLOGE("Write distributed camera settings failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_ON_SETTINGS_RESULT, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return DCamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderProxy::Notify(const std::shared_ptr &dhBase, + const std::shared_ptr &event) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + bool nullFlag = (event != nullptr); + if (!data.WriteBool(nullFlag)) { + DHLOGE("Write distributed camera hdf event null flag failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + if (nullFlag && !IpcDataUtils::EncodeDCameraHDFEvent(event, data)) { + DHLOGE("Write distributed camera hdf event failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_NOTIFY, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return DCamRetCode::INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +void* DCameraProviderProxy::DCameraMemoryMap(const BufferHandle *buffer) +{ + if (buffer == nullptr) { + DHLOGE("mmap the buffer handle is NULL"); + return nullptr; + } + if (buffer->reserveFds <= 0) { + DHLOGE("invalid file descriptor num : %d", buffer->reserveFds); + return nullptr; + } + void* virAddr = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer->reserve[0], 0); + if (virAddr == MAP_FAILED) { + DHLOGE("mmap failed errno %s, fd : %d", strerror(errno), buffer->fd); + return nullptr; + } + return virAddr; +} + +void DCameraProviderProxy::DCameraMemoryUnmap(BufferHandle *buffer) +{ + if (buffer == nullptr) { + DHLOGE("unmmap the buffer handle is NULL"); + return; + } + if (buffer->virAddr == nullptr) { + DHLOGE("virAddr is NULL , has not map the buffer"); + return; + } + int ret = munmap(buffer->virAddr, buffer->size); + if (ret != 0) { + DHLOGE("munmap failed err: %s", strerror(errno)); + } + buffer->virAddr = nullptr; + FreeBufferHandle(buffer); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.h b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.h new file mode 100644 index 00000000..5c41f334 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/client/provider/dcamera_provider_proxy.h @@ -0,0 +1,59 @@ +/* + * 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_CLIENT_PROXY_H +#define DISTRIBUTED_CAMERA_PROVIDER_CLIENT_PROXY_H + +#include "iremote_proxy.h" +#include "buffer_handle.h" +#include "idistributed_camera_provider.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraProviderProxy : public IRemoteProxy { +public: + explicit DCameraProviderProxy(const sptr &impl) : IRemoteProxy(impl) {} + virtual ~DCameraProviderProxy() = default; + + virtual DCamRetCode EnableDCameraDevice(const std::shared_ptr &dhBase, + const std::string &abilityInfo, + const sptr &callback) override; + virtual DCamRetCode DisableDCameraDevice(const std::shared_ptr &dhBase) override; + virtual DCamRetCode AcquireBuffer(const std::shared_ptr &dhBase, int streamId, + std::shared_ptr &buffer) override; + virtual DCamRetCode ShutterBuffer(const std::shared_ptr &dhBase, int streamId, + const std::shared_ptr &buffer) override; + virtual DCamRetCode OnSettingsResult(const std::shared_ptr &dhBase, + const std::shared_ptr &result) override; + virtual DCamRetCode Notify(const std::shared_ptr &dhBase, + const std::shared_ptr &event) override; + +private: + static void* DCameraMemoryMap(const BufferHandle *buffer); + static void DCameraMemoryUnmap(BufferHandle *buffer); + +private: + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_ENABLE_DEVICE = 0; + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_DISABLE_DEVICE = 1; + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_ACQUIRE_BUFFER = 2; + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_SHUTTER_BUFFER = 3; + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_ON_SETTINGS_RESULT = 4; + static constexpr int CMD_DISTRIBUTED_CAMERA_PROVIDER_NOTIFY = 5; + + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_CLIENT_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/config/host/BUILD.gn b/camera_hdf/interfaces/hdi_ipc/config/host/BUILD.gn new file mode 100644 index 00000000..77652f8a --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/config/host/BUILD.gn @@ -0,0 +1,73 @@ +# 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/adapter/uhdf2/uhdf.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_host_config") { + include_dirs = [ + "${distributedcamera_hdf_path}/interfaces/include", + "${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_impl/include/dcamera_host", + "${distributedcamera_hdf_path}/hdi_impl/include/dcamera_device", + "${distributedcamera_hdf_path}/hdi_impl/include/dstream_operator", + "${distributedcamera_hdf_path}/hdi_impl/include/utils", + "${common_path}/include/constants", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${camera_hdf_path}/camera/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", + + #producer + "//foundation/graphic/standard/frameworks/surface/include", + "//foundation/graphic/standard/interfaces/kits/surface", + "//foundation/graphic/standard/utils/include", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/multimedia/camera_standard/frameworks/native/metadata/include", + ] + + sources = [ + "dcamera_host_config.cpp" + ] + + deps = [ + "//utils/native/base:utils", + "${distributedcamera_hdf_path}/hdi_impl:distributed_camera_hdf", + "//foundation/graphic/standard/frameworks/surface:surface", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + install_images = [ chipset_base_dir ] + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} diff --git a/camera_hdf/interfaces/hdi_ipc/config/host/dcamera_host_config.cpp b/camera_hdf/interfaces/hdi_ipc/config/host/dcamera_host_config.cpp new file mode 100644 index 00000000..da30b84d --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/config/host/dcamera_host_config.cpp @@ -0,0 +1,92 @@ +/* + * 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 + +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); + return DCHostServiceOnRemoteRequest(service->instance, cmdId, data, reply); +} + +int HdfDCameraHostDriverInit(struct HdfDeviceObject *deviceObject) +{ + return HDF_SUCCESS; +} + +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; +} + +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); +} + +struct HdfDriverEntry g_dCameraHostDriverEntry = { + .moduleVersion = 1, + .moduleName = "distributed_camera_service", + .Bind = HdfDCameraHostDriverBind, + .Init = HdfDCameraHostDriverInit, + .Release = HdfDCameraHostDriverRelease, +}; + +#ifndef __cplusplus +extern "C" { +#endif + +HDF_INIT(g_dCameraHostDriverEntry); + +#ifndef __cplusplus +} +#endif \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/config/provider/BUILD.gn b/camera_hdf/interfaces/hdi_ipc/config/provider/BUILD.gn new file mode 100644 index 00000000..8c2f45ee --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/config/provider/BUILD.gn @@ -0,0 +1,68 @@ +# 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/adapter/uhdf2/uhdf.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_provider_config") { + include_dirs = [ + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/server/provider", + "${distributedcamera_hdf_path}/interfaces/include", + "${distributedcamera_hdf_path}/hdi_impl/include/dcamera_provider", + "${distributedcamera_hdf_path}/hdi_impl/include/utils", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${camera_hdf_path}/camera/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", + + #producer + "//foundation/graphic/standard/frameworks/surface/include", + "//foundation/graphic/standard/interfaces/kits/surface", + "//foundation/graphic/standard/utils/include", + "//foundation/communication/ipc/ipc/native/src/core/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/multimedia/camera_standard/frameworks/native/metadata/include", + ] + + sources = [ + "dcamera_provider_config.cpp" + ] + + deps = [ + "//utils/native/base:utils", + "${distributedcamera_hdf_path}/hdi_impl:distributed_camera_hdf", + "//foundation/graphic/standard/frameworks/surface:surface", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerahdf\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + install_images = [ chipset_base_dir ] + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} diff --git a/camera_hdf/interfaces/hdi_ipc/config/provider/dcamera_provider_config.cpp b/camera_hdf/interfaces/hdi_ipc/config/provider/dcamera_provider_config.cpp new file mode 100644 index 00000000..75933736 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/config/provider/dcamera_provider_config.cpp @@ -0,0 +1,93 @@ +/* + * 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_stub.h" +#include +#include +#include +#include + +struct HdfDCameraProviderService { + struct IDeviceIoService ioservice; + void *instance; +}; + +static int32_t DCameraProviderServiceDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + HdfDCameraProviderService *service = CONTAINER_OF(client->device->service, HdfDCameraProviderService, ioservice); + return DCProviderServiceOnRemoteRequest(service->instance, cmdId, data, reply); +} + +int HdfDCameraProviderConfigInit(struct HdfDeviceObject *deviceObject) +{ + return HDF_SUCCESS; +} + +int HdfDCameraProviderConfigBind(HdfDeviceObject *deviceObject) +{ + HDF_LOGI("HdfDCameraProviderConfigBind enter!"); + if (deviceObject == nullptr) { + HDF_LOGE("HdfDCameraProviderConfigBind: HdfDeviceObject is NULL !"); + return HDF_FAILURE; + } + + HdfDCameraProviderService *service = + reinterpret_cast(malloc(sizeof(HdfDCameraProviderService))); + if (service == nullptr) { + HDF_LOGE("HdfDCameraProviderConfigBind malloc HdfDCameraProviderService failed!"); + return HDF_FAILURE; + } + + service->ioservice.Dispatch = DCameraProviderServiceDispatch; + service->ioservice.Open = nullptr; + service->ioservice.Release = nullptr; + service->instance = DCameraProviderStubInstance(); + + deviceObject->service = &service->ioservice; + return HDF_SUCCESS; +} + +void HdfDCameraProviderConfigRelease(HdfDeviceObject *deviceObject) +{ + if (deviceObject == nullptr || deviceObject->service == nullptr) { + HDF_LOGE("HdfDCameraProviderConfigRelease: deviceObject or deviceObject->service is NULL!"); + return; + } + HdfDCameraProviderService *service = CONTAINER_OF(deviceObject->service, HdfDCameraProviderService, ioservice); + if (service == nullptr) { + HDF_LOGE("HdfDCameraProviderConfigRelease: service is NULL!"); + return; + } + free(service); +} + +struct HdfDriverEntry g_dCameraProviderConfigEntry = { + .moduleVersion = 1, + .moduleName = "distributed_camera_provider_service", + .Bind = HdfDCameraProviderConfigBind, + .Init = HdfDCameraProviderConfigInit, + .Release = HdfDCameraProviderConfigRelease, +}; + +#ifndef __cplusplus +extern "C" { +#endif + +HDF_INIT(g_dCameraProviderConfigEntry); + +#ifndef __cplusplus +} +#endif diff --git a/camera_hdf/interfaces/hdi_ipc/ipc_data_utils.h b/camera_hdf/interfaces/hdi_ipc/ipc_data_utils.h new file mode 100644 index 00000000..b57c44e6 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/ipc_data_utils.h @@ -0,0 +1,102 @@ +/* + * 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 +#include + +namespace OHOS { +namespace DistributedHardware { +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 = (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(); + } +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // HDI_IPC_DATA_UTILS_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp new file mode 100644 index 00000000..c1d7c658 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.cpp @@ -0,0 +1,85 @@ +/* + * 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 "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 (!CameraStandard::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; + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_callback_proxy.h new file mode 100644 index 00000000..764feb4a --- /dev/null +++ b/camera_hdf/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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_CALLBACK_PROXY_H diff --git a/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp new file mode 100644 index 00000000..81be1631 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.cpp @@ -0,0 +1,232 @@ +/* + * 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 "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 INVALID_ARGUMENT; + } + + 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; + CameraStandard::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; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.h b/camera_hdf/interfaces/hdi_ipc/server/device/dcamera_device_stub.h new file mode 100644 index 00000000..7e8cf2ed --- /dev/null +++ b/camera_hdf/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); +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_DEVICE_SERVER_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp new file mode 100644 index 00000000..eed9b4f4 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.cpp @@ -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. + */ + +#include "dcamera_host_callback_proxy.h" +#include +#include +#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); + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_callback_proxy.h new file mode 100644 index 00000000..07801f35 --- /dev/null +++ b/camera_hdf/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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_HOST_CALLBACK_PROXY_H diff --git a/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp new file mode 100644 index 00000000..d561e83d --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp @@ -0,0 +1,260 @@ +/* + * 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 "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 = CameraStandard::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; +} +} // end namespace DistributedHardware +} // end 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); + stubObj = nullptr; +} + +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/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.h b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.h new file mode 100644 index 00000000..4939a8c3 --- /dev/null +++ b/camera_hdf/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; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +void* DCameraHostStubInstance(); + +void DestroyDCameraHostStub(void* obj); + +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/camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp new file mode 100644 index 00000000..d378f32b --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.cpp @@ -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. + */ + +#include "doffline_stream_operator_stub.h" +#include +#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("%s: write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h b/camera_hdf/interfaces/hdi_ipc/server/operator/doffline_stream_operator_stub.h new file mode 100644 index 00000000..53d1a8e1 --- /dev/null +++ b/camera_hdf/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); +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_OFFLINE_STREAM_OPERATOR_SERVER_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp new file mode 100644 index 00000000..9e206856 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.cpp @@ -0,0 +1,159 @@ +/* + * 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 "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 = %d 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 = %d 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); + } +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_callback_proxy.h new file mode 100644 index 00000000..15d270cd --- /dev/null +++ b/camera_hdf/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_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_CALLBACK_PROXY_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp new file mode 100644 index 00000000..b8dc46ad --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.cpp @@ -0,0 +1,352 @@ +/* + * 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 "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) { + CameraStandard::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; + CameraStandard::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; + CameraStandard::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("%s: 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; +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h b/camera_hdf/interfaces/hdi_ipc/server/operator/dstream_operator_stub.h new file mode 100644 index 00000000..654c2ce1 --- /dev/null +++ b/camera_hdf/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); +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_STREAM_OPERATOR_SERVER_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.cpp new file mode 100644 index 00000000..8a9acc63 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.cpp @@ -0,0 +1,267 @@ +/* + * 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_callback_proxy.h" +#include +#include +#include "distributed_hardware_log.h" +#include "ipc_data_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DCamRetCode DCameraProviderCallbackProxy::OpenSession(const std::shared_ptr &dhBase) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_OPEN_SESSION, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::CloseSession(const std::shared_ptr &dhBase) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CLOSE_SESSION, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + size_t size = streamInfos.size(); + if (!data.WriteInt32(static_cast(size))) { + DHLOGE("Write stream info size failed."); + return INVALID_ARGUMENT; + } + for (size_t i = 0; i < size; i++) { + auto streamInfo = streamInfos.at(i); + bool bRet = data.WriteBuffer((void *)streamInfo.get(), sizeof(DCStreamInfo)); + if (!bRet) { + DHLOGE("Write stream info index = %d failed.", i); + return INVALID_ARGUMENT; + } + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CONFIGURE_STREAMS, + data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::ReleaseStreams(const std::shared_ptr &dhBase, + const std::vector &streamIds) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + std::vector pxyStreamIds = streamIds; + if (!data.WriteInt32Vector(pxyStreamIds)) { + DHLOGE("Write streamId failed."); + return INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_RELEASE_STREAMS, + data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + size_t size = captureInfos.size(); + if (!data.WriteInt32(static_cast(size))) { + DHLOGE("Write distributed camera capture info size failed."); + return INVALID_ARGUMENT; + } + for (size_t i = 0; i < size; i++) { + auto captureInfo = captureInfos.at(i); + if (!data.WriteInt32Vector(captureInfo->streamIds_)) { + DHLOGE("Write streamIds vector failed."); + return INVALID_ARGUMENT; + } + data.WriteInt32(static_cast(captureInfo->width_)); + data.WriteInt32(static_cast(captureInfo->height_)); + data.WriteInt32(static_cast(captureInfo->stride_)); + data.WriteInt32(static_cast(captureInfo->format_)); + data.WriteInt32(static_cast(captureInfo->dataspace_)); + data.WriteBool(static_cast(captureInfo->isCapture_)); + data.WriteInt32(static_cast(captureInfo->encodeType_)); + data.WriteInt32(static_cast(captureInfo->type_)); + + std::vector> capSettings = captureInfo->captureSettings_; + size_t settingsSize = capSettings.size(); + if (!data.WriteInt32(static_cast(settingsSize))) { + DHLOGE("Write distributed camera capture settings size failed."); + return INVALID_ARGUMENT; + } + for (size_t k = 0; k < settingsSize; k++) { + bool bRet = IpcDataUtils::EncodeDCameraSettings(capSettings.at(k), data); + if (!bRet) { + DHLOGE("Write distributed camera capture settings failed."); + return INVALID_ARGUMENT; + } + } + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_START_CAPTURE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::StopCapture(const std::shared_ptr &dhBase) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_STOP_CAPTURE, data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} + +DCamRetCode DCameraProviderCallbackProxy::UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(DCameraProviderCallbackProxy::GetDescriptor())) { + DHLOGE("Write token failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + if (!data.WriteString(dhBase->deviceId_) || !data.WriteString(dhBase->dhId_)) { + DHLOGE("Write distributed camera base info or ability info failed."); + return DCamRetCode::INVALID_ARGUMENT; + } + + size_t size = settings.size(); + if (!data.WriteInt32(static_cast(size))) { + DHLOGE("Write distributed camera settings size failed."); + return INVALID_ARGUMENT; + } + for (size_t i = 0; i < size; i++) { + bool bRet = IpcDataUtils::EncodeDCameraSettings(settings.at(i), data); + if (!bRet) { + DHLOGE("Write distributed camera settings index = %d failed.", i); + return INVALID_ARGUMENT; + } + } + + int32_t ret = Remote()->SendRequest(CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_UPDATE_SETTINGS, + data, reply, option); + if (ret != HDF_SUCCESS) { + DHLOGE("SendRequest failed, error code is %d.", ret); + return INVALID_ARGUMENT; + } + return static_cast(reply.ReadInt32()); +} +} // end namespace DistributedHardware +} // end namespace OHOS \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.h b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.h new file mode 100644 index 00000000..4930eed6 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_callback_proxy.h @@ -0,0 +1,48 @@ +/* + * 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_CALLBACK_PROXY_H +#define DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_PROXY_H + +#include "iremote_proxy.h" +#include "idistributed_camera_provider_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraProviderCallbackProxy : public IRemoteProxy { +public: + explicit DCameraProviderCallbackProxy(const sptr &impl) + : IRemoteProxy(impl) {} + + virtual ~DCameraProviderCallbackProxy() = default; + + virtual DCamRetCode OpenSession(const std::shared_ptr &dhBase); + virtual DCamRetCode CloseSession(const std::shared_ptr &dhBase); + virtual DCamRetCode ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos); + virtual DCamRetCode ReleaseStreams(const std::shared_ptr &dhBase, + const std::vector &streamIds); + virtual DCamRetCode StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos); + virtual DCamRetCode StopCapture(const std::shared_ptr &dhBase); + virtual DCamRetCode UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings); + +private: + static inline BrokerDelegator delegator_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS +#endif // DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_PROXY_H diff --git a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp new file mode 100644 index 00000000..9bb5d24b --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp @@ -0,0 +1,296 @@ +/* + * 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_stub.h" +#include +#include +#include +#include "distributed_hardware_log.h" +#include "idistributed_camera_provider.h" +#include "ipc_data_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraProviderStub::DCameraProviderStub() +{ +} + +int32_t DCameraProviderStub::Init() +{ + dcameraProvider_ = DCameraProvider::GetInstance(); + if (dcameraProvider_ == nullptr) { + DHLOGE("Get distributed camera provider instance failed."); + return HDF_FAILURE; + } + DHLOGI("Get distributed camera provider instance success."); + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubEnableDCameraDevice(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + const std::string abilitySet = data.ReadString(); + if (abilitySet.empty()) { + DHLOGE("Read input param is empty."); + return HDF_ERR_INVALID_PARAM; + } + + sptr dcProviderCallback = nullptr; + bool flag = data.ReadBool(); + if (flag) { + sptr remoteObj = data.ReadRemoteObject(); + if (remoteObj == nullptr) { + DHLOGE("Read distributed camera provider callback failed."); + return HDF_FAILURE; + } + dcProviderCallback = OHOS::iface_cast(remoteObj); + } + + DCamRetCode ret = dcameraProvider_->EnableDCameraDevice(dhBase, abilitySet, dcProviderCallback); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubDisableDCameraDevice(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + DCamRetCode ret = dcameraProvider_->DisableDCameraDevice(dhBase); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubAcquireBuffer(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + int32_t streamId = data.ReadInt32(); + + std::shared_ptr dCamerabuffer = std::make_shared(); + DCamRetCode ret = dcameraProvider_->AcquireBuffer(dhBase, streamId, dCamerabuffer); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + if (ret != DCamRetCode::SUCCESS) { + DHLOGE("Acquire avaliable buffer failed."); + return HDF_SUCCESS; + } + if (!reply.WriteInt32(dCamerabuffer->index_) || !reply.WriteInt32(dCamerabuffer->size_)) { + DHLOGE("write buffer index and size parameter failed."); + return HDF_FAILURE; + } + + BufferHandle* bufferHandle = dCamerabuffer->bufferHandle_; + if (!WriteBufferHandle(reply, *bufferHandle)) { + DHLOGE("Write buffer handle failed."); + FreeBufferHandle(bufferHandle); + return HDF_ERR_INVALID_PARAM; + } + + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubShutterBuffer(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + int32_t streamId = data.ReadInt32(); + + std::shared_ptr buffer = nullptr; + bool flag = data.ReadBool(); + if (flag) { + buffer = std::make_shared(); + buffer->index_ = data.ReadInt32(); + buffer->size_ = data.ReadInt32(); + buffer->bufferHandle_ = nullptr; + } + DCamRetCode ret = dcameraProvider_->ShutterBuffer(dhBase, streamId, buffer); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubOnSettingsResult(MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + std::shared_ptr dCameraSettings = std::make_shared(); + bool flag = data.ReadBool(); + if (flag) { + IpcDataUtils::DecodeDCameraSettings(data, dCameraSettings); + if (dCameraSettings == nullptr) { + DHLOGE("Read distributed camera settings failed."); + return HDF_FAILURE; + } + } + DCamRetCode ret = dcameraProvider_->OnSettingsResult(dhBase, dCameraSettings); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::DCProviderStubNotify(MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + if (data.ReadInterfaceToken() != DCameraProviderStub::GetDescriptor()) { + DHLOGE("invalid token."); + return HDF_FAILURE; + } + + std::shared_ptr dhBase = std::make_shared(data.ReadString(), data.ReadString()); + + std::shared_ptr dCameraEvent = std::make_shared(); + bool flag = data.ReadBool(); + if (flag) { + IpcDataUtils::DecodeDCameraHDFEvent(data, dCameraEvent); + if (dCameraEvent == nullptr) { + DHLOGE("Read distributed camera hdf event failed."); + return HDF_FAILURE; + } + } + DCamRetCode ret = dcameraProvider_->Notify(dhBase, dCameraEvent); + if (!reply.WriteInt32(static_cast(ret))) { + DHLOGE("Write retcode failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t DCameraProviderStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option) +{ + int32_t ret = HDF_SUCCESS; + switch (code) { + case CMD_DISTRIBUTED_CAMERA_PROVIDER_ENABLE_DEVICE: { + ret = DCProviderStubEnableDCameraDevice(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_DISABLE_DEVICE: { + ret = DCProviderStubDisableDCameraDevice(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_ACQUIRE_BUFFER: { + ret = DCProviderStubAcquireBuffer(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_SHUTTER_BUFFER: { + ret = DCProviderStubShutterBuffer(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_ON_SETTINGS_RESULT: { + ret = DCProviderStubOnSettingsResult(data, reply, option); + break; + } + case CMD_DISTRIBUTED_CAMERA_PROVIDER_NOTIFY: { + ret = DCProviderStubNotify(data, reply, option); + break; + } + default: { + DHLOGE("Unknown remote request code=%d.", code); + } + } + return ret; +} +} // end namespace DistributedHardware +} // end namespace OHOS + +void *DCameraProviderStubInstance() +{ + OHOS::DistributedHardware::DCameraProviderStub *stub = + new (std::nothrow) OHOS::DistributedHardware::DCameraProviderStub(); + if (stub == nullptr) { + HDF_LOGE("%{public}s: camera provider 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 DestroyDCameraProviderStub(void *stubObj) +{ + delete reinterpret_cast(stubObj); + stubObj = nullptr; +} + +int32_t DCProviderServiceOnRemoteRequest(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::DCameraProviderStub *providerStub = + 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 providerStub->OnRemoteRequest(cmdId, *dataParcel, *replyParcel, option); +} \ No newline at end of file diff --git a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.h b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.h new file mode 100644 index 00000000..e5170a16 --- /dev/null +++ b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.h @@ -0,0 +1,60 @@ +/* + * 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_SERVER_STUB_H +#define DISTRIBUTED_CAMERA_PROVIDER_SERVER_STUB_H + +#include +#include +#include +#include "dcamera_provider.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraProviderStub { +public: + DCameraProviderStub(); + virtual ~DCameraProviderStub() {} + int32_t Init(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option); + +private: + int32_t DCProviderStubEnableDCameraDevice(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCProviderStubDisableDCameraDevice(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCProviderStubAcquireBuffer(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCProviderStubShutterBuffer(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCProviderStubOnSettingsResult(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t DCProviderStubNotify(MessageParcel& data, MessageParcel& reply, MessageOption& option); + static inline const std::u16string metaDescriptor_ = u"HDI.DCamera.V1_0.Provider"; + static inline const std::u16string &GetDescriptor() + { + return metaDescriptor_; + } + +private: + std::shared_ptr dcameraProvider_ = nullptr; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +void* DCameraProviderStubInstance(); + +void DestroyDCameraProviderStub(void* obj); + +int32_t DCProviderServiceOnRemoteRequest(void* stub, int cmdId, struct HdfSBuf* data, struct HdfSBuf* reply); + +#endif // DISTRIBUTED_CAMERA_PROVIDER_SERVER_STUB_H \ No newline at end of file diff --git a/camera_hdf/interfaces/include/idistributed_camera_provider.h b/camera_hdf/interfaces/include/idistributed_camera_provider.h new file mode 100644 index 00000000..e9365b5b --- /dev/null +++ b/camera_hdf/interfaces/include/idistributed_camera_provider.h @@ -0,0 +1,164 @@ +/* + * 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. + */ + +/** + * @file idistributed_camera_provider.h + * + * @brief Transfer interfaces call between distributed camera SA service and distributed camera HDF service, + * and provide Hardware Driver Interfaces (HDIs) for the upper layer. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef HDI_DISTRIBUTED_CAMERA_PROVIDER_H +#define HDI_DISTRIBUTED_CAMERA_PROVIDER_H + +#include "idistributed_camera_provider_callback.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + CMD_DISTRIBUTED_CAMERA_PROVIDER_ENABLE_DEVICE = 0, + CMD_DISTRIBUTED_CAMERA_PROVIDER_DISABLE_DEVICE, + CMD_DISTRIBUTED_CAMERA_PROVIDER_ACQUIRE_BUFFER, + CMD_DISTRIBUTED_CAMERA_PROVIDER_SHUTTER_BUFFER, + CMD_DISTRIBUTED_CAMERA_PROVIDER_ON_SETTINGS_RESULT, + CMD_DISTRIBUTED_CAMERA_PROVIDER_NOTIFY, +}; + +class IDCameraProvider : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"HDI.DCamera.V1_0.Provider"); + virtual ~IDCameraProvider() {} + +public: + /** + * @brief Obtains an IDCameraProvider instance. + * This function provides the entry to the distributed camera SA service. + * You must use this function to obtain an IDCameraProvider instance before performing other operations. + * + * @return Returns the IDCameraProvider instance if the operation is successful, + * returns nullptr otherwise. + * + * @since 1.0 + * @version 1.0 + */ + static sptr Get(); + + /** + * @brief Enable distributed camera device and set callback. For details about the callbacks, + * see {@link IDCameraProviderCallback}. + * + * @param dhBase [in] Distributed hardware device base info. + * + * @param abilityInfo [in] The static capability info of the distributed camera device to be enabled. + * + * @param callback [in] Indicates the callbacks to set. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode EnableDCameraDevice(const std::shared_ptr &dhBase, + const std::string &abilityInfo, const sptr &callback) = 0; + + /** + * @brief Disable distributed camera device. + * + * @param dhBase [in] Distributed hardware device base info + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode DisableDCameraDevice(const std::shared_ptr &dhBase) = 0; + + /** + * @brief Acquire a frame buffer from the procedure handle which attached to the streamId. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param streamId [in] Indicates the ID of the stream to which the procedure handle is to be attached. + * + * @param buffer [out] A frame buffer + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode AcquireBuffer(const std::shared_ptr &dhBase, int streamId, + std::shared_ptr &buffer) = 0; + + /** + * @brief Notify distributed camera HDF service when a frame buffer has been filled. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param streamId [in] Indicates the ID of the stream to which the frame buffer is to be attached. + * + * @param buffer [out] output frame buffer + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode ShutterBuffer(const std::shared_ptr &dhBase, int streamId, + const std::shared_ptr &buffer) = 0; + + /** + * @brief Called to report metadata related to the distributed camera device. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param result Indicates the metadata reported. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode OnSettingsResult(const std::shared_ptr &dhBase, + const std::shared_ptr &result) = 0; + + /** + * @brief Called to notify some events from distributed camera SA service to distributed camera HDF service. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param event [in] Detail event contents + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode Notify(const std::shared_ptr &dhBase, + const std::shared_ptr &event) = 0; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // HDI_DISTRIBUTED_CAMERA_PROVIDER_H \ No newline at end of file diff --git a/camera_hdf/interfaces/include/idistributed_camera_provider_callback.h b/camera_hdf/interfaces/include/idistributed_camera_provider_callback.h new file mode 100644 index 00000000..a6ec4d76 --- /dev/null +++ b/camera_hdf/interfaces/include/idistributed_camera_provider_callback.h @@ -0,0 +1,161 @@ +/* + * 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. + */ + +/** + * @file idistributed_camera_provider_callback.h + * + * @brief Declares callbacks for distributed camera SA service. The caller needs to implement the callbacks. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef HDI_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H +#define HDI_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H + +#include +#include +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +enum { + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_OPEN_SESSION = 0, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CLOSE_SESSION, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_CONFIGURE_STREAMS, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_RELEASE_STREAMS, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_START_CAPTURE, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_STOP_CAPTURE, + CMD_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_UPDATE_SETTINGS, +}; + +class IDCameraProviderCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"HDI.DCamera.V1_0.ProviderCallback"); + virtual ~IDCameraProviderCallback() {} + +public: + /** + * @brief Create the transmission channel between the source device and the sink device. + * Open and initialize the distributed camera session. + * + * @param dhBase [in] Distributed hardware device base info + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode OpenSession(const std::shared_ptr &dhBase) = 0; + + /** + * @brief Close the distributed camera session, and destroy the transmission channel between + * the source device and the sink device. + * + * @param dhBase [in] Distributed hardware device base info + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode CloseSession(const std::shared_ptr &dhBase) = 0; + + /** + * @brief Configures streams. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param streamInfos [in] Indicates the list of stream information, which is defined by {@link DCStreamInfo}. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode ConfigureStreams(const std::shared_ptr &dhBase, + const std::vector> &streamInfos) = 0; + + /** + * @brief Releases streams. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param streamIds [IN] Indicates the IDs of the streams to release. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode ReleaseStreams(const std::shared_ptr &dhBase, const std::vector &streamIds) = 0; + + /** + * @brief Start capture images. + * This function must be called after {@link ConfigStreams}. + * There are two image capture modes: continuous capture and single capture. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param captureInfos [in] Indicates the capture request configuration information. + * For details, see {@link DCCaptureInfo}. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode StartCapture(const std::shared_ptr &dhBase, + const std::vector> &captureInfos) = 0; + + /** + * @brief Stop capture images. + * + * @param dhBase [in] Distributed hardware device base info + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode StopCapture(const std::shared_ptr &dhBase) = 0; + + /** + * @brief Updates distributed camera device control parameters. + * + * @param dhBase [in] Distributed hardware device base info + * + * @param settings [in] Indicates the camera parameters, including the sensor frame rate and 3A parameters. + * For details about the settings, see {@link DCameraSettings}. + * + * @return Returns NO_ERROR if the operation is successful, + * returns an error code defined in {@link DCamRetCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ + virtual DCamRetCode UpdateSettings(const std::shared_ptr &dhBase, + const std::vector> &settings) = 0; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // HDI_DISTRIBUTED_CAMERA_PROVIDER_CALLBACK_H \ No newline at end of file diff --git a/camera_hdf/interfaces/include/types.h b/camera_hdf/interfaces/include/types.h new file mode 100644 index 00000000..d49e2d95 --- /dev/null +++ b/camera_hdf/interfaces/include/types.h @@ -0,0 +1,307 @@ +/* + * 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. + */ + +/** + * @file types.h + * + * @brief Declares data types used by the Hardware Driver Interfaces (HDIs) of this module. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef DISTRIBUTED_CAMERA_PROVIDER_TYPES_H +#define DISTRIBUTED_CAMERA_PROVIDER_TYPES_H + +#include +#include +#include "buffer_handle.h" + +namespace OHOS { +namespace DistributedHardware { +/** + * @brief Enumerates distributed camera metadata updating types. + */ +using DCSettingsType = enum _DCSettingsType : int32_t { + /** + * Set the whole package metadata. + */ + UPDATE_METADATA = 0, + /** + * Enable metadata. + */ + ENABLE_METADATA = 1, + /** + * Disable metadata. + */ + DISABLE_METADATA = 2, + /** + * Metadata result. + */ + METADATA_RESULT = 3, + /** + * Set flash light. + */ + SET_FLASH_LIGHT = 4, + /** + * Set fps range. + */ + FPS_RANGE = 5 +}; + +/** + * @brief Enumerates return values of the HDIs. + */ +using DCamRetCode = enum _DCamRetCode : int32_t { + /** + * Successful call. + */ + SUCCESS = 0, + /** + * The camera device is busy. + */ + CAMERA_BUSY = 1, + /** + * Invalid parameters. + */ + INVALID_ARGUMENT = 2, + /** + * Unsupported function. + */ + METHOD_NOT_SUPPORTED = 3, + /** + * The camera device is offlined. + */ + CAMERA_OFFLINE = 4, + /** + * The number of distributed camera devices enabled exceeds the limit. + */ + EXCEED_MAX_NUMBER = 5, + /** + * The device is not initialized. + */ + DEVICE_NOT_INIT = 6, + /** + * Failed call. + */ + FAILED = -1, +}; + + /** + * @brief Enumerates encoding types of stream data. + */ +using DCEncodeType = enum _DCEncodeType : int32_t { + /** + * Unspecified + */ + ENCODE_TYPE_NULL = 0, + + /** + * H.264 + */ + ENCODE_TYPE_H264 = 1, + + /** + * H.265 + */ + ENCODE_TYPE_H265 = 2, + + /** + * JPEG + */ + ENCODE_TYPE_JPEG = 3, +}; + +/** + * @brief Enumerates distributed camera inner stream types. + */ +using DCStreamType = enum _DCStreamType : int32_t { + /** + * Continuous capture stream. For example preview streams, video streams. + */ + CONTINUOUS_FRAME = 0, + /** + * Single capture stream. For example photographing streams. + */ + SNAPSHOT_FRAME = 1 +}; + +/** + * @brief Distributed hardware device base info. + */ +using DHBase = struct _DHBase { + /** + * The device id. + */ + std::string deviceId_; + /** + * The distributed hardware id. + */ + std::string dhId_; + + _DHBase() : deviceId_(""), dhId_("") {} + + _DHBase(const std::string &deviceId, const std::string &dhId) : deviceId_(deviceId), dhId_(dhId) {} + + bool operator ==(const _DHBase& others) const + { + return this->deviceId_ == others.deviceId_ && this->dhId_ == others.dhId_; + } + + bool operator < (const _DHBase& others) const + { + return (this->deviceId_ + this->dhId_) < (others.deviceId_ + others.dhId_); + } +}; + +/** + * @brief The control settings of the distributed camera device. + */ +using DCameraSettings = struct _DCameraSettings { + /** + * Settings type. + */ + DCSettingsType type_; + /** + * Settings value. Serialized from bool, array, structure, etc. + */ + std::string value_; +}; + +/** + * @brief Defines the inner stream information of the distributed camera, + * which is used to pass configuration parameters during stream creation. + */ +using DCStreamInfo = struct _DCStreamInfo { + /** + * Stream ID, which uniquely identifies a stream on a camera device. + */ + int streamId_; + /** + * Image width. + */ + int width_; + /** + * Image height. + */ + int height_; + /** + * Image stride. + */ + int stride_; + /** + * Image format. + */ + int format_; + /** + * Image color space. + */ + int dataspace_; + /** + * Encoding type. + */ + DCEncodeType encodeType_; + /** + * Stream type. + */ + DCStreamType type_; +}; + +/** + * @brief Defines the information about a inner capture request of the distributed camera. + */ +using DCCaptureInfo = struct _DCCaptureInfo { + /** + * IDs of captured streams. + */ + std::vector streamIds_; + /** + * Image width. + */ + int width_; + /** + * Image height. + */ + int height_; + /** + * Image stride. + */ + int stride_; + /** + * Image format. + */ + int format_; + /** + * Image color space. + */ + int dataspace_; + /** + * Capture Info + */ + bool isCapture_; + /** + * Encoding type. + */ + DCEncodeType encodeType_; + /** + * Stream type. + */ + DCStreamType type_; + /** + * Stream settings. + */ + std::vector> captureSettings_; +}; + +/** + * @brief Defines the inner buffer of the distributed camera, + * which is used to acquire buffer during procesing capture requests. + */ +using DCameraBuffer = struct _DCameraBuffer { + /** + * Buffer index. + */ + int32_t index_; + /** + * Buffer size. + */ + uint32_t size_; + /** + * Buffer handle. + */ + BufferHandle* bufferHandle_; +}; + +/** + * @brief Notification event of the distributed camera. + */ +using DCameraHDFEvent = struct _DCameraHDFEvent { + /** + * Event type. + */ + int32_t type_; + /** + * Event result. + */ + int32_t result_; + /** + * Extended content (optional). + */ + std::string content_; +}; +} // end namespace DistributedHardware +} // end namespace OHOS + +#endif // DISTRIBUTED_CAMERA_PROVIDER_TYPES_H \ No newline at end of file diff --git a/common/BUILD.gn b/common/BUILD.gn new file mode 100644 index 00000000..b8bb86a6 --- /dev/null +++ b/common/BUILD.gn @@ -0,0 +1,56 @@ +# 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("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_utils") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include/", + "${fwk_utils_path}/include", + "${fwk_utils_path}/include/log", + ] + + include_dirs += [ + "include/constants", + "include/utils", + ] + + sources = [ + "src/utils/data_buffer.cpp", + "src/utils/dcamera_utils_tools.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${fwk_utils_path}:distributedhardwareutils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedcamerautils\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} diff --git a/common/include/constants/distributed_camera_constants.h b/common/include/constants/distributed_camera_constants.h new file mode 100644 index 00000000..bc122510 --- /dev/null +++ b/common/include/constants/distributed_camera_constants.h @@ -0,0 +1,117 @@ +/* + * 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_DISTRIBUTED_CAMERA_CONSTANTS_H +#define OHOS_DISTRIBUTED_CAMERA_CONSTANTS_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_SRV_STATE_NOT_START, + DCAMERA_SRV_STATE_RUNNING +} DCameraServiceState; + +typedef enum { + DCAMERA_AUTHORIZATION_DEFAULT = 0, + DCAMERA_AUTHORIZATION_AGREE = 1, + DCAMERA_AUTHORIZATION_REJECT = 2, + DCAMERA_AUTHORIZATION_TIMEOUT = 3, +} AuthorizationState; + +typedef enum { + DCAMERA_SAME_ACCOUNT = 0, + DCAMERA_DIFF_ACCOUNT = 1, + DCAMERA_NO_ACCOUNT = 2, +} AccessControlType; + +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, +} DCameraEventResult; + +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; + +const uint32_t DCAMERA_MAX_NUM = 1; +const uint32_t DCAMERA_PRODUCER_ONE_MINUTE_MS = 1000; +const uint32_t DCAMERA_PRODUCER_FPS_DEFAULT = 30; +const uint32_t DCAMERA_MAX_RECV_DATA_LEN = 104857600; +const uint32_t DISTRIBUTED_HARDWARE_CAMERA_SOURCE_SA_ID = 4803; +const uint32_t DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID = 4804; +const std::string DCAMERA_PKG_NAME = "DBinderBus_" + std::to_string(getpid()); +const std::string SNAP_SHOT_SESSION_FLAG = "dataSnapshot"; +const std::string CONTINUE_SESSION_FLAG = "dataContinue"; + +const std::string DISTRIBUTED_HARDWARE_ID_KEY = "dhID"; +const std::string CAMERA_ID_PREFIX = "Camera_"; +const std::string CAMERA_PROTOCOL_VERSION_KEY = "ProtocolVer"; +const std::string CAMERA_PROTOCOL_VERSION_VALUE = "1.0"; +const std::string CAMERA_POSITION_KEY = "Position"; +const std::string CAMERA_POSITION_BACK = "BACK"; +const std::string CAMERA_POSITION_FRONT = "FRONT"; +const std::string CAMERA_POSITION_UNSPECIFIED = "UNSPECIFIED"; +const std::string CAMERA_METADATA_KEY = "MetaData"; +const std::string CAMERA_CODEC_TYPE_KEY = "CodecType"; +const std::string CAMERA_FORMAT_KEY = "OutputFormat"; +const std::string CAMERA_FORMAT_PREVIEW = "Preview"; +const std::string CAMERA_FORMAT_VIDEO = "Video"; +const std::string CAMERA_FORMAT_PHOTO = "Photo"; +const std::string CAMERA_RESOLUTION_KEY = "Resolution"; +const std::string CAMERA_SURFACE_FORMAT = "CAMERA_SURFACE_FORMAT"; + +const int32_t RESOLUTION_MAX_WIDTH_SNAPSHOT = 4096; +const int32_t RESOLUTION_MAX_HEIGHT_SNAPSHOT = 3072; +const int32_t RESOLUTION_MAX_WIDTH_CONTINUOUS = 1920; +const int32_t RESOLUTION_MAX_HEIGHT_CONTINUOUS = 1080; +const int32_t RESOLUTION_MIN_WIDTH = 320; +const int32_t RESOLUTION_MIN_HEIGHT = 240; + +const uint32_t DCAMERA_SHIFT_32 = 32; +const uint32_t DCAMERA_SHIFT_24 = 24; +const uint32_t DCAMERA_SHIFT_16 = 16; +const uint32_t DCAMERA_SHIFT_8 = 8; + +const uint32_t UINT32_SHIFT_MASK_24 = 0xff000000; +const uint32_t UINT32_SHIFT_MASK_16 = 0x00ff0000; +const uint32_t UINT32_SHIFT_MASK_8 = 0x0000ff00; +const uint32_t UINT32_SHIFT_MASK_0 = 0x000000ff; +const uint16_t UINT16_SHIFT_MASK_0 = 0x00ff; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_CONSTANTS_H \ No newline at end of file diff --git a/common/include/constants/distributed_camera_errno.h b/common/include/constants/distributed_camera_errno.h new file mode 100644 index 00000000..0a1f7e99 --- /dev/null +++ b/common/include/constants/distributed_camera_errno.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 OHOS_DISTRIBUTED_CAMERA_ERRNO_H +#define OHOS_DISTRIBUTED_CAMERA_ERRNO_H + +namespace OHOS { +namespace DistributedHardware { + enum DistributedCameraErrno { + DCAMERA_OK = 0, + DCAMERA_MEMORY_OPT_ERROR = -1, + DCAMERA_BAD_VALUE = -2, + DCAMERA_BAD_TYPE = -3, + DCAMERA_ALREADY_EXISTS = -4, + DCAMERA_INIT_ERR = -5, + DCAMERA_NOT_FOUND = -6, + DCAMERA_WRONG_STATE = -7, + DCAMERA_BAD_OPERATE = -8, + DCAMERA_OPEN_CONFLICT = -9, + DCAMERA_DISABLE_PROCESS = -10, + DCAMERA_INDEX_OVERFLOW = -11, + DCAMERA_REGIST_HAL_FAILED = -12, + DCAMERA_UNREGIST_HAL_FAILED = -13, + }; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_ERRNO_H \ No newline at end of file diff --git a/common/include/utils/data_buffer.h b/common/include/utils/data_buffer.h new file mode 100644 index 00000000..3c35a462 --- /dev/null +++ b/common/include/utils/data_buffer.h @@ -0,0 +1,60 @@ +/* + * 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_DATA_BUFFER_H +#define OHOS_DATA_BUFFER_H + +#include +#include + +using std::string; +using std::map; + +namespace OHOS { +namespace DistributedHardware { +class DataBuffer { +public: + DataBuffer(size_t capacity); + + size_t Size() const; + size_t Offset() const; + size_t Capacity() const; + uint8_t *Data() const; + int32_t SetRange(size_t offset, size_t size); + + void SetInt32(const string name, int32_t value); + void SetInt64(const string name, int64_t value); + void SetString(const string name, string value); + bool FindInt32(const string& name, int32_t& value); + bool FindInt64(const string& name, int64_t& value); + bool FindString(const string& name, string& value); + + virtual ~DataBuffer(); +private: + size_t capacity_ = 0; + size_t rangeOffset_ = 0; + size_t rangeLength_ = 0; + uint8_t *data_ = nullptr; + + map int32Map_; + map int64Map_; + map stringMap_; + + DataBuffer(const DataBuffer &) = delete; + DataBuffer &operator = (const DataBuffer &) = delete; +}; +} +} +#endif \ No newline at end of file diff --git a/common/include/utils/dcamera_index.h b/common/include/utils/dcamera_index.h new file mode 100644 index 00000000..d9c69ceb --- /dev/null +++ b/common/include/utils/dcamera_index.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_INDEX_H +#define OHOS_DCAMERA_INDEX_H + +#include + +namespace OHOS { +namespace DistributedHardware { +class DCameraIndex { +public: + DCameraIndex() = default; + explicit DCameraIndex(std::string devId, std::string dhId) : devId_(devId), dhId_(dhId) {} + ~DCameraIndex() = default; + + bool operator == (const DCameraIndex& index) const + { + return this->devId_ == index.devId_ && this->dhId_ == index.dhId_; + } + + bool operator < (const DCameraIndex& index) const + { + return (this->devId_ + this->dhId_) < (index.devId_ + index.dhId_); + } + + std::string devId_; + std::string dhId_; +}; +} +} +#endif \ No newline at end of file diff --git a/common/include/utils/dcamera_utils_tools.h b/common/include/utils/dcamera_utils_tools.h new file mode 100644 index 00000000..4068f4e1 --- /dev/null +++ b/common/include/utils/dcamera_utils_tools.h @@ -0,0 +1,35 @@ +/* + * 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_UTILS_TOOL_H +#define OHOS_DCAMERA_UTILS_TOOL_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +const std::string BASE_64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int32_t GetLocalDeviceNetworkId(std::string& networkId); +int64_t GetNowTimeStampMs(); +int64_t GetNowTimeStampUs(); +std::string Base64Encode(const unsigned char *toEncode, unsigned int len); +std::string Base64Decode(const std::string& basicString); +bool IsBase64(unsigned char c); +} +} +#endif \ No newline at end of file diff --git a/common/src/utils/data_buffer.cpp b/common/src/utils/data_buffer.cpp new file mode 100644 index 00000000..6e4ae71f --- /dev/null +++ b/common/src/utils/data_buffer.cpp @@ -0,0 +1,119 @@ +/* + * 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 "data_buffer.h" +#include "distributed_camera_errno.h" + +namespace OHOS { +namespace DistributedHardware { +DataBuffer::DataBuffer(size_t capacity) +{ + if (capacity != 0) { + data_ = new uint8_t[capacity] {0}; + if (data_ != nullptr) { + capacity_ = capacity; + rangeLength_ = capacity; + } + } +} + +size_t DataBuffer::Capacity() const +{ + return capacity_; +} + +size_t DataBuffer::Size() const +{ + return rangeLength_; +} + +size_t DataBuffer::Offset() const +{ + return rangeOffset_; +} + +uint8_t *DataBuffer::Data() const +{ + return data_ + rangeOffset_; +} + +int32_t DataBuffer::SetRange(size_t offset, size_t size) +{ + if (!(offset <= capacity_) || !(offset + size <= capacity_)) { + return DCAMERA_BAD_VALUE; + } + + rangeOffset_ = offset; + rangeLength_ = size; + return DCAMERA_OK; +} + +void DataBuffer::SetInt32(const string name, int32_t value) +{ + int32Map_[name] = value; +} + +void DataBuffer::SetInt64(const string name, int64_t value) +{ + int64Map_[name] = value; +} + +void DataBuffer::SetString(const string name, string value) +{ + stringMap_[name] = value; +} + +bool DataBuffer::FindInt32(const string& name, int32_t& value) +{ + if (int32Map_.count(name) != 0) { + value = int32Map_[name]; + return true; + } else { + value = 0; + return false; + } +} + +bool DataBuffer::FindInt64(const string& name, int64_t& value) +{ + if (int64Map_.count(name) != 0) { + value = int64Map_[name]; + return true; + } else { + value = 0; + return false; + } +} + +bool DataBuffer::FindString(const string& name, string& value) +{ + if (stringMap_.count(name) != 0) { + value = stringMap_[name]; + return true; + } else { + value = ""; + return false; + } +} + +DataBuffer::~DataBuffer() +{ + if (data_ != nullptr) { + delete[] data_; + data_ = nullptr; + } +} +} +} \ No newline at end of file diff --git a/common/src/utils/dcamera_utils_tools.cpp b/common/src/utils/dcamera_utils_tools.cpp new file mode 100644 index 00000000..9040ef91 --- /dev/null +++ b/common/src/utils/dcamera_utils_tools.cpp @@ -0,0 +1,157 @@ +/* + * 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_utils_tools.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "softbus_bus_center.h" + +namespace OHOS { +namespace DistributedHardware { +const int OFFSET2 = 2; +const int OFFSET4 = 4; +const int OFFSET6 = 6; +const int INDEX_FIRST = 0; +const int INDEX_SECOND = 1; +const int INDEX_THIRD = 2; +const int INDEX_FORTH = 3; +int32_t GetLocalDeviceNetworkId(std::string& networkId) +{ + NodeBasicInfo basicInfo = { { 0 } }; + int32_t ret = GetLocalNodeDeviceInfo(DCAMERA_PKG_NAME.c_str(), &basicInfo); + if (ret != DCAMERA_OK) { + DHLOGE("GetLocalDeviceNetworkId GetLocalNodeDeviceInfo failed ret: %d", ret); + return ret; + } + + networkId = std::string(basicInfo.networkId); + return DCAMERA_OK; +} + +int64_t GetNowTimeStampMs() +{ + std::chrono::milliseconds nowMs = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + return nowMs.count(); +} + +int64_t GetNowTimeStampUs() +{ + std::chrono::microseconds nowUs = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + return nowUs.count(); +} + +std::string Base64Encode(const unsigned char *toEncode, unsigned int len) +{ + std::string ret; + uint32_t i = 0; + uint32_t j = 0; + unsigned char charArray3[3]; + unsigned char charArray4[4]; + + while (len--) { + charArray3[i++] = *(toEncode++); + if (i == sizeof(charArray3)) { + charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & 0xfc) >> OFFSET2; + charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & 0x03) << OFFSET4) + + ((charArray3[INDEX_SECOND] & 0xf0) >> OFFSET4); + charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & 0x0f) << OFFSET2) + + ((charArray3[INDEX_THIRD] & 0xc0) >> OFFSET6); + charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & 0x3f; + for (i = 0; i < sizeof(charArray4); i++) { + ret += BASE_64_CHARS[charArray4[i]]; + } + i = 0; + } + } + + if (i) { + for (j = i; j < sizeof(charArray3); j++) { + charArray3[j] = '\0'; + } + charArray4[INDEX_FIRST] = (charArray3[INDEX_FIRST] & 0xfc) >> OFFSET2; + charArray4[INDEX_SECOND] = ((charArray3[INDEX_FIRST] & 0x03) << OFFSET4) + + ((charArray3[INDEX_SECOND] & 0xf0) >> OFFSET4); + charArray4[INDEX_THIRD] = ((charArray3[INDEX_SECOND] & 0x0f) << OFFSET2) + + ((charArray3[INDEX_THIRD] & 0xc0) >> OFFSET6); + charArray4[INDEX_FORTH] = charArray3[INDEX_THIRD] & 0x3f; + 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; + uint32_t j = 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) { + 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 == '/')); +} +} +} \ No newline at end of file diff --git a/distributedcamera.gni b/distributedcamera.gni new file mode 100644 index 00000000..8207be52 --- /dev/null +++ b/distributedcamera.gni @@ -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. + +distributedcamera_path = "//foundation/distributedhardware/distributedcamera" + +distributedhardwarefwk_path = "//foundation/distributedhardware/distributedhardwarefwk" + +hdf_framework_path = "//drivers/framework" + +camera_hdf_path = "//drivers/peripheral/adapter" + +display_hdf_path = "//drivers/peripheral/display" + +camerastandard_path = "//foundation/multimedia/camera_standard" + +mediastandard_path = "//foundation/multimedia/media_standard" + +graphicstandard_path = "//foundation/graphic/standard" + +common_path = "${distributedcamera_path}/common" + +services_path = "${distributedcamera_path}/services" + +innerkits_path = "${distributedcamera_path}/interfaces/inner_kits" + +distributedcamera_hdf_path = "${distributedcamera_path}/camera_hdf" + +fwk_utils_path = "${distributedhardwarefwk_path}/utils" + +fwk_common_path = "${distributedhardwarefwk_path}/common" + +fwk_services_path = "${distributedhardwarefwk_path}/services" + +build_flags = [ "-Werror" ] diff --git a/figures/distributedcamera_arch.png b/figures/distributedcamera_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..c2097be48adb30e27303a408e0a713257f56ad18 GIT binary patch literal 99835 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 z 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�fj-b?j?;$JR_ldV(rV=#GrG{Rhb$$jQb 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 GetSinkLocalDHMS(); + void OnSinkLocalDmsDied(const wptr& remote); + +private: + DCameraSinkHandlerIpc(); + ~DCameraSinkHandlerIpc(); + void OnSinkLocalDmsDied(const sptr& remote); + void DeleteSinkLocalDhms(); + + class SinkLocalRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr& remote) override; + }; + sptr sinkLocalRecipient_; + sptr localSink_; + std::mutex sinkLocalDmsLock_; + + bool isInit_; + std::shared_ptr serviceHandler_; + std::mutex initDmsLock_; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_sink/include/distributed_camera_sink_proxy.h b/interfaces/inner_kits/native_cpp/camera_sink/include/distributed_camera_sink_proxy.h new file mode 100644 index 00000000..c987e71b --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_sink/include/distributed_camera_sink_proxy.h @@ -0,0 +1,50 @@ +/* + * 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_DISTRIBUTED_CAMERA_SINK_PROXY_H +#define OHOS_DISTRIBUTED_CAMERA_SINK_PROXY_H + +#include "idistributed_camera_sink.h" + +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "refbase.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSinkProxy : public IRemoteProxy { +public: + explicit DistributedCameraSinkProxy(const sptr& impl) + : IRemoteProxy(impl) + { + } + + ~DistributedCameraSinkProxy() {} + int32_t InitSink(const std::string& params) override; + int32_t ReleaseSink() override; + int32_t SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) override; + int32_t UnsubscribeLocalHardware(const std::string& dhId) override; + int32_t StopCapture(const std::string& dhId) override; + int32_t ChannelNeg(const std::string& dhId, std::string& channelInfo) override; + int32_t GetCameraInfo(const std::string& dhId, std::string& cameraInfo) override; + int32_t OpenChannel(const std::string& dhId, std::string& openInfo) override; + int32_t CloseChannel(const std::string& dhId) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_SINK_PROXY_H \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_sink/include/idistributed_camera_sink.h b/interfaces/inner_kits/native_cpp/camera_sink/include/idistributed_camera_sink.h new file mode 100644 index 00000000..c3613201 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_sink/include/idistributed_camera_sink.h @@ -0,0 +1,52 @@ +/* + * 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_IDISTRIBUTED_CAMERA_SINK_H +#define OHOS_IDISTRIBUTED_CAMERA_SINK_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace DistributedHardware { +class IDistributedCameraSink : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.distributedcamerasink"); + enum { + INIT_SINK = 0, + RELEASE_SINK = 1, + SUBSCRIBE_LOCAL_HARDWARE = 2, + UNSUBSCRIBE_LOCAL_HARDWARE = 3, + STOP_CAPTURE = 4, + CHANNEL_NEG = 5, + GET_CAMERA_INFO = 6, + OPEN_CHANNEL = 7, + CLOSE_CHANNEL = 8, + }; + + IDistributedCameraSink() = default; + virtual ~IDistributedCameraSink() = default; + virtual int32_t InitSink(const std::string& params) = 0; + virtual int32_t ReleaseSink() = 0; + virtual int32_t SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) = 0; + virtual int32_t UnsubscribeLocalHardware(const std::string& dhId) = 0; + virtual int32_t StopCapture(const std::string& dhId) = 0; + virtual int32_t ChannelNeg(const std::string& dhId, std::string& channelInfo) = 0; + virtual int32_t GetCameraInfo(const std::string& dhId, std::string& cameraInfo) = 0; + virtual int32_t OpenChannel(const std::string& dhId, std::string& openInfo) = 0; + virtual int32_t CloseChannel(const std::string& dhId) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_IDISTRIBUTED_CAMERA_SINK_H \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler.cpp b/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler.cpp new file mode 100644 index 00000000..4ddea60a --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler.cpp @@ -0,0 +1,92 @@ +/* + * 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_sink_handler.h" + +#include "anonymous_string.h" +#include "dcamera_sink_handler_ipc.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DCameraSinkHandler); + +DCameraSinkHandler::~DCameraSinkHandler() +{ + DHLOGI("~DCameraSinkHandler"); +} + +int32_t DCameraSinkHandler::InitSink(const std::string& params) +{ + DHLOGI("DCameraSinkHandler::InitSink"); + DCameraSinkHandlerIpc::GetInstance().Init(); + sptr dCameraSinkSrv = DCameraSinkHandlerIpc::GetInstance().GetSinkLocalDHMS(); + if (dCameraSinkSrv == nullptr) { + DHLOGE("DCameraSinkHandler::InitSink get Service failed"); + return DCAMERA_INIT_ERR; + } + return dCameraSinkSrv->InitSink(params); +} + +int32_t DCameraSinkHandler::ReleaseSink() +{ + DHLOGI("DCameraSinkHandler::ReleaseSink"); + sptr dCameraSinkSrv = DCameraSinkHandlerIpc::GetInstance().GetSinkLocalDHMS(); + if (dCameraSinkSrv == nullptr) { + DHLOGE("DCameraSinkHandler::ReleaseSink get Service failed"); + return DCAMERA_BAD_VALUE; + } + + int32_t ret = dCameraSinkSrv->ReleaseSink(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkHandler::ReleaseSink sink service release failed, ret: %d", ret); + return ret; + } + + DCameraSinkHandlerIpc::GetInstance().UnInit(); + DHLOGI("DCameraSinkHandler::ReleaseSink success"); + return DCAMERA_OK; +} + +int32_t DCameraSinkHandler::SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) +{ + DHLOGI("DCameraSinkHandler::SubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + sptr dCameraSinkSrv = DCameraSinkHandlerIpc::GetInstance().GetSinkLocalDHMS(); + if (dCameraSinkSrv == nullptr) { + DHLOGE("DCameraSinkHandler::SubscribeLocalHardware get Service failed"); + return DCAMERA_BAD_VALUE; + } + return dCameraSinkSrv->SubscribeLocalHardware(dhId, parameters); +} + +int32_t DCameraSinkHandler::UnsubscribeLocalHardware(const std::string& dhId) +{ + DHLOGI("DCameraSinkHandler::UnsubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + sptr dCameraSinkSrv = DCameraSinkHandlerIpc::GetInstance().GetSinkLocalDHMS(); + if (dCameraSinkSrv == nullptr) { + DHLOGE("DCameraSinkHandler::UnsubscribeLocalHardware get Service failed"); + return DCAMERA_BAD_VALUE; + } + return dCameraSinkSrv->UnsubscribeLocalHardware(dhId); +} + +IDistributedHardwareSink *GetSinkHardwareHandler() +{ + DHLOGI("DCameraSinkHandler::GetSinkHardwareHandler"); + return &DCameraSinkHandler::GetInstance(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler_ipc.cpp b/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler_ipc.cpp new file mode 100644 index 00000000..77a1888b --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_sink/src/dcamera_sink_handler_ipc.cpp @@ -0,0 +1,159 @@ +/* + * 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_sink_handler_ipc.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkHandlerIpc::DCameraSinkHandlerIpc() : isInit_(false) +{ + DHLOGI("DCameraSinkHandlerIpc Create"); +} + +DCameraSinkHandlerIpc::~DCameraSinkHandlerIpc() +{ + DHLOGI("DCameraSinkHandlerIpc Delete"); + UnInit(); +} + +IMPLEMENT_SINGLE_INSTANCE(DCameraSinkHandlerIpc); + +void DCameraSinkHandlerIpc::Init() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSinkHandlerIpc Init Start"); + if (isInit_) { + DHLOGI("DCameraSinkHandlerIpc has already init"); + return; + } + auto runner = AppExecFwk::EventRunner::Create("DCameraSinkHandlerIpcHandler"); + serviceHandler_ = std::make_shared(runner); + sinkLocalRecipient_ = new SinkLocalRecipient(); + isInit_ = true; + DHLOGI("DCameraSinkHandlerIpc Init End"); +} + +void DCameraSinkHandlerIpc::UnInit() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSinkHandlerIpc UnInit Start"); + if (!isInit_) { + DHLOGI("DCameraSinkHandlerIpc has already UnInit"); + return; + } + DeleteSinkLocalDhms(); + DHLOGI("DCameraSinkHandlerIpc Start free serviceHandler"); + serviceHandler_ = nullptr; + DHLOGI("DCameraSinkHandlerIpc Start free recipient"); + sinkLocalRecipient_ = nullptr; + isInit_ = false; + DHLOGI("DCameraSinkHandlerIpc UnInit End"); +} + +sptr DCameraSinkHandlerIpc::GetSinkLocalDHMS() +{ + { + std::lock_guard autoLock(sinkLocalDmsLock_); + if (localSink_ != nullptr) { + DHLOGI("DCameraSinkHandlerIpc GetSinkLocalDHMS from cache"); + return localSink_; + } + } + DHLOGI("GetSinkLocalDHMS Start"); + sptr sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sm == nullptr) { + DHLOGE("GetSinkLocalDHMS GetSystemAbilityManager failed"); + return nullptr; + } + + sptr object = sm->GetSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID); + if (object == nullptr) { + DHLOGE("GetSinkLocalDHMS GetSystemAbility failed"); + return nullptr; + } + int32_t ret = object->AddDeathRecipient(sinkLocalRecipient_); + sptr localSink = iface_cast(object); + if (localSink == nullptr) { + DHLOGI("GetSinkLocalDHMS failed, localSink is null ret: %d", ret); + return nullptr; + } + { + std::lock_guard autoLock(sinkLocalDmsLock_); + if (localSink_ != nullptr) { + localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_); + } + localSink_ = localSink; + } + DHLOGI("GetSinkLocalDHMS success, AddDeathRecipient ret: %d", ret); + return localSink; +} + +void DCameraSinkHandlerIpc::DeleteSinkLocalDhms() +{ + DHLOGI("DeleteSinkLocalDhms start"); + std::lock_guard autoLock(sinkLocalDmsLock_); + if (localSink_ != nullptr) { + localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_); + } + localSink_ = nullptr; + DHLOGI("DeleteSinkLocalDhms end"); +} + +void DCameraSinkHandlerIpc::SinkLocalRecipient::OnRemoteDied(const wptr& remote) +{ + DHLOGI("SinkLocalRecipient OnRemoteDied received died notify!"); + DCameraSinkHandlerIpc::GetInstance().OnSinkLocalDmsDied(remote); +} + +void DCameraSinkHandlerIpc::OnSinkLocalDmsDied(const wptr& remote) +{ + sptr diedRemoted = remote.promote(); + if (diedRemoted == nullptr) { + DHLOGE("OnSinkLocalDmsDied promote failed!"); + return; + } + DHLOGI("OnSinkLocalDmsDied delete diedRemoted"); + auto remoteDmsDiedFunc = [this, diedRemoted]() { + OnSinkLocalDmsDied(diedRemoted); + }; + if (serviceHandler_ != nullptr) { + serviceHandler_->PostTask(remoteDmsDiedFunc); + } +} + +void DCameraSinkHandlerIpc::OnSinkLocalDmsDied(const sptr& remote) +{ + std::lock_guard autoLock(sinkLocalDmsLock_); + if (localSink_->AsObject() != remote) { + DHLOGI("OnSinkLocalDmsDied not found remote object"); + return; + } + + DHLOGI("OnSinkLocalDmsDied Clear"); + if (localSink_ != nullptr) { + localSink_->AsObject()->RemoveDeathRecipient(sinkLocalRecipient_); + } + localSink_ = nullptr; +} +} +} \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_sink/src/distributed_camera_sink_proxy.cpp b/interfaces/inner_kits/native_cpp/camera_sink/src/distributed_camera_sink_proxy.cpp new file mode 100644 index 00000000..28b9033a --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_sink/src/distributed_camera_sink_proxy.cpp @@ -0,0 +1,248 @@ +/* + * 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 "distributed_camera_sink_proxy.h" + +#include "parcel.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DistributedCameraSinkProxy::InitSink(const std::string& params) +{ + DHLOGI("DistributedCameraSinkProxy::InitSink"); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::InitSink remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::InitSink write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(params)) { + DHLOGE("DistributedCameraSinkProxy::InitSink write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(INIT_SINK, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::ReleaseSink() +{ + DHLOGI("DistributedCameraSinkProxy::ReleaseSink"); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::ReleaseSink remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::ReleaseSink write token failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(RELEASE_SINK, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) +{ + DHLOGI("DistributedCameraSinkProxy::SubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::SubscribeLocalHardware remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::SubscribeLocalHardware write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId) || !data.WriteString(parameters)) { + DHLOGE("DistributedCameraSinkProxy::SubscribeLocalHardware write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(SUBSCRIBE_LOCAL_HARDWARE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::UnsubscribeLocalHardware(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkProxy::UnsubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::UnsubscribeLocalHardware remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::UnsubscribeLocalHardware write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId)) { + DHLOGE("DistributedCameraSinkProxy::UnsubscribeLocalHardware write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(UNSUBSCRIBE_LOCAL_HARDWARE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::StopCapture(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkProxy::StopCapture dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::StopCapture remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option = { MessageOption::TF_ASYNC }; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::StopCapture write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId)) { + DHLOGE("DistributedCameraSinkProxy::StopCapture write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(STOP_CAPTURE, data, reply, option); + int32_t result = reply.ReadInt32(); + DHLOGI("DistributedCameraSinkProxy::StopCapture async dhId: %s", GetAnonyString(dhId).c_str()); + return result; +} + +int32_t DistributedCameraSinkProxy::ChannelNeg(const std::string& dhId, std::string& channelInfo) +{ + DHLOGI("DistributedCameraSinkProxy::ChannelNeg dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::ChannelNeg remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::ChannelNeg write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId) || !data.WriteString(channelInfo)) { + DHLOGE("DistributedCameraSinkProxy::ChannelNeg write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(CHANNEL_NEG, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::GetCameraInfo(const std::string& dhId, std::string& cameraInfo) +{ + DHLOGI("DistributedCameraSinkProxy::GetCameraInfo dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::GetCameraInfo remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::GetCameraInfo write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId) || !data.WriteString(cameraInfo)) { + DHLOGE("DistributedCameraSinkProxy::GetCameraInfo write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(GET_CAMERA_INFO, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::OpenChannel(const std::string& dhId, std::string& openInfo) +{ + DHLOGI("DistributedCameraSinkProxy::OpenChannel dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::OpenChannel remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::OpenChannel write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId) || !data.WriteString(openInfo)) { + DHLOGE("DistributedCameraSinkProxy::OpenChannel write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(OPEN_CHANNEL, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSinkProxy::CloseChannel(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkProxy::CloseChannel dhId: %s", GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSinkProxy::CloseChannel remote service is null"); + return DCAMERA_BAD_VALUE; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSinkProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSinkProxy::CloseChannel write token failed"); + return DCAMERA_BAD_VALUE; + } + if (!data.WriteString(dhId)) { + DHLOGE("DistributedCameraSinkProxy::CloseChannel write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(CLOSE_CHANNEL, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/BUILD.gn b/interfaces/inner_kits/native_cpp/camera_source/BUILD.gn new file mode 100644 index 00000000..d7a463a3 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/BUILD.gn @@ -0,0 +1,63 @@ +# 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("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_source_sdk") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "include", + "include/callback", + "${common_path}/include/constants", + ] + + sources = [ + "src/dcamera_source_handler_ipc.cpp", + "src/distributed_camera_source_proxy.cpp", + "src/dcamera_source_handler.cpp", + "src/callback/dcamera_source_callback_stub.cpp", + "src/callback/dcamera_source_callback.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${fwk_utils_path}:distributedhardwareutils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcamerasourcekits\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "eventhandler:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} + diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback.h b/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback.h new file mode 100644 index 00000000..97288bd4 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback.h @@ -0,0 +1,46 @@ +/* + * 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_SOURCE_CALLBACK_H +#define OHOS_DCAMERA_SOURCE_CALLBACK_H + +#include + +#include "dcamera_source_callback_stub.h" +#include "idistributed_hardware_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceCallback : public DCameraSourceCallbackStub { +public: + DCameraSourceCallback() = default; + ~DCameraSourceCallback(); + + int32_t OnNotifyRegResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; + int32_t OnNotifyUnregResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; + + void PushRegCallback(std::string& reqId, std::shared_ptr& callback); + void PopRegCallback(std::string& reqId); + void PushUnregCallback(std::string& reqId, std::shared_ptr& callback); + void PopUnregCallback(std::string& reqId); +private: + std::map> regCallbacks_; + std::map> unregCallbacks_; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback_stub.h b/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback_stub.h new file mode 100644 index 00000000..d4ed3bc4 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/callback/dcamera_source_callback_stub.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 OHOS_DCAMERA_SOURCE_CALLBACK_STUB_H +#define OHOS_DCAMERA_SOURCE_CALLBACK_STUB_H + +#include +#include "iremote_stub.h" + +#include "idcamera_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceCallbackStub : public IRemoteStub { +public: + DCameraSourceCallbackStub(); + virtual ~DCameraSourceCallbackStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t NotifyRegResultInner(MessageParcel &data, MessageParcel &reply); + int32_t NotifyUnregResultInner(MessageParcel &data, MessageParcel &reply); + + using DCameraFunc = int32_t (DCameraSourceCallbackStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/callback/idcamera_source_callback.h b/interfaces/inner_kits/native_cpp/camera_source/include/callback/idcamera_source_callback.h new file mode 100644 index 00000000..1c095392 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/callback/idcamera_source_callback.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 OHOS_IDCAMERA_SOURCE_CALLBACL_H +#define OHOS_IDCAMERA_SOURCE_CALLBACL_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace DistributedHardware { +class IDCameraSourceCallback : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.dcamerasourcecallback"); + enum { + NOTIFY_REG_RESULT = 0, + NOTIFY_UNREG_RESULT = 1, + }; + + virtual ~IDCameraSourceCallback() {} + virtual int32_t OnNotifyRegResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) = 0; + virtual int32_t OnNotifyUnregResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler.h b/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler.h new file mode 100644 index 00000000..ea9f10f1 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler.h @@ -0,0 +1,61 @@ +/* + * 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_SOURCE_HANDLER_H +#define OHOS_DCAMERA_SOURCE_HANDLER_H + +#include + +#include "iremote_proxy.h" +#include "iremote_broker.h" +#include "refbase.h" + +#include "dcamera_source_callback.h" +#include "idistributed_hardware_source.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceHandler : public IDistributedHardwareSource { +DECLARE_SINGLE_INSTANCE_BASE(DCameraSourceHandler); +public: + int32_t InitSource(const std::string& params) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const EnableParam& param, std::shared_ptr callback) override; + int32_t UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + std::shared_ptr callback) override; + int32_t ConfigDistributedHardware(const std::string& devId, const std::string& dhId, const std::string& key, + const std::string& value) override; + +private: + DCameraSourceHandler() = default; + ~DCameraSourceHandler(); + +private: + std::mutex optLock_; + sptr callback_; +}; + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((visibility("default"))) IDistributedHardwareSource *GetSourceHardwareHandler(); +#ifdef __cplusplus +} +#endif +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler_ipc.h b/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler_ipc.h new file mode 100644 index 00000000..cdee7ccd --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/dcamera_source_handler_ipc.h @@ -0,0 +1,53 @@ +/* + * 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_SOURCE_HANDLER_IPC_H +#define OHOS_DCAMERA_SOURCE_HANDLER_IPC_H + +#include "event_handler.h" +#include "idistributed_camera_source.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceHandlerIpc { +DECLARE_SINGLE_INSTANCE_BASE(DCameraSourceHandlerIpc); +public: + void Init(); + void UnInit(); + sptr GetSourceLocalDHMS(); + void OnSourceLocalDmsDied(const wptr& remote); + +private: + DCameraSourceHandlerIpc(); + ~DCameraSourceHandlerIpc(); + void OnSourceLocalDmsDied(const sptr& remote); + void DeleteSourceLocalDhms(); + + class SourceLocalRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr& remote) override; + }; + sptr sourceLocalRecipient_; + sptr localSource_; + std::mutex sourceLocalDmsLock_; + + bool isInit_; + std::shared_ptr serviceHandler_; + std::mutex initDmsLock_; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/distributed_camera_source_proxy.h b/interfaces/inner_kits/native_cpp/camera_source/include/distributed_camera_source_proxy.h new file mode 100644 index 00000000..2da59697 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/distributed_camera_source_proxy.h @@ -0,0 +1,50 @@ +/* + * 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_DISTRIBUTED_CAMERA_SOURCE_PROXY_H +#define OHOS_DISTRIBUTED_CAMERA_SOURCE_PROXY_H + +#include + +#include "iremote_proxy.h" +#include "iremote_broker.h" +#include "refbase.h" + +#include "idistributed_camera_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSourceProxy : public IRemoteProxy { +public: + explicit DistributedCameraSourceProxy(const sptr& impl) + : IRemoteProxy(impl) + { + } + + ~DistributedCameraSourceProxy() {} + int32_t InitSource(const std::string& params, const sptr& callback) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const EnableParam& param) override; + int32_t UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId) override; + int32_t DCameraNotify(const std::string& devId, const std::string& dhId, std::string& events) override; + +private: + static inline BrokerDelegator delegator_; +}; +} +} + +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/include/idistributed_camera_source.h b/interfaces/inner_kits/native_cpp/camera_source/include/idistributed_camera_source.h new file mode 100644 index 00000000..d7f98a29 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/include/idistributed_camera_source.h @@ -0,0 +1,48 @@ +/* + * 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_IDISTRIBUTED_CAMERA_SOURCE_H +#define OHOS_IDISTRIBUTED_CAMERA_SOURCE_H + +#include "iremote_broker.h" + +#include "idcamera_source_callback.h" +#include "idistributed_hardware_source.h" + +namespace OHOS { +namespace DistributedHardware { +class IDistributedCameraSource : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.distributedcamerasource"); + enum { + INIT_SOURCE = 0, + RELEASE_SOURCE = 1, + REGISTER_DISTRIBUTED_HARDWARE = 2, + UNREGISTER_DISTRIBUTED_HARDWARE = 3, + CAMERA_NOTIFY = 4, + }; + + virtual ~IDistributedCameraSource() {} + virtual int32_t InitSource(const std::string& params, const sptr& callback) = 0; + virtual int32_t ReleaseSource() = 0; + virtual int32_t RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const EnableParam& param) = 0; + virtual int32_t UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId) = 0; + virtual int32_t DCameraNotify(const std::string& devId, const std::string& dhId, std::string& events) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback.cpp b/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback.cpp new file mode 100644 index 00000000..9117994f --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback.cpp @@ -0,0 +1,90 @@ +/* + * 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_source_callback.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceCallback::~DCameraSourceCallback() +{ + regCallbacks_.clear(); + unregCallbacks_.clear(); +} + +int32_t DCameraSourceCallback::OnNotifyRegResult(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + DHLOGI("DCameraSourceCallback OnNotifyRegResult devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + auto iter = regCallbacks_.find(reqId); + if (iter == regCallbacks_.end()) { + DHLOGE("DCameraSourceCallback OnNotifyRegResult not found devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return DCAMERA_NOT_FOUND; + } + int32_t ret = iter->second->OnRegisterResult(devId, dhId, status, data); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCallback OnNotifyRegResult failed, devId: %s dhId: %s ret: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), ret); + } + regCallbacks_.erase(iter); + return ret; +} + +int32_t DCameraSourceCallback::OnNotifyUnregResult(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + DHLOGI("DCameraSourceCallback OnNotifyUnregResult devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + auto iter = unregCallbacks_.find(reqId); + if (iter == unregCallbacks_.end()) { + DHLOGE("DCameraSourceCallback OnNotifyUnregResult not found devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return DCAMERA_NOT_FOUND; + } + int32_t ret = iter->second->OnUnregisterResult(devId, dhId, status, data); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCallback OnNotifyUnregResult failed, devId: %s dhId: %s ret: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), ret); + } + unregCallbacks_.erase(iter); + return ret; +} + +void DCameraSourceCallback::PushRegCallback(std::string& reqId, std::shared_ptr& callback) +{ + regCallbacks_.emplace(reqId, callback); +} + +void DCameraSourceCallback::PopRegCallback(std::string& reqId) +{ + regCallbacks_.erase(reqId); +} + +void DCameraSourceCallback::PushUnregCallback(std::string& reqId, std::shared_ptr& callback) +{ + unregCallbacks_.emplace(reqId, callback); +} + +void DCameraSourceCallback::PopUnregCallback(std::string& reqId) +{ + unregCallbacks_.erase(reqId); +} +} +} \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback_stub.cpp b/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback_stub.cpp new file mode 100644 index 00000000..9da85fb0 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/src/callback/dcamera_source_callback_stub.cpp @@ -0,0 +1,82 @@ +/* + * 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_source_callback_stub.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceCallbackStub::DCameraSourceCallbackStub() +{ + memberFuncMap_[NOTIFY_REG_RESULT] = &DCameraSourceCallbackStub::NotifyRegResultInner; + memberFuncMap_[NOTIFY_UNREG_RESULT] = &DCameraSourceCallbackStub::NotifyUnregResultInner; +} + +DCameraSourceCallbackStub::~DCameraSourceCallbackStub() +{} + +int32_t DCameraSourceCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DCameraSourceCallbackStub OnRemoteRequest code: %d", code); + std::u16string desc = DCameraSourceCallbackStub::GetDescriptor(); + std::u16string remoteDesc = data.ReadInterfaceToken(); + if (desc != remoteDesc) { + DHLOGE("DCameraSourceCallbackStub::OnRemoteRequest remoteDesc is invalid!"); + return ERR_INVALID_DATA; + } + auto itFunc = memberFuncMap_.find(code); + if (itFunc == memberFuncMap_.end()) { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + + auto memberFunc = itFunc->second; + return (this->*memberFunc)(data, reply); +} + +int32_t DCameraSourceCallbackStub::NotifyRegResultInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DCameraSourceCallbackStub NotifyRegResultInner"); + int32_t ret = DCAMERA_OK; + do { + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + int32_t status = data.ReadInt32(); + std::string result = data.ReadString(); + ret = OnNotifyRegResult(devId, dhId, reqId, status, result); + } while (0); + reply.WriteInt32(ret); + return ret; +} + +int32_t DCameraSourceCallbackStub::NotifyUnregResultInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DCameraSourceCallbackStub NotifyUnregResultInner"); + int32_t ret = DCAMERA_OK; + do { + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + int32_t status = data.ReadInt32(); + std::string result = data.ReadString(); + ret = OnNotifyUnregResult(devId, dhId, reqId, status, result); + } while (0); + reply.WriteInt32(ret); + return ret; +} +} +} \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler.cpp b/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler.cpp new file mode 100644 index 00000000..5c22664a --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler.cpp @@ -0,0 +1,126 @@ +/* + * 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_source_handler.h" +#include "dcamera_source_callback.h" + +#include "anonymous_string.h" +#include "dcamera_source_handler_ipc.h" +#include "dh_utils_tool.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DCameraSourceHandler); + +DCameraSourceHandler::~DCameraSourceHandler() +{ + DHLOGI("~DCameraSourceHandler"); +} + +int32_t DCameraSourceHandler::InitSource(const std::string& params) +{ + DHLOGI("DCameraSourceHandler InitSource Start"); + DCameraSourceHandlerIpc::GetInstance().Init(); + sptr dCameraSourceSrv = DCameraSourceHandlerIpc::GetInstance().GetSourceLocalDHMS(); + if (dCameraSourceSrv == nullptr) { + DHLOGE("DCameraSourceHandler InitSource get Service failed"); + return DCAMERA_INIT_ERR; + } + + callback_ = new DCameraSourceCallback(); + if (callback_ == nullptr) { + DHLOGE("DCameraSourceHandler InitSource init callback failed"); + return DCAMERA_INIT_ERR; + } + int32_t ret = dCameraSourceSrv->InitSource(params, callback_); + DHLOGI("DCameraSourceHandler InitSource end, ret: %d", ret); + return ret; +} + +int32_t DCameraSourceHandler::ReleaseSource() +{ + DHLOGI("DCameraSourceHandler ReleaseSource Start"); + sptr dCameraSourceSrv = DCameraSourceHandlerIpc::GetInstance().GetSourceLocalDHMS(); + if (dCameraSourceSrv == nullptr) { + DHLOGE("DCameraSourceHandler ReleaseSource get Service failed"); + return DCAMERA_INIT_ERR; + } + dCameraSourceSrv->ReleaseSource(); + DCameraSourceHandlerIpc::GetInstance().UnInit(); + DHLOGI("DCameraSourceHandler ReleaseSource end"); + return DCAMERA_OK; +} + +int32_t DCameraSourceHandler::RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const EnableParam& param, std::shared_ptr callback) +{ + DHLOGI("DCameraSourceHandler RegisterDistributedHardware devId: %s dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr dCameraSourceSrv = DCameraSourceHandlerIpc::GetInstance().GetSourceLocalDHMS(); + if (dCameraSourceSrv == nullptr) { + DHLOGE("DCameraSourceHandler RegisterDistributedHardware get Service failed"); + return DCAMERA_BAD_VALUE; + } + + std::lock_guard autoLock(optLock_); + std::string reqId = GetRandomID(); + callback_->PushRegCallback(reqId, callback); + int32_t ret = dCameraSourceSrv->RegisterDistributedHardware(devId, dhId, reqId, param); + if (ret != DCAMERA_OK) { + callback_->PopRegCallback(reqId); + } + DHLOGI("DCameraSourceHandler RegisterDistributedHardware end, ret: %d devId: %s dhId: %s version: %s", + ret, GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), param.version.c_str()); + return ret; +} + +int32_t DCameraSourceHandler::UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + std::shared_ptr callback) +{ + DHLOGI("DCameraSourceHandler UnregisterDistributedHardware devId: %s dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr dCameraSourceSrv = DCameraSourceHandlerIpc::GetInstance().GetSourceLocalDHMS(); + if (dCameraSourceSrv == nullptr) { + DHLOGE("DCameraSourceHandler UnregisterDistributedHardware get Service failed"); + return DCAMERA_BAD_VALUE; + } + + std::lock_guard autoLock(optLock_); + std::string reqId = GetRandomID(); + callback_->PushUnregCallback(reqId, callback); + int32_t ret = dCameraSourceSrv->UnregisterDistributedHardware(devId, dhId, reqId); + if (ret != DCAMERA_OK) { + callback_->PopUnregCallback(reqId); + } + DHLOGI("DCameraSourceHandler UnregisterDistributedHardware end, ret: %d devId: %s dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; +} + +int32_t DCameraSourceHandler::ConfigDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& key, const std::string& value) +{ + return DCAMERA_OK; +} + +IDistributedHardwareSource *GetSourceHardwareHandler() +{ + DHLOGI("DCameraSourceHandler GetSourceHardwareHandler Start"); + return &DCameraSourceHandler::GetInstance(); +} +} +} \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler_ipc.cpp b/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler_ipc.cpp new file mode 100644 index 00000000..ccf062d2 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/src/dcamera_source_handler_ipc.cpp @@ -0,0 +1,159 @@ +/* + * 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_source_handler_ipc.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceHandlerIpc::DCameraSourceHandlerIpc() : isInit_(false) +{ + DHLOGI("DCameraSourceHandlerIpc Create"); +} + +DCameraSourceHandlerIpc::~DCameraSourceHandlerIpc() +{ + DHLOGI("DCameraSourceHandlerIpc Delete"); + UnInit(); +} + +IMPLEMENT_SINGLE_INSTANCE(DCameraSourceHandlerIpc); + +void DCameraSourceHandlerIpc::Init() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSourceHandlerIpc Init Start"); + if (isInit_) { + DHLOGI("DCameraSourceHandlerIpc has already init"); + return; + } + auto runner = AppExecFwk::EventRunner::Create("DCameraSourceHandlerIpcHandler"); + serviceHandler_ = std::make_shared(runner); + sourceLocalRecipient_ = new SourceLocalRecipient(); + isInit_ = true; + DHLOGI("DCameraSourceHandlerIpc Init End"); +} + +void DCameraSourceHandlerIpc::UnInit() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSourceHandlerIpc UnInit Start"); + if (!isInit_) { + DHLOGI("DCameraSourceHandlerIpc has already UnInit"); + return; + } + DeleteSourceLocalDhms(); + DHLOGI("DCameraSourceHandlerIpc Start free serviceHandler"); + serviceHandler_ = nullptr; + DHLOGI("DCameraSourceHandlerIpc Start free recipient"); + sourceLocalRecipient_ = nullptr; + isInit_ = false; + DHLOGI("DCameraSourceHandlerIpc UnInit End"); +} + +sptr DCameraSourceHandlerIpc::GetSourceLocalDHMS() +{ + { + std::lock_guard autoLock(sourceLocalDmsLock_); + if (localSource_ != nullptr) { + DHLOGI("DCameraSourceHandlerIpc GetSourceLocalDHMS from cache"); + return localSource_; + } + } + DHLOGI("GetSourceLocalDHMS Start"); + sptr sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sm == nullptr) { + DHLOGE("GetSourceLocalDHMS GetSystemAbilityManager failed"); + return nullptr; + } + + sptr object = sm->GetSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SOURCE_SA_ID); + if (object == nullptr) { + DHLOGE("GetSourceLocalDHMS GetSystemAbility failed"); + return nullptr; + } + int32_t ret = object->AddDeathRecipient(sourceLocalRecipient_); + sptr localSource = iface_cast(object); + if (localSource == nullptr) { + DHLOGI("GetSourceLocalDHMS failed, localSource is null ret: %d", ret); + return nullptr; + } + { + std::lock_guard autoLock(sourceLocalDmsLock_); + if (localSource_ != nullptr) { + localSource_->AsObject()->RemoveDeathRecipient(sourceLocalRecipient_); + } + localSource_ = localSource; + } + DHLOGI("GetSourceLocalDHMS success, AddDeathRecipient ret: %d", ret); + return localSource; +} + +void DCameraSourceHandlerIpc::DeleteSourceLocalDhms() +{ + DHLOGI("DeleteSourceLocalDhms start"); + std::lock_guard autoLock(sourceLocalDmsLock_); + if (localSource_ != nullptr) { + localSource_->AsObject()->RemoveDeathRecipient(sourceLocalRecipient_); + } + localSource_ = nullptr; + DHLOGI("DeleteSourceLocalDhms end"); +} + +void DCameraSourceHandlerIpc::SourceLocalRecipient::OnRemoteDied(const wptr& remote) +{ + DHLOGI("SourceLocalRecipient OnRemoteDied received died notify!"); + DCameraSourceHandlerIpc::GetInstance().OnSourceLocalDmsDied(remote); +} + +void DCameraSourceHandlerIpc::OnSourceLocalDmsDied(const wptr& remote) +{ + sptr diedRemoted = remote.promote(); + if (diedRemoted == nullptr) { + DHLOGE("OnSourceLocalDmsDied promote failed!"); + return; + } + DHLOGI("OnSourceLocalDmsDied delete diedRemoted"); + auto remoteDmsDiedFunc = [this, diedRemoted]() { + OnSourceLocalDmsDied(diedRemoted); + }; + if (serviceHandler_ != nullptr) { + serviceHandler_->PostTask(remoteDmsDiedFunc); + } +} + +void DCameraSourceHandlerIpc::OnSourceLocalDmsDied(const sptr& remote) +{ + std::lock_guard autoLock(sourceLocalDmsLock_); + if (localSource_->AsObject() != remote) { + DHLOGI("OnSourceLocalDmsDied not found remote object"); + return; + } + + DHLOGI("OnSourceLocalDmsDied Clear"); + if (localSource_ != nullptr) { + localSource_->AsObject()->RemoveDeathRecipient(sourceLocalRecipient_); + } + localSource_ = nullptr; +} +} +} \ No newline at end of file diff --git a/interfaces/inner_kits/native_cpp/camera_source/src/distributed_camera_source_proxy.cpp b/interfaces/inner_kits/native_cpp/camera_source/src/distributed_camera_source_proxy.cpp new file mode 100644 index 00000000..07d5ddf3 --- /dev/null +++ b/interfaces/inner_kits/native_cpp/camera_source/src/distributed_camera_source_proxy.cpp @@ -0,0 +1,160 @@ +/* + * 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 "distributed_camera_source_proxy.h" + +#include "parcel.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DistributedCameraSourceProxy::InitSource(const std::string& params, + const sptr& callback) +{ + DHLOGI("DistributedCameraSourceProxy InitSource"); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSourceProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSourceProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSourceProxy InitSource write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!data.WriteString(params)) { + DHLOGE("DistributedCameraSourceProxy InitSource write params failed"); + return DCAMERA_BAD_VALUE; + } + + if (!data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("DistributedCameraSourceProxy InitSource write callback failed"); + return DCAMERA_BAD_VALUE; + } + + remote->SendRequest(INIT_SOURCE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSourceProxy::ReleaseSource() +{ + DHLOGI("DistributedCameraSourceProxy ReleaseSource"); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSourceProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSourceProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSourceProxy InitSource write token failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(RELEASE_SOURCE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSourceProxy::RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const EnableParam& param) +{ + DHLOGI("DistributedCameraSourceProxy RegisterDistributedHardware devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSourceProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSourceProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSourceProxy RegisterDistributedHardware write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) || !data.WriteString(reqId) || + !data.WriteString(param.version) || !data.WriteString(param.attrs)) { + DHLOGE("DistributedCameraSourceProxy RegisterDistributedHardware write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(REGISTER_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSourceProxy::UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId) +{ + DHLOGI("DistributedCameraSourceProxy UnregisterDistributedHardware devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSourceProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSourceProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSourceProxy UnregisterDistributedHardware write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) || !data.WriteString(reqId)) { + DHLOGE("DistributedCameraSourceProxy UnregisterDistributedHardware write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(UNREGISTER_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DistributedCameraSourceProxy::DCameraNotify(const std::string& devId, const std::string& dhId, + std::string& events) +{ + DHLOGI("DCameraNotify devId: %s dhId: %s events: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), events.c_str()); + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DistributedCameraSourceProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(DistributedCameraSourceProxy::GetDescriptor())) { + DHLOGE("DistributedCameraSourceProxy DCameraNotify write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) || !data.WriteString(events)) { + DHLOGE("DistributedCameraSourceProxy DCameraNotify write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(CAMERA_NOTIFY, data, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} +} +} \ No newline at end of file diff --git a/sa_profile/4803.xml b/sa_profile/4803.xml new file mode 100644 index 00000000..32f4655e --- /dev/null +++ b/sa_profile/4803.xml @@ -0,0 +1,27 @@ + + + + dhardware + + 4803 + libdistributed_camera_source.z.so + + + true + true + 1 + + diff --git a/sa_profile/4804.xml b/sa_profile/4804.xml new file mode 100644 index 00000000..d01ba659 --- /dev/null +++ b/sa_profile/4804.xml @@ -0,0 +1,27 @@ + + + + dhardware + + 4804 + libdistributed_camera_sink.z.so + + + true + true + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 00000000..8d10ac4f --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,23 @@ +# 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/sa_profile/sa_profile.gni") + +ohos_sa_profile("dcamera_sa_profile") { + sources = [ + "4803.xml", + "4804.xml", + ] + + part_name = "distributed_camera" +} diff --git a/services/cameraservice/base/include/dcamera_capture_info_cmd.h b/services/cameraservice/base/include/dcamera_capture_info_cmd.h new file mode 100644 index 00000000..4f54f8b7 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_capture_info_cmd.h @@ -0,0 +1,54 @@ +/* + * 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_CAPTURE_INFO_H +#define OHOS_DCAMERA_CAPTURE_INFO_H + +#include "distributed_camera_constants.h" +#include "json/json.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraCaptureInfo { +public: + int32_t width_; + int32_t height_; + int32_t format_; + int32_t dataspace_; + bool isCapture_; + DCEncodeType encodeType_; + DCStreamType streamType_; + std::vector> captureSettings_; +}; + +class DCameraCaptureInfoCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::vector> value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); + +private: + int32_t UmarshalValue(Json::Value& rootValue); + int32_t UmarshalSettings(Json::Value& valueJson, std::shared_ptr& captureInfo); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_channel_info_cmd.h b/services/cameraservice/base/include/dcamera_channel_info_cmd.h new file mode 100644 index 00000000..fe6506d4 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_channel_info_cmd.h @@ -0,0 +1,57 @@ +/* + * 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_CHANNEL_INFO_H +#define OHOS_DCAMERA_CHANNEL_INFO_H + +#include +#include +#include +#include + +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraChannelDetail { +public: + DCameraChannelDetail() = default; + DCameraChannelDetail(std::string dataSessionFlag, DCStreamType streamType) + : dataSessionFlag_(dataSessionFlag), streamType_(streamType) + {} + ~DCameraChannelDetail() = default; + std::string dataSessionFlag_; + DCStreamType streamType_; +}; + +class DCameraChannelInfo { +public: + std::string sourceDevId_; + std::vector detail_; +}; + +class DCameraChannelInfoCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::shared_ptr value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_event_cmd.h b/services/cameraservice/base/include/dcamera_event_cmd.h new file mode 100644 index 00000000..cf940603 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_event_cmd.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 OHOS_DCAMERA_EVENT_H +#define OHOS_DCAMERA_EVENT_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +class DCameraEvent { +public: + int32_t eventType_; + int32_t eventResult_; + std::string eventContent_; +}; + +class DCameraEventCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::shared_ptr value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_info_cmd.h b/services/cameraservice/base/include/dcamera_info_cmd.h new file mode 100644 index 00000000..1519de6f --- /dev/null +++ b/services/cameraservice/base/include/dcamera_info_cmd.h @@ -0,0 +1,48 @@ +/* + * 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_INFO_H +#define OHOS_DCAMERA_INFO_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +enum { + DCAMERA_LOCAL_CLOSE = 0, + DCAMERA_LOCAL_OPEN = 1, +}; + +class DCameraInfo { +public: + int32_t state_; +}; + +class DCameraInfoCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::shared_ptr value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_metadata_setting_cmd.h b/services/cameraservice/base/include/dcamera_metadata_setting_cmd.h new file mode 100644 index 00000000..b6ea22e0 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_metadata_setting_cmd.h @@ -0,0 +1,36 @@ +/* + * 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_METADATA_SETTING_H +#define OHOS_DCAMERA_METADATA_SETTING_H + +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraMetadataSettingCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::vector> value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_open_info_cmd.h b/services/cameraservice/base/include/dcamera_open_info_cmd.h new file mode 100644 index 00000000..eeda2644 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_open_info_cmd.h @@ -0,0 +1,46 @@ +/* + * 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_OPEN_INFO_H +#define OHOS_DCAMERA_OPEN_INFO_H + +#include +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +class DCameraOpenInfo { +public: + DCameraOpenInfo() {} + DCameraOpenInfo(std::string sourceDevId) : sourceDevId_(sourceDevId) {} + ~DCameraOpenInfo() = default; + std::string sourceDevId_; +}; + +class DCameraOpenInfoCmd { +public: + std::string type_; + std::string dhId_; + std::string command_; + std::shared_ptr value_; + +public: + int32_t Marshal(std::string& jsonStr); + int32_t Unmarshal(const std::string& jsonStr); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/dcamera_protocol.h b/services/cameraservice/base/include/dcamera_protocol.h new file mode 100644 index 00000000..7cbdb4b7 --- /dev/null +++ b/services/cameraservice/base/include/dcamera_protocol.h @@ -0,0 +1,37 @@ +/* + * 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_PROTOCOL_H +#define OHOS_DCAMERA_PROTOCOL_H + +#include + +namespace OHOS { +namespace DistributedHardware { +static const std::string DCAMERA_PROTOCOL_TYPE_MESSAGE = "MESSAGE"; +static const std::string DCAMERA_PROTOCOL_TYPE_OPERATION = "OPERATION"; + +static const std::string DCAMERA_PROTOCOL_CMD_GET_INFO = "GET_INFO"; +static const std::string DCAMERA_PROTOCOL_CMD_CHAN_NEG = "CHANNEL_NEG"; +static const std::string DCAMERA_PROTOCOL_CMD_UPDATE_METADATA = "UPDATE_METADATA"; +static const std::string DCAMERA_PROTOCOL_CMD_METADATA_RESULT = "METADATA_RESULT"; +static const std::string DCAMERA_PROTOCOL_CMD_STATE_NOTIFY = "STATE_NOTIFY"; +static const std::string DCAMERA_PROTOCOL_CMD_CAPTURE = "CAPTURE"; +static const std::string DCAMERA_PROTOCOL_CMD_STOP_CAPTURE = "STOP_CAPTURE"; +static const std::string DCAMERA_PROTOCOL_CMD_OPEN_CHANNEL = "OPEN_CHANNEL"; +static const std::string DCAMERA_PROTOCOL_CMD_CLOSE_CHANNEL = "CLOSE_CHANNEL"; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/include/icamera_controller.h b/services/cameraservice/base/include/icamera_controller.h new file mode 100644 index 00000000..47da557a --- /dev/null +++ b/services/cameraservice/base/include/icamera_controller.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 OHOS_ICAMERA_CONTROLLER_H +#define OHOS_ICAMERA_CONTROLLER_H +#include "dcamera_capture_info_cmd.h" +#include "dcamera_channel_info_cmd.h" +#include "dcamera_event_cmd.h" +#include "dcamera_info_cmd.h" +#include "dcamera_index.h" +#include "dcamera_open_info_cmd.h" + +namespace OHOS { +namespace DistributedHardware { +class ICameraController { +public: + ICameraController() = default; + virtual ~ICameraController() = default; + + virtual int32_t StartCapture(std::vector>& captureInfos) = 0; + virtual int32_t StopCapture() = 0; + virtual int32_t ChannelNeg(std::shared_ptr& info) = 0; + virtual int32_t DCameraNotify(std::shared_ptr& events) = 0; + virtual int32_t UpdateSettings(std::vector>& settings) = 0; + virtual int32_t GetCameraInfo(std::shared_ptr& camInfo) = 0; + virtual int32_t OpenChannel(std::shared_ptr& openInfo) = 0; + virtual int32_t CloseChannel() = 0; + virtual int32_t Init(std::vector& indexs) = 0; + virtual int32_t UnInit() = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp b/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp new file mode 100644 index 00000000..9d5665dc --- /dev/null +++ b/services/cameraservice/base/src/dcamera_capture_info_cmd.cpp @@ -0,0 +1,170 @@ +/* + * 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_capture_info_cmd.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraCaptureInfoCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + Json::Value captureInfos; + for (auto iter = value_.begin(); iter != value_.end(); iter++) { + Json::Value captureInfo; + std::shared_ptr capture = *iter; + captureInfo["Width"] = Json::Value(capture->width_); + captureInfo["Height"] = Json::Value(capture->height_); + captureInfo["Format"] = Json::Value(capture->format_); + captureInfo["DataSpace"] = Json::Value(capture->dataspace_); + captureInfo["IsCapture"] = Json::Value(capture->isCapture_); + captureInfo["EncodeType"] = Json::Value(capture->encodeType_); + captureInfo["StreamType"] = Json::Value(capture->streamType_); + + Json::Value captureSettings; + for (auto settingIter = capture->captureSettings_.begin(); + settingIter != capture->captureSettings_.end(); settingIter++) { + Json::Value captureSetting; + captureSetting["SettingType"] = Json::Value((*settingIter)->type_); + captureSetting["SettingValue"] = Json::Value((*settingIter)->value_); + captureSettings.append(captureSetting); + } + + captureInfo["CaptureSettings"] = captureSettings; + captureInfos.append(captureInfo); + } + + rootValue["Value"] = captureInfos; + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraCaptureInfoCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isArray()) { + return DCAMERA_BAD_VALUE; + } + + int32_t ret = UmarshalValue(rootValue); + if (ret != DCAMERA_OK) { + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraCaptureInfoCmd::UmarshalValue(Json::Value& rootValue) +{ + for (Json::ArrayIndex i = 0; i < rootValue["Value"].size(); i++) { + Json::Value valueJson = rootValue["Value"][i]; + std::shared_ptr captureInfo = std::make_shared(); + if (!valueJson.isMember("Width") || !valueJson["Width"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->width_ = valueJson["Width"].asInt(); + + if (!valueJson.isMember("Height") || !valueJson["Height"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->height_ = valueJson["Height"].asInt(); + + if (!valueJson.isMember("Format") || !valueJson["Format"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->format_ = valueJson["Format"].asInt(); + + if (!valueJson.isMember("DataSpace") || !valueJson["DataSpace"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->dataspace_ = valueJson["DataSpace"].asInt(); + + if (!valueJson.isMember("IsCapture") || !valueJson["IsCapture"].isBool()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->isCapture_ = valueJson["IsCapture"].asBool(); + + if (!valueJson.isMember("EncodeType") || !valueJson["EncodeType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->encodeType_ = (DCEncodeType)valueJson["EncodeType"].asInt(); + + if (!valueJson.isMember("StreamType") || !valueJson["StreamType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + captureInfo->streamType_ = (DCStreamType)valueJson["StreamType"].asInt(); + + if (!valueJson.isMember("CaptureSettings") || !valueJson["CaptureSettings"].isArray()) { + return DCAMERA_BAD_VALUE; + } + + int32_t ret = UmarshalSettings(valueJson, captureInfo); + if (ret != DCAMERA_OK) { + return ret; + } + value_.push_back(captureInfo); + } + return DCAMERA_OK; +} + +int32_t DCameraCaptureInfoCmd::UmarshalSettings(Json::Value& valueJson, + std::shared_ptr& captureInfo) +{ + for (Json::ArrayIndex j = 0; j < valueJson["CaptureSettings"].size(); j++) { + Json::Value settingJson = valueJson["CaptureSettings"][j]; + if (!settingJson.isMember("SettingType") || !settingJson["SettingType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + if (!settingJson.isMember("SettingValue") || !settingJson["SettingValue"].isString()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr setting = std::make_shared(); + setting->type_ = (DCSettingsType)settingJson["SettingType"].asInt(); + setting->value_ = settingJson["SettingValue"].asString(); + captureInfo->captureSettings_.push_back(setting); + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_channel_info_cmd.cpp b/services/cameraservice/base/src/dcamera_channel_info_cmd.cpp new file mode 100644 index 00000000..20adf00a --- /dev/null +++ b/services/cameraservice/base/src/dcamera_channel_info_cmd.cpp @@ -0,0 +1,108 @@ +/* + * 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_channel_info_cmd.h" + +#include "json/json.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraChannelInfoCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + + Json::Value channelInfo; + channelInfo["SourceDevId"] = Json::Value(value_->sourceDevId_); + Json::Value details; + for (auto iter = value_->detail_.begin(); iter != value_->detail_.end(); iter++) { + Json::Value detail; + detail["DataSessionFlag"] = Json::Value(iter->dataSessionFlag_); + detail["StreamType"] = Json::Value(iter->streamType_); + details.append(detail); + } + channelInfo["Detail"] = details; + rootValue["Value"] = channelInfo; + + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraChannelInfoCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isObject()) { + return DCAMERA_BAD_VALUE; + } + Json::Value valueJson = rootValue["Value"]; + + if (!valueJson.isMember("SourceDevId") || !valueJson["SourceDevId"].isString()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr channelInfo = std::make_shared(); + channelInfo->sourceDevId_ = valueJson["SourceDevId"].asString(); + + if (!valueJson.isMember("Detail") || !valueJson["Detail"].isArray()) { + return DCAMERA_BAD_VALUE; + } + + for (Json::ArrayIndex i = 0; i < valueJson["Detail"].size(); i++) { + Json::Value detailJson = valueJson["Detail"][i]; + DCameraChannelDetail channelDetail; + if (!detailJson.isMember("DataSessionFlag") || !detailJson["DataSessionFlag"].isString()) { + return DCAMERA_BAD_VALUE; + } + if (!detailJson.isMember("StreamType") || !detailJson["StreamType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + channelDetail.dataSessionFlag_ = detailJson["DataSessionFlag"].asString(); + channelDetail.streamType_ = (DCStreamType)detailJson["StreamType"].asInt(); + channelInfo->detail_.push_back(channelDetail); + } + value_ = channelInfo; + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_event_cmd.cpp b/services/cameraservice/base/src/dcamera_event_cmd.cpp new file mode 100644 index 00000000..d7629fa9 --- /dev/null +++ b/services/cameraservice/base/src/dcamera_event_cmd.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 "dcamera_event_cmd.h" + +#include "json/json.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraEventCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + + Json::Value event; + event["EventType"] = Json::Value(value_->eventType_); + event["EventResult"] = Json::Value(value_->eventResult_); + event["EventContent"] = Json::Value(value_->eventContent_); + rootValue["Value"] = event; + + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraEventCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isObject()) { + return DCAMERA_BAD_VALUE; + } + Json::Value valueJson = rootValue["Value"]; + + if (!valueJson.isMember("EventType") || !valueJson["EventType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr event = std::make_shared(); + event->eventType_ = valueJson["EventType"].asInt(); + + if (!valueJson.isMember("EventResult") || !valueJson["EventResult"].isInt()) { + return DCAMERA_BAD_VALUE; + } + event->eventResult_ = valueJson["EventResult"].asInt(); + + if (!valueJson.isMember("EventContent") || !valueJson["EventContent"].isString()) { + return DCAMERA_BAD_VALUE; + } + event->eventContent_ = valueJson["EventContent"].asString(); + + value_ = event; + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_info_cmd.cpp b/services/cameraservice/base/src/dcamera_info_cmd.cpp new file mode 100644 index 00000000..ee34a4b3 --- /dev/null +++ b/services/cameraservice/base/src/dcamera_info_cmd.cpp @@ -0,0 +1,83 @@ +/* + * 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_info_cmd.h" + +#include "json/json.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraInfoCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + + Json::Value info; + info["State"] = Json::Value(value_->state_); + rootValue["Value"] = info; + + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraInfoCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isObject()) { + return DCAMERA_BAD_VALUE; + } + Json::Value valueJson = rootValue["Value"]; + + if (!valueJson.isMember("State") || !valueJson["State"].isInt()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr info = std::make_shared(); + info->state_ = valueJson["State"].asInt(); + + value_ = info; + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp b/services/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp new file mode 100644 index 00000000..9c11e677 --- /dev/null +++ b/services/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp @@ -0,0 +1,93 @@ +/* + * 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_metadata_setting_cmd.h" + +#include "json/json.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraMetadataSettingCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + + Json::Value settings; + for (auto iter = value_.begin(); iter != value_.end(); iter++) { + Json::Value setting; + setting["SettingType"] = (*iter)->type_; + setting["SettingValue"] = (*iter)->value_; + settings.append(setting); + } + + rootValue["Value"] = settings; + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraMetadataSettingCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isArray()) { + return DCAMERA_BAD_VALUE; + } + + for (Json::ArrayIndex i = 0; i < rootValue["Value"].size(); i++) { + Json::Value valueJsonEle = rootValue["Value"][i]; + if (!valueJsonEle.isMember("SettingType") || !valueJsonEle["SettingType"].isInt()) { + return DCAMERA_BAD_VALUE; + } + if (!valueJsonEle.isMember("SettingValue") || !valueJsonEle["SettingValue"].isString()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr setting = std::make_shared(); + setting->type_ = (DCSettingsType)valueJsonEle["SettingType"].asInt(); + setting->value_ = valueJsonEle["SettingValue"].asString(); + value_.push_back(setting); + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/src/dcamera_open_info_cmd.cpp b/services/cameraservice/base/src/dcamera_open_info_cmd.cpp new file mode 100644 index 00000000..d8024026 --- /dev/null +++ b/services/cameraservice/base/src/dcamera_open_info_cmd.cpp @@ -0,0 +1,82 @@ +/* + * 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_open_info_cmd.h" + +#include "json/json.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraOpenInfoCmd::Marshal(std::string& jsonStr) +{ + Json::Value rootValue; + rootValue["Type"] = Json::Value(type_); + rootValue["dhId"] = Json::Value(dhId_); + rootValue["Command"] = Json::Value(command_); + + Json::Value openInfo; + openInfo["SourceDevId"] = Json::Value(value_->sourceDevId_); + rootValue["Value"] = openInfo; + + jsonStr = rootValue.toStyledString(); + return DCAMERA_OK; +} + +int32_t DCameraOpenInfoCmd::Unmarshal(const std::string& jsonStr) +{ + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return DCAMERA_BAD_VALUE; + } + + if (!rootValue.isMember("Type") || !rootValue["Type"].isString()) { + return DCAMERA_BAD_VALUE; + } + type_ = rootValue["Type"].asString(); + + if (!rootValue.isMember("dhId") || !rootValue["dhId"].isString()) { + return DCAMERA_BAD_VALUE; + } + dhId_ = rootValue["dhId"].asString(); + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return DCAMERA_BAD_VALUE; + } + command_ = rootValue["Command"].asString(); + + if (!rootValue.isMember("Value") || !rootValue["Value"].isObject()) { + return DCAMERA_BAD_VALUE; + } + Json::Value valueJson = rootValue["Value"]; + + if (!valueJson.isMember("SourceDevId") || !valueJson["SourceDevId"].isString()) { + return DCAMERA_BAD_VALUE; + } + std::shared_ptr openInfo = std::make_shared(); + openInfo->sourceDevId_ = valueJson["SourceDevId"].asString(); + value_ = openInfo; + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/base/test/unittest/BUILD.gn b/services/cameraservice/base/test/unittest/BUILD.gn new file mode 100644 index 00000000..a92ba40f --- /dev/null +++ b/services/cameraservice/base/test/unittest/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +group("services_base_test") { + testonly = true + deps = [ + "common/dcameraprotocol:dcamera_protocol_test", + ] +} \ No newline at end of file diff --git a/services/cameraservice/base/test/unittest/common/dcameraprotocol/BUILD.gn b/services/cameraservice/base/test/unittest/common/dcameraprotocol/BUILD.gn new file mode 100644 index 00000000..f6e7b2ea --- /dev/null +++ b/services/cameraservice/base/test/unittest/common/dcameraprotocol/BUILD.gn @@ -0,0 +1,75 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributedcamera/dcamera_protocol_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//drivers/peripheral/base", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_sink/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + "${services_path}/cameraservice/base/include", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${distributedcamera_hdf_path}/interfaces/include", + ] +} + +ohos_unittest("DCameraProtocolTest") { + module_out_path = module_out_path + + sources = [ + "dcamera_protocol_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gtest_main", + "//third_party/jsoncpp:jsoncpp", + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "//utils/native/base:utils", + "${services_path}/cameraservice/sourceservice:distributed_camera_source" + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DCameraProtocolTest\"", + "LOG_DOMAIN=0xD004100", + ] +} + +group("dcamera_protocol_test") { + testonly = true + deps = [ ":DCameraProtocolTest" ] +} \ No newline at end of file diff --git a/services/cameraservice/base/test/unittest/common/dcameraprotocol/dcamera_protocol_test.cpp b/services/cameraservice/base/test/unittest/common/dcameraprotocol/dcamera_protocol_test.cpp new file mode 100644 index 00000000..8527053a --- /dev/null +++ b/services/cameraservice/base/test/unittest/common/dcameraprotocol/dcamera_protocol_test.cpp @@ -0,0 +1,198 @@ +/* + * 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 "anonymous_string.h" +#include "distributed_hardware_log.h" + +#include "dcamera_capture_info_cmd.h" +#include "dcamera_channel_info_cmd.h" +#include "dcamera_event_cmd.h" +#include "dcamera_info_cmd.h" +#include "dcamera_metadata_setting_cmd.h" +#include "dcamera_protocol.h" +#include "dcamera_utils_tools.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraProtocolTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +static std::string g_testDeviceId; +static const std::string TEST_CAPTURE_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CAPTURE", + "Value": [ + {"Width": 1920, "Height": 1080, "Format": 1, "DataSpace": 1, + "IsCapture":true, "EncodeType": 1, "StreamType": 1, + "CaptureSettings": [{"SettingType": 1, "SettingValue": "TestSetting"}]} + ] +})"; + +static const std::string TEST_CHANNEL_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CHANNEL_NEG", + "Value": {"SourceDevId": "TestDevId", "Detail": [{"DataSessionFlag": "TestFlag", "StreamType": 1}]} +})"; + +static const std::string TEST_EVENT_CMD_JSON = R"({ + "Type": "MESSAGE", + "dhId": "camrea_0", + "Command": "STATE_NOTIFY", + "Value": {"EventType": 1, "EventResult": 1, "EventContent": "TestContent"} +})"; + +static const std::string TEST_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "GET_INFO", + "Value": {"State": 1} +})"; + +static const std::string TEST_METADATA_SETTING_CMD_JSON = R"({ + "Type": "MESSAGE", + "dhId": "camrea_0", + "Command": "UPDATE_METADATA", + "Value": [{"SettingType": 1, "SettingValue": "TestSetting"}] +})"; + +void DCameraProtocolTest::SetUpTestCase(void) +{ + GetLocalDeviceNetworkId(g_testDeviceId); +} + +void DCameraProtocolTest::TearDownTestCase(void) +{ +} + +void DCameraProtocolTest::SetUp(void) +{ +} + +void DCameraProtocolTest::TearDown(void) +{ +} + +/** + * @tc.name: dcamera_protocol_test_001 + * @tc.desc: Verify Get ServiceAbility. + * @tc.type: FUNC + * @tc.require: AR000GK6MH + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_001, TestSize.Level1) +{ + int32_t ret = DCAMERA_OK; + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_protocol_test_002 + * @tc.desc: Verify CaptureInfoCmd Json. + * @tc.type: FUNC + * @tc.require: AR000GK6MH + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_002, TestSize.Level1) +{ + DCameraCaptureInfoCmd cmd; + int32_t ret = cmd.Unmarshal(TEST_CAPTURE_INFO_CMD_JSON); + EXPECT_EQ(DCAMERA_OK, ret); + + std::string jsonStr; + ret = cmd.Marshal(jsonStr); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_protocol_test_003 + * @tc.desc: Verify ChannelInfoCmd Json. + * @tc.type: FUNC + * @tc.require: AR000GK6MI + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_003, TestSize.Level1) +{ + DCameraChannelInfoCmd cmd; + int32_t ret = cmd.Unmarshal(TEST_CHANNEL_INFO_CMD_JSON); + EXPECT_EQ(DCAMERA_OK, ret); + + std::string jsonStr; + ret = cmd.Marshal(jsonStr); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_protocol_test_004 + * @tc.desc: Verify EventCmd Json. + * @tc.type: FUNC + * @tc.require: AR000GK6MI + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_004, TestSize.Level1) +{ + DCameraEventCmd cmd; + int32_t ret = cmd.Unmarshal(TEST_EVENT_CMD_JSON); + EXPECT_EQ(DCAMERA_OK, ret); + + std::string jsonStr; + ret = cmd.Marshal(jsonStr); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_protocol_test_005 + * @tc.desc: Verify CameraInfoCmd Json. + * @tc.type: FUNC + * @tc.require: AR000GS3AA + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_005, TestSize.Level1) +{ + DCameraInfoCmd cmd; + int32_t ret = cmd.Unmarshal(TEST_INFO_CMD_JSON); + EXPECT_EQ(DCAMERA_OK, ret); + + std::string jsonStr; + ret = cmd.Marshal(jsonStr); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_protocol_test_006 + * @tc.desc: Verify MetaDataSettingCmd Json. + * @tc.type: FUNC + * @tc.require: AR000GS3AA + */ +HWTEST_F(DCameraProtocolTest, dcamera_protocol_test_006, TestSize.Level1) +{ + DCameraMetadataSettingCmd cmd; + int32_t ret = cmd.Unmarshal(TEST_METADATA_SETTING_CMD_JSON); + EXPECT_EQ(DCAMERA_OK, ret); + + std::string jsonStr; + ret = cmd.Marshal(jsonStr); + EXPECT_EQ(DCAMERA_OK, ret); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/BUILD.gn b/services/cameraservice/cameraoperator/client/BUILD.gn new file mode 100644 index 00000000..c92d304e --- /dev/null +++ b/services/cameraservice/cameraoperator/client/BUILD.gn @@ -0,0 +1,85 @@ +# 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("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_client") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${graphicstandard_path}/frameworks/surface/include", + "${camerastandard_path}/frameworks/native/metadata/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/input", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/output", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/session", + "${camerastandard_path}/services/camera_service/binder/base/include", + "${camerastandard_path}/services/camera_service/binder/client/include", + "${camerastandard_path}/services/camera_service/binder/server/include", + "${camerastandard_path}/services/camera_service/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "include", + "include/callback", + "include/listener", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${distributedcamera_hdf_path}/interfaces/include", + "${services_path}/cameraservice/base/include", + "//third_party/jsoncpp/include", + ] + + sources = [ + "src/dcamera_client.cpp", + "src/callback/dcamera_input_callback.cpp", + "src/callback/dcamera_manager_callback.cpp", + "src/callback/dcamera_photo_callback.cpp", + "src/callback/dcamera_preview_callback.cpp", + "src/callback/dcamera_session_callback.cpp", + "src/callback/dcamera_video_callback.cpp", + "src/listener/dcamera_photo_surface_listener.cpp", + "src/listener/dcamera_video_surface_listener.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${graphicstandard_path}:libsurface", + "${camerastandard_path}/frameworks/native/camera:camera_framework", + "${camerastandard_path}/frameworks/native/metadata:metadata", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcameraclient\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_input_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_input_callback.h new file mode 100644 index 00000000..e29fcc70 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_input_callback.h @@ -0,0 +1,35 @@ +/* + * 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_INPUT_CALLBACK_H +#define OHOS_DCAMERA_INPUT_CALLBACK_H + +#include "camera_input.h" + +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraInputCallback : public CameraStandard::ErrorCallback { +public: + explicit DCameraInputCallback(const std::shared_ptr& callback); + void OnError(const int32_t errorType, const int32_t errorMsg) const override; + +private: + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_INPUT_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_manager_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_manager_callback.h new file mode 100644 index 00000000..b6f35f3f --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_manager_callback.h @@ -0,0 +1,31 @@ +/* + * 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_MANAGER_CALLBACK_H +#define OHOS_DCAMERA_MANAGER_CALLBACK_H + +#include "camera_manager.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraManagerCallback : public CameraStandard::CameraManagerCallback { +public: + void OnCameraStatusChanged(const CameraStandard::CameraStatusInfo &cameraStatusInfo) const override; + void OnFlashlightStatusChanged(const std::string &cameraID, + const CameraStandard::FlashlightStatus flashStatus) const override; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_MANAGER_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_photo_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_photo_callback.h new file mode 100644 index 00000000..5cc4804d --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_photo_callback.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_PHOTO_CALLBACK_H +#define OHOS_DCAMERA_PHOTO_CALLBACK_H + +#include "photo_output.h" + +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPhotoCallback : public CameraStandard::PhotoCallback { +public: + explicit DCameraPhotoCallback(const std::shared_ptr& callback); + void OnCaptureStarted(const int32_t captureID) const override; + void OnCaptureEnded(const int32_t captureID, int32_t frameCount) const override; + void OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const override; + void OnCaptureError(const int32_t captureId, const int32_t errorCode) const override; + +private: + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_PHOTO_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_preview_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_preview_callback.h new file mode 100644 index 00000000..c38caccf --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_preview_callback.h @@ -0,0 +1,37 @@ +/* + * 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_PREVIEW_CALLBACK_H +#define OHOS_DCAMERA_PREVIEW_CALLBACK_H + +#include "preview_output.h" + +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPreviewCallback : public CameraStandard::PreviewCallback { +public: + explicit DCameraPreviewCallback(const std::shared_ptr& callback); + void OnFrameStarted() const override; + void OnFrameEnded(const int32_t frameCount) const override; + void OnError(const int32_t errorCode) const override; + +private: + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_PREVIEW_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_session_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_session_callback.h new file mode 100644 index 00000000..343d1c2a --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_session_callback.h @@ -0,0 +1,35 @@ +/* + * 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_SESSION_CALLBACK_H +#define OHOS_DCAMERA_SESSION_CALLBACK_H + +#include "capture_session.h" + +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSessionCallback : public CameraStandard::SessionCallback { +public: + explicit DCameraSessionCallback(const std::shared_ptr& callback); + void OnError(int32_t errorCode) override; + +private: + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SESSION_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/callback/dcamera_video_callback.h b/services/cameraservice/cameraoperator/client/include/callback/dcamera_video_callback.h new file mode 100644 index 00000000..6f82f159 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/callback/dcamera_video_callback.h @@ -0,0 +1,37 @@ +/* + * 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_VIDEO_CALLBACK_H +#define OHOS_DCAMERA_VIDEO_CALLBACK_H + +#include "video_output.h" + +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraVideoCallback : public CameraStandard::VideoCallback { +public: + explicit DCameraVideoCallback(const std::shared_ptr& callback); + void OnFrameStarted() const override; + void OnFrameEnded(const int32_t frameCount) const override; + void OnError(const int32_t errorCode) const override; + +private: + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_VIDEO_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/dcamera_client.h b/services/cameraservice/cameraoperator/client/include/dcamera_client.h new file mode 100644 index 00000000..73591141 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/dcamera_client.h @@ -0,0 +1,77 @@ +/* + * 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_CLIENT_H +#define OHOS_DCAMERA_CLIENT_H + +#include "icamera_operator.h" + +#include "camera_info.h" +#include "camera_input.h" +#include "camera_manager.h" +#include "capture_input.h" +#include "capture_output.h" +#include "capture_session.h" +#include "photo_output.h" +#include "preview_output.h" +#include "video_output.h" + +#include "dcamera_photo_surface_listener.h" +#include "dcamera_video_surface_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraClient : public ICameraOperator { +public: + explicit DCameraClient(const std::string& dhId); + ~DCameraClient(); + + int32_t Init() override; + int32_t UnInit() override; + int32_t UpdateSettings(std::vector>& settings) override; + int32_t StartCapture(std::vector>& captureInfos) override; + int32_t StopCapture() override; + int32_t SetStateCallback(std::shared_ptr& callback) override; + int32_t SetResultCallback(std::shared_ptr& callback) override; + +private: + int32_t ConfigCaptureSession(std::vector>& captureInfos); + int32_t ConfigCaptureSessionInner(); + int32_t CreateCaptureOutput(std::vector>& captureInfos); + int32_t CreatePhotoOutput(std::shared_ptr& info); + int32_t CreateVideoOutput(std::shared_ptr& info); + int32_t StartCaptureInner(std::shared_ptr& info); + int32_t StartPhotoOutput(std::shared_ptr& info); + int32_t StartVideoOutput(); + + bool isInit_; + std::string cameraId_; + sptr photoSurface_; + sptr videoSurface_; + sptr cameraInfo_; + sptr cameraManager_; + sptr captureSession_; + sptr cameraInput_; + sptr photoOutput_; + sptr previewOutput_; + sptr videoOutput_; + std::shared_ptr stateCallback_; + std::shared_ptr resultCallback_; + std::shared_ptr photoListener_; + std::shared_ptr videoListener_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_CLIENT_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/icamera_operator.h b/services/cameraservice/cameraoperator/client/include/icamera_operator.h new file mode 100644 index 00000000..6f787d36 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/icamera_operator.h @@ -0,0 +1,64 @@ +/* + * 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_ICAMERA_OPERATOR_H +#define OHOS_ICAMERA_OPERATOR_H + +#include +#include +#include +#include + +#include "data_buffer.h" +#include "dcamera_capture_info_cmd.h" +#include "dcamera_event_cmd.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class StateCallback { +public: + StateCallback() = default; + virtual ~StateCallback() = default; + + virtual void OnStateChanged(std::shared_ptr& event) = 0; + virtual void OnMetadataResult() = 0; +}; + +class ResultCallback { +public: + ResultCallback() = default; + virtual ~ResultCallback() = default; + + virtual void OnPhotoResult(std::shared_ptr& buffer) = 0; + virtual void OnVideoResult(std::shared_ptr& buffer) = 0; +}; + +class ICameraOperator { +public: + ICameraOperator() = default; + virtual ~ICameraOperator() = default; + + virtual int32_t Init() = 0; + virtual int32_t UnInit() = 0; + virtual int32_t UpdateSettings(std::vector>& settings) = 0; + virtual int32_t StartCapture(std::vector>& captureInfos) = 0; + virtual int32_t StopCapture() = 0; + virtual int32_t SetStateCallback(std::shared_ptr& callback) = 0; + virtual int32_t SetResultCallback(std::shared_ptr& callback) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_ICAMERA_OPERATOR_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/listener/dcamera_photo_surface_listener.h b/services/cameraservice/cameraoperator/client/include/listener/dcamera_photo_surface_listener.h new file mode 100644 index 00000000..54a9e50c --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/listener/dcamera_photo_surface_listener.h @@ -0,0 +1,36 @@ +/* + * 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_PHOTO_SURFACE_LISTENER_H +#define OHOS_DCAMERA_PHOTO_SURFACE_LISTENER_H + +#include "surface.h" +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPhotoSurfaceListener : public IBufferConsumerListener { +public: + DCameraPhotoSurfaceListener(const sptr& surface, + const std::shared_ptr& callback); + void OnBufferAvailable() override; + +private: + sptr surface_; + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_PHOTO_SURFACE_LISTENER_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/include/listener/dcamera_video_surface_listener.h b/services/cameraservice/cameraoperator/client/include/listener/dcamera_video_surface_listener.h new file mode 100644 index 00000000..c1bae897 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/include/listener/dcamera_video_surface_listener.h @@ -0,0 +1,36 @@ +/* + * 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_VIDEO_SURFACE_LISTENER_H +#define OHOS_DCAMERA_VIDEO_SURFACE_LISTENER_H + +#include "surface.h" +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraVideoSurfaceListener : public IBufferConsumerListener { +public: + DCameraVideoSurfaceListener(const sptr& surface, + const std::shared_ptr& callback); + void OnBufferAvailable() override; + +private: + sptr surface_; + std::shared_ptr callback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_VIDEO_SURFACE_LISTENER_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_input_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_input_callback.cpp new file mode 100644 index 00000000..e915aac5 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_input_callback.cpp @@ -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. + */ + +#include "dcamera_input_callback.h" + +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraInputCallback::DCameraInputCallback(const std::shared_ptr& callback) : callback_(callback) +{ +} + +void DCameraInputCallback::OnError(const int32_t errorType, const int32_t errorMsg) const +{ + DHLOGE("DCameraInputCallback::OnError, errorType: %d, errorMsg: %d", errorType, errorMsg); + if (callback_ == nullptr) { + DHLOGE("DCameraInputCallback::OnError StateCallback is null"); + return; + } + + std::shared_ptr event = std::make_shared(); + event->eventType_ = DCAMERA_MESSAGE; + event->eventResult_ = DCAMERA_EVENT_CAMERA_ERROR; + callback_->OnStateChanged(event); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_manager_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_manager_callback.cpp new file mode 100644 index 00000000..0f3865d7 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_manager_callback.cpp @@ -0,0 +1,36 @@ +/* + * 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_manager_callback.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DCameraManagerCallback::OnCameraStatusChanged(const CameraStandard::CameraStatusInfo &cameraStatusInfo) const +{ + DHLOGI("DCameraManagerCallback::OnCameraStatusChanged, cameraStatus: %d", cameraStatusInfo.cameraStatus); +} + +void DCameraManagerCallback::OnFlashlightStatusChanged(const std::string &cameraID, + const CameraStandard::FlashlightStatus flashStatus) const +{ + DHLOGI("DCameraManagerCallback::OnFlashlightStatusChanged, cameraID: %s, flashStatus: %d", + GetAnonyString(cameraID).c_str(), flashStatus); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_photo_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_photo_callback.cpp new file mode 100644 index 00000000..62f283ef --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_photo_callback.cpp @@ -0,0 +1,56 @@ +/* + * 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_photo_callback.h" + +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraPhotoCallback::DCameraPhotoCallback(const std::shared_ptr& callback) : callback_(callback) +{ +} + +void DCameraPhotoCallback::OnCaptureStarted(const int32_t captureID) const +{ + DHLOGI("DCameraPhotoCallback::OnCaptureStarted, captureID: %d", captureID); +} + +void DCameraPhotoCallback::OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const +{ + DHLOGI("DCameraPhotoCallback::OnCaptureEnded, captureID: %d, frameCount: %d", captureID, frameCount); +} + +void DCameraPhotoCallback::OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const +{ + DHLOGI("DCameraPhotoCallback::OnFrameShutter, captureId: %d, timestamp: %llu", captureId, timestamp); +} + +void DCameraPhotoCallback::OnCaptureError(const int32_t captureId, const int32_t errorCode) const +{ + DHLOGE("DCameraPhotoCallback::OnCaptureError, captureId: %d, errorCode: %d", captureId, errorCode); + if (callback_ == nullptr) { + DHLOGE("DCameraPhotoCallback::OnCaptureError StateCallback is null"); + return; + } + + std::shared_ptr event = std::make_shared(); + event->eventType_ = DCAMERA_MESSAGE; + event->eventResult_ = DCAMERA_EVENT_CAMERA_ERROR; + callback_->OnStateChanged(event); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_preview_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_preview_callback.cpp new file mode 100644 index 00000000..1eb36092 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_preview_callback.cpp @@ -0,0 +1,51 @@ +/* + * 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_preview_callback.h" + +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraPreviewCallback::DCameraPreviewCallback(const std::shared_ptr& callback) : callback_(callback) +{ +} + +void DCameraPreviewCallback::OnFrameStarted() const +{ + DHLOGI("DCameraPreviewCallback::OnFrameStarted"); +} + +void DCameraPreviewCallback::OnFrameEnded(const int32_t frameCount) const +{ + DHLOGI("DCameraPreviewCallback::OnFrameEnded, frameCount: %d", frameCount); +} + +void DCameraPreviewCallback::OnError(const int32_t errorCode) const +{ + DHLOGE("DCameraPreviewCallback::OnError, errorCode: %d", errorCode); + if (callback_ == nullptr) { + DHLOGE("DCameraPreviewCallback::OnError StateCallback is null"); + return; + } + + std::shared_ptr event = std::make_shared(); + event->eventType_ = DCAMERA_MESSAGE; + event->eventResult_ = DCAMERA_EVENT_CAMERA_ERROR; + callback_->OnStateChanged(event); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_session_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_session_callback.cpp new file mode 100644 index 00000000..d26fb922 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_session_callback.cpp @@ -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. + */ + +#include "dcamera_session_callback.h" + +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSessionCallback::DCameraSessionCallback(const std::shared_ptr& callback) : callback_(callback) +{ +} + +void DCameraSessionCallback::OnError(int32_t errorCode) +{ + DHLOGE("DCameraSessionCallback::OnError, errorCode: %d", errorCode); + if (callback_ == nullptr) { + DHLOGE("DCameraSessionCallback::OnError StateCallback is null"); + return; + } + + std::shared_ptr event = std::make_shared(); + event->eventType_ = DCAMERA_MESSAGE; + event->eventResult_ = DCAMERA_EVENT_CAMERA_ERROR; + callback_->OnStateChanged(event); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/callback/dcamera_video_callback.cpp b/services/cameraservice/cameraoperator/client/src/callback/dcamera_video_callback.cpp new file mode 100644 index 00000000..8adb9731 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/callback/dcamera_video_callback.cpp @@ -0,0 +1,51 @@ +/* + * 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_video_callback.h" + +#include "distributed_camera_constants.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraVideoCallback::DCameraVideoCallback(const std::shared_ptr& callback) : callback_(callback) +{ +} + +void DCameraVideoCallback::OnFrameStarted() const +{ + DHLOGI("DCameraVideoCallback::OnFrameStarted"); +} + +void DCameraVideoCallback::OnFrameEnded(const int32_t frameCount) const +{ + DHLOGI("DCameraVideoCallback::OnFrameEnded, frameCount: %d", frameCount); +} + +void DCameraVideoCallback::OnError(const int32_t errorCode) const +{ + DHLOGE("DCameraVideoCallback::OnError, errorCode: %d", errorCode); + if (callback_ == nullptr) { + DHLOGE("DCameraVideoCallback StateCallback is null"); + return; + } + + std::shared_ptr event = std::make_shared(); + event->eventType_ = DCAMERA_MESSAGE; + event->eventResult_ = DCAMERA_EVENT_CAMERA_ERROR; + callback_->OnStateChanged(event); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp b/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp new file mode 100644 index 00000000..e52b3966 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/dcamera_client.cpp @@ -0,0 +1,437 @@ +/* + * 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_client.h" + +#include "anonymous_string.h" +#include "dcamera_input_callback.h" +#include "dcamera_manager_callback.h" +#include "dcamera_photo_callback.h" +#include "dcamera_session_callback.h" +#include "dcamera_utils_tools.h" +#include "dcamera_video_callback.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraClient::DCameraClient(const std::string& dhId) +{ + DHLOGI("DCameraClient Constructor dhId: %s", GetAnonyString(dhId).c_str()); + cameraId_ = dhId.substr(CAMERA_ID_PREFIX.size()); + isInit_ = false; +} + +DCameraClient::~DCameraClient() +{ + if (isInit_) { + UnInit(); + } +} + +int32_t DCameraClient::Init() +{ + DHLOGI("DCameraClient::Init cameraId: %s", GetAnonyString(cameraId_).c_str()); + cameraManager_ = CameraStandard::CameraManager::GetInstance(); + if (cameraManager_ == nullptr) { + DHLOGE("DCameraClient::Init cameraManager getInstance failed"); + return DCAMERA_BAD_VALUE; + } + cameraManager_->SetCallback(std::make_shared()); + + std::vector> cameraList = cameraManager_->GetCameras(); + DHLOGI("DCameraClient::Init camera size: %d", cameraList.size()); + for (auto& info : cameraList) { + if (info->GetID() == cameraId_) { + DHLOGI("DCameraClient::Init cameraInfo get id: %s", GetAnonyString(info->GetID()).c_str()); + cameraInfo_ = info; + break; + } + } + if (cameraInfo_ == nullptr) { + DHLOGE("DCameraClient::Init cameraInfo is null"); + return DCAMERA_BAD_VALUE; + } + + isInit_ = true; + DHLOGI("DCameraClient::Init %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::UnInit() +{ + DHLOGI("DCameraClient::UnInit cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (cameraManager_ != nullptr) { + DHLOGI("DCameraClient::UnInit unregister cameraManager callback"); + cameraManager_->SetCallback(nullptr); + } + + isInit_ = false; + cameraInfo_ = nullptr; + cameraManager_ = nullptr; + DHLOGI("DCameraClient::UnInit %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::UpdateSettings(std::vector>& settings) +{ + DHLOGI("DCameraClient::UpdateCameraSettings cameraId: %s", GetAnonyString(cameraId_).c_str()); + for (auto& setting : settings) { + switch (setting->type_) { + case UPDATE_METADATA: { + DHLOGI("DCameraClient::UpdateCameraSettings %s update metadata settings", + GetAnonyString(cameraId_).c_str()); + std::string metadataStr = Base64Decode(setting->value_); + int32_t ret = ((sptr &)cameraInput_)->SetCameraSettings(metadataStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::UpdateSettings %s update metadata settings failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + break; + } + default: { + DHLOGE("DCameraClient::UpdateSettings unknown setting type"); + break; + } + } + } + DHLOGI("DCameraClient::UpdateCameraSettings %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::StartCapture(std::vector>& captureInfos) +{ + DHLOGI("DCameraClient::StartCapture cameraId: %s", GetAnonyString(cameraId_).c_str()); + if ((photoOutput_ == nullptr) && (videoOutput_ == nullptr)) { + DHLOGI("DCameraClient::StartCapture %s config capture session", GetAnonyString(cameraId_).c_str()); + int32_t ret = ConfigCaptureSession(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StartCapture config capture session failed, cameraId: %s, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } + + for (auto& info : captureInfos) { + if (!(info->isCapture_)) { + continue; + } + int32_t ret = StartCaptureInner(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StartCapture failed, cameraId: %s, ret: %d", GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } + DHLOGI("DCameraClient::StartCapture %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::StopCapture() +{ + DHLOGI("DCameraClient::StopCapture cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (videoOutput_ != nullptr) { + DHLOGI("DCameraClient::StopCapture %s stop videoOutput", GetAnonyString(cameraId_).c_str()); + int32_t ret = ((sptr &)videoOutput_)->Stop(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StopCapture videoOutput stop failed, cameraId: %s, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + } + } + + if (captureSession_ != nullptr) { + DHLOGI("DCameraClient::StopCapture %s stop captureSession", GetAnonyString(cameraId_).c_str()); + int32_t ret = captureSession_->Stop(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StopCapture captureSession stop failed, cameraId: %s, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + } + DHLOGI("DCameraClient::StopCapture %s release captureSession", GetAnonyString(cameraId_).c_str()); + captureSession_->Release(); + } + + if (cameraInput_ != nullptr) { + DHLOGI("DCameraClient::StopCapture %s release cameraInput", GetAnonyString(cameraId_).c_str()); + cameraInput_->Release(); + } + + photoOutput_ = nullptr; + videoOutput_ = nullptr; + cameraInput_ = nullptr; + captureSession_ = nullptr; + DHLOGI("DCameraClient::StopCapture %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::SetStateCallback(std::shared_ptr& callback) +{ + DHLOGI("DCameraClient::SetStateCallback cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (callback == nullptr) { + DHLOGE("DCameraClient::SetStateCallback %s unregistering state callback", GetAnonyString(cameraId_).c_str()); + } + stateCallback_ = callback; + return DCAMERA_OK; +} + +int32_t DCameraClient::SetResultCallback(std::shared_ptr& callback) +{ + DHLOGI("DCameraClient::SetResultCallback cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (callback == nullptr) { + DHLOGE("DCameraClient::SetResultCallback %s unregistering result callback", GetAnonyString(cameraId_).c_str()); + } + resultCallback_ = callback; + return DCAMERA_OK; +} + +int32_t DCameraClient::ConfigCaptureSession(std::vector>& captureInfos) +{ + DHLOGI("DCameraClient::ConfigCaptureSession cameraId: %s", GetAnonyString(cameraId_).c_str()); + cameraInput_ = cameraManager_->CreateCameraInput(cameraInfo_); + if (cameraInput_ == nullptr) { + DHLOGE("DCameraClient::ConfigCaptureSession %s create cameraInput failed", GetAnonyString(cameraId_).c_str()); + return DCAMERA_BAD_VALUE; + } + std::shared_ptr inputCallback = std::make_shared(stateCallback_); + ((sptr &)cameraInput_)->SetErrorCallback(inputCallback); + + captureSession_ = cameraManager_->CreateCaptureSession(); + if (captureSession_ == nullptr) { + DHLOGE("DCameraClient::ConfigCaptureSession %s create captureSession failed", + GetAnonyString(cameraId_).c_str()); + return DCAMERA_BAD_VALUE; + } + captureSession_->SetCallback(std::make_shared(stateCallback_)); + + int32_t ret = CreateCaptureOutput(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession create capture output failed, cameraId: %s, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + + return ConfigCaptureSessionInner(); +} + +int32_t DCameraClient::ConfigCaptureSessionInner() +{ + int32_t ret = captureSession_->BeginConfig(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s config captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + + ret = captureSession_->AddInput(cameraInput_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s add cameraInput to captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + + if (photoOutput_ != nullptr) { + ret = captureSession_->AddOutput(photoOutput_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s add photoOutput to captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } + + if (videoOutput_ != nullptr) { + ret = captureSession_->AddOutput(videoOutput_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s add videoOutput to captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } + + ret = captureSession_->CommitConfig(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s commit captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + + ret = captureSession_->Start(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::ConfigCaptureSession %s start captureSession failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + } + + DHLOGI("DCameraClient::ConfigCaptureSession %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::CreateCaptureOutput(std::vector>& captureInfos) +{ + if (captureInfos.empty()) { + DHLOGE("DCameraClient::CreateCaptureOutput no capture info, cameraId: %s", GetAnonyString(cameraId_).c_str()); + return DCAMERA_BAD_VALUE; + } + + for (auto& info : captureInfos) { + if (info->streamType_ == SNAPSHOT_FRAME) { + int32_t ret = CreatePhotoOutput(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::CreateCaptureOutput %s create photo output failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } else if (info->streamType_ == CONTINUOUS_FRAME) { + int32_t ret = CreateVideoOutput(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::CreateCaptureOutput %s create video output failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + } else { + DHLOGE("DCameraClient::CreateCaptureOutput unknown stream type"); + return DCAMERA_BAD_VALUE; + } + } + return DCAMERA_OK; +} + +int32_t DCameraClient::CreatePhotoOutput(std::shared_ptr& info) +{ + DHLOGI("DCameraClient::CreatePhotoOutput camId: %s, width: %d, height: %d, format: %d, stream: %d, isCapture: %d", + GetAnonyString(cameraId_).c_str(), info->width_, info->height_, info->format_, + info->streamType_, info->isCapture_); + photoSurface_ = Surface::CreateSurfaceAsConsumer(); + photoSurface_->SetDefaultWidthAndHeight(info->width_, info->height_); + photoSurface_->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(info->format_)); + photoListener_ = std::make_shared(photoSurface_, resultCallback_); + photoSurface_->RegisterConsumerListener((sptr &)photoListener_); + photoOutput_ = cameraManager_->CreatePhotoOutput(photoSurface_); + if (photoOutput_ == nullptr) { + DHLOGE("DCameraClient::CreatePhotoOutput %s create photo output failed", GetAnonyString(cameraId_).c_str()); + return DCAMERA_BAD_VALUE; + } + std::shared_ptr photoCallback = std::make_shared(stateCallback_); + ((sptr &)photoOutput_)->SetCallback(photoCallback); + DHLOGI("DCameraClient::CreatePhotoOutput %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::CreateVideoOutput(std::shared_ptr& info) +{ + DHLOGI("DCameraClient::CreateVideoOutput camId: %s, width: %d, height: %d, format: %d, stream: %d, isCapture: %d", + GetAnonyString(cameraId_).c_str(), info->width_, info->height_, info->format_, + info->streamType_, info->isCapture_); + videoSurface_ = Surface::CreateSurfaceAsConsumer(); + videoSurface_->SetDefaultWidthAndHeight(info->width_, info->height_); + videoSurface_->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(info->format_)); + videoListener_ = std::make_shared(videoSurface_, resultCallback_); + videoSurface_->RegisterConsumerListener((sptr &)videoListener_); + videoOutput_ = cameraManager_->CreateVideoOutput(videoSurface_); + if (videoOutput_ == nullptr) { + DHLOGE("DCameraClient::CreateVideoOutput %s create video output failed", GetAnonyString(cameraId_).c_str()); + return DCAMERA_BAD_VALUE; + } + std::shared_ptr videoCallback = std::make_shared(stateCallback_); + ((sptr &)videoOutput_)->SetCallback(videoCallback); + DHLOGI("DCameraClient::CreateVideoOutput %s success", GetAnonyString(cameraId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraClient::StartCaptureInner(std::shared_ptr& info) +{ + switch (info->streamType_) { + case CONTINUOUS_FRAME: { + return StartVideoOutput(); + } + case SNAPSHOT_FRAME: { + return StartPhotoOutput(info); + } + default: { + DHLOGE("DCameraClient::StartCaptureInner unknown stream type"); + return DCAMERA_BAD_VALUE; + } + } +} + +int32_t DCameraClient::StartPhotoOutput(std::shared_ptr& info) +{ + DHLOGI("DCameraClient::StartPhotoOutput cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (photoOutput_ == nullptr) { + DHLOGE("DCameraClient::StartPhotoOutput photoOutput is null"); + return DCAMERA_BAD_VALUE; + } + + std::vector> captureSettings = info->captureSettings_; + std::string metadataSetting; + for (auto& setting : captureSettings) { + if (setting->type_ == UPDATE_METADATA) { + DHLOGI("DCameraClient::StartPhotoOutput %s update metadata settings", GetAnonyString(cameraId_).c_str()); + metadataSetting = setting->value_; + } + } + + if (metadataSetting.empty()) { + DHLOGE("DCameraClient::StartPhotoOutput no metadata settings to update"); + int32_t ret = ((sptr &)photoOutput_)->Capture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StartPhotoOutput %s photoOutput capture failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + return DCAMERA_OK; + } + + camera_metadata_item_t item; + CameraStandard::PhotoCaptureSetting::RotationConfig rotation = + CameraStandard::PhotoCaptureSetting::RotationConfig::Rotation_0; + std::shared_ptr cameraMetadata = + CameraStandard::MetadataUtils::DecodeFromString(Base64Decode(metadataSetting)); + int32_t ret = CameraStandard::FindCameraMetadataItem(cameraMetadata->get(), OHOS_JPEG_ORIENTATION, &item); + if (ret == DCAMERA_OK) { + DHLOGI("DCameraClient::StartPhotoOutput %s find camera metadata item", GetAnonyString(cameraId_).c_str()); + rotation = static_cast(item.data.i32[0]); + } + + DHLOGI("DCameraClient::StartPhotoOutput %s photo capture settings set rotation: %d", + GetAnonyString(cameraId_).c_str(), rotation); + std::shared_ptr photoCaptureSettings = + std::make_shared(); + photoCaptureSettings->SetRotation(rotation); + ret = ((sptr &)photoOutput_)->Capture(photoCaptureSettings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StartPhotoOutput %s photoOutput capture failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraClient::StartVideoOutput() +{ + DHLOGI("DCameraClient::StartVideoOutput cameraId: %s", GetAnonyString(cameraId_).c_str()); + if (videoOutput_ == nullptr) { + DHLOGE("DCameraClient::StartVideoOutput videoOutput is null"); + return DCAMERA_BAD_VALUE; + } + int32_t ret = ((sptr &)videoOutput_)->Start(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraClient::StartVideoOutput %s videoOutput start failed, ret: %d", + GetAnonyString(cameraId_).c_str(), ret); + return ret; + } + return DCAMERA_OK; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/listener/dcamera_photo_surface_listener.cpp b/services/cameraservice/cameraoperator/client/src/listener/dcamera_photo_surface_listener.cpp new file mode 100644 index 00000000..7a2ea6c4 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/listener/dcamera_photo_surface_listener.cpp @@ -0,0 +1,70 @@ +/* + * 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_photo_surface_listener.h" + +#include + +#include "data_buffer.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraPhotoSurfaceListener::DCameraPhotoSurfaceListener(const sptr& surface, + const std::shared_ptr& callback) : surface_(surface), callback_(callback) +{ +} + +void DCameraPhotoSurfaceListener::OnBufferAvailable() +{ + DHLOGI("DCameraPhotoSurfaceListener::OnBufferAvailable"); + OHOS::sptr buffer = nullptr; + int32_t flushFence = 0; + int64_t timestamp = 0; + OHOS::Rect damage; + + do { + surface_->AcquireBuffer(buffer, flushFence, timestamp, damage); + if (buffer == nullptr) { + DHLOGE("DCameraPhotoSurfaceListener AcquireBuffer failed"); + break; + } + + char *address = static_cast(buffer->GetVirAddr()); + int32_t size = static_cast(buffer->GetSize()); + if ((address == nullptr) || (size <= 0)) { + DHLOGE("DCameraPhotoSurfaceListener invalid params, size: %d", size); + break; + } + + DHLOGI("DCameraPhotoSurfaceListener size: %d", size); + std::shared_ptr dataBuffer = std::make_shared(size); + int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), address, size); + if (ret != EOK) { + DHLOGE("DCameraPhotoSurfaceListener Memory Copy failed, ret: %d", ret); + break; + } + + if (callback_ == nullptr) { + DHLOGE("DCameraPhotoSurfaceListener ResultCallback is null"); + break; + } + callback_->OnPhotoResult(dataBuffer); + } while (0); + surface_->ReleaseBuffer(buffer, -1); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/src/listener/dcamera_video_surface_listener.cpp b/services/cameraservice/cameraoperator/client/src/listener/dcamera_video_surface_listener.cpp new file mode 100644 index 00000000..8d7865e3 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/src/listener/dcamera_video_surface_listener.cpp @@ -0,0 +1,75 @@ +/* + * 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_video_surface_listener.h" + +#include + +#include "data_buffer.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraVideoSurfaceListener::DCameraVideoSurfaceListener(const sptr& surface, + const std::shared_ptr& callback) : surface_(surface), callback_(callback) +{ +} + +void DCameraVideoSurfaceListener::OnBufferAvailable() +{ + DHLOGI("DCameraVideoSurfaceListener::OnBufferAvailable"); + OHOS::sptr buffer = nullptr; + int32_t flushFence = 0; + int64_t timestamp = 0; + OHOS::Rect damage; + + do { + surface_->AcquireBuffer(buffer, flushFence, timestamp, damage); + if (buffer == nullptr) { + DHLOGE("DCameraVideoSurfaceListener AcquireBuffer failed"); + break; + } + + char *address = static_cast(buffer->GetVirAddr()); + int32_t size = buffer->GetSize(); + int32_t width = buffer->GetWidth(); + int32_t height = buffer->GetHeight(); + if ((address == nullptr) || (size <= 0) || (width <= 0) || (height <= 0)) { + DHLOGE("DCameraVideoSurfaceListener invalid params, width: %d, height: %d, size: %d", width, height, size); + break; + } + + DHLOGI("DCameraVideoSurfaceListener width: %d, height: %d, size: %d", width, height, size); + int32_t y2UvRatio = 2; + int32_t bytesPerPixel = 3; + size_t validImgSize = static_cast(width * height * bytesPerPixel / y2UvRatio); + std::shared_ptr dataBuffer = std::make_shared(validImgSize); + int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), address, validImgSize); + if (ret != EOK) { + DHLOGE("DCameraVideoSurfaceListener Memory Copy failed, ret: %d", ret); + break; + } + + if (callback_ == nullptr) { + DHLOGE("DCameraVideoSurfaceListener ResultCallback is null"); + break; + } + callback_->OnVideoResult(dataBuffer); + } while (0); + surface_->ReleaseBuffer(buffer, -1); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/test/unittest/BUILD.gn b/services/cameraservice/cameraoperator/client/test/unittest/BUILD.gn new file mode 100644 index 00000000..11aa5aca --- /dev/null +++ b/services/cameraservice/cameraoperator/client/test/unittest/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +group("camera_client_test") { + testonly = true + deps = [ + "common/cameraoperator:dcamera_client_test", + ] +} \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/BUILD.gn b/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/BUILD.gn new file mode 100644 index 00000000..46082450 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/BUILD.gn @@ -0,0 +1,90 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributed_camera/dcamera_client_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/jsoncpp/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${graphicstandard_path}/frameworks/surface/include", + "${camerastandard_path}/frameworks/native/metadata/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/input", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/output", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/session", + "${camerastandard_path}/services/camera_service/binder/base/include", + "${camerastandard_path}/services/camera_service/binder/client/include", + "${camerastandard_path}/services/camera_service/binder/server/include", + "${camerastandard_path}/services/camera_service/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "${distributedcamera_hdf_path}/interfaces/include", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${services_path}/cameraservice/base/include", + "${services_path}/cameraservice/cameraoperator/client/include", + "${services_path}/cameraservice/cameraoperator/client/include/callback", + "${services_path}/cameraservice/cameraoperator/client/include/listener", + ] +} + +ohos_unittest("DCameraClientTest") { + module_out_path = module_out_path + + sources = [ + "dcamera_client_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gtest_main", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${graphicstandard_path}:libsurface", + "${camerastandard_path}/frameworks/native/camera:camera_framework", + "${camerastandard_path}/frameworks/native/metadata:metadata", + "${services_path}/cameraservice/cameraoperator/client:distributed_camera_client", + "${services_path}/cameraservice/sinkservice:distributed_camera_sink" + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "eventhandler:libeventhandler", + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DCameraClientTest\"", + "LOG_DOMAIN=0xD004100", + ] +} + +group("dcamera_client_test") { + testonly = true + deps = [ ":DCameraClientTest" ] +} diff --git a/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/dcamera_client_test.cpp b/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/dcamera_client_test.cpp new file mode 100644 index 00000000..95a787a2 --- /dev/null +++ b/services/cameraservice/cameraoperator/client/test/unittest/common/cameraoperator/dcamera_client_test.cpp @@ -0,0 +1,269 @@ +/* + * 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 "anonymous_string.h" +#include "dcamera_client.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraClientTestStateCallback : public StateCallback { +public: + void OnStateChanged(std::shared_ptr& event) + { + DHLOGI("DCameraClientTestStateCallback::OnStateChanged type: %d, result: %d", + event->eventType_, event->eventResult_); + } + + void OnMetadataResult() + { + DHLOGI("DCameraClientTestStateCallback::OnMetadataResult"); + } +}; + +class DCameraClientTestResultCallback : public ResultCallback { +public: + void OnPhotoResult(std::shared_ptr& buffer) + { + DHLOGI("DCameraClientTestResultCallback::OnPhotoResult"); + } + + void OnVideoResult(std::shared_ptr& buffer) + { + DHLOGI("DCameraClientTestResultCallback::OnVideoResult"); + } +}; + +const int32_t TEST_WIDTH = 1920; +const int32_t TEST_HEIGHT = 1080; +const int32_t TEST_FORMAT_3 = 3; +const int32_t TEST_FORMAT_4 = 4; +const int32_t TEST_SLEEP_SEC = 2; +const std::string TEST_CAMERA_ID = "Camera_device@3.5/legacy/1"; + +class DCameraClientTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr client_; + std::shared_ptr photoInfo_false_; + std::shared_ptr videoInfo_false_; + std::shared_ptr photoInfo_true_; + std::shared_ptr videoInfo_true_; +}; + +void DCameraClientTest::SetUpTestCase(void) +{ + DHLOGI("DCameraClientTest::SetUpTestCase"); +} + +void DCameraClientTest::TearDownTestCase(void) +{ + DHLOGI("DCameraClientTest::TearDownTestCase"); +} + +void DCameraClientTest::SetUp(void) +{ + DHLOGI("DCameraClientTest::SetUp"); + client_ = std::make_shared(TEST_CAMERA_ID); + + photoInfo_false_ = std::make_shared(); + photoInfo_false_->width_ = TEST_WIDTH; + photoInfo_false_->height_ = TEST_HEIGHT; + photoInfo_false_->format_ = TEST_FORMAT_4; + photoInfo_false_->isCapture_ = false; + photoInfo_false_->streamType_ = SNAPSHOT_FRAME; + + videoInfo_false_ = std::make_shared(); + videoInfo_false_->width_ = TEST_WIDTH; + videoInfo_false_->height_ = TEST_HEIGHT; + videoInfo_false_->format_ = TEST_FORMAT_3; + videoInfo_false_->isCapture_ = false; + videoInfo_false_->streamType_ = CONTINUOUS_FRAME; + + photoInfo_true_ = std::make_shared(); + photoInfo_true_->width_ = TEST_WIDTH; + photoInfo_true_->height_ = TEST_HEIGHT; + photoInfo_true_->format_ = TEST_FORMAT_4; + photoInfo_true_->isCapture_ = true; + photoInfo_true_->streamType_ = SNAPSHOT_FRAME; + + videoInfo_true_ = std::make_shared(); + videoInfo_true_->width_ = TEST_WIDTH; + videoInfo_true_->height_ = TEST_HEIGHT; + videoInfo_true_->format_ = TEST_FORMAT_3; + videoInfo_true_->isCapture_ = true; + videoInfo_true_->streamType_ = CONTINUOUS_FRAME; +} + +void DCameraClientTest::TearDown(void) +{ + DHLOGI("DCameraClientTest::TearDown"); + client_ = nullptr; + photoInfo_false_ = nullptr; + videoInfo_false_ = nullptr; + photoInfo_true_ = nullptr; + videoInfo_true_ = nullptr; +} + +/** + * @tc.name: dcamera_client_test_001 + * @tc.desc: Verify SetStateCallback + * @tc.type: FUNC + * @tc.require: AR000GK6MN + */ +HWTEST_F(DCameraClientTest, dcamera_client_test_001, TestSize.Level1) +{ + DHLOGI("DCameraClientTest dcamera_client_test_001: test set state callback"); + std::shared_ptr stateCallback = std::make_shared(); + int32_t ret = client_->SetStateCallback(stateCallback); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_client_test_002 + * @tc.desc: Verify SetResultCallback + * @tc.type: FUNC + * @tc.require: AR000GK6MN + */ +HWTEST_F(DCameraClientTest, dcamera_client_test_002, TestSize.Level1) +{ + DHLOGI("DCameraClientTest dcamera_client_test_002: test set result callback"); + std::shared_ptr resultCallback = std::make_shared(); + int32_t ret = client_->SetResultCallback(resultCallback); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_client_test_003 + * @tc.desc: Verify Init and UnInit + * @tc.type: FUNC + * @tc.require: AR000GK6ML + */ +HWTEST_F(DCameraClientTest, dcamera_client_test_003, TestSize.Level1) +{ + DHLOGI("DCameraClientTest dcamera_client_test_003: test init and release client"); + std::shared_ptr stateCallback = std::make_shared(); + int32_t ret = client_->SetStateCallback(stateCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + std::shared_ptr resultCallback = std::make_shared(); + ret = client_->SetResultCallback(resultCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->Init(); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_client_test_004 + * @tc.desc: Verify StartCapture and StopCapture + * @tc.type: FUNC + * @tc.require: AR000GK6ML + */ +HWTEST_F(DCameraClientTest, dcamera_client_test_004, TestSize.Level1) +{ + DHLOGI("DCameraClientTest dcamera_client_test_004: test startCapture and stopCapture"); + std::shared_ptr stateCallback = std::make_shared(); + int32_t ret = client_->SetStateCallback(stateCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + std::shared_ptr resultCallback = std::make_shared(); + ret = client_->SetResultCallback(resultCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->Init(); + EXPECT_EQ(DCAMERA_OK, ret); + + DHLOGI("DCameraClientTest dcamera_client_test_004: video width: %d, height: %d, format: %d, isCapture: %d", + videoInfo_true_->width_, videoInfo_true_->height_, videoInfo_true_->format_, videoInfo_true_->isCapture_); + std::vector> captureInfos; + captureInfos.push_back(videoInfo_true_); + ret = client_->StartCapture(captureInfos); + EXPECT_EQ(DCAMERA_OK, ret); + + sleep(TEST_SLEEP_SEC); + + ret = client_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_client_test_005 + * @tc.desc: Verify StartCapture and StopCapture + * @tc.type: FUNC + * @tc.require: AR000GK6ML + */ +HWTEST_F(DCameraClientTest, dcamera_client_test_005, TestSize.Level1) +{ + DHLOGI("DCameraClientTest dcamera_client_test_005: test startCapture and stopCapture"); + std::shared_ptr stateCallback = std::make_shared(); + int32_t ret = client_->SetStateCallback(stateCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + std::shared_ptr resultCallback = std::make_shared(); + ret = client_->SetResultCallback(resultCallback); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->Init(); + EXPECT_EQ(DCAMERA_OK, ret); + + DHLOGI("DCameraClientTest dcamera_client_test_005: video width: %d, height: %d, format: %d, isCapture: %d", + videoInfo_true_->width_, videoInfo_true_->height_, videoInfo_true_->format_, videoInfo_true_->isCapture_); + DHLOGI("DCameraClientTest dcamera_client_test_005: photo width: %d, height: %d, format: %d, isCapture: %d", + photoInfo_false_->width_, photoInfo_false_->height_, photoInfo_false_->format_, photoInfo_false_->isCapture_); + std::vector> captureInfos; + captureInfos.push_back(videoInfo_true_); + captureInfos.push_back(photoInfo_false_); + ret = client_->StartCapture(captureInfos); + EXPECT_EQ(DCAMERA_OK, ret); + + sleep(TEST_SLEEP_SEC); + + DHLOGI("DCameraClientTest dcamera_client_test_005: video width: %d, height: %d, format: %d, isCapture: %d", + videoInfo_false_->width_, videoInfo_false_->height_, videoInfo_false_->format_, videoInfo_false_->isCapture_); + DHLOGI("DCameraClientTest dcamera_client_test_005: photo width: %d, height: %d, format: %d, isCapture: %d", + photoInfo_true_->width_, photoInfo_true_->height_, photoInfo_true_->format_, photoInfo_true_->isCapture_); + captureInfos.clear(); + captureInfos.push_back(videoInfo_false_); + captureInfos.push_back(photoInfo_true_); + ret = client_->StartCapture(captureInfos); + EXPECT_EQ(DCAMERA_OK, ret); + + sleep(TEST_SLEEP_SEC); + + ret = client_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = client_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/handler/BUILD.gn b/services/cameraservice/cameraoperator/handler/BUILD.gn new file mode 100644 index 00000000..39c468a2 --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/BUILD.gn @@ -0,0 +1,77 @@ +# 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("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_handler") { + include_dirs = [ + "//third_party/jsoncpp/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${graphicstandard_path}/frameworks/surface/include", + "${camerastandard_path}/frameworks/native/metadata/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/input", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/output", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/session", + "${camerastandard_path}/services/camera_service/binder/base/include", + "${camerastandard_path}/services/camera_service/binder/client/include", + "${camerastandard_path}/services/camera_service/binder/server/include", + "${camerastandard_path}/services/camera_service/include", + "${mediastandard_path}/interfaces/innerkits/native/media/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "include", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${distributedcamera_hdf_path}/interfaces/include", + "${services_path}/cameraservice/cameraoperator/client/include/callback", + ] + + sources = [ + "src/dcamera_handler.cpp", + "${services_path}/cameraservice/cameraoperator/client/src/callback/dcamera_manager_callback.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${graphicstandard_path}:libsurface", + "${camerastandard_path}/frameworks/native/camera:camera_framework", + "${camerastandard_path}/frameworks/native/metadata:metadata", + "//utils/native/base:utils", + "//third_party/jsoncpp:jsoncpp", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcamerahandler\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/handler/include/dcamera_handler.h b/services/cameraservice/cameraoperator/handler/include/dcamera_handler.h new file mode 100644 index 00000000..4167d4f3 --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/include/dcamera_handler.h @@ -0,0 +1,73 @@ +/* + * 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_HANDLER_H +#define OHOS_DCAMERA_HANDLER_H + +#include "ihardware_handler.h" + +#include + +#include "camera_info.h" +#include "camera_input.h" +#include "camera_manager.h" +#include "json/json.h" +#include "single_instance.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +struct ConfigInfo { + DCStreamType type; + std::string formatKey; + sptr cameraInput; +}; + +class DCameraHandler : public IHardwareHandler { +DECLARE_SINGLE_INSTANCE_BASE(DCameraHandler); +public: + int32_t Initialize() override; + std::vector Query() override; + std::map QueryExtraInfo() override; + bool IsSupportPlugin() override; + void RegisterPluginListener(std::shared_ptr listener) override; + + std::vector GetCameras(); + +private: + DCameraHandler() = default; + ~DCameraHandler(); + +private: + DHItem CreateDHItem(sptr& info); + std::string GetCameraPosition(camera_position_enum_t position); + void ConfigFormatAndResolution(ConfigInfo& info, Json::Value& outputFormat, Json::Value& resolution, + std::vector& formatList, std::set& formatSet); + bool IsValid(DCStreamType type, CameraStandard::CameraPicSize& size); + + sptr cameraManager_; + std::shared_ptr pluginListener_; +}; + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((visibility("default"))) IHardwareHandler* GetHardwareHandler(); +#ifdef __cplusplus +} +#endif +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_HANDLER_H \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/handler/src/dcamera_handler.cpp b/services/cameraservice/cameraoperator/handler/src/dcamera_handler.cpp new file mode 100644 index 00000000..116029db --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/src/dcamera_handler.cpp @@ -0,0 +1,256 @@ +/* + * 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_handler.h" + +#include "anonymous_string.h" +#include "avcodec_info.h" +#include "avcodec_list.h" +#include "dcamera_manager_callback.h" +#include "dcamera_utils_tools.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" +#include "metadata_utils.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DCameraHandler); + +DCameraHandler::~DCameraHandler() +{ + DHLOGI("~DCameraHandler"); +} + +int32_t DCameraHandler::Initialize() +{ + DHLOGI("DCameraHandler::Initialize"); + cameraManager_ = CameraStandard::CameraManager::GetInstance(); + if (cameraManager_ == nullptr) { + DHLOGE("DCameraHandler::Initialize cameraManager getInstance failed"); + return DCAMERA_INIT_ERR; + } + std::shared_ptr cameraMgrCallback = std::make_shared(); + cameraManager_->SetCallback(cameraMgrCallback); + DHLOGI("DCameraHandler::Initialize success"); + return DCAMERA_OK; +} + +std::vector DCameraHandler::Query() +{ + std::vector itemList; + std::vector> cameraList = cameraManager_->GetCameras(); + DHLOGI("DCameraHandler::Query get %d cameras", cameraList.size()); + if (cameraList.empty()) { + DHLOGE("DCameraHandler::Query no camera device"); + return itemList; + } + for (auto& info : cameraList) { + if (info->GetConnectionType() != OHOS_CAMERA_CONNECTION_TYPE_BUILTIN) { + DHLOGI("DCameraHandler::Query connection type: %d", info->GetConnectionType()); + continue; + } + if ((info->GetPosition() == OHOS_CAMERA_POSITION_FRONT) || + (info->GetPosition() == OHOS_CAMERA_POSITION_BACK && info->GetCameraType() == OHOS_CAMERA_TYPE_LOGICAL)) { + DHItem item = CreateDHItem(info); + itemList.push_back(item); + } + } + DHLOGI("DCameraHandler::Query success, get %d items", itemList.size()); + return itemList; +} + +std::map DCameraHandler::QueryExtraInfo() +{ + DHLOGI("DCameraHandler::QueryExtraInfo"); + std::map extraInfo; + return extraInfo; +} + +bool DCameraHandler::IsSupportPlugin() +{ + DHLOGI("DCameraHandler::IsSupportPlugin"); + return false; +} + +void DCameraHandler::RegisterPluginListener(std::shared_ptr listener) +{ + DHLOGI("DCameraHandler::RegisterPluginListener"); + if (listener == nullptr) { + DHLOGE("DCameraHandler unregistering plugin listener"); + } + pluginListener_ = listener; +} + +std::vector DCameraHandler::GetCameras() +{ + std::vector cameras; + std::vector> cameraList = cameraManager_->GetCameras(); + DHLOGI("DCameraHandler::GetCameras get %d cameras", cameraList.size()); + if (cameraList.empty()) { + DHLOGE("DCameraHandler::GetCameras no camera device"); + return cameras; + } + for (auto& info : cameraList) { + if (info->GetConnectionType() != OHOS_CAMERA_CONNECTION_TYPE_BUILTIN) { + DHLOGI("DCameraHandler::GetCameras connection type: %d", info->GetConnectionType()); + continue; + } + if ((info->GetPosition() == OHOS_CAMERA_POSITION_FRONT) || + (info->GetPosition() == OHOS_CAMERA_POSITION_BACK && info->GetCameraType() == OHOS_CAMERA_TYPE_LOGICAL)) { + std::string dhId = CAMERA_ID_PREFIX + info->GetID(); + cameras.push_back(dhId); + } + } + DHLOGI("DCameraHandler::GetCameras success, get %d items", cameras.size()); + return cameras; +} + +DHItem DCameraHandler::CreateDHItem(sptr& info) +{ + DHItem item; + std::string id = info->GetID(); + item.dhId = CAMERA_ID_PREFIX + id; + DHLOGI("DCameraHandler::CreateDHItem camera id: %s", GetAnonyString(id).c_str()); + + Json::Value root; + root[CAMERA_PROTOCOL_VERSION_KEY] = Json::Value(CAMERA_PROTOCOL_VERSION_VALUE); + root[CAMERA_POSITION_KEY] = Json::Value(GetCameraPosition(info->GetPosition())); + + std::shared_ptr avCodecList = Media::AVCodecListFactory::CreateAVCodecList(); + std::vector> videoCapsList = avCodecList->GetVideoEncoderCaps(); + for (auto& videoCaps : videoCapsList) { + std::shared_ptr codecInfo = videoCaps->GetCodecInfo(); + std::string name = codecInfo->GetName(); + root[CAMERA_CODEC_TYPE_KEY].append(name); + DHLOGI("DCameraHandler::CreateDHItem codec type: %s", name.c_str()); + } + + sptr cameraInput = cameraManager_->CreateCameraInput(info); + if (cameraInput == nullptr) { + DHLOGE("DCameraHandler::CreateDHItem create cameraInput failed"); + return item; + } + + Json::Value outputFormat; + Json::Value resolution; + std::set formatSet; + + std::vector videoFormats = cameraInput->GetSupportedVideoFormats(); + ConfigInfo videoConfig = {CONTINUOUS_FRAME, CAMERA_FORMAT_VIDEO, cameraInput}; + ConfigFormatAndResolution(videoConfig, outputFormat, resolution, videoFormats, formatSet); + + std::vector previewFormats = cameraInput->GetSupportedPreviewFormats(); + ConfigInfo previewInfo = {CONTINUOUS_FRAME, CAMERA_FORMAT_PREVIEW, cameraInput}; + ConfigFormatAndResolution(previewInfo, outputFormat, resolution, previewFormats, formatSet); + + std::vector photoFormats = cameraInput->GetSupportedPhotoFormats(); + ConfigInfo photoConfig = {SNAPSHOT_FRAME, CAMERA_FORMAT_PHOTO, cameraInput}; + ConfigFormatAndResolution(photoConfig, outputFormat, resolution, photoFormats, formatSet); + + root[CAMERA_FORMAT_KEY] = outputFormat; + root[CAMERA_RESOLUTION_KEY] = resolution; + + std::string abilityString = cameraInput->GetCameraSettings(); + std::string encodeString = Base64Encode(reinterpret_cast(abilityString.c_str()), + abilityString.length()); + root[CAMERA_METADATA_KEY] = Json::Value(encodeString); + + item.attrs = root.toStyledString(); + cameraInput->Release(); + return item; +} + +std::string DCameraHandler::GetCameraPosition(camera_position_enum_t position) +{ + DHLOGI("DCameraHandler::GetCameraPosition position: %d", position); + std::string ret = ""; + switch (position) { + case OHOS_CAMERA_POSITION_BACK: { + ret = CAMERA_POSITION_BACK; + break; + } + case OHOS_CAMERA_POSITION_FRONT: { + ret = CAMERA_POSITION_FRONT; + break; + } + case OHOS_CAMERA_POSITION_OTHER: { + ret = CAMERA_POSITION_UNSPECIFIED; + break; + } + default: { + DHLOGE("DCameraHandler::GetCameraPosition unknown camera position"); + break; + } + } + DHLOGI("DCameraHandler::GetCameraPosition success ret: %s", ret.c_str()); + return ret; +} + +void DCameraHandler::ConfigFormatAndResolution(ConfigInfo& info, Json::Value& outputFormat, Json::Value& resolution, + std::vector& formatList, std::set& formatSet) +{ + DHLOGI("DCameraHandler::ConfigFormatAndResolution camera format size: %d", formatList.size()); + for (auto& format : formatList) { + DHLOGI("DCameraHandler::ConfigFormatAndResolution %s format: %d", info.formatKey.c_str(), format); + outputFormat[info.formatKey].append(format); + if (formatSet.insert(format).second) { + std::vector picSizes = info.cameraInput->getSupportedSizes(format); + std::string keyName = std::to_string(format); + DHLOGI("DCameraHandler::ConfigFormatAndResolution get %d supported camera pic size", picSizes.size()); + for (auto& size : picSizes) { + if (IsValid(info.type, size)) { + std::string value = std::to_string(size.width) + "*" + std::to_string(size.height); + resolution[keyName].append(value); + DHLOGI("DCameraHandler::ConfigFormatAndResolution format %d resolution %s", format, value.c_str()); + } + } + } + } +} + +bool DCameraHandler::IsValid(DCStreamType type, CameraStandard::CameraPicSize& size) +{ + bool ret = false; + switch (type) { + case CONTINUOUS_FRAME: { + ret = (size.width >= RESOLUTION_MIN_WIDTH) && + (size.height >= RESOLUTION_MIN_HEIGHT) && + (size.width <= RESOLUTION_MAX_WIDTH_CONTINUOUS) && + (size.height <= RESOLUTION_MAX_HEIGHT_CONTINUOUS); + break; + } + case SNAPSHOT_FRAME: { + ret = (size.width >= RESOLUTION_MIN_WIDTH) && + (size.height >= RESOLUTION_MIN_HEIGHT) && + (size.width <= RESOLUTION_MAX_WIDTH_SNAPSHOT) && + (size.height <= RESOLUTION_MAX_HEIGHT_SNAPSHOT); + break; + } + default: { + DHLOGE("DCameraHandler::isValid unknown stream type"); + break; + } + } + return ret; +} + +IHardwareHandler* GetHardwareHandler() +{ + DHLOGI("DCameraHandler::GetHardwareHandler"); + return &DCameraHandler::GetInstance(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/handler/test/unittest/BUILD.gn b/services/cameraservice/cameraoperator/handler/test/unittest/BUILD.gn new file mode 100644 index 00000000..0cdc5b07 --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/test/unittest/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +group("camera_handler_test") { + testonly = true + deps = [ + "common/dcamerahandler:dcamera_handler_test", + ] +} \ No newline at end of file diff --git a/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/BUILD.gn b/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/BUILD.gn new file mode 100644 index 00000000..17312387 --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/BUILD.gn @@ -0,0 +1,87 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributed_camera/dcamera_handler_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${graphicstandard_path}/frameworks/surface/include", + "${camerastandard_path}/frameworks/native/metadata/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/input", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/output", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/session", + "${camerastandard_path}/services/camera_service/binder/base/include", + "${camerastandard_path}/services/camera_service/binder/client/include", + "${camerastandard_path}/services/camera_service/binder/server/include", + "${camerastandard_path}/services/camera_service/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "${distributedcamera_hdf_path}/interfaces/include", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${services_path}/cameraservice/base/include", + "${services_path}/cameraservice/cameraoperator/client/include/callback", + "${services_path}/cameraservice/cameraoperator/handler/include", + ] +} + +ohos_unittest("DCameraHandlerTest") { + module_out_path = module_out_path + + sources = [ + "dcamera_handler_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gtest_main", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${graphicstandard_path}:libsurface", + "${camerastandard_path}/frameworks/native/camera:camera_framework", + "${camerastandard_path}/frameworks/native/metadata:metadata", + "${services_path}/cameraservice/cameraoperator/handler:distributed_camera_handler", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "eventhandler:libeventhandler", + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DCameraHandlerTest\"", + "LOG_DOMAIN=0xD004100", + ] +} + +group("dcamera_handler_test") { + testonly = true + deps = [ ":DCameraHandlerTest" ] +} diff --git a/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/dcamera_handler_test.cpp b/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/dcamera_handler_test.cpp new file mode 100644 index 00000000..c4607fee --- /dev/null +++ b/services/cameraservice/cameraoperator/handler/test/unittest/common/dcamerahandler/dcamera_handler_test.cpp @@ -0,0 +1,90 @@ +/* + * 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 "dcamera_handler.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraHandlerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DCameraHandlerTest::SetUpTestCase(void) +{ + DHLOGI("DCameraHandlerTest::SetUpTestCase"); +} + +void DCameraHandlerTest::TearDownTestCase(void) +{ + DHLOGI("DCameraHandlerTest::TearDownTestCase"); +} + +void DCameraHandlerTest::SetUp(void) +{ + DHLOGI("DCameraHandlerTest::SetUp"); +} + +void DCameraHandlerTest::TearDown(void) +{ + DHLOGI("DCameraHandlerTest::TearDown"); +} + +/** + * @tc.name: dcamera_handler_test_001 + * @tc.desc: Verify Initialize + * @tc.type: FUNC + * @tc.require: AR000GK6MF + */ +HWTEST_F(DCameraHandlerTest, dcamera_handler_test_001, TestSize.Level1) +{ + int32_t ret = DCameraHandler::GetInstance().Initialize(); + EXPECT_EQ(ret, DCAMERA_OK); +} + +/** + * @tc.name: dcamera_handler_test_002 + * @tc.desc: Verify GetCameras + * @tc.type: FUNC + * @tc.require: AR000GK6MF + */ +HWTEST_F(DCameraHandlerTest, dcamera_handler_test_002, TestSize.Level1) +{ + int32_t ret = DCameraHandler::GetInstance().GetCameras().size(); + EXPECT_GT(ret, DCAMERA_OK); +} + +/** + * @tc.name: dcamera_handler_test_003 + * @tc.desc: Verify Query + * @tc.type: FUNC + * @tc.require: AR000GK6MF + */ +HWTEST_F(DCameraHandlerTest, dcamera_handler_test_003, TestSize.Level1) +{ + int32_t ret = DCameraHandler::GetInstance().Query().size(); + EXPECT_GT(ret, DCAMERA_OK); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/BUILD.gn b/services/cameraservice/sinkservice/BUILD.gn new file mode 100644 index 00000000..8f442aed --- /dev/null +++ b/services/cameraservice/sinkservice/BUILD.gn @@ -0,0 +1,128 @@ +# 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("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_sink") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${graphicstandard_path}/frameworks/surface/include", + "${camerastandard_path}/frameworks/native/metadata/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/input", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/output", + "${camerastandard_path}/interfaces/inner_api/native/camera/include/session", + "${camerastandard_path}/services/camera_service/binder/base/include", + "${camerastandard_path}/services/camera_service/binder/client/include", + "${camerastandard_path}/services/camera_service/binder/server/include", + "${camerastandard_path}/services/camera_service/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/eventbus", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + "//third_party/jsoncpp/include", + ] + + include_dirs += [ + "include/distributedcamera", + "include/distributedcameramgr", + "include/distributedcameramgr/callback", + "include/distributedcameramgr/eventbus", + "include/distributedcameramgr/interface", + "include/distributedcameramgr/listener", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${innerkits_path}/native_cpp/camera_sink/include", + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + "${distributedcamera_hdf_path}/interfaces/include", + "${services_path}/cameraservice/base/include", + "${services_path}/cameraservice/cameraoperator/client/include", + "${services_path}/cameraservice/cameraoperator/client/include/callback", + "${services_path}/cameraservice/cameraoperator/client/include/listener", + "${services_path}/cameraservice/cameraoperator/handler/include", + "${services_path}/channel/include", + "${services_path}/data_process/include/eventbus", + "${services_path}/data_process/include/interfaces", + "${services_path}/data_process/include/pipeline", + "${services_path}/data_process/include/utils", + ] + + sources = [ + "src/distributedcamera/distributed_camera_sink_service.cpp", + "src/distributedcamera/distributed_camera_sink_stub.cpp", + "${innerkits_path}/native_cpp/camera_source/src/distributed_camera_source_proxy.cpp", + + "src/distributedcameramgr/callback/dcamera_sink_controller_state_callback.cpp", + "src/distributedcameramgr/callback/dcamera_sink_output_result_callback.cpp", + + "src/distributedcameramgr/eventbus/dcamera_frame_trigger_event.cpp", + "src/distributedcameramgr/eventbus/dcamera_photo_output_event.cpp", + "src/distributedcameramgr/eventbus/dcamera_post_authorization_event.cpp", + "src/distributedcameramgr/eventbus/dcamera_video_output_event.cpp", + + "src/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.cpp", + "src/distributedcameramgr/listener/dcamera_sink_data_process_listener.cpp", + "src/distributedcameramgr/listener/dcamera_sink_output_channel_listener.cpp", + + "src/distributedcameramgr/dcamera_sink_access_control.cpp", + "src/distributedcameramgr/dcamera_sink_controller.cpp", + "src/distributedcameramgr/dcamera_sink_data_process.cpp", + "src/distributedcameramgr/dcamera_sink_dev.cpp", + "src/distributedcameramgr/dcamera_sink_output.cpp", + "src/distributedcameramgr/dcamera_sink_service_ipc.cpp", + + "${services_path}/cameraservice/base/src/dcamera_capture_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_channel_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_event_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_open_info_cmd.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${graphicstandard_path}:libsurface", + "${camerastandard_path}/frameworks/native/camera:camera_framework", + "${camerastandard_path}/frameworks/native/metadata:metadata", + "${services_path}/cameraservice/cameraoperator/client:distributed_camera_client", + "${services_path}/cameraservice/cameraoperator/handler:distributed_camera_handler", + "${services_path}/channel:distributed_camera_channel", + "${services_path}/data_process:distributed_camera_data_process", + "//utils/native/base:utils", + "//third_party/jsoncpp:jsoncpp", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcamerasinksvr\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "eventhandler:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_service.h b/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_service.h new file mode 100644 index 00000000..b356ffa3 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_service.h @@ -0,0 +1,59 @@ +/* + * 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_DISTRIBUTED_CAMERA_SINK_SERVICE_H +#define OHOS_DISTRIBUTED_CAMERA_SINK_SERVICE_H + +#include "system_ability.h" +#include "ipc_object_stub.h" + +#include "dcamera_sink_dev.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_sink_stub.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSinkService : public SystemAbility, public DistributedCameraSinkStub { +DECLARE_SYSTEM_ABILITY(DistributedCameraSinkService); +public: + DistributedCameraSinkService(int32_t saId, bool runOnCreate); + ~DistributedCameraSinkService() = default; + + int32_t InitSink(const std::string& params) override; + int32_t ReleaseSink() override; + int32_t SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) override; + int32_t UnsubscribeLocalHardware(const std::string& dhId) override; + int32_t StopCapture(const std::string& dhId) override; + int32_t ChannelNeg(const std::string& dhId, std::string& channelInfo) override; + int32_t GetCameraInfo(const std::string& dhId, std::string& cameraInfo) override; + int32_t OpenChannel(const std::string& dhId, std::string& openInfo) override; + int32_t CloseChannel(const std::string& dhId) override; + +protected: + void OnStart() override; + void OnStop() override; + DISALLOW_COPY_AND_MOVE(DistributedCameraSinkService); + +private: + bool Init(); + bool registerToService_ = false; + DCameraServiceState state_ = DCameraServiceState::DCAMERA_SRV_STATE_NOT_START; + + std::string sinkVer_; + std::map> camerasMap_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_SINK_SERVICE_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_stub.h b/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_stub.h new file mode 100644 index 00000000..3f31c97c --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcamera/distributed_camera_sink_stub.h @@ -0,0 +1,48 @@ +/* + * 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_DISTRIBUTED_CAMERA_SINK_STUB_H +#define OHOS_DISTRIBUTED_CAMERA_SINK_STUB_H + +#include +#include "iremote_stub.h" + +#include "idistributed_camera_sink.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSinkStub : public IRemoteStub { +public: + DistributedCameraSinkStub(); + virtual ~DistributedCameraSinkStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t InitSinkInner(MessageParcel &data, MessageParcel &reply); + int32_t ReleaseSinkInner(MessageParcel &data, MessageParcel &reply); + int32_t SubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply); + int32_t UnsubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply); + int32_t StopCaptureInner(MessageParcel &data, MessageParcel &reply); + int32_t ChannelNegInner(MessageParcel &data, MessageParcel &reply); + int32_t GetCameraInfoInner(MessageParcel &data, MessageParcel &reply); + int32_t OpenChannelInner(MessageParcel &data, MessageParcel &reply); + int32_t CloseChannelInner(MessageParcel &data, MessageParcel &reply); + + using DCameraFunc = int32_t (DistributedCameraSinkStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CAMERA_SINK_STUB_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_controller_state_callback.h b/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_controller_state_callback.h new file mode 100644 index 00000000..70110cce --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_controller_state_callback.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_SINK_CONTROLLER_STATE_CALLBACK_H +#define OHOS_DCAMERA_SINK_CONTROLLER_STATE_CALLBACK_H + +#include "icamera_operator.h" + +#include "dcamera_sink_controller.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkControllerStateCallback : public StateCallback { +public: + explicit DCameraSinkControllerStateCallback(std::shared_ptr& controller); + ~DCameraSinkControllerStateCallback() = default; + + void OnStateChanged(std::shared_ptr& event) override; + void OnMetadataResult() override; + +private: + std::weak_ptr controller_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_CONTROLLER_STATE_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_output_result_callback.h b/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_output_result_callback.h new file mode 100644 index 00000000..d2c62906 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/callback/dcamera_sink_output_result_callback.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_SINK_OUTPUT_RESULT_CALLBACK_H +#define OHOS_DCAMERA_SINK_OUTPUT_RESULT_CALLBACK_H + +#include "icamera_operator.h" + +#include "dcamera_sink_output.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkOutputResultCallback : public ResultCallback { +public: + explicit DCameraSinkOutputResultCallback(std::shared_ptr& output); + ~DCameraSinkOutputResultCallback() = default; + + void OnPhotoResult(std::shared_ptr& buffer) override; + void OnVideoResult(std::shared_ptr& buffer) override; + +private: + std::weak_ptr output_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_OUTPUT_RESULT_CALLBACK_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_access_control.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_access_control.h new file mode 100644 index 00000000..7fac01cd --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_access_control.h @@ -0,0 +1,35 @@ +/* + * 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_SINK_ACCESS_CONTROL_H +#define OHOS_DCAMERA_SINK_ACCESS_CONTROL_H + +#include "icamera_sink_access_control.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkAccessControl : public ICameraSinkAccessControl { +public: + DCameraSinkAccessControl() = default; + ~DCameraSinkAccessControl() = default; + + bool IsSensitiveSrcAccess(const std::string& srcType) override; + bool NotifySensitiveSrc(const std::string& srcType) override; + int32_t TriggerFrame(const std::string& deviceName) override; + int32_t GetAccessControlType(const std::string& accessType) override; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_ACCESS_CONTROL_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h new file mode 100644 index 00000000..1de1b4f2 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_controller.h @@ -0,0 +1,84 @@ +/* + * 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_SINK_CONTROLLER_H +#define OHOS_DCAMERA_SINK_CONTROLLER_H + +#include "event_bus.h" +#include "dcamera_frame_trigger_event.h" +#include "dcamera_post_authorization_event.h" +#include "icamera_controller.h" + +#include "icamera_channel.h" +#include "icamera_operator.h" +#include "icamera_sink_access_control.h" +#include "icamera_sink_output.h" +#include + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkController : public ICameraController, public EventSender, + public DistributedHardware::EventBusHandler, + public DistributedHardware::EventBusHandler, + public std::enable_shared_from_this { +public: + explicit DCameraSinkController(std::shared_ptr& accessControl); + ~DCameraSinkController(); + + int32_t StartCapture(std::vector>& captureInfos) override; + int32_t StopCapture() override; + int32_t ChannelNeg(std::shared_ptr& info) override; + int32_t DCameraNotify(std::shared_ptr& events) override; + int32_t UpdateSettings(std::vector>& settings) override; + int32_t GetCameraInfo(std::shared_ptr& camInfo) override; + int32_t OpenChannel(std::shared_ptr& openInfo) override; + int32_t CloseChannel() override; + int32_t Init(std::vector& indexs) override; + int32_t UnInit() override; + + void OnEvent(DCameraFrameTriggerEvent& event) override; + void OnEvent(DCameraPostAuthorizationEvent& event) override; + + void OnStateChanged(std::shared_ptr& event); + void OnMetadataResult(); + + void OnSessionState(int32_t state); + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail); + void OnDataReceived(std::vector>& buffers); + +private: + int32_t StartCaptureInner(std::vector>& captureInfos); + int32_t DCameraNotifyInner(int32_t type, int32_t result, std::string content); + int32_t HandleReceivedData(std::shared_ptr& dataBuffer); + void PostAuthorization(std::vector>& captureInfos); + + bool isInit_; + int32_t sessionState_; + std::mutex captureLock_; + std::mutex channelLock_; + std::string dhId_; + std::string srcDevId_; + std::shared_ptr eventBus_; + std::shared_ptr channel_; + std::shared_ptr operator_; + std::shared_ptr accessControl_; + std::shared_ptr output_; + + const std::string SESSION_FLAG = "control"; + const std::string SRC_TYPE = "camera"; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_CONTROLLER_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_data_process.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_data_process.h new file mode 100644 index 00000000..01c108d3 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_data_process.h @@ -0,0 +1,61 @@ +/* + * 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_SINK_DATA_PROCESS_H +#define OHOS_DCAMERA_SINK_DATA_PROCESS_H + +#include "event_bus.h" +#include "dcamera_photo_output_event.h" +#include "dcamera_video_output_event.h" +#include "icamera_sink_data_process.h" + +#include "icamera_channel.h" +#include "idata_process_pipeline.h" +#include "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkDataProcess : public ICameraSinkDataProcess, public EventSender, + public DistributedHardware::EventBusHandler, + public DistributedHardware::EventBusHandler, + public std::enable_shared_from_this { +public: + DCameraSinkDataProcess(const std::string& dhId, std::shared_ptr& channel); + ~DCameraSinkDataProcess() = default; + + int32_t StartCapture(std::shared_ptr& captureInfo) override; + int32_t StopCapture() override; + int32_t FeedStream(std::shared_ptr& dataBuffer) override; + + void OnEvent(DCameraPhotoOutputEvent& event) override; + void OnEvent(DCameraVideoOutputEvent& event) override; + + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult); + void OnError(DataProcessErrorType errorType); + +private: + int32_t FeedStreamInner(std::shared_ptr& dataBuffer); + VideoCodecType GetPipelineCodecType(DCEncodeType encodeType); + Videoformat GetPipelineFormat(int32_t format); + + std::string dhId_; + std::shared_ptr captureInfo_; + std::shared_ptr eventBus_; + std::shared_ptr channel_; + std::shared_ptr pipeline_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_DATA_PROCESS_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_dev.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_dev.h new file mode 100644 index 00000000..295e562e --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_dev.h @@ -0,0 +1,51 @@ +/* + * 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_SINK_DEV_H +#define OHOS_DCAMERA_SINK_DEV_H + +#include +#include +#include + +#include "icamera_controller.h" +#include "icamera_sink_access_control.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkDev { +public: + explicit DCameraSinkDev(const std::string& dhId); + ~DCameraSinkDev(); + + int32_t Init(); + int32_t UnInit(); + int32_t SubscribeLocalHardware(const std::string& parameters); + int32_t UnsubscribeLocalHardware(); + int32_t StopCapture(); + int32_t ChannelNeg(std::string& channelInfo); + int32_t GetCameraInfo(std::string& cameraInfo); + int32_t OpenChannel(std::string& openInfo); + int32_t CloseChannel(); + +private: + bool isInit_; + std::string dhId_; + std::shared_ptr controller_; + std::shared_ptr accessControl_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_DEV_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_output.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_output.h new file mode 100644 index 00000000..839a8c14 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_output.h @@ -0,0 +1,60 @@ +/* + * 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_SINK_OUTPUT_H +#define OHOS_DCAMERA_SINK_OUTPUT_H + +#include "icamera_sink_output.h" + +#include + +#include "icamera_channel.h" +#include "icamera_operator.h" +#include "icamera_sink_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkOutput : public ICameraSinkOutput, public std::enable_shared_from_this { +public: + DCameraSinkOutput(const std::string& dhId, std::shared_ptr& cameraOperator); + ~DCameraSinkOutput(); + + int32_t Init() override; + int32_t UnInit() override; + int32_t StartCapture(std::vector>& captureInfos) override; + int32_t StopCapture() override; + int32_t OpenChannel(std::shared_ptr& info) override; + int32_t CloseChannel() override; + + void OnPhotoResult(std::shared_ptr& buffer); + void OnVideoResult(std::shared_ptr& buffer); + + void OnSessionState(DCStreamType type, int32_t state); + void OnSessionError(DCStreamType type, int32_t eventType, int32_t eventReason, std::string detail); + void OnDataReceived(DCStreamType type, std::vector>& dataBuffers); + +private: + void InitInner(DCStreamType type); + + bool isInit_; + std::string dhId_; + std::map sessionState_; + std::map> channels_; + std::map> dataProcesses_; + std::shared_ptr operator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_OUTPUT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_service_ipc.h b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_service_ipc.h new file mode 100644 index 00000000..ee19ae09 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/dcamera_sink_service_ipc.h @@ -0,0 +1,54 @@ +/* + * 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_SINK_SERVICE_IPC_H +#define OHOS_DCAMERA_SINK_SERVICE_IPC_H + +#include "event_handler.h" +#include "idistributed_camera_source.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkServiceIpc { +DECLARE_SINGLE_INSTANCE_BASE(DCameraSinkServiceIpc); +public: + void Init(); + void UnInit(); + sptr GetSourceRemoteDHMS(const std::string& deviceId); + void OnSourceRemoteDmsDied(const wptr& remote); + void DeleteSourceRemoteDhms(const std::string& deviceId); + +private: + DCameraSinkServiceIpc(); + ~DCameraSinkServiceIpc(); + void OnSourceRemoteDmsDied(const sptr& remote); + void ClearSourceRemoteDhms(); + + class SourceRemoteRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr& remote) override; + }; + sptr sourceRemoteRecipient_; + std::map> remoteSources_; + std::mutex sourceRemoteDmsLock_; + + bool isInit_; + std::shared_ptr serviceHandler_; + std::mutex initDmsLock_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_frame_trigger_event.h b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_frame_trigger_event.h new file mode 100644 index 00000000..7024a9dd --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_frame_trigger_event.h @@ -0,0 +1,36 @@ +/* + * 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_FRAME_TRIGER_EVENT_H +#define OHOS_DCAMERA_FRAME_TRIGER_EVENT_H + +#include "event.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraFrameTriggerEvent : public Event { +TYPEINDENT(DCameraFrameTriggerEvent); +public: + explicit DCameraFrameTriggerEvent(EventSender& sender); + DCameraFrameTriggerEvent(EventSender& sender, std::string& param); + ~DCameraFrameTriggerEvent() = default; + std::string GetParam(); + +private: + std::string param_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_FRAME_TRIGER_EVENT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_photo_output_event.h b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_photo_output_event.h new file mode 100644 index 00000000..d42e84fa --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_photo_output_event.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_PHOTO_OUTPUT_EVENT_H +#define OHOS_DCAMERA_PHOTO_OUTPUT_EVENT_H + +#include "event.h" + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPhotoOutputEvent : public Event { +TYPEINDENT(DCameraPhotoOutputEvent); +public: + explicit DCameraPhotoOutputEvent(EventSender& sender); + DCameraPhotoOutputEvent(EventSender& sender, const std::shared_ptr& param); + ~DCameraPhotoOutputEvent() = default; + std::shared_ptr GetParam(); + +private: + std::shared_ptr param_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_PHOTO_OUTPUT_EVENT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_post_authorization_event.h b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_post_authorization_event.h new file mode 100644 index 00000000..5c23084c --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_post_authorization_event.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_POST_AUTHORIZATION_EVENT_H +#define OHOS_DCAMERA_POST_AUTHORIZATION_EVENT_H + +#include "event.h" + +#include "dcamera_capture_info_cmd.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPostAuthorizationEvent : public Event { +TYPEINDENT(DCameraPostAuthorizationEvent); +public: + explicit DCameraPostAuthorizationEvent(EventSender& sender); + DCameraPostAuthorizationEvent(EventSender& sender, std::vector>& param); + ~DCameraPostAuthorizationEvent() = default; + std::vector> GetParam(); + +private: + std::vector> param_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_POST_AUTHORIZATION_EVENT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_video_output_event.h b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_video_output_event.h new file mode 100644 index 00000000..f0cb6382 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/eventbus/dcamera_video_output_event.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_VIDEO_OUTPUT_EVENT_H +#define OHOS_DCAMERA_VIDEO_OUTPUT_EVENT_H + +#include "event.h" + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraVideoOutputEvent : public Event { +TYPEINDENT(DCameraVideoOutputEvent); +public: + explicit DCameraVideoOutputEvent(EventSender& sender); + DCameraVideoOutputEvent(EventSender& sender, const std::shared_ptr& param); + ~DCameraVideoOutputEvent() = default; + std::shared_ptr GetParam(); + +private: + std::shared_ptr param_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_VIDEO_OUTPUT_EVENT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_access_control.h b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_access_control.h new file mode 100644 index 00000000..06e264ff --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_access_control.h @@ -0,0 +1,36 @@ +/* + * 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_ICAMERA_SINK_ACCESS_CONTROL_H +#define OHOS_ICAMERA_SINK_ACCESS_CONTROL_H + +#include +#include + +namespace OHOS { +namespace DistributedHardware { +class ICameraSinkAccessControl { +public: + ICameraSinkAccessControl() = default; + virtual ~ICameraSinkAccessControl() = default; + + virtual bool IsSensitiveSrcAccess(const std::string& srcType) = 0; + virtual bool NotifySensitiveSrc(const std::string& srcType) = 0; + virtual int32_t TriggerFrame(const std::string& deviceName) = 0; + virtual int32_t GetAccessControlType(const std::string& accessType) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_ICAMERA_SINK_ACCESS_CONTROL_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_data_process.h b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_data_process.h new file mode 100644 index 00000000..035cec5e --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_data_process.h @@ -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. + */ + +#ifndef OHOS_ICAMERA_SINK_DATA_PROCESS_H +#define OHOS_ICAMERA_SINK_DATA_PROCESS_H + +#include +#include + +#include "data_buffer.h" +#include "dcamera_capture_info_cmd.h" + +namespace OHOS { +namespace DistributedHardware { +class ICameraSinkDataProcess { +public: + ICameraSinkDataProcess() = default; + virtual ~ICameraSinkDataProcess() = default; + + virtual int32_t StartCapture(std::shared_ptr& captureInfo) = 0; + virtual int32_t StopCapture() = 0; + virtual int32_t FeedStream(std::shared_ptr& dataBuffer) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_ICAMERA_SINK_DATA_PROCESS_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_output.h b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_output.h new file mode 100644 index 00000000..2355b70b --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/interface/icamera_sink_output.h @@ -0,0 +1,42 @@ +/* + * 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_ICAMERA_SINK_OUTPUT_H +#define OHOS_ICAMERA_SINK_OUTPUT_H + +#include +#include +#include + +#include "dcamera_capture_info_cmd.h" +#include "dcamera_channel_info_cmd.h" + +namespace OHOS { +namespace DistributedHardware { +class ICameraSinkOutput { +public: + ICameraSinkOutput() = default; + virtual ~ICameraSinkOutput() = default; + + virtual int32_t Init() = 0; + virtual int32_t UnInit() = 0; + virtual int32_t StartCapture(std::vector>& captureInfos) = 0; + virtual int32_t StopCapture() = 0; + virtual int32_t OpenChannel(std::shared_ptr& info) = 0; + virtual int32_t CloseChannel() = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_ICAMERA_SINK_OUTPUT_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.h b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.h new file mode 100644 index 00000000..1c7d88fa --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.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 OHOS_DCAMERA_SINK_CONTROLLER_CHANNEL_LISTENER_H +#define OHOS_DCAMERA_SINK_CONTROLLER_CHANNEL_LISTENER_H + +#include "icamera_channel_listener.h" + +#include "dcamera_sink_controller.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkControllerChannelListener : public ICameraChannelListener { +public: + explicit DCameraSinkControllerChannelListener(std::shared_ptr& controller); + ~DCameraSinkControllerChannelListener() = default; + + void OnSessionState(int32_t state) override; + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) override; + void OnDataReceived(std::vector>& buffers) override; + +private: + std::weak_ptr controller_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_CONTROLLER_CHANNEL_LISTENER_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_data_process_listener.h b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_data_process_listener.h new file mode 100644 index 00000000..ec6376d3 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_data_process_listener.h @@ -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. + */ + +#ifndef OHOS_DCAMERA_SINK_DATA_PROCESS_LISTENER_H +#define OHOS_DCAMERA_SINK_DATA_PROCESS_LISTENER_H + +#include "data_process_listener.h" + +#include "dcamera_sink_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkDataProcessListener : public DataProcessListener { +public: + explicit DCameraSinkDataProcessListener(std::shared_ptr& dataProcess); + ~DCameraSinkDataProcessListener() = default; + + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult) override; + void OnError(DataProcessErrorType errorType) override; + +private: + std::weak_ptr dataProcess_; +}; +} // namespace OHOS +} // namespace DistributedHardware +#endif // OHOS_DCAMERA_SINK_DATA_PROCESS_LISTENER_H diff --git a/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_output_channel_listener.h b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_output_channel_listener.h new file mode 100644 index 00000000..65e72912 --- /dev/null +++ b/services/cameraservice/sinkservice/include/distributedcameramgr/listener/dcamera_sink_output_channel_listener.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 OHOS_DCAMERA_SINK_OUTPUT_CHANNEL_LISTENER_H +#define OHOS_DCAMERA_SINK_OUTPUT_CHANNEL_LISTENER_H + +#include "icamera_channel_listener.h" + +#include "dcamera_sink_output.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkOutputChannelListener : public ICameraChannelListener { +public: + DCameraSinkOutputChannelListener(DCStreamType type, std::shared_ptr& output); + ~DCameraSinkOutputChannelListener() = default; + + void OnSessionState(int32_t state) override; + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) override; + void OnDataReceived(std::vector>& buffers) override; + +private: + DCStreamType streamType_; + std::weak_ptr output_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DCAMERA_SINK_OUTPUT_CHANNEL_LISTENER_H \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_service.cpp b/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_service.cpp new file mode 100644 index 00000000..888708d8 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_service.cpp @@ -0,0 +1,256 @@ +/* + * 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 "distributed_camera_sink_service.h" + +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "anonymous_string.h" +#include "dcamera_handler.h" +#include "dcamera_sink_service_ipc.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +REGISTER_SYSTEM_ABILITY_BY_ID(DistributedCameraSinkService, DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID, true); + +DistributedCameraSinkService::DistributedCameraSinkService(int32_t saId, bool runOnCreate) + : SystemAbility(saId, runOnCreate) +{ +} + +void DistributedCameraSinkService::OnStart() +{ + DHLOGI("DistributedCameraSinkService::OnStart"); + if (state_ == DCameraServiceState::DCAMERA_SRV_STATE_RUNNING) { + DHLOGI("DistributedCameraSinkService has already started."); + return; + } + + if (!Init()) { + DHLOGE("DistributedCameraSinkService init failed"); + return; + } + state_ = DCameraServiceState::DCAMERA_SRV_STATE_RUNNING; + DHLOGI("DCameraServiceState OnStart service success."); +} + +bool DistributedCameraSinkService::Init() +{ + DHLOGI("DistributedCameraSinkService start init"); + DCameraSinkServiceIpc::GetInstance().Init(); + if (!registerToService_) { + bool ret = Publish(this); + if (!ret) { + DHLOGE("DistributedCameraSinkService Publish service failed"); + return false; + } + registerToService_ = true; + } + DHLOGI("DistributedCameraSinkService init success"); + return true; +} + +void DistributedCameraSinkService::OnStop() +{ + DHLOGI("DistributedCameraSinkService OnStop service"); + state_ = DCameraServiceState::DCAMERA_SRV_STATE_NOT_START; + registerToService_ = false; + DCameraSinkServiceIpc::GetInstance().UnInit(); +} + +int32_t DistributedCameraSinkService::InitSink(const std::string& params) +{ + DHLOGI("DistributedCameraSinkService::InitSink"); + sinkVer_ = params; + int32_t ret = DCameraHandler::GetInstance().Initialize(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::InitSink handler initialize failed, ret: %d", ret); + return ret; + } + + std::vector cameras = DCameraHandler::GetInstance().GetCameras(); + if (cameras.empty()) { + DHLOGE("DistributedCameraSinkService::InitSink no camera device"); + return DCAMERA_BAD_VALUE; + } + for (auto& dhId : cameras) { + std::shared_ptr sinkDevice = std::make_shared(dhId); + ret = sinkDevice->Init(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::InitSink sink device init failed, ret: %d", ret); + return ret; + } + camerasMap_.emplace(dhId, sinkDevice); + } + DHLOGI("DistributedCameraSinkService::InitSink success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::ReleaseSink() +{ + DHLOGI("DistributedCameraSinkService::ReleaseSink"); + for (auto iter = camerasMap_.begin(); iter != camerasMap_.end(); iter++) { + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::ReleaseSink release sink device failed, ret: %d", ret); + } + } + camerasMap_.clear(); + DHLOGI("DistributedCameraSinkService::ReleaseSink success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) +{ + DHLOGI("DistributedCameraSinkService::SubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::SubscribeLocalHardware device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->SubscribeLocalHardware(parameters); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::SubscribeLocalHardware failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::SubscribeLocalHardware success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::UnsubscribeLocalHardware(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkService::UnsubscribeLocalHardware dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::UnsubscribeLocalHardware device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->UnsubscribeLocalHardware(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::UnsubscribeLocalHardware failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::UnsubscribeLocalHardware success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::StopCapture(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkService::StopCapture dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::StopCapture device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::StopCapture failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::StopCapture success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::ChannelNeg(const std::string& dhId, std::string& channelInfo) +{ + DHLOGI("DistributedCameraSinkService::ChannelNeg dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::ChannelNeg device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->ChannelNeg(channelInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::ChannelNeg failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::ChannelNeg success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::GetCameraInfo(const std::string& dhId, std::string& cameraInfo) +{ + DHLOGI("DistributedCameraSinkService::GetCameraInfo dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::GetCameraInfo device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->GetCameraInfo(cameraInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::GetCameraInfo failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::GetCameraInfo success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::OpenChannel(const std::string& dhId, std::string& openInfo) +{ + DHLOGI("DistributedCameraSinkService::OpenChannel dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::OpenChannel device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->OpenChannel(openInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::OpenChannel failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::OpenChannel success"); + return DCAMERA_OK; +} + +int32_t DistributedCameraSinkService::CloseChannel(const std::string& dhId) +{ + DHLOGI("DistributedCameraSinkService::CloseChannel dhId: %s", GetAnonyString(dhId).c_str()); + auto iter = camerasMap_.find(dhId); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSinkService::CloseChannel device not found"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr sinkDevice = iter->second; + int32_t ret = sinkDevice->CloseChannel(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSinkService::CloseChannel failed, ret: %d", ret); + return ret; + } + DHLOGI("DistributedCameraSinkService::CloseChannel success"); + return DCAMERA_OK; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_stub.cpp b/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_stub.cpp new file mode 100644 index 00000000..8ebb3152 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcamera/distributed_camera_sink_stub.cpp @@ -0,0 +1,141 @@ +/* + * 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 "distributed_camera_sink_stub.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DistributedCameraSinkStub::DistributedCameraSinkStub() +{ + memberFuncMap_[INIT_SINK] = &DistributedCameraSinkStub::InitSinkInner; + memberFuncMap_[RELEASE_SINK] = &DistributedCameraSinkStub::ReleaseSinkInner; + memberFuncMap_[SUBSCRIBE_LOCAL_HARDWARE] = &DistributedCameraSinkStub::SubscribeLocalHardwareInner; + memberFuncMap_[UNSUBSCRIBE_LOCAL_HARDWARE] = &DistributedCameraSinkStub::UnsubscribeLocalHardwareInner; + memberFuncMap_[STOP_CAPTURE] = &DistributedCameraSinkStub::StopCaptureInner; + memberFuncMap_[CHANNEL_NEG] = &DistributedCameraSinkStub::ChannelNegInner; + memberFuncMap_[GET_CAMERA_INFO] = &DistributedCameraSinkStub::GetCameraInfoInner; + memberFuncMap_[OPEN_CHANNEL] = &DistributedCameraSinkStub::OpenChannelInner; + memberFuncMap_[CLOSE_CHANNEL] = &DistributedCameraSinkStub::CloseChannelInner; +} + +DistributedCameraSinkStub::~DistributedCameraSinkStub() +{} + +int32_t DistributedCameraSinkStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DistributedCameraSinkStub::OnRemoteRequest code: %d", code); + std::u16string desc = DistributedCameraSinkStub::GetDescriptor(); + std::u16string remoteDesc = data.ReadInterfaceToken(); + if (desc != remoteDesc) { + DHLOGE("DistributedCameraSinkStub::OnRemoteRequest remoteDesc is invalid!"); + return ERR_INVALID_DATA; + } + auto itFunc = memberFuncMap_.find(code); + if (itFunc == memberFuncMap_.end()) { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + + auto memberFunc = itFunc->second; + return (this->*memberFunc)(data, reply); +} + +int32_t DistributedCameraSinkStub::InitSinkInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::InitSinkInner"); + std::string params = data.ReadString(); + int32_t ret = InitSink(params); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::ReleaseSinkInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::ReleaseSinkInner"); + int32_t ret = ReleaseSink(); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::SubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::SubscribeLocalHardwareInner"); + std::string dhId = data.ReadString(); + std::string parameters = data.ReadString(); + int32_t ret = SubscribeLocalHardware(dhId, parameters); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::UnsubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::UnsubscribeLocalHardwareInner"); + std::string dhId = data.ReadString(); + int32_t ret = UnsubscribeLocalHardware(dhId); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::StopCaptureInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::StopCaptureInner"); + std::string dhId = data.ReadString(); + int32_t ret = StopCapture(dhId); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::ChannelNegInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::ChannelNegInner"); + std::string dhId = data.ReadString(); + std::string channelInfo = data.ReadString(); + int32_t ret = ChannelNeg(dhId, channelInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::GetCameraInfoInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::GetCameraInfoInner"); + std::string dhId = data.ReadString(); + std::string cameraInfo = data.ReadString(); + int32_t ret = GetCameraInfo(dhId, cameraInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::OpenChannelInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::OpenChannelInner"); + std::string dhId = data.ReadString(); + std::string openInfo = data.ReadString(); + int32_t ret = OpenChannel(dhId, openInfo); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSinkStub::CloseChannelInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSinkStub::CloseChannelInner"); + std::string dhId = data.ReadString(); + int32_t ret = CloseChannel(dhId); + reply.WriteInt32(ret); + return ret; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_controller_state_callback.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_controller_state_callback.cpp new file mode 100644 index 00000000..ed6f9255 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_controller_state_callback.cpp @@ -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. + */ + +#include "dcamera_sink_controller_state_callback.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkControllerStateCallback::DCameraSinkControllerStateCallback( + std::shared_ptr& controller) : controller_(controller) +{ +} + +void DCameraSinkControllerStateCallback::OnStateChanged(std::shared_ptr& event) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSinkControllerStateCallback::OnStateChanged controller is null"); + return; + } + controller->OnStateChanged(event); +} + +void DCameraSinkControllerStateCallback::OnMetadataResult() +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSinkControllerStateCallback::OnMetadataResult controller is null"); + return; + } + controller->OnMetadataResult(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_output_result_callback.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_output_result_callback.cpp new file mode 100644 index 00000000..ab2f3cca --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/callback/dcamera_sink_output_result_callback.cpp @@ -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. + */ + +#include "dcamera_sink_output_result_callback.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkOutputResultCallback::DCameraSinkOutputResultCallback( + std::shared_ptr& output) : output_(output) +{ +} + +void DCameraSinkOutputResultCallback::OnPhotoResult(std::shared_ptr& buffer) +{ + std::shared_ptr output = output_.lock(); + if (output == nullptr) { + DHLOGE("DCameraSinkOutputResultCallback::OnPhotoResult output is null"); + return; + } + output->OnPhotoResult(buffer); +} + +void DCameraSinkOutputResultCallback::OnVideoResult(std::shared_ptr& buffer) +{ + std::shared_ptr output = output_.lock(); + if (output == nullptr) { + DHLOGE("DCameraSinkOutputResultCallback::OnVideoResult output is null"); + return; + } + output->OnVideoResult(buffer); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_access_control.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_access_control.cpp new file mode 100644 index 00000000..b03992af --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_access_control.cpp @@ -0,0 +1,48 @@ +/* + * 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_sink_access_control.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +bool DCameraSinkAccessControl::IsSensitiveSrcAccess(const std::string& srcType) +{ + DHLOGI("DCameraSinkAccessControl::IsSensitiveSrcAccess srcType: %s", srcType.c_str()); + return true; +} + +bool DCameraSinkAccessControl::NotifySensitiveSrc(const std::string& srcType) +{ + DHLOGI("DCameraSinkAccessControl::NotifySensitiveSrc srcType: %s", srcType.c_str()); + return true; +} + +int32_t DCameraSinkAccessControl::TriggerFrame(const std::string& deviceName) +{ + DHLOGI("DCameraSinkAccessControl::TriggerFrame deviceName: %s", deviceName.c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkAccessControl::GetAccessControlType(const std::string& accessType) +{ + DHLOGI("DCameraSinkAccessControl::GetAccessControlType accessType: %s", accessType.c_str()); + return DCAMERA_SAME_ACCOUNT; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp new file mode 100644 index 00000000..40e3388a --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_controller.cpp @@ -0,0 +1,442 @@ +/* + * 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_sink_controller.h" + +#include "anonymous_string.h" +#include "dcamera_channel_sink_impl.h" +#include "dcamera_client.h" +#include "dcamera_metadata_setting_cmd.h" +#include "dcamera_protocol.h" +#include "dcamera_utils_tools.h" + +#include "dcamera_sink_access_control.h" +#include "dcamera_sink_controller_channel_listener.h" +#include "dcamera_sink_controller_state_callback.h" +#include "dcamera_sink_output.h" +#include "dcamera_sink_service_ipc.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" +#include "idistributed_camera_source.h" +#include "json/json.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkController::DCameraSinkController(std::shared_ptr& accessControl) + : isInit_(false), sessionState_(DCAMERA_CHANNEL_STATE_DISCONNECTED), accessControl_(accessControl) +{ +} + +DCameraSinkController::~DCameraSinkController() +{ + if (isInit_) { + UnInit(); + } +} + +int32_t DCameraSinkController::StartCapture(std::vector>& captureInfos) +{ + DHLOGI("DCameraSinkController::StartCapture dhId: %s", GetAnonyString(dhId_).c_str()); + std::string accessType = ""; + if ((accessControl_->IsSensitiveSrcAccess(SRC_TYPE)) && + (accessControl_->GetAccessControlType(accessType) == DCAMERA_SAME_ACCOUNT)) { + int32_t ret = StartCaptureInner(captureInfos); + if (ret == DCAMERA_OK) { + accessControl_->NotifySensitiveSrc(SRC_TYPE); + } + return ret; + } else { + std::string param = ""; + DCameraFrameTriggerEvent triggerEvent(*this, param); + DCameraPostAuthorizationEvent authEvent(*this, captureInfos); + eventBus_->PostEvent(triggerEvent, POSTMODE::POST_ASYNC); + eventBus_->PostEvent(authEvent, POSTMODE::POST_ASYNC); + } + return DCAMERA_OK; +} + +int32_t DCameraSinkController::StopCapture() +{ + std::lock_guard autoLock(captureLock_); + DHLOGI("DCameraSinkController::StopCapture dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = operator_->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::StopCapture client stop capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_ERROR, std::string("operator stop capture failed")); + return ret; + } + + ret = output_->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::StopCapture output stop capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_ERROR, std::string("output stop capture failed")); + return ret; + } + + DHLOGI("DCameraSinkController::StopCapture %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::ChannelNeg(std::shared_ptr& info) +{ + DHLOGI("DCameraSinkController::ChannelNeg dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = output_->OpenChannel(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::ChannelNeg channel negotiate failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DHLOGI("DCameraSinkController::ChannelNeg %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::DCameraNotify(std::shared_ptr& events) +{ + DHLOGI("DCameraSinkController::DCameraNotify dhId: %s", GetAnonyString(dhId_).c_str()); + if (srcDevId_.empty()) { + DHLOGE("DCameraSinkController::DCameraNotify source deviceId is empty"); + return DCAMERA_BAD_VALUE; + } + + sptr sourceSA = DCameraSinkServiceIpc::GetInstance().GetSourceRemoteDHMS(srcDevId_); + if (sourceSA == nullptr) { + DHLOGE("DCameraSinkController::DCameraNotify sourceSA is null"); + return DCAMERA_BAD_VALUE; + } + + DCameraEventCmd eventCmd; + std::string jsonStr = ""; + eventCmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE; + eventCmd.dhId_ = dhId_; + eventCmd.command_ = DCAMERA_PROTOCOL_CMD_STATE_NOTIFY; + eventCmd.value_ = events; + int32_t ret = eventCmd.Marshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::DCameraNotify DCameraEventCmd marshal failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + std::string sinkDevId; + ret = GetLocalDeviceNetworkId(sinkDevId); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::DCameraNotify GetLocalDeviceNetworkId failed, devId: %s, dhId: %s, ret: %d", + GetAnonyString(sinkDevId).c_str(), GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + ret = sourceSA->DCameraNotify(sinkDevId, dhId_, jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::DCameraNotify SourceSA notify failed, srcId: %s, sinkId: %s, dhId: %s, ret: %d", + GetAnonyString(srcDevId_).c_str(), GetAnonyString(sinkDevId).c_str(), + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DHLOGI("DCameraSinkController::DCameraNotify %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::UpdateSettings(std::vector>& settings) +{ + DHLOGI("DCameraSinkController::UpdateSettings dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = operator_->UpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::UpdateSettings failed, dhId: %s, ret: %d", GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DHLOGI("DCameraSinkController::UpdateSettings %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::GetCameraInfo(std::shared_ptr& camInfo) +{ + DHLOGI("DCameraSinkController::GetCameraInfo dhId: %s, session state: %d", + GetAnonyString(dhId_).c_str(), sessionState_); + camInfo->state_ = sessionState_; + return DCAMERA_OK; +} + +int32_t DCameraSinkController::OpenChannel(std::shared_ptr& openInfo) +{ + DHLOGI("DCameraSinkController::OpenChannel dhId: %s", GetAnonyString(dhId_).c_str()); + if (sessionState_ != DCAMERA_CHANNEL_STATE_DISCONNECTED) { + DHLOGE("DCameraSinkController::OpenChannel wrong state, dhId: %s, sessionState: %d", + GetAnonyString(dhId_).c_str(), sessionState_); + return DCAMERA_WRONG_STATE; + } + srcDevId_ = openInfo->sourceDevId_; + std::vector indexs; + indexs.push_back(DCameraIndex(srcDevId_, dhId_)); + auto controller = std::shared_ptr(shared_from_this()); + std::shared_ptr listener = + std::make_shared(controller); + int32_t ret = channel_->CreateSession(indexs, SESSION_FLAG, DCAMERA_SESSION_MODE_CTRL, listener); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::Init channel create session failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + DHLOGI("DCameraSinkController::OpenChannel %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::CloseChannel() +{ + std::lock_guard autoLock(channelLock_); + DHLOGI("DCameraSinkController::CloseChannel dhId: %s", GetAnonyString(dhId_).c_str()); + DCameraSinkServiceIpc::GetInstance().DeleteSourceRemoteDhms(srcDevId_); + srcDevId_.clear(); + int32_t ret = channel_->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController release channel failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + + ret = output_->CloseChannel(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController CloseChannel failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + sessionState_ = DCAMERA_CHANNEL_STATE_DISCONNECTED; + DHLOGI("DCameraSinkController::CloseChannel %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::Init(std::vector& indexs) +{ + DHLOGI("DCameraSinkController::Init"); + dhId_ = indexs[0].dhId_; + operator_ = std::make_shared(dhId_); + output_ = std::make_shared(dhId_, operator_); + int32_t ret = output_->Init(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::Init output init failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + auto controller = std::shared_ptr(shared_from_this()); + std::shared_ptr stateCallback = std::make_shared(controller); + operator_->SetStateCallback(stateCallback); + ret = operator_->Init(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::Init operator init failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + channel_ = std::make_shared(); + eventBus_ = std::make_shared(); + DCameraFrameTriggerEvent triggerEvent(*this); + DCameraPostAuthorizationEvent authEvent(*this); + eventBus_->AddHandler(triggerEvent.GetType(), *this); + eventBus_->AddHandler(authEvent.GetType(), *this); + + isInit_ = true; + DHLOGI("DCameraSinkController::Init %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::UnInit() +{ + DHLOGI("DCameraSinkController::UnInit dhId: %s", GetAnonyString(dhId_).c_str()); + if (output_ != nullptr) { + int32_t ret = output_->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController release output failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + } + + if (operator_ != nullptr) { + int32_t ret = operator_->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController release operator failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + } + + isInit_ = false; + DHLOGI("DCameraSinkController::UnInit %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +void DCameraSinkController::OnEvent(DCameraFrameTriggerEvent& event) +{ + std::string param = event.GetParam(); + accessControl_->TriggerFrame(param); +} + +void DCameraSinkController::OnEvent(DCameraPostAuthorizationEvent& event) +{ + std::vector> captureInfos = event.GetParam(); + PostAuthorization(captureInfos); +} + +void DCameraSinkController::OnStateChanged(std::shared_ptr& event) +{ + DHLOGI("DCameraSinkController::OnStateChanged dhId: %s, result: %d", + GetAnonyString(dhId_).c_str(), event->eventResult_); + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_ERROR, std::string("camera error")); +} + +void DCameraSinkController::OnMetadataResult() +{ + DHLOGI("DCameraSinkController::OnMetadataResult dhId: %s", GetAnonyString(dhId_).c_str()); +} + +void DCameraSinkController::OnSessionState(int32_t state) +{ + DHLOGI("DCameraSinkController::OnSessionState dhId: %s, state: %d", GetAnonyString(dhId_).c_str(), state); + sessionState_ = state; + switch (state) { + case DCAMERA_CHANNEL_STATE_CONNECTING: { + DHLOGI("DCameraSinkController::OnSessionState channel is connecting"); + break; + } + case DCAMERA_CHANNEL_STATE_CONNECTED: { + DHLOGI("DCameraSinkController::OnSessionState channel is connected"); + break; + } + case DCAMERA_CHANNEL_STATE_DISCONNECTED: { + DHLOGI("DCameraSinkController::OnSessionState channel is disconnected"); + int32_t ret = StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::OnSessionState session state: %d, %s stop capture failed, ret: %d", + sessionState_, GetAnonyString(dhId_).c_str(), ret); + } + ret = CloseChannel(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::OnSessionState session state: %d, %s close channel failed, ret: %d", + sessionState_, GetAnonyString(dhId_).c_str(), ret); + } + break; + } + default: { + DHLOGE("DCameraSinkController::OnSessionState unknown session state"); + break; + } + } +} + +void DCameraSinkController::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + DHLOGI("DCameraSinkController::OnSessionError dhId: %s, eventType: %d, eventReason: %d, detail: %s", + GetAnonyString(dhId_).c_str(), eventType, eventReason, detail.c_str()); +} + +void DCameraSinkController::OnDataReceived(std::vector>& buffers) +{ + DHLOGI("DCameraSinkController::OnReceivedData %s control channel receive data", GetAnonyString(dhId_).c_str()); + for (auto& buffer : buffers) { + HandleReceivedData(buffer); + } +} + +void DCameraSinkController::PostAuthorization(std::vector>& captureInfos) +{ + DHLOGI("DCameraSinkController::PostAuthorization dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = StartCaptureInner(captureInfos); + if (ret == DCAMERA_OK) { + accessControl_->NotifySensitiveSrc(SRC_TYPE); + } +} + +int32_t DCameraSinkController::StartCaptureInner(std::vector>& captureInfos) +{ + std::lock_guard autoLock(captureLock_); + DHLOGI("DCameraSinkController::StartCaptureInner dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = output_->StartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::StartCaptureInner output start capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_ERROR, std::string("output start capture failed")); + return ret; + } + + ret = operator_->StartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::StartCaptureInner camera client start capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_ERROR, std::string("operator start capture failed")); + return ret; + } + + DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_SUCCESS, std::string("operator start capture success")); + DHLOGI("DCameraSinkController::StartCaptureInner %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkController::DCameraNotifyInner(int32_t type, int32_t result, std::string reason) +{ + std::shared_ptr event = std::make_shared(); + event->eventType_ = type; + event->eventResult_ = result; + event->eventContent_ = reason; + return DCameraNotify(event); +} + +int32_t DCameraSinkController::HandleReceivedData(std::shared_ptr& dataBuffer) +{ + DHLOGI("DCameraSinkController::HandleReceivedData dhId: %s", GetAnonyString(dhId_).c_str()); + uint8_t *data = dataBuffer->Data(); + std::string jsonStr((const char *)data, dataBuffer->Capacity()); + + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value root; + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if ((!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &root, &errs)) || + (!root.isObject())) { + DHLOGE("DCameraSinkController::HandleReceivedData parse json string failed"); + return DCAMERA_BAD_VALUE; + } + + if ((!root.isMember("Command")) || (!root["Command"].isString())) { + DHLOGE("DCameraSinkController::HandleReceivedData parse command failed"); + return DCAMERA_BAD_VALUE; + } + + std::string command = root["Command"].asString(); + if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_CAPTURE) == 0)) { + DCameraCaptureInfoCmd captureInfoCmd; + int ret = captureInfoCmd.Unmarshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::HandleReceivedData Capture Info Unmarshal failed, dhId: %s ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + return StartCapture(captureInfoCmd.value_); + } else if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_UPDATE_METADATA) == 0)) { + DCameraMetadataSettingCmd metadataSettingCmd; + int ret = metadataSettingCmd.Unmarshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkController::HandleReceivedData Metadata Setting Unmarshal failed, dhId: %s ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + return UpdateSettings(metadataSettingCmd.value_); + } + return DCAMERA_BAD_VALUE; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_data_process.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_data_process.cpp new file mode 100644 index 00000000..d870b710 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_data_process.cpp @@ -0,0 +1,185 @@ +/* + * 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_sink_data_process.h" + +#include "anonymous_string.h" +#include "dcamera_channel_sink_impl.h" +#include "dcamera_pipeline_sink.h" +#include "dcamera_sink_data_process_listener.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkDataProcess::DCameraSinkDataProcess(const std::string& dhId, std::shared_ptr& channel) + : dhId_(dhId), channel_(channel) +{ + DHLOGI("DCameraSinkDataProcess Constructor dhId: %s", GetAnonyString(dhId_).c_str()); + eventBus_ = std::make_shared(); + DCameraPhotoOutputEvent photoEvent(*this); + DCameraVideoOutputEvent videoEvent(*this); + eventBus_->AddHandler(photoEvent.GetType(), *this); + eventBus_->AddHandler(videoEvent.GetType(), *this); +} + +int32_t DCameraSinkDataProcess::StartCapture(std::shared_ptr& captureInfo) +{ + DHLOGI("DCameraSinkDataProcess::StartCapture dhId: %s, width: %d, height: %d, format: %d, stream: %d, encode: %d", + GetAnonyString(dhId_).c_str(), captureInfo->width_, captureInfo->height_, captureInfo->format_, + captureInfo->streamType_, captureInfo->encodeType_); + captureInfo_ = captureInfo; + if (pipeline_ != nullptr) { + DHLOGI("DCameraSinkDataProcess::StartCapture %s pipeline already exits", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; + } + + if ((captureInfo->streamType_ == CONTINUOUS_FRAME) && (captureInfo->format_ != captureInfo->encodeType_)) { + DHLOGI("DCameraSinkDataProcess::StartCapture %s create data process pipeline", GetAnonyString(dhId_).c_str()); + pipeline_ = std::make_shared(); + auto dataProcess = std::shared_ptr(shared_from_this()); + std::shared_ptr listener = std::make_shared(dataProcess); + VideoConfigParams srcParams(VideoCodecType::NO_CODEC, + GetPipelineFormat(captureInfo->format_), + DCAMERA_PRODUCER_FPS_DEFAULT, + captureInfo->width_, + captureInfo->height_); + VideoConfigParams destParams(GetPipelineCodecType(captureInfo->encodeType_), + GetPipelineFormat(captureInfo->format_), + DCAMERA_PRODUCER_FPS_DEFAULT, + captureInfo->width_, + captureInfo->height_); + int32_t ret = pipeline_->CreateDataProcessPipeline(PipelineType::VIDEO, srcParams, destParams, listener); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDataProcess::StartCapture create data process pipeline failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + } + DHLOGI("DCameraSinkDataProcess::StartCapture %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkDataProcess::StopCapture() +{ + DHLOGI("DCameraSinkDataProcess::StopCapture dhId: %s", GetAnonyString(dhId_).c_str()); + if (pipeline_ != nullptr) { + pipeline_->DestroyDataProcessPipeline(); + pipeline_ = nullptr; + } + return DCAMERA_OK; +} + +int32_t DCameraSinkDataProcess::FeedStream(std::shared_ptr& dataBuffer) +{ + DCStreamType type = captureInfo_->streamType_; + DHLOGI("DCameraSinkDataProcess::FeedStream dhId: %s, stream type: %d", GetAnonyString(dhId_).c_str(), type); + switch (type) { + case CONTINUOUS_FRAME: { + int32_t ret = FeedStreamInner(dataBuffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDataProcess::FeedStream continuous frame failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + break; + } + case SNAPSHOT_FRAME: { + DCameraPhotoOutputEvent photoEvent(*this, dataBuffer); + eventBus_->PostEvent(photoEvent, POSTMODE::POST_ASYNC); + break; + } + default: { + DHLOGE("DCameraSinkDataProcess::FeedStream %s unknown stream type: %d", + GetAnonyString(dhId_).c_str(), type); + break; + } + } + DHLOGI("DCameraSinkDataProcess::FeedStream %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +void DCameraSinkDataProcess::OnEvent(DCameraPhotoOutputEvent& event) +{ + std::shared_ptr buffer = event.GetParam(); + int32_t ret = channel_->SendData(buffer); + DHLOGI("DCameraSinkDataProcess::OnEvent %s send photo output data ret: %d", GetAnonyString(dhId_).c_str(), ret); +} + +void DCameraSinkDataProcess::OnEvent(DCameraVideoOutputEvent& event) +{ + std::shared_ptr buffer = event.GetParam(); + int32_t ret = channel_->SendData(buffer); + DHLOGI("DCameraSinkDataProcess::OnEvent %s send video output data ret: %d", GetAnonyString(dhId_).c_str(), ret); +} + +void DCameraSinkDataProcess::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + DCameraVideoOutputEvent videoEvent(*this, videoResult); + eventBus_->PostEvent(videoEvent, POSTMODE::POST_ASYNC); +} + +void DCameraSinkDataProcess::OnError(DataProcessErrorType errorType) +{ + DHLOGE("DCameraSinkDataProcess::OnError %s data process pipeline error, errorType: %d", + GetAnonyString(dhId_).c_str(), errorType); +} + +int32_t DCameraSinkDataProcess::FeedStreamInner(std::shared_ptr& dataBuffer) +{ + DHLOGI("DCameraSinkDataProcess::FeedStreamInner dhId: %s", GetAnonyString(dhId_).c_str()); + if (captureInfo_->format_ == captureInfo_->encodeType_) { + DHLOGI("DCameraSinkDataProcess::FeedStreamInner %s send video buffer", GetAnonyString(dhId_).c_str()); + DCameraVideoOutputEvent videoEvent(*this, dataBuffer); + eventBus_->PostEvent(videoEvent, POSTMODE::POST_ASYNC); + return DCAMERA_OK; + } + + std::vector> buffers; + buffers.push_back(dataBuffer); + int32_t ret = pipeline_->ProcessData(buffers); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDataProcess::FeedStreamInner process data failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + DHLOGI("DCameraSinkDataProcess::FeedStreamInner %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +VideoCodecType DCameraSinkDataProcess::GetPipelineCodecType(DCEncodeType encodeType) +{ + VideoCodecType codecType; + switch (encodeType) { + case ENCODE_TYPE_H264: + codecType = VideoCodecType::CODEC_H264; + break; + case ENCODE_TYPE_H265: + codecType = VideoCodecType::CODEC_H265; + break; + default: + codecType = VideoCodecType::NO_CODEC; + break; + } + return codecType; +} + +Videoformat DCameraSinkDataProcess::GetPipelineFormat(int32_t format) +{ + return Videoformat::NV21; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_dev.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_dev.cpp new file mode 100644 index 00000000..e9db8f9f --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_dev.cpp @@ -0,0 +1,160 @@ +/* + * 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_sink_dev.h" + +#include "anonymous_string.h" +#include "dcamera_channel_info_cmd.h" +#include "dcamera_info_cmd.h" +#include "dcamera_protocol.h" +#include "dcamera_sink_access_control.h" +#include "dcamera_sink_controller.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkDev::DCameraSinkDev(const std::string& dhId) : dhId_(dhId) +{ + DHLOGI("DCameraSinkDev Constructor dhId: %s", GetAnonyString(dhId_).c_str()); + isInit_ = false; +} + +DCameraSinkDev::~DCameraSinkDev() +{ + if (isInit_) { + UnInit(); + } +} + +int32_t DCameraSinkDev::Init() +{ + DHLOGI("DCameraSinkDev::Init dhId: %s", GetAnonyString(dhId_).c_str()); + accessControl_ = std::make_shared(); + controller_ = std::make_shared(accessControl_); + DCameraIndex index("", dhId_); + std::vector indexs; + indexs.push_back(index); + int32_t ret = controller_->Init(indexs); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::Init init controller failed, dhId: %s, ret: %d", GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + isInit_ = true; + DHLOGI("DCameraSinkDev::Init %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkDev::UnInit() +{ + if (controller_ != nullptr) { + int32_t ret = controller_->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::UnInit release controller failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + } + isInit_ = false; + return DCAMERA_OK; +} + +int32_t DCameraSinkDev::SubscribeLocalHardware(const std::string& parameters) +{ + DHLOGI("DCameraSinkDev::SubscribeLocalHardware"); + return DCAMERA_OK; +} + +int32_t DCameraSinkDev::UnsubscribeLocalHardware() +{ + DHLOGI("DCameraSinkDev::UnsubscribeLocalHardware"); + return DCAMERA_OK; +} + +int32_t DCameraSinkDev::StopCapture() +{ + DHLOGI("DCameraSinkDev::StopCapture dhId: %s", GetAnonyString(dhId_).c_str()); + return controller_->StopCapture(); +} + +int32_t DCameraSinkDev::ChannelNeg(std::string& channelInfo) +{ + DHLOGI("DCameraSinkDev::ChannelNeg dhId: %s", GetAnonyString(dhId_).c_str()); + if (channelInfo.empty()) { + DHLOGE("DCameraSinkDev::ChannelNeg channelInfo is empty"); + return DCAMERA_BAD_VALUE; + } + + DCameraChannelInfoCmd channelInfoCmd; + int32_t ret = channelInfoCmd.Unmarshal(channelInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::ChannelNeg channelInfo unmarshal failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + return controller_->ChannelNeg(channelInfoCmd.value_); +} + +int32_t DCameraSinkDev::GetCameraInfo(std::string& cameraInfo) +{ + DHLOGI("DCameraSinkDev::GetCameraInfo dhId: %s", GetAnonyString(dhId_).c_str()); + std::shared_ptr info = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::GetCameraInfo get state failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DCameraInfoCmd cameraInfoCmd; + cameraInfoCmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE; + cameraInfoCmd.dhId_ = dhId_; + cameraInfoCmd.command_ = DCAMERA_PROTOCOL_CMD_GET_INFO; + cameraInfoCmd.value_ = info; + ret = cameraInfoCmd.Marshal(cameraInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::GetCameraInfo cameraInfoCmd marshal failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + DHLOGI("DCameraSinkDev::GetCameraInfo %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkDev::OpenChannel(std::string& openInfo) +{ + DHLOGI("DCameraSinkDev::OpenChannel dhId: %s", GetAnonyString(dhId_).c_str()); + if (openInfo.empty()) { + DHLOGE("DCameraSinkDev::OpenChannel openInfo is empty"); + return DCAMERA_BAD_VALUE; + } + + DCameraOpenInfoCmd cmd; + int32_t ret = cmd.Unmarshal(openInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkDev::OpenChannel openInfo unmarshal failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + return controller_->OpenChannel(cmd.value_); +} + +int32_t DCameraSinkDev::CloseChannel() +{ + DHLOGI("DCameraSinkDev::CloseChannel dhId: %s", GetAnonyString(dhId_).c_str()); + return controller_->CloseChannel(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_output.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_output.cpp new file mode 100644 index 00000000..7397bb8d --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_output.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_sink_output.h" + +#include "anonymous_string.h" +#include "dcamera_channel_sink_impl.h" +#include "dcamera_client.h" +#include "dcamera_sink_data_process.h" +#include "dcamera_sink_output_channel_listener.h" +#include "dcamera_sink_output_result_callback.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkOutput::DCameraSinkOutput(const std::string& dhId, std::shared_ptr& cameraOperator) + : dhId_(dhId), operator_(cameraOperator) +{ + DHLOGI("DCameraSinkOutput Constructor dhId: %s", GetAnonyString(dhId_).c_str()); + isInit_ = false; +} + +DCameraSinkOutput::~DCameraSinkOutput() +{ + if (isInit_) { + UnInit(); + } +} + +int32_t DCameraSinkOutput::Init() +{ + DHLOGI("DCameraSinkOutput::Init dhId: %s", GetAnonyString(dhId_).c_str()); + auto output = std::shared_ptr(shared_from_this()); + std::shared_ptr resultCallback = std::make_shared(output); + operator_->SetResultCallback(resultCallback); + + InitInner(CONTINUOUS_FRAME); + InitInner(SNAPSHOT_FRAME); + isInit_ = true; + DHLOGI("DCameraSinkOutput::Init %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +void DCameraSinkOutput::InitInner(DCStreamType type) +{ + std::shared_ptr channel = std::make_shared(); + std::shared_ptr dataProcess = std::make_shared(dhId_, channel); + dataProcesses_.emplace(type, dataProcess); + channels_.emplace(type, channel); + sessionState_.emplace(type, DCAMERA_CHANNEL_STATE_DISCONNECTED); +} + +int32_t DCameraSinkOutput::UnInit() +{ + DHLOGI("DCameraSinkOutput::UnInit dhId: %s", GetAnonyString(dhId_).c_str()); + channels_.clear(); + dataProcesses_.clear(); + sessionState_.clear(); + isInit_ = false; + DHLOGI("DCameraSinkOutput::UnInit %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSinkOutput::OpenChannel(std::shared_ptr& info) +{ + DHLOGI("DCameraSinkOutput::OpenChannel dhId: %s", GetAnonyString(dhId_).c_str()); + std::map modeMaps; + modeMaps.emplace(CONTINUOUS_FRAME, DCAMERA_SESSION_MODE_VIDEO); + modeMaps.emplace(SNAPSHOT_FRAME, DCAMERA_SESSION_MODE_JPEG); + std::vector indexs; + indexs.push_back(DCameraIndex(info->sourceDevId_, dhId_)); + for (auto iter = info->detail_.begin(); iter != info->detail_.end(); iter++) { + if (sessionState_[iter->streamType_] != DCAMERA_CHANNEL_STATE_DISCONNECTED) { + DHLOGE("DCameraSinkOutput::OpenChannel wrong state, sessionState: %d", sessionState_[iter->streamType_]); + return DCAMERA_WRONG_STATE; + } + auto iterCh = channels_.find(iter->streamType_); + if (iterCh == channels_.end()) { + continue; + } + auto output = std::shared_ptr(shared_from_this()); + std::shared_ptr channelListener = + std::make_shared(iter->streamType_, output); + int32_t ret = iterCh->second->CreateSession(indexs, iter->dataSessionFlag_, modeMaps[iter->streamType_], + channelListener); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkOutput::Init channel create session failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + } + return DCAMERA_OK; +} + +int32_t DCameraSinkOutput::CloseChannel() +{ + DHLOGI("DCameraSinkOutput::CloseChannel dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = DCAMERA_OK; + auto iterCon = channels_.find(CONTINUOUS_FRAME); + if (iterCon != channels_.end()) { + ret = iterCon->second->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSinkOutput UnInit release continue session failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + sessionState_[CONTINUOUS_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED; + } + + auto iterSnap = channels_.find(SNAPSHOT_FRAME); + if (iterSnap != channels_.end()) { + ret = iterSnap->second->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSinkOutput UnInit release snapshot session failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + } + sessionState_[SNAPSHOT_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED; + } + return DCAMERA_OK; +} + +int32_t DCameraSinkOutput::StartCapture(std::vector>& captureInfos) +{ + DHLOGI("DCameraSinkOutput::StartCapture dhId: %s", GetAnonyString(dhId_).c_str()); + for (auto& info : captureInfos) { + if (dataProcesses_.find(info->streamType_) == dataProcesses_.end()) { + DHLOGE("DCameraSinkOutput::StartCapture has no data process, streamType: %d", info->streamType_); + break; + } + int32_t ret = dataProcesses_[info->streamType_]->StartCapture(info); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkOutput::StartCapture failed, dhId: %s, ret: %d", GetAnonyString(dhId_).c_str(), ret); + return ret; + } + } + return DCAMERA_OK; +} + +int32_t DCameraSinkOutput::StopCapture() +{ + DHLOGI("DCameraSinkOutput::StopCapture dhId: %s", GetAnonyString(dhId_).c_str()); + int32_t ret = dataProcesses_[CONTINUOUS_FRAME]->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkOutput::StopCapture continuous data process stop capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + ret = dataProcesses_[SNAPSHOT_FRAME]->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSinkOutput::StopCapture snapshot data process stop capture failed, dhId: %s, ret: %d", + GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DHLOGI("DCameraSinkOutput::StopCapture %s success", GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +void DCameraSinkOutput::OnVideoResult(std::shared_ptr& buffer) +{ + if (sessionState_[CONTINUOUS_FRAME] != DCAMERA_CHANNEL_STATE_CONNECTED) { + DHLOGE("DCameraSinkOutput::OnVideoResult dhId: %s, channel state: %d", + GetAnonyString(dhId_).c_str(), sessionState_[CONTINUOUS_FRAME]); + return; + } + if (dataProcesses_.find(CONTINUOUS_FRAME) == dataProcesses_.end()) { + DHLOGE("DCameraSinkOutput::OnVideoResult %s has no continuous data process", GetAnonyString(dhId_).c_str()); + return; + } + dataProcesses_[CONTINUOUS_FRAME]->FeedStream(buffer); +} + +void DCameraSinkOutput::OnPhotoResult(std::shared_ptr& buffer) +{ + if (dataProcesses_.find(SNAPSHOT_FRAME) == dataProcesses_.end()) { + DHLOGE("DCameraSinkOutput::OnPhotoResult %s has no snapshot data process", GetAnonyString(dhId_).c_str()); + return; + } + dataProcesses_[SNAPSHOT_FRAME]->FeedStream(buffer); +} + +void DCameraSinkOutput::OnSessionState(DCStreamType type, int32_t state) +{ + DHLOGI("DCameraSinkOutput::OnSessionState dhId: %s, stream type: %d, state: %d", + GetAnonyString(dhId_).c_str(), type, state); + sessionState_[type] = state; + switch (state) { + case DCAMERA_CHANNEL_STATE_CONNECTING: { + DHLOGI("DCameraSinkOutput::OnSessionState channel is connecting, dhId: %s, stream type: %d", + GetAnonyString(dhId_).c_str(), type); + break; + } + case DCAMERA_CHANNEL_STATE_CONNECTED: { + DHLOGI("DCameraSinkOutput::OnSessionState channel is connected, dhId: %s, stream type: %d", + GetAnonyString(dhId_).c_str(), type); + break; + } + case DCAMERA_CHANNEL_STATE_DISCONNECTED: { + DHLOGI("DCameraSinkOutput::OnSessionState channel is disconnected, dhId: %s, stream type: %d", + GetAnonyString(dhId_).c_str(), type); + break; + } + default: { + DHLOGE("DCameraSinkOutput::OnSessionState %s unknown session state", GetAnonyString(dhId_).c_str()); + break; + } + } +} + +void DCameraSinkOutput::OnSessionError(DCStreamType type, int32_t eventType, int32_t eventReason, std::string detail) +{ + DHLOGI("DCameraSinkOutput::OnSessionError dhId: %s, stream type: %d, eventType: %d, eventReason: %d, detail: %s", + GetAnonyString(dhId_).c_str(), type, eventType, eventReason, detail.c_str()); +} + +void DCameraSinkOutput::OnDataReceived(DCStreamType type, std::vector>& dataBuffers) +{ +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_service_ipc.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_service_ipc.cpp new file mode 100644 index 00000000..7cc2b1dd --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/dcamera_sink_service_ipc.cpp @@ -0,0 +1,191 @@ +/* + * 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_sink_service_ipc.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkServiceIpc::DCameraSinkServiceIpc() : isInit_(false) +{ + DHLOGI("DCameraSinkServiceIpc Create"); +} + +DCameraSinkServiceIpc::~DCameraSinkServiceIpc() +{ + DHLOGI("DCameraSinkServiceIpc Delete"); + UnInit(); +} + +IMPLEMENT_SINGLE_INSTANCE(DCameraSinkServiceIpc); + +void DCameraSinkServiceIpc::Init() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSinkServiceIpc Init Start"); + if (isInit_) { + DHLOGI("DCameraSinkServiceIpc has already init"); + return; + } + auto runner = AppExecFwk::EventRunner::Create("DCameraSinkServiceIpcHandler"); + serviceHandler_ = std::make_shared(runner); + sourceRemoteRecipient_ = new SourceRemoteRecipient(); + isInit_ = true; + DHLOGI("DCameraSinkServiceIpc Init End"); +} + +void DCameraSinkServiceIpc::UnInit() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSinkServiceIpc UnInit Start"); + if (!isInit_) { + DHLOGI("DCameraSinkServiceIpc has already UnInit"); + return; + } + ClearSourceRemoteDhms(); + DHLOGI("DCameraSinkServiceIpc Start free serviceHandler"); + serviceHandler_ = nullptr; + DHLOGI("DCameraSinkServiceIpc Start free recipient"); + sourceRemoteRecipient_ = nullptr; + isInit_ = false; + DHLOGI("DCameraSinkServiceIpc UnInit End"); +} + +sptr DCameraSinkServiceIpc::GetSourceRemoteDHMS(const std::string& deviceId) +{ + if (deviceId.empty()) { + DHLOGE("GetSourceRemoteDHMS deviceId is empty"); + return nullptr; + } + { + std::lock_guard autoLock(sourceRemoteDmsLock_); + auto iter = remoteSources_.find(deviceId); + if (iter != remoteSources_.end()) { + auto object = iter->second; + if (object != nullptr) { + DHLOGI("DCameraSinkServiceIpc GetSourceRemoteDHMS from cache devId: %s", + GetAnonyString(deviceId).c_str()); + return object; + } + } + } + DHLOGI("GetSourceRemoteDHMS remote deviceid is %s", GetAnonyString(deviceId).c_str()); + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + DHLOGE("GetSourceRemoteDHMS failed to connect to systemAbilityMgr!"); + return nullptr; + } + + auto object = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SOURCE_SA_ID, deviceId); + if (object == nullptr) { + DHLOGE("GetSourceRemoteDHMS failed get remote DHMS %s", GetAnonyString(deviceId).c_str()); + return nullptr; + } + int32_t ret = object->AddDeathRecipient(sourceRemoteRecipient_); + sptr remoteDmsObj = iface_cast(object); + if (remoteDmsObj == nullptr) { + DHLOGI("GetSourceRemoteDHMS failed, remoteDmsObj is null ret: %d", ret); + return nullptr; + } + { + std::lock_guard autoLock(sourceRemoteDmsLock_); + auto iter = remoteSources_.find(deviceId); + if (iter != remoteSources_.end()) { + iter->second->AsObject()->RemoveDeathRecipient(sourceRemoteRecipient_); + } + remoteSources_[deviceId] = remoteDmsObj; + } + DHLOGI("GetSourceRemoteDHMS success, AddDeathRecipient ret: %d", ret); + return remoteDmsObj; +} + +void DCameraSinkServiceIpc::DeleteSourceRemoteDhms(const std::string& deviceId) +{ + DHLOGI("DeleteSourceRemoteDhms devId: %s", GetAnonyString(deviceId).c_str()); + std::lock_guard autoLock(sourceRemoteDmsLock_); + auto item = remoteSources_.find(deviceId); + if (item == remoteSources_.end()) { + DHLOGI("DeleteSourceRemoteDhms not found device: %s", GetAnonyString(deviceId).c_str()); + return; + } + + if (item->second != nullptr) { + item->second->AsObject()->RemoveDeathRecipient(sourceRemoteRecipient_); + } + remoteSources_.erase(item); +} + +void DCameraSinkServiceIpc::ClearSourceRemoteDhms() +{ + DHLOGI("ClearSourceRemoteDhms Start"); + std::lock_guard autoLock(sourceRemoteDmsLock_); + for (auto iter = remoteSources_.begin(); iter != remoteSources_.end(); iter++) { + if (iter->second != nullptr) { + iter->second->AsObject()->RemoveDeathRecipient(sourceRemoteRecipient_); + } + } + remoteSources_.clear(); + DHLOGI("ClearSourceRemoteDhms end"); +} + +void DCameraSinkServiceIpc::SourceRemoteRecipient::OnRemoteDied(const wptr& remote) +{ + DHLOGI("SourceRemoteRecipient OnRemoteDied received died notify!"); + DCameraSinkServiceIpc::GetInstance().OnSourceRemoteDmsDied(remote); +} + +void DCameraSinkServiceIpc::OnSourceRemoteDmsDied(const wptr& remote) +{ + sptr diedRemoted = remote.promote(); + if (diedRemoted == nullptr) { + DHLOGE("OnSourceRemoteDmsDied promote failed!"); + return; + } + DHLOGI("OnSourceRemoteDmsDied delete diedRemoted"); + auto remoteDmsDiedFunc = [this, diedRemoted]() { + OnSourceRemoteDmsDied(diedRemoted); + }; + if (serviceHandler_ != nullptr) { + serviceHandler_->PostTask(remoteDmsDiedFunc); + } +} + +void DCameraSinkServiceIpc::OnSourceRemoteDmsDied(const sptr& remote) +{ + std::lock_guard autoLock(sourceRemoteDmsLock_); + auto iter = std::find_if(remoteSources_.begin(), remoteSources_.end(), [&]( + const std::pair> &item)->bool { + return item.second->AsObject() == remote; + }); + if (iter == remoteSources_.end()) { + DHLOGI("OnSourceRemoteDmsDied not found remote object"); + return; + } + + DHLOGI("OnSourceRemoteDmsDied remote.devId: %s", GetAnonyString(iter->first).c_str()); + if (iter->second != nullptr) { + iter->second->AsObject()->RemoveDeathRecipient(sourceRemoteRecipient_); + } + remoteSources_.erase(iter); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_frame_trigger_event.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_frame_trigger_event.cpp new file mode 100644 index 00000000..9ef08a79 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_frame_trigger_event.cpp @@ -0,0 +1,34 @@ +/* + * 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_frame_trigger_event.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraFrameTriggerEvent::DCameraFrameTriggerEvent(EventSender& sender) : Event(sender) +{ +} + +DCameraFrameTriggerEvent::DCameraFrameTriggerEvent(EventSender& sender, std::string& param) + : Event(sender), param_(param) +{ +} + +std::string DCameraFrameTriggerEvent::GetParam() +{ + return param_; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_photo_output_event.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_photo_output_event.cpp new file mode 100644 index 00000000..1db88ea7 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_photo_output_event.cpp @@ -0,0 +1,34 @@ +/* + * 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_photo_output_event.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraPhotoOutputEvent::DCameraPhotoOutputEvent(EventSender& sender) : Event(sender) +{ +} + +DCameraPhotoOutputEvent::DCameraPhotoOutputEvent(EventSender& sender, const std::shared_ptr& param) + : Event(sender), param_(param) +{ +} + +std::shared_ptr DCameraPhotoOutputEvent::GetParam() +{ + return param_; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_post_authorization_event.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_post_authorization_event.cpp new file mode 100644 index 00000000..97bd0a6f --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_post_authorization_event.cpp @@ -0,0 +1,34 @@ +/* + * 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_post_authorization_event.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraPostAuthorizationEvent::DCameraPostAuthorizationEvent(EventSender& sender) : Event(sender) +{ +} + +DCameraPostAuthorizationEvent::DCameraPostAuthorizationEvent(EventSender& sender, + std::vector>& param) : Event(sender), param_(param) +{ +} + +std::vector> DCameraPostAuthorizationEvent::GetParam() +{ + return param_; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_video_output_event.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_video_output_event.cpp new file mode 100644 index 00000000..6de51a9a --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/eventbus/dcamera_video_output_event.cpp @@ -0,0 +1,34 @@ +/* + * 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_video_output_event.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraVideoOutputEvent::DCameraVideoOutputEvent(EventSender& sender) : Event(sender) +{ +} + +DCameraVideoOutputEvent::DCameraVideoOutputEvent(EventSender& sender, const std::shared_ptr& param) + : Event(sender), param_(param) +{ +} + +std::shared_ptr DCameraVideoOutputEvent::GetParam() +{ + return param_; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.cpp new file mode 100644 index 00000000..4203ca53 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_controller_channel_listener.cpp @@ -0,0 +1,57 @@ +/* + * 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_sink_controller_channel_listener.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkControllerChannelListener::DCameraSinkControllerChannelListener( + std::shared_ptr& controller) : controller_(controller) +{ +} + +void DCameraSinkControllerChannelListener::OnSessionState(int32_t state) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSinkControllerChannelListener::OnSessionState controller is null"); + return; + } + controller->OnSessionState(state); +} + +void DCameraSinkControllerChannelListener::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSinkControllerChannelListener::OnSessionError controller is null"); + return; + } + controller->OnSessionError(eventType, eventReason, detail); +} + +void DCameraSinkControllerChannelListener::OnDataReceived(std::vector>& buffers) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSinkControllerChannelListener::OnReceivedData controller is null"); + return; + } + controller->OnDataReceived(buffers); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_data_process_listener.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_data_process_listener.cpp new file mode 100644 index 00000000..1944688c --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_data_process_listener.cpp @@ -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. + */ + +#include "dcamera_sink_data_process_listener.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkDataProcessListener::DCameraSinkDataProcessListener( + std::shared_ptr& dataProcess) : dataProcess_(dataProcess) +{ +} + +void DCameraSinkDataProcessListener::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + std::shared_ptr dataProcess = dataProcess_.lock(); + if (dataProcess == nullptr) { + DHLOGE("DCameraSinkDataProcessListener::OnProcessedVideoBuffer dataProcess is null"); + return; + } + dataProcess->OnProcessedVideoBuffer(videoResult); +} + +void DCameraSinkDataProcessListener::OnError(DataProcessErrorType errorType) +{ + std::shared_ptr dataProcess = dataProcess_.lock(); + if (dataProcess == nullptr) { + DHLOGE("DCameraSinkDataProcessListener::OnError dataProcess is null"); + return; + } + dataProcess->OnError(errorType); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_output_channel_listener.cpp b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_output_channel_listener.cpp new file mode 100644 index 00000000..d2649c20 --- /dev/null +++ b/services/cameraservice/sinkservice/src/distributedcameramgr/listener/dcamera_sink_output_channel_listener.cpp @@ -0,0 +1,57 @@ +/* + * 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_sink_output_channel_listener.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSinkOutputChannelListener::DCameraSinkOutputChannelListener( + DCStreamType type, std::shared_ptr& output) : streamType_(type), output_(output) +{ +} + +void DCameraSinkOutputChannelListener::OnSessionState(int32_t state) +{ + std::shared_ptr output = output_.lock(); + if (output == nullptr) { + DHLOGE("DCameraSinkOutputChannelListener::OnSessionState output is null"); + return; + } + output->OnSessionState(streamType_, state); +} + +void DCameraSinkOutputChannelListener::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + std::shared_ptr output = output_.lock(); + if (output == nullptr) { + DHLOGE("DCameraSinkOutputChannelListener::OnSessionError output is null"); + return; + } + output->OnSessionError(streamType_, eventType, eventReason, detail); +} + +void DCameraSinkOutputChannelListener::OnDataReceived(std::vector>& buffers) +{ + std::shared_ptr output = output_.lock(); + if (output == nullptr) { + DHLOGE("DCameraSinkOutputChannelListener::OnReceivedData output is null"); + return; + } + output->OnDataReceived(streamType_, buffers); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/BUILD.gn b/services/cameraservice/sinkservice/test/unittest/BUILD.gn new file mode 100644 index 00000000..5f701090 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/BUILD.gn @@ -0,0 +1,20 @@ +# 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. + +group("sink_service_test") { + testonly = true + deps = [ + "common/distributedcamera:dcamera_sink_test", + "common/distributedcameramgr:dcamera_sink_mgr_test", + ] +} \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/BUILD.gn b/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/BUILD.gn new file mode 100644 index 00000000..07221ccd --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/BUILD.gn @@ -0,0 +1,61 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributedcamera/dcamera_sink_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "${services_path}/cameraservice/sinkservice/include/distributedcamera", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr/interface", + "${services_path}/cameraservice/base/include", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${distributedcamera_hdf_path}/interfaces/include", + "${innerkits_path}/native_cpp/camera_sink/include", + "//drivers/peripheral/base", + ] +} + +ohos_unittest("DistributedCameraSinkServiceTest") { + module_out_path = module_out_path + + sources = [ + "distributed_camera_sink_service_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "${services_path}/cameraservice/sinkservice:distributed_camera_sink", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + ] + external_deps = [ + "ipc:ipc_core", + "safwk:system_ability_fwk", + "eventhandler:libeventhandler", + ] +} + +group("dcamera_sink_test") { + testonly = true + deps = [ ":DistributedCameraSinkServiceTest" ] +} \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/distributed_camera_sink_service_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/distributed_camera_sink_service_test.cpp new file mode 100644 index 00000000..0146dcce --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcamera/distributed_camera_sink_service_test.cpp @@ -0,0 +1,204 @@ +/* + * 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 +#define private public +#include "distributed_camera_sink_service.h" +#undef private + +#include "distributed_camera_errno.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSinkServiceTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr service_; +}; +std::string g_testParams = ""; +std::string g_testCameraInfo = ""; +const int32_t TEST_SA_ID = 4804; +const bool TEST_RUN_ON_CREATE = true; + +std::string g_testChannelInfoContinue = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CHANNEL_NEG", + "Value": {"SourceDevId": "TestDevId", + "Detail": [{"DataSessionFlag": "dataContinue", "StreamType": 0}]} +})"; + +std::string g_testOpenInfoService = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "OPEN_CHANNEL", + "Value": {"SourceDevId": "TestDevId"} +})"; + +void DistributedCameraSinkServiceTest::SetUpTestCase(void) +{ +} + +void DistributedCameraSinkServiceTest::TearDownTestCase(void) +{ +} + +void DistributedCameraSinkServiceTest::SetUp(void) +{ + service_ = std::make_shared(TEST_SA_ID, TEST_RUN_ON_CREATE); +} + +void DistributedCameraSinkServiceTest::TearDown(void) +{ + service_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_service_test_001 + * @tc.desc: Verify the InitSink and ReleaseSink function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_001, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(g_testParams, service_->sinkVer_); + EXPECT_NE(0, (int32_t)service_->camerasMap_.size()); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(0, (int32_t)service_->camerasMap_.size()); +} + +/** + * @tc.name: dcamera_sink_service_test_002 + * @tc.desc: Verify the SubscribeLocalHardware function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_002, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->SubscribeLocalHardware(service_->camerasMap_.begin()->first, g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_service_test_003 + * @tc.desc: Verify the UnSubscribeLocalHardware function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_003, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->UnsubscribeLocalHardware(service_->camerasMap_.begin()->first); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_service_test_004 + * @tc.desc: Verify the StopCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_004, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->StopCapture(service_->camerasMap_.begin()->first); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_service_test_005 + * @tc.desc: Verify the ChannelNeg function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_005, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ChannelNeg(service_->camerasMap_.begin()->first, g_testChannelInfoContinue); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_service_test_006 + * @tc.desc: Verify the GetCameraInfo function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_006, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->GetCameraInfo(service_->camerasMap_.begin()->first, g_testCameraInfo); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_service_test_007 + * @tc.desc: Verify the OpenChannel and CloseChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DistributedCameraSinkServiceTest, dcamera_sink_service_test_007, TestSize.Level1) +{ + int32_t ret = service_->InitSink(g_testParams); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->OpenChannel(service_->camerasMap_.begin()->first, g_testOpenInfoService); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->CloseChannel(service_->camerasMap_.begin()->first); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = service_->ReleaseSink(); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/BUILD.gn b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/BUILD.gn new file mode 100644 index 00000000..5308312d --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/BUILD.gn @@ -0,0 +1,86 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributedcamera/dcamera_sink_mgr_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr/callback", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr/eventbus", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr/interface", + "${services_path}/cameraservice/sinkservice/include/distributedcameramgr/listener", + "${services_path}/cameraservice/cameraoperator/client/include", + "${services_path}/cameraservice/base/include", + "${services_path}/channel/include", + "${services_path}/data_process/include/pipeline", + "${services_path}/data_process/include/interfaces", + "${services_path}/data_process/include/utils", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${distributedcamera_hdf_path}/interfaces/include", + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + + "${fwk_utils_path}/include/eventbus", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + "${fwk_common_path}/utils/include", + "${fwk_common_path}/log/include", + + "//drivers/peripheral/base", + ] +} + +ohos_unittest("DCameraSinkMgrTest") { + module_out_path = module_out_path + + sources = [ + "dcamera_sink_dev_test.cpp", + "dcamera_sink_access_control_test.cpp", + "dcamera_sink_controller_test.cpp", + "dcamera_sink_output_test.cpp", + "dcamera_sink_data_process_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "${services_path}/cameraservice/sinkservice:distributed_camera_sink", + "${services_path}/channel:distributed_camera_channel", + "${common_path}:distributed_camera_utils", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + + "${fwk_utils_path}:distributedhardwareutils", + ] + + external_deps = [ + "ipc:ipc_core", + "eventhandler:libeventhandler", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DCameraSinkMgrTest\"", + "LOG_DOMAIN=0xD004100", + ] +} + +group("dcamera_sink_mgr_test") { + testonly = true + deps = [ ":DCameraSinkMgrTest" ] +} \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_access_control_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_access_control_test.cpp new file mode 100644 index 00000000..0458e230 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_access_control_test.cpp @@ -0,0 +1,108 @@ +/* + * 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 +#define private public +#include "dcamera_sink_access_control.h" +#undef private + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkAccessControlTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr accessControl_; +}; +const std::string TEST_SRC_TYPE = "camera"; +const std::string TEST_DEVICE_NAME = ""; +const std::string TEST_ACCESS_TYPE = ""; + +void DCameraSinkAccessControlTest::SetUpTestCase(void) +{ +} + +void DCameraSinkAccessControlTest::TearDownTestCase(void) +{ +} + +void DCameraSinkAccessControlTest::SetUp(void) +{ + accessControl_ = std::make_shared(); +} + +void DCameraSinkAccessControlTest::TearDown(void) +{ + accessControl_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_access_control_test_001 + * @tc.desc: Verify the IsSensitiveSrcAccess function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkAccessControlTest, dcamera_sink_access_control_test_001, TestSize.Level1) +{ + bool ret = accessControl_->IsSensitiveSrcAccess(TEST_SRC_TYPE); + EXPECT_EQ(true, ret); +} + +/** + * @tc.name: dcamera_sink_access_control_test_002 + * @tc.desc: Verify the NotifySensitiveSrc function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkAccessControlTest, dcamera_sink_access_control_test_002, TestSize.Level1) +{ + bool ret = accessControl_->NotifySensitiveSrc(TEST_SRC_TYPE); + EXPECT_EQ(true, ret); +} + +/** + * @tc.name: dcamera_sink_access_control_test_003 + * @tc.desc: Verify the GetAccessControlType function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkAccessControlTest, dcamera_sink_access_control_test_003, TestSize.Level1) +{ + int32_t ret = accessControl_->GetAccessControlType(TEST_ACCESS_TYPE); + EXPECT_EQ(DCAMERA_SAME_ACCOUNT, ret); +} + +/** + * @tc.name: dcamera_sink_access_control_test_004 + * @tc.desc: Verify the TriggerFrame function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkAccessControlTest, dcamera_sink_access_control_test_004, TestSize.Level1) +{ + int32_t ret = accessControl_->TriggerFrame(TEST_DEVICE_NAME); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_test.cpp new file mode 100644 index 00000000..058fca2c --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_controller_test.cpp @@ -0,0 +1,356 @@ +/* + * 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 +#define private public +#include "dcamera_sink_controller.h" +#undef private + +#include "distributed_hardware_log.h" + +#include "mock_camera_channel.h" +#include "mock_camera_operator.h" +#include "mock_dcamera_sink_output.h" + +#include "dcamera_metadata_setting_cmd.h" +#include "dcamera_sink_access_control.h" +#include "dcamera_sink_dev.h" +#include "dcamera_utils_tools.h" +#include "distributed_camera_errno.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkControllerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr controller_; + std::shared_ptr accessControl_; +}; +std::string g_testDeviceIdController; +const std::string TEST_DH_ID = "Camera_device@3.5/legacy/1"; +const std::string SESSION_FLAG_CONTINUE = "dataContinue"; +const std::string SESSION_FLAG_SNAPSHOT = "dataSnapshot"; +const std::string TEST_DEVICE_ID_EMPTY = ""; + +const std::string TEST_CAPTURE_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CAPTURE", + "Value": [ + {"Width": 1920, "Height": 1080, "Format": 1, + "DataSpace": 1, "IsCapture":true, "EncodeType": 1, "StreamType": 1, + "CaptureSettings": [{"SettingType": 1, "SettingValue": "TestSetting"}]} + ] +})"; + +const std::string TEST_CHANNEL_INFO_CMD_CONTINUE_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CHANNEL_NEG", + "Value": {"SourceDevId": "TestDevId", + "Detail": [{"DataSessionFlag": "dataContinue", "StreamType": 0}]} +})"; + +const std::string TEST_EVENT_CMD_JSON = R"({ + "Type": "MESSAGE", + "dhId": "camrea_0", + "Command": "STATE_NOTIFY", + "Value": {"EventType": 1, "EventResult": 1, "EventContent": "TestContent"} +})"; + +const std::string TEST_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "GET_INFO", + "Value": {"State": 1} +})"; + +const std::string TEST_METADATA_SETTING_CMD_JSON = R"({ + "Type": "MESSAGE", + "dhId": "camrea_0", + "Command": "UPDATE_METADATA", + "Value": [{"SettingType": 1, "SettingValue": "TestSetting"}] +})"; + +const std::string TEST_OPEN_INFO_CMD_JSON = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "OPEN_CHANNEL", + "Value": {"SourceDevId": "TestDevId" } +})"; + +std::vector g_testCamIndex; + +void DCameraSinkControllerTest::SetUpTestCase(void) +{ + GetLocalDeviceNetworkId(g_testDeviceIdController); + g_testCamIndex.push_back(DCameraIndex(g_testDeviceIdController, TEST_DH_ID)); +} + +void DCameraSinkControllerTest::TearDownTestCase(void) +{ +} + +void DCameraSinkControllerTest::SetUp(void) +{ + accessControl_ = std::make_shared(); + controller_ = std::make_shared(accessControl_); + + controller_->channel_ = std::make_shared(); + controller_->operator_ = std::make_shared(); + controller_->output_ = std::make_shared(TEST_DH_ID, controller_->operator_); + controller_->srcDevId_ = g_testDeviceIdController; + controller_->dhId_ = TEST_DH_ID; +} + +void DCameraSinkControllerTest::TearDown(void) +{ + accessControl_ = nullptr; + controller_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_controller_test_001 + * @tc.desc: Verify the Init and UnInit function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_001, TestSize.Level1) +{ + int32_t ret = controller_->Init(g_testCamIndex); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(true, controller_->isInit_); + + ret = controller_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(false, controller_->isInit_); +} + +/** + * @tc.name: dcamera_sink_controller_test_002 + * @tc.desc: Verify the GetCameraInfo function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_002, TestSize.Level1) +{ + DCameraInfoCmd cmd; + cmd.value_ = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(DCAMERA_CHANNEL_STATE_DISCONNECTED, cmd.value_->state_); +} + +/** + * @tc.name: dcamera_sink_controller_test_003 + * @tc.desc: Verify the ChannelNeg function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_003, TestSize.Level1) +{ + DCameraChannelInfoCmd cmd; + cmd.Unmarshal(TEST_CHANNEL_INFO_CMD_CONTINUE_JSON); + int32_t ret = controller_->ChannelNeg(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_004 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_004, TestSize.Level1) +{ + DCameraCaptureInfoCmd cmd; + cmd.Unmarshal(TEST_CAPTURE_INFO_CMD_JSON); + int32_t ret = controller_->StartCapture(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_005 + * @tc.desc: Verify the UpdateSettings function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_005, TestSize.Level1) +{ + DCameraCaptureInfoCmd cmd; + cmd.Unmarshal(TEST_CAPTURE_INFO_CMD_JSON); + int32_t ret = controller_->StartCapture(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + + DCameraMetadataSettingCmd cmdMetadata; + cmdMetadata.Unmarshal(TEST_METADATA_SETTING_CMD_JSON); + ret = controller_->UpdateSettings(cmdMetadata.value_); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_006 + * @tc.desc: Verify the StopCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_006, TestSize.Level1) +{ + DCameraCaptureInfoCmd cmd; + cmd.Unmarshal(TEST_CAPTURE_INFO_CMD_JSON); + int32_t ret = controller_->StartCapture(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = controller_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_007 + * @tc.desc: Verify the DCameraNotify function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_007, TestSize.Level1) +{ + controller_->srcDevId_ = TEST_DEVICE_ID_EMPTY; + + DCameraEventCmd cmd; + cmd.Unmarshal(TEST_EVENT_CMD_JSON); + int32_t ret = controller_->DCameraNotify(cmd.value_); + EXPECT_EQ(DCAMERA_BAD_VALUE, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_008 + * @tc.desc: Verify the DCameraNotify function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_008, TestSize.Level1) +{ + DCameraEventCmd cmd; + cmd.Unmarshal(TEST_EVENT_CMD_JSON); + int32_t ret = controller_->DCameraNotify(cmd.value_); + EXPECT_NE(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_009 + * @tc.desc: Verify the OnSessionState and GetCameraInfo function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_009, TestSize.Level1) +{ + controller_->OnSessionState(DCAMERA_CHANNEL_STATE_CONNECTING); + + DCameraInfoCmd cmd; + cmd.value_ = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(DCAMERA_CHANNEL_STATE_CONNECTING, cmd.value_->state_); +} + +/** + * @tc.name: dcamera_sink_controller_test_010 + * @tc.desc: Verify the OnSessionState function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_010, TestSize.Level1) +{ + controller_->OnSessionState(DCAMERA_CHANNEL_STATE_CONNECTED); + + DCameraInfoCmd cmd; + cmd.value_ = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(DCAMERA_CHANNEL_STATE_CONNECTED, cmd.value_->state_); +} + +/** + * @tc.name: dcamera_sink_controller_test_011 + * @tc.desc: Verify the OnSessionState function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_011, TestSize.Level1) +{ + controller_->OnSessionState(DCAMERA_CHANNEL_STATE_DISCONNECTED); + + DCameraInfoCmd cmd; + cmd.value_ = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(DCAMERA_CHANNEL_STATE_DISCONNECTED, cmd.value_->state_); +} + +/** + * @tc.name: dcamera_sink_controller_test_012 + * @tc.desc: Verify the OpenChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_012, TestSize.Level1) +{ + DCameraOpenInfoCmd cmd; + cmd.Unmarshal(TEST_OPEN_INFO_CMD_JSON); + int32_t ret = controller_->OpenChannel(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_013 + * @tc.desc: Verify the OpenChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_013, TestSize.Level1) +{ + controller_->OnSessionState(DCAMERA_CHANNEL_STATE_CONNECTED); + + DCameraInfoCmd cmd; + cmd.value_ = std::make_shared(); + int32_t ret = controller_->GetCameraInfo(cmd.value_); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(DCAMERA_CHANNEL_STATE_CONNECTED, cmd.value_->state_); + + DCameraOpenInfoCmd cmdOpenInfo; + cmdOpenInfo.Unmarshal(TEST_OPEN_INFO_CMD_JSON); + ret = controller_->OpenChannel(cmdOpenInfo.value_); + EXPECT_EQ(DCAMERA_WRONG_STATE, ret); +} + +/** + * @tc.name: dcamera_sink_controller_test_014 + * @tc.desc: Verify the CloseChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkControllerTest, dcamera_sink_controller_test_014, TestSize.Level1) +{ + int32_t ret = controller_->CloseChannel(); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_data_process_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_data_process_test.cpp new file mode 100644 index 00000000..4509a2a5 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_data_process_test.cpp @@ -0,0 +1,198 @@ +/* + * 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 +#define private public +#include "dcamera_sink_data_process.h" +#undef private + +#include +#include + +#include "distributed_camera_errno.h" +#include "mock_camera_channel.h" +#include "mock_data_process_pipeline.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkDataProcessTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr dataProcess_; + std::shared_ptr channel_; +}; +const std::string TEST_DH_ID = "Camera_device@3.5/legacy/1"; +const std::string TEST_STRING = "test_string"; +const int32_t TEST_WIDTH = 1080; +const int32_t TEST_HEIGHT = 1920; + +std::shared_ptr g_testCaptureInfoContinuousNotEncode; +std::shared_ptr g_testCaptureInfoContinuousNeedEncode; +std::shared_ptr g_testCaptureInfoSnapshot; + +std::shared_ptr g_testDataBuffer; + +void DCameraSinkDataProcessTest::SetUpTestCase(void) +{ + std::shared_ptr cameraSetting = std::make_shared(); + cameraSetting->type_ = UPDATE_METADATA; + cameraSetting->value_ = ""; + + g_testCaptureInfoContinuousNotEncode = std::make_shared(); + g_testCaptureInfoContinuousNotEncode->width_ = TEST_WIDTH; + g_testCaptureInfoContinuousNotEncode->height_ = TEST_HEIGHT; + g_testCaptureInfoContinuousNotEncode->format_ = ENCODE_TYPE_H264; + g_testCaptureInfoContinuousNotEncode->dataspace_ = 0; + g_testCaptureInfoContinuousNotEncode->encodeType_ = ENCODE_TYPE_H264; + g_testCaptureInfoContinuousNotEncode->streamType_ = CONTINUOUS_FRAME; + g_testCaptureInfoContinuousNotEncode->captureSettings_.push_back(cameraSetting); + + g_testCaptureInfoContinuousNeedEncode = std::make_shared(); + g_testCaptureInfoContinuousNeedEncode->width_ = TEST_WIDTH; + g_testCaptureInfoContinuousNeedEncode->height_ = TEST_HEIGHT; + g_testCaptureInfoContinuousNeedEncode->format_ = ENCODE_TYPE_H264; + g_testCaptureInfoContinuousNeedEncode->dataspace_ = 0; + g_testCaptureInfoContinuousNeedEncode->encodeType_ = ENCODE_TYPE_H265; + g_testCaptureInfoContinuousNeedEncode->streamType_ = CONTINUOUS_FRAME; + g_testCaptureInfoContinuousNeedEncode->captureSettings_.push_back(cameraSetting); + + g_testCaptureInfoSnapshot = std::make_shared(); + g_testCaptureInfoSnapshot->width_ = TEST_WIDTH; + g_testCaptureInfoSnapshot->height_ = TEST_HEIGHT; + g_testCaptureInfoSnapshot->format_ = ENCODE_TYPE_JPEG; + g_testCaptureInfoSnapshot->dataspace_ = 0; + g_testCaptureInfoSnapshot->encodeType_ = ENCODE_TYPE_JPEG; + g_testCaptureInfoSnapshot->streamType_ = SNAPSHOT_FRAME; + g_testCaptureInfoSnapshot->captureSettings_.push_back(cameraSetting); + + g_testDataBuffer = std::make_shared(TEST_STRING.length() + 1); + memcpy_s(g_testDataBuffer->Data(), g_testDataBuffer->Capacity(), + (uint8_t *)TEST_STRING.c_str(), TEST_STRING.length()); +} + +void DCameraSinkDataProcessTest::TearDownTestCase(void) +{ +} + +void DCameraSinkDataProcessTest::SetUp(void) +{ + channel_ = std::make_shared(); + dataProcess_ = std::make_shared(TEST_DH_ID, channel_); + + dataProcess_->pipeline_ = std::make_shared(); + dataProcess_->captureInfo_ = g_testCaptureInfoContinuousNeedEncode; +} + +void DCameraSinkDataProcessTest::TearDown(void) +{ + channel_ = nullptr; + dataProcess_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_data_process_test_001 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_001, TestSize.Level1) +{ + int32_t ret = dataProcess_->StartCapture(g_testCaptureInfoContinuousNotEncode); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_002 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_002, TestSize.Level1) +{ + int32_t ret = dataProcess_->StartCapture(g_testCaptureInfoContinuousNeedEncode); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_003 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_003, TestSize.Level1) +{ + int32_t ret = dataProcess_->StartCapture(g_testCaptureInfoSnapshot); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_004 + * @tc.desc: Verify the StopCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_004, TestSize.Level1) +{ + int32_t ret = dataProcess_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_005 + * @tc.desc: Verify the FeedStream function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_005, TestSize.Level1) +{ + dataProcess_->captureInfo_ = g_testCaptureInfoContinuousNotEncode; + int32_t ret = dataProcess_->FeedStream(g_testDataBuffer); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_006 + * @tc.desc: Verify the FeedStream function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_006, TestSize.Level1) +{ + dataProcess_->captureInfo_ = g_testCaptureInfoContinuousNeedEncode; + int32_t ret = dataProcess_->FeedStream(g_testDataBuffer); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_data_process_test_007 + * @tc.desc: Verify the FeedStream function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkDataProcessTest, dcamera_sink_data_process_test_007, TestSize.Level1) +{ + dataProcess_->captureInfo_ = g_testCaptureInfoSnapshot; + int32_t ret = dataProcess_->FeedStream(g_testDataBuffer); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_dev_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_dev_test.cpp new file mode 100644 index 00000000..d79a09b9 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_dev_test.cpp @@ -0,0 +1,215 @@ +/* + * 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 "anonymous_string.h" +#include "distributed_hardware_log.h" + +#define private public +#include "dcamera_sink_access_control.h" +#include "dcamera_sink_controller.h" +#include "dcamera_sink_dev.h" +#undef private + +#include "dcamera_utils_tools.h" +#include "distributed_camera_errno.h" +#include "mock_dcamera_sink_controller.h" + + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkDevTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr dev_; +}; +const std::string TEST_CAMERA_DH_ID_0 = "Camera_device@3.5/legacy/1"; +const std::string TEST_PARAMETER = ""; +std::string g_testCameraInfo = ""; + +std::string g_testChannelInfoDevContinue = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "CHANNEL_NEG", + "Value": {"SourceDevId": "TestDevId", + "Detail": [{"DataSessionFlag": "dataContinue", "StreamType": 0}]} +})"; + +std::string g_testOpenInfoDev = R"({ + "Type": "OPERATION", + "dhId": "camrea_0", + "Command": "OPEN_CHANNEL", + "Value": {"SourceDevId": "TestDevId"} +})"; + +std::string g_testChannelInfoDevEmpty = ""; +std::string g_testOpenInfoDevEmpty = ""; + +void DCameraSinkDevTest::SetUpTestCase(void) +{ +} + +void DCameraSinkDevTest::TearDownTestCase(void) +{ +} + +void DCameraSinkDevTest::SetUp(void) +{ + dev_ = std::make_shared(TEST_CAMERA_DH_ID_0); + + dev_->accessControl_ = std::make_shared(); + dev_->controller_ = std::make_shared(dev_->accessControl_); +} + +void DCameraSinkDevTest::TearDown(void) +{ + dev_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_dev_test_001 + * @tc.desc: Verify the Init and UnInit function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_001, TestSize.Level1) +{ + int32_t ret = dev_->Init(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(true, dev_->isInit_); + + ret = dev_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(false, dev_->isInit_); +} + +/** + * @tc.name: dcamera_sink_dev_test_002 + * @tc.desc: Verify the SubscribeLocalHardware function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_002, TestSize.Level1) +{ + int32_t ret = dev_->SubscribeLocalHardware(TEST_PARAMETER); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_003 + * @tc.desc: Verify the UnsubscribeLocalHardware function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_003, TestSize.Level1) +{ + int32_t ret = dev_->UnsubscribeLocalHardware(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_004 + * @tc.desc: Verify the GetCameraInfo function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_004, TestSize.Level1) +{ + int32_t ret = dev_->GetCameraInfo(g_testCameraInfo); + EXPECT_EQ(DCAMERA_OK, ret); + DHLOGI("DCameraSinkDevTest::GetCameraInfo cameraInfo is %s", GetAnonyString(g_testCameraInfo).c_str()); +} + +/** + * @tc.name: dcamera_sink_dev_test_005 + * @tc.desc: Verify the ChannelNeg function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_005, TestSize.Level1) +{ + int32_t ret = dev_->ChannelNeg(g_testChannelInfoDevEmpty); + EXPECT_EQ(DCAMERA_BAD_VALUE, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_006 + * @tc.desc: Verify the ChannelNeg function. + * @tc.type: FUNC + * @tc.require: AR000GK6MT + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_006, TestSize.Level1) +{ + int32_t ret = dev_->ChannelNeg(g_testChannelInfoDevContinue); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_007 + * @tc.desc: Verify the StopCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_007, TestSize.Level1) +{ + int32_t ret = dev_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_008 + * @tc.desc: Verify the OpenChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_008, TestSize.Level1) +{ + int32_t ret = dev_->OpenChannel(g_testOpenInfoDevEmpty); + EXPECT_EQ(DCAMERA_BAD_VALUE, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_009 + * @tc.desc: Verify the OpenChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_009, TestSize.Level1) +{ + int32_t ret = dev_->OpenChannel(g_testOpenInfoDev); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_dev_test_010 + * @tc.desc: Verify the CloseChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkDevTest, dcamera_sink_dev_test_010, TestSize.Level1) +{ + int32_t ret = dev_->CloseChannel(); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp new file mode 100644 index 00000000..d4e64ec6 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/dcamera_sink_output_test.cpp @@ -0,0 +1,240 @@ +/* + * 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 +#define private public +#include "dcamera_sink_output.h" +#undef private + +#include "mock_camera_channel.h" +#include "mock_camera_operator.h" +#include "mock_dcamera_sink_data_process.h" + +#include "dcamera_sink_access_control.h" +#include "dcamera_sink_controller.h" +#include "dcamera_sink_data_process.h" +#include "dcamera_sink_dev.h" +#include "dcamera_utils_tools.h" +#include "distributed_camera_errno.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSinkOutputTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr output_; + std::shared_ptr operator_; + std::shared_ptr channel_; + std::shared_ptr dataProcess_; +}; +const std::string TEST_DH_ID = "Camera_device@3.5/legacy/1"; +const std::string SESSION_FLAG_CONTINUE = "dataContinue"; +const std::string SESSION_FLAG_SNAPSHOT = "dataSnapshot"; +const int32_t TEST_WIDTH = 1080; +const int32_t TEST_HEIGHT = 1920; + +std::string g_testDeviceIdOutput; +DCameraChannelDetail g_testDetailOutput; + +std::shared_ptr g_testCaptureInfoOutputContinuousNotEncode; +std::shared_ptr g_testCaptureInfoOutputContinuousNeedEncode; +std::shared_ptr g_testCaptureInfoOutputSnapshot; + +std::shared_ptr g_testChannelInfo; + +std::vector> g_testCaptureInfosOutput; + +void DCameraSinkOutputTest::SetUpTestCase(void) +{ + GetLocalDeviceNetworkId(g_testDeviceIdOutput); + + std::shared_ptr cameraSetting = std::make_shared(); + cameraSetting->type_ = UPDATE_METADATA; + cameraSetting->value_ = ""; + + g_testCaptureInfoOutputContinuousNotEncode = std::make_shared(); + g_testCaptureInfoOutputContinuousNotEncode->width_ = TEST_WIDTH; + g_testCaptureInfoOutputContinuousNotEncode->height_ = TEST_HEIGHT; + g_testCaptureInfoOutputContinuousNotEncode->format_ = ENCODE_TYPE_H264; + g_testCaptureInfoOutputContinuousNotEncode->dataspace_ = 0; + g_testCaptureInfoOutputContinuousNotEncode->encodeType_ = ENCODE_TYPE_H264; + g_testCaptureInfoOutputContinuousNotEncode->streamType_ = CONTINUOUS_FRAME; + g_testCaptureInfoOutputContinuousNotEncode->captureSettings_.push_back(cameraSetting); + + g_testCaptureInfoOutputContinuousNeedEncode = std::make_shared(); + g_testCaptureInfoOutputContinuousNeedEncode->width_ = TEST_WIDTH; + g_testCaptureInfoOutputContinuousNeedEncode->height_ = TEST_HEIGHT; + g_testCaptureInfoOutputContinuousNeedEncode->format_ = ENCODE_TYPE_H264; + g_testCaptureInfoOutputContinuousNeedEncode->dataspace_ = 0; + g_testCaptureInfoOutputContinuousNeedEncode->encodeType_ = ENCODE_TYPE_H265; + g_testCaptureInfoOutputContinuousNeedEncode->streamType_ = CONTINUOUS_FRAME; + g_testCaptureInfoOutputContinuousNeedEncode->captureSettings_.push_back(cameraSetting); + + g_testCaptureInfoOutputSnapshot = std::make_shared(); + g_testCaptureInfoOutputSnapshot->width_ = TEST_WIDTH; + g_testCaptureInfoOutputSnapshot->height_ = TEST_HEIGHT; + g_testCaptureInfoOutputSnapshot->format_ = ENCODE_TYPE_JPEG; + g_testCaptureInfoOutputSnapshot->dataspace_ = 0; + g_testCaptureInfoOutputSnapshot->encodeType_ = ENCODE_TYPE_JPEG; + g_testCaptureInfoOutputSnapshot->streamType_ = SNAPSHOT_FRAME; + g_testCaptureInfoOutputSnapshot->captureSettings_.push_back(cameraSetting); + + g_testDetailOutput.dataSessionFlag_ = SESSION_FLAG_CONTINUE; + g_testDetailOutput.streamType_ = CONTINUOUS_FRAME; + + g_testChannelInfo = std::make_shared(); + g_testChannelInfo->sourceDevId_ = g_testDeviceIdOutput; + std::vector detail0; + detail0.push_back(g_testDetailOutput); + g_testChannelInfo->detail_ = detail0; +} + +void DCameraSinkOutputTest::TearDownTestCase(void) +{ +} + +void DCameraSinkOutputTest::SetUp(void) +{ + operator_ = std::make_shared(); + output_ = std::make_shared(TEST_DH_ID, operator_); + channel_ = std::make_shared(); + dataProcess_ = std::make_shared(channel_); + output_->channels_.emplace(SNAPSHOT_FRAME, channel_); + output_->channels_.emplace(CONTINUOUS_FRAME, channel_); + output_->dataProcesses_.emplace(SNAPSHOT_FRAME, dataProcess_); + output_->dataProcesses_.emplace(CONTINUOUS_FRAME, dataProcess_); +} + +void DCameraSinkOutputTest::TearDown(void) +{ + output_->channels_.clear(); + output_->dataProcesses_.clear(); + + operator_ = nullptr; + output_ = nullptr; +} + +/** + * @tc.name: dcamera_sink_output_test_001 + * @tc.desc: Verify the UnInit function. + * @tc.type: FUNC + * @tc.require: AR000GK6MV + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_001, TestSize.Level1) +{ + int32_t ret = output_->Init(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(true, output_->isInit_); + + ret = output_->UnInit(); + EXPECT_EQ(DCAMERA_OK, ret); + EXPECT_EQ(false, output_->isInit_); +} + +/** + * @tc.name: dcamera_sink_output_test_002 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_002, TestSize.Level1) +{ + g_testCaptureInfosOutput.push_back(g_testCaptureInfoOutputContinuousNotEncode); + int32_t ret = output_->StartCapture(g_testCaptureInfosOutput); + EXPECT_EQ(DCAMERA_OK, ret); + + g_testCaptureInfosOutput.clear(); +} + +/** + * @tc.name: dcamera_sink_output_test_003 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_003, TestSize.Level1) +{ + g_testCaptureInfosOutput.push_back(g_testCaptureInfoOutputContinuousNeedEncode); + int32_t ret = output_->StartCapture(g_testCaptureInfosOutput); + EXPECT_EQ(DCAMERA_OK, ret); + + g_testCaptureInfosOutput.clear(); +} + +/** + * @tc.name: dcamera_sink_output_test_004 + * @tc.desc: Verify the StartCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6MU + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_004, TestSize.Level1) +{ + g_testCaptureInfosOutput.push_back(g_testCaptureInfoOutputSnapshot); + int32_t ret = output_->StartCapture(g_testCaptureInfosOutput); + EXPECT_EQ(DCAMERA_OK, ret); + + g_testCaptureInfosOutput.clear(); +} + +/** + * @tc.name: dcamera_sink_output_test_005 + * @tc.desc: Verify the StopCapture function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_005, TestSize.Level1) +{ + g_testCaptureInfosOutput.push_back(g_testCaptureInfoOutputContinuousNotEncode); + int32_t ret = output_->StartCapture(g_testCaptureInfosOutput); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = output_->StopCapture(); + EXPECT_EQ(DCAMERA_OK, ret); + + g_testCaptureInfosOutput.clear(); +} + +/** + * @tc.name: dcamera_sink_output_test_006 + * @tc.desc: Verify the OpenChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_006, TestSize.Level1) +{ + int32_t ret = output_->OpenChannel(g_testChannelInfo); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_sink_output_test_007 + * @tc.desc: Verify the CloseChannel function. + * @tc.type: FUNC + * @tc.require: AR000GK6N1 + */ +HWTEST_F(DCameraSinkOutputTest, dcamera_sink_output_test_007, TestSize.Level1) +{ + int32_t ret = output_->CloseChannel(); + EXPECT_EQ(DCAMERA_OK, ret); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_channel.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_channel.h new file mode 100644 index 00000000..479caf75 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_channel.h @@ -0,0 +1,63 @@ +/* + * 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_MOCK_CAMERA_CHANNEL_H +#define OHOS_MOCK_CAMERA_CHANNEL_H + +#include "distributed_camera_errno.h" +#include "icamera_channel.h" + +namespace OHOS { +namespace DistributedHardware { +class MockCameraChannel : public ICameraChannel { +public: + explicit MockCameraChannel() + { + } + + ~MockCameraChannel() + { + } + + int32_t OpenSession() + { + return DCAMERA_OK; + } + + int32_t CloseSession() + { + return DCAMERA_OK; + } + + int32_t CreateSession(std::vector& camIndexs, std::string sessionFlag, + DCameraSessionMode sessionMode, std::shared_ptr& listener) + { + return DCAMERA_OK; + } + + int32_t ReleaseSession() + { + return DCAMERA_OK; + } + + int32_t SendData(std::shared_ptr& buffer) + { + return DCAMERA_OK; + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h new file mode 100644 index 00000000..48deca9a --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_camera_operator.h @@ -0,0 +1,82 @@ +/* + * 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_MOCK_CAMERA_OPERATOR_H +#define OHOS_MOCK_CAMERA_OPERATOR_H + +#include "distributed_camera_errno.h" +#include "icamera_operator.h" + +namespace OHOS { +namespace DistributedHardware { +class MockCameraOperator : public ICameraOperator { +public: + explicit MockCameraOperator() + { + } + + ~MockCameraOperator() + { + } + + int32_t Init() + { + return DCAMERA_OK; + } + + int32_t UnInit() + { + return DCAMERA_OK; + } + + int32_t UpdateSettings(std::vector>& settings) + { + return DCAMERA_OK; + } + + int32_t OpenCamera(std::vector>& captureInfos) + { + return DCAMERA_OK; + } + + int32_t CloseCamera() + { + return DCAMERA_OK; + } + + int32_t StartCapture(std::vector>& captureInfos) + { + return DCAMERA_OK; + } + + int32_t StopCapture() + { + return DCAMERA_OK; + } + + int32_t SetStateCallback(std::shared_ptr& callback) + { + return DCAMERA_OK; + } + + int32_t SetResultCallback(std::shared_ptr& callback) + { + return DCAMERA_OK; + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_data_process_pipeline.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_data_process_pipeline.h new file mode 100644 index 00000000..dca14bbf --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_data_process_pipeline.h @@ -0,0 +1,56 @@ +/* + * 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_MOCK_DATA_PROCESS_PIPELINE_H +#define OHOS_MOCK_DATA_PROCESS_PIPELINE_H + +#include +#include + +#include "data_buffer.h" +#include "data_process_listener.h" +#include "distributed_camera_errno.h" +#include "idata_process_pipeline.h" +#include "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +class MockDataProcessPipeline : public IDataProcessPipeline, + public std::enable_shared_from_this { +public: + ~MockDataProcessPipeline() + { + } + + int32_t CreateDataProcessPipeline(PipelineType piplineType, + const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig, + const std::shared_ptr& listener) + { + return DCAMERA_OK; + } + + int32_t ProcessData(std::vector>& dataBuffers) + { + return DCAMERA_OK; + } + + void DestroyDataProcessPipeline() + { + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_controller.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_controller.h new file mode 100644 index 00000000..abb5601d --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_controller.h @@ -0,0 +1,78 @@ +/* + * 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_MOCK_DCAMERA_SINK_CONTROLLER_H +#define OHOS_MOCK_DCAMERA_SINK_CONTROLLER_H + +#include "icamera_controller.h" +#include "icamera_sink_access_control.h" + +namespace OHOS { +namespace DistributedHardware { +class MockDCameraSinkController : public ICameraController { +public: + explicit MockDCameraSinkController(const std::shared_ptr& accessControl) + { + } + + ~MockDCameraSinkController() + { + } + + int32_t StartCapture(std::vector>& captureInfos) + { + return DCAMERA_OK; + } + int32_t StopCapture() + { + return DCAMERA_OK; + } + int32_t ChannelNeg(std::shared_ptr& info) + { + return DCAMERA_OK; + } + int32_t DCameraNotify(std::shared_ptr& events) + { + return DCAMERA_OK; + } + int32_t UpdateSettings(std::vector>& settings) + { + return DCAMERA_OK; + } + int32_t GetCameraInfo(std::shared_ptr& camInfo) + { + return DCAMERA_OK; + } + int32_t OpenChannel(std::shared_ptr& openInfo) + { + return DCAMERA_OK; + } + int32_t CloseChannel() + { + return DCAMERA_OK; + } + int32_t Init(std::vector& indexs) + { + return DCAMERA_OK; + } + int32_t UnInit() + { + return DCAMERA_OK; + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_data_process.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_data_process.h new file mode 100644 index 00000000..7096cd47 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_data_process.h @@ -0,0 +1,78 @@ +/* + * 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_MOCK_DCAMERA_SINK_DATA_PROCESS_H +#define OHOS_MOCK_DCAMERA_SINK_DATA_PROCESS_H + +#include +#include + +#include "event.h" +#include "event_bus.h" + +#include "data_buffer.h" +#include "data_process_listener.h" +#include "dcamera_capture_info_cmd.h" +#include "dcamera_index.h" +#include "dcamera_photo_output_event.h" +#include "dcamera_video_output_event.h" +#include "icamera_channel.h" +#include "icamera_channel_listener.h" +#include "icamera_sink_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +class MockDCameraSinkDataProcess : public ICameraSinkDataProcess, public EventSender, + public DistributedHardware::EventBusHandler, + public DistributedHardware::EventBusHandler, + public std::enable_shared_from_this { +public: + explicit MockDCameraSinkDataProcess(const std::shared_ptr& channel) + { + } + + ~MockDCameraSinkDataProcess() + { + } + + int32_t StartCapture(std::shared_ptr& captureInfo) + { + return DCAMERA_OK; + } + int32_t StopCapture() + { + return DCAMERA_OK; + } + int32_t FeedStream(std::shared_ptr& dataBuffer) + { + return DCAMERA_OK; + } + void OnEvent(DCameraPhotoOutputEvent& event) + { + } + void OnEvent(DCameraVideoOutputEvent& event) + { + } + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult) + { + } + void OnError(DataProcessErrorType errorType) + { + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_output.h b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_output.h new file mode 100644 index 00000000..56ca76b0 --- /dev/null +++ b/services/cameraservice/sinkservice/test/unittest/common/distributedcameramgr/mock_dcamera_sink_output.h @@ -0,0 +1,63 @@ +/* + * 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_MOCK_DCAMERA_SINK_OUTPUT_H +#define OHOS_MOCK_DCAMERA_SINK_OUTPUT_H + +#include "distributed_camera_errno.h" +#include "icamera_operator.h" +#include "icamera_sink_output.h" + +namespace OHOS { +namespace DistributedHardware { +class MockDCameraSinkOutput : public ICameraSinkOutput { +public: + explicit MockDCameraSinkOutput(const std::string& dhId, const std::shared_ptr& cameraOperator) + { + } + + ~MockDCameraSinkOutput() + { + } + + int32_t Init() + { + return DCAMERA_OK; + } + int32_t UnInit() + { + return DCAMERA_OK; + } + int32_t StartCapture(std::vector>& captureInfos) + { + return DCAMERA_OK; + } + int32_t StopCapture() + { + return DCAMERA_OK; + } + int32_t OpenChannel(std::shared_ptr& info) + { + return DCAMERA_OK; + } + int32_t CloseChannel() + { + return DCAMERA_OK; + } +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/BUILD.gn b/services/cameraservice/sourceservice/BUILD.gn new file mode 100644 index 00000000..54b3d772 --- /dev/null +++ b/services/cameraservice/sourceservice/BUILD.gn @@ -0,0 +1,115 @@ +# 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("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_source") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/eventbus", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + "//third_party/jsoncpp/include", + "//drivers/peripheral/base", + ] + + include_dirs += [ + "include/distributedcamera", + "include/distributedcameramgr", + "include/distributedcameramgr/dcamerainterface", + "include/distributedcameramgr/dcamerastate", + "include/distributedcameramgr/dcameracontrol", + "include/distributedcameramgr/dcameradata", + "include/distributedcameramgr/dcamerahdf", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_sink/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + "${distributedcamera_hdf_path}/interfaces/include", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client/provider", + "${services_path}/cameraservice/base/include", + "${services_path}/channel/include", + "${services_path}/data_process/include/eventbus", + "${services_path}/data_process/include/interfaces", + "${services_path}/data_process/include/pipeline", + "${services_path}/data_process/include/utils", + ] + + sources = [ + "src/distributedcamera/dcamera_service_state_listener.cpp", + "src/distributedcamera/distributed_camera_source_service.cpp", + "${innerkits_path}/native_cpp/camera_sink/src/distributed_camera_sink_proxy.cpp", + "src/distributedcamera/distributed_camera_source_stub.cpp", + "src/distributedcamera/dcamera_source_callback_proxy.cpp", + "src/distributedcameramgr/dcamera_source_dev.cpp", + "src/distributedcameramgr/dcamera_source_event.cpp", + "src/distributedcameramgr/dcamera_source_service_ipc.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_state_factory.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_state_machine.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_init_state.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_regist_state.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_opened_state.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.cpp", + "src/distributedcameramgr/dcamerastate/dcamera_source_capture_state.cpp", + "src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp", + "src/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.cpp", + "${services_path}/cameraservice/base/src/dcamera_capture_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_channel_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_event_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_info_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_metadata_setting_cmd.cpp", + "${services_path}/cameraservice/base/src/dcamera_open_info_cmd.cpp", + + "src/distributedcameramgr/dcameradata/dcamera_source_data_process.cpp", + "src/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.cpp", + "src/distributedcameramgr/dcameradata/dcamera_source_input.cpp", + "src/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.cpp", + "src/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.cpp", + "src/distributedcameramgr/dcameradata/dcamera_stream_data_process.cpp", + "src/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "${services_path}/channel:distributed_camera_channel", + "${services_path}/data_process:distributed_camera_data_process", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client:distributed_camera_hdf_client", + "//utils/native/base:utils", + "//third_party/jsoncpp:jsoncpp", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcamerasourcesvr\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "eventhandler:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcamera/dcamera_service_state_listener.h b/services/cameraservice/sourceservice/include/distributedcamera/dcamera_service_state_listener.h new file mode 100644 index 00000000..938e5662 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcamera/dcamera_service_state_listener.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 OHOS_DCAMERA_SERVICE_STATE_LISTENER_H +#define OHOS_DCAMERA_SERVICE_STATE_LISTENER_H + +#include "icamera_state_listener.h" +#include "idcamera_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraServiceStateListener : public ICameraStateListener { +public: + DCameraServiceStateListener(sptr callback); + ~DCameraServiceStateListener(); + + int32_t OnRegisterNotify(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; + int32_t OnUnregisterNotify(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; + +private: + sptr callbackProxy_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcamera/dcamera_source_callback_proxy.h b/services/cameraservice/sourceservice/include/distributedcamera/dcamera_source_callback_proxy.h new file mode 100644 index 00000000..e2afe9ba --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcamera/dcamera_source_callback_proxy.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 OHOS_DCAMERA_SOURCE_CALLBACK_PROXY_H +#define OHOS_DCAMERA_SOURCE_CALLBACK_PROXY_H +#include + +#include "iremote_proxy.h" +#include "iremote_broker.h" +#include "refbase.h" + +#include "idcamera_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceCallbackProxy : public IRemoteProxy { +public: + explicit DCameraSourceCallbackProxy(const sptr &impl) : IRemoteProxy(impl) + {} + ~DCameraSourceCallbackProxy() + {} + + int32_t OnNotifyRegResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; + int32_t OnNotifyUnregResult(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) override; +private: + static inline BrokerDelegator delegator_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_service.h b/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_service.h new file mode 100644 index 00000000..6dfb6ee5 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_service.h @@ -0,0 +1,68 @@ +/* + * 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_DISTRIBUTED_CAMERA_SOURCE_SERVICE_H +#define OHOS_DISTRIBUTED_CAMERA_SOURCE_SERVICE_H + +#include +#include +#include + +#include "system_ability.h" +#include "ipc_object_stub.h" + +#include "dcamera_index.h" +#include "dcamera_source_dev.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_source_stub.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSourceService : public SystemAbility, public DistributedCameraSourceStub { +DECLARE_SYSTEM_ABILITY(DistributedCameraSourceService); +public: + DistributedCameraSourceService(int32_t saId, bool runOnCreate); + ~DistributedCameraSourceService() = default; + + int32_t InitSource(const std::string& params, const sptr& callback) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const EnableParam& param) override; + int32_t UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId) override; + int32_t DCameraNotify(const std::string& devId, const std::string& dhId, std::string& events) override; + + static std::map> camerasMap_; + +protected: + void OnStart() override; + void OnStop() override; + DISALLOW_COPY_AND_MOVE(DistributedCameraSourceService); + +private: + bool Init(); + int32_t LoadDCameraHDF(); + int32_t UnLoadCameraHDF(); + + bool registerToService_ = false; + DCameraServiceState state_ = DCameraServiceState::DCAMERA_SRV_STATE_NOT_START; + + sptr callbackProxy_; + std::string sourceVer_; +}; +} +} + +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_stub.h b/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_stub.h new file mode 100644 index 00000000..60eee154 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcamera/distributed_camera_source_stub.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 OHOS_DISTRIBUTED_CAMERA_SOURCE_STUB_H +#define OHOS_DISTRIBUTED_CAMERA_SOURCE_STUB_H + +#include +#include "iremote_stub.h" + +#include "idistributed_camera_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DistributedCameraSourceStub : public IRemoteStub { +public: + DistributedCameraSourceStub(); + virtual ~DistributedCameraSourceStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t InitSourceInner(MessageParcel &data, MessageParcel &reply); + int32_t ReleaseSourceInner(MessageParcel &data, MessageParcel &reply); + int32_t RegisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply); + int32_t UnregisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply); + int32_t DCameraNotifyInner(MessageParcel &data, MessageParcel &reply); + + using DCameraFunc = int32_t (DistributedCameraSourceStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} +} + +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_dev.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_dev.h new file mode 100644 index 00000000..9e864ac1 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_dev.h @@ -0,0 +1,93 @@ +/* + * 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_SOURCE_DEV_H +#define OHOS_DCAMERA_SOURCE_DEV_H + +#include "dcamera_index.h" +#include "dcamera_source_event.h" +#include "dcamera_source_state_machine.h" +#include "event_bus.h" +#include "icamera_controller.h" +#include "icamera_state_listener.h" +#include "icamera_input.h" + +#include "idistributed_camera_provider_callback.h" +#include "idistributed_camera_provider.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceDev : public EventSender, public DistributedHardware::EventBusHandler, + public std::enable_shared_from_this { +public: + explicit DCameraSourceDev(std::string devId, std::string dhId, std::shared_ptr& stateLisener); + virtual ~DCameraSourceDev(); + + int32_t InitDCameraSourceDev(); + int32_t RegisterDistributedHardware(const std::string& devId, const std::string& dhId, const std::string& reqId, + const std::string& ver, const std::string attrs); + int32_t UnRegisterDistributedHardware(const std::string devId, const std::string dhId, const std::string reqId); + int32_t DCameraNotify(std::string& eventStr); + + int32_t OpenSession(DCameraIndex& camIndex); + int32_t CloseSession(DCameraIndex& camIndex); + int32_t ConfigStreams(const std::vector>& streamInfos); + int32_t ReleaseStreams(const std::vector& streamIds); + int32_t StartCapture(const std::vector>& captureInfos); + int32_t StopCapture(); + int32_t UpdateCameraSettings(const std::vector>& settings); + + void OnEvent(DCameraSourceEvent& event) override; + +public: + virtual int32_t ExecuteRegister(std::shared_ptr& param); + virtual int32_t ExecuteUnRegister(std::shared_ptr& param); + virtual int32_t ExecuteOpenCamera(); + virtual int32_t ExecuteCloseCamera(); + virtual int32_t ExecuteConfigStreams(std::vector>& streamInfos); + virtual int32_t ExecuteReleaseStreams(std::vector& streamIds, bool& isAllRelease); + virtual int32_t ExecuteReleaseAllStreams(); + virtual int32_t ExecuteStartCapture(std::vector>& captureInfos); + virtual int32_t ExecuteStopCapture(); + virtual int32_t ExecuteUpdateSettings(std::vector>& settings); + virtual int32_t ExecuteCameraEventNotify(std::shared_ptr& events); + +private: + using DCameraNotifyFunc = void (DCameraSourceDev::*)(DCAMERA_EVENT eventType, DCameraSourceEvent& event, + int32_t result); + + void NotifyResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result); + void NotifyRegisterResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result); + void NotifyUnregisterResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result); + void NotifyHalResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result); + +private: + std::string devId_; + std::string dhId_; + std::string version_; + std::set actualDevInfo_; + std::shared_ptr stateListener_; + std::shared_ptr eventBus_; + std::shared_ptr stateMachine_; + std::shared_ptr controller_; + std::shared_ptr input_; + sptr hdiCallback_; + + std::map memberFuncMap_; + std::map eventResultMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_event.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_event.h new file mode 100644 index 00000000..7517da9b --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_event.h @@ -0,0 +1,124 @@ +/* + * 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_SOURCE_EVENT_H +#define OHOS_DCAMERA_SOURCE_EVENT_H + +#include + +#include "event.h" +#include "types.h" + +#include "dcamera_event_cmd.h" +#include "dcamera_index.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_EVENT_REGIST = 0, + DCAMERA_EVENT_UNREGIST = 1, + DCAMERA_EVENT_OPEN = 2, + DCAMERA_EVENT_CLOSE = 3, + DCAMERA_EVENT_CONFIG_STREAMS = 4, + DCAMERA_EVENT_RELEASE_STREAMS = 5, + DCAMERA_EVENT_START_CAPTURE = 6, + DCAMERA_EVENT_STOP_CAPTURE = 7, + DCAMERA_EVENT_UPDATE_SETTINGS = 8, + DCAMERA_EVENT_NOFIFY = 9, +} DCAMERA_EVENT; + +class DCameraRegistParam { +public: + DCameraRegistParam() = default; + DCameraRegistParam(std::string devId, std::string dhId, std::string reqId, std::string param) + : devId_(devId), dhId_(dhId), reqId_(reqId), param_(param) + {} + ~DCameraRegistParam() = default; + std::string devId_; + std::string dhId_; + std::string reqId_; + std::string param_; +}; + +class DCameraSourceEvent : public Event { + TYPEINDENT(DCameraSourceEvent) +public: + DCameraSourceEvent(EventSender& sender) : Event(sender) {} + ~DCameraSourceEvent() = default; + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType) + : Event(sender), eventType_(eventType) {} + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, DCameraIndex& index) + : Event(sender), eventType_(eventType) + { + eventParam_ = index; + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, + std::shared_ptr& param) : Event(sender), eventType_(eventType) + { + eventParam_ = param; + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, + const std::vector>& streamInfos) : Event(sender), eventType_(eventType) + { + eventParam_ = std::move(streamInfos); + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, + const std::vector>& captureInfos) : Event(sender), eventType_(eventType) + { + eventParam_ = std::move(captureInfos); + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, + const std::vector>& settings) : Event(sender), eventType_(eventType) + { + eventParam_ = std::move(settings); + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, const std::vector& streamIds) + : Event(sender), eventType_(eventType) + { + eventParam_ = std::move(streamIds); + } + + explicit DCameraSourceEvent(EventSender& sender, DCAMERA_EVENT eventType, std::shared_ptr& camEvent) + : Event(sender), eventType_(eventType) + { + eventParam_ = camEvent; + } + + int32_t GetDCameraIndex(DCameraIndex& index); + int32_t GetDCameraRegistParam(std::shared_ptr& param); + int32_t GetStreamInfos(std::vector>& streamInfos); + int32_t GetCaptureInfos(std::vector>& captureInfos); + int32_t GetCameraSettings(std::vector>& settings); + int32_t GetStreamIds(std::vector& streamIds); + int32_t GetCameraEvent(std::shared_ptr& camEvent); + DCAMERA_EVENT GetEventType(); + +private: + using EventParam = std::variant, + std::vector>, std::vector>, + std::vector>, std::vector, std::shared_ptr>; + +private: + DCAMERA_EVENT eventType_; + EventParam eventParam_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_service_ipc.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_service_ipc.h new file mode 100644 index 00000000..b3bb6ced --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamera_source_service_ipc.h @@ -0,0 +1,54 @@ +/* + * 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_SOURCE_SERVICE_IPC_H +#define OHOS_DCAMERA_SOURCE_SERVICE_IPC_H + +#include "event_handler.h" +#include "idistributed_camera_sink.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceServiceIpc { +DECLARE_SINGLE_INSTANCE_BASE(DCameraSourceServiceIpc); +public: + void Init(); + void UnInit(); + sptr GetSinkRemoteDHMS(const std::string& deviceId); + void OnSinkRemoteDmsDied(const wptr& remote); + void DeleteSinkRemoteDhms(const std::string& deviceId); + +private: + DCameraSourceServiceIpc(); + ~DCameraSourceServiceIpc(); + void OnSinkRemoteDmsDied(const sptr& remote); + void ClearSinkRemoteDhms(); + + class SinkRemoteRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr& remote) override; + }; + sptr sinkRemoteRecipient_; + std::map> remoteSinks_; + std::mutex sinkRemoteDmsLock_; + + bool isInit_; + std::shared_ptr serviceHandler_; + std::mutex initDmsLock_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h new file mode 100644 index 00000000..3817bce0 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller.h @@ -0,0 +1,70 @@ +/* + * 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_SOURCE_CONTROLLER_H +#define OHOS_DCAMERA_SOURCE_CONTROLLER_H + +#include "icamera_controller.h" + +#include "dcamera_index.h" +#include "icamera_channel_listener.h" +#include "dcamera_source_state_machine.h" +#include "event_bus.h" +#include "icamera_channel.h" + +#include "idistributed_camera_provider.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceController : public ICameraController, public EventSender, + public std::enable_shared_from_this { +public: + DCameraSourceController(std::string devId, std::string dhId, + std::shared_ptr& stateMachine, std::shared_ptr& eventBus); + ~DCameraSourceController(); + int32_t StartCapture(std::vector>& captureInfos) override; + int32_t StopCapture() override; + int32_t ChannelNeg(std::shared_ptr& info) override; + int32_t DCameraNotify(std::shared_ptr& events) override; + int32_t UpdateSettings(std::vector>& settings) override; + int32_t GetCameraInfo(std::shared_ptr& camInfo) override; + int32_t OpenChannel(std::shared_ptr& openInfo) override; + int32_t CloseChannel() override; + int32_t Init(std::vector& indexs) override; + int32_t UnInit() override; + + void OnSessionState(int32_t state); + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail); + void OnDataReceived(std::vector>& buffers); + +private: + void HandleMetaDataResult(std::string& jsonStr); + +private: + std::string devId_; + std::string dhId_; + std::shared_ptr channel_; + std::shared_ptr listener_; + std::vector indexs_; + std::shared_ptr stateMachine_; + std::shared_ptr eventBus_; + int32_t channelState_; + + bool isInit; + const std::string SESSION_FLAG = "control"; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.h new file mode 100644 index 00000000..316e3831 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.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 OHOS_DCAMERA_SOURCE_CONTROLLER_CHANNEL_LISTENER_H +#define OHOS_DCAMERA_SOURCE_CONTROLLER_CHANNEL_LISTENER_H + +#include + +#include "icamera_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceController; +class DCameraSourceControllerChannelListener : public ICameraChannelListener { +public: + DCameraSourceControllerChannelListener(std::shared_ptr& controller); + ~DCameraSourceControllerChannelListener(); + void OnSessionState(int32_t state) override; + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) override; + void OnDataReceived(std::vector>& buffers) override; + +private: + std::weak_ptr controller_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_data_process.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_data_process.h new file mode 100644 index 00000000..8ab873c7 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_data_process.h @@ -0,0 +1,50 @@ +/* + * 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_SOURCE_DATRA_PROCESS_H +#define OHOS_DCAMERA_SOURCE_DATRA_PROCESS_H + +#include +#include + +#include "dcamera_stream_data_process.h" +#include "icamera_source_data_process.h" + +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceDataProcess : public ICameraSourceDataProcess { +public: + DCameraSourceDataProcess(std::string devId, std::string dhId, DCStreamType streamType); + ~DCameraSourceDataProcess(); + + int32_t FeedStream(std::vector>& buffers) override; + int32_t ConfigStreams(std::vector>& streamInfos) override; + int32_t ReleaseStreams(std::vector& streamIds) override; + int32_t StartCapture(std::shared_ptr& captureInfo) override; + int32_t StopCapture() override; + void GetAllStreamIds(std::vector& streamIds) override; + +private: + std::vector> streamProcess_; + std::set streamIds_; + std::string devId_; + std::string dhId_; + DCStreamType streamType_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h new file mode 100644 index 00000000..c67b59df --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input.h @@ -0,0 +1,65 @@ +/* + * 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_SOURCE_INPUT_H +#define OHOS_DCAMERA_SOURCE_INPUT_H + +#include "icamera_channel.h" +#include "icamera_channel_listener.h" +#include "icamera_input.h" +#include "icamera_source_data_process.h" + +#include "event_bus.h" +#include "event_sender.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceInput : public ICameraInput, public EventSender, + public std::enable_shared_from_this { +public: + DCameraSourceInput(std::string devId, std::string dhId, std::shared_ptr& eventBus); + ~DCameraSourceInput(); + + int32_t ConfigStreams(std::vector>& streamInfos) override; + int32_t ReleaseStreams(std::vector& streamIds, bool& isAllRelease) override; + int32_t ReleaseAllStreams() override; + int32_t StartCapture(std::vector>& captureInfos) override; + int32_t StopCapture() override; + int32_t OpenChannel(std::vector& indexs) override; + int32_t CloseChannel() override; + int32_t Init() override; + int32_t UnInit() override; + int32_t UpdateSettings(std::vector>& settings) override; + + void OnSessionState(DCStreamType streamType, int32_t state); + void OnSessionError(DCStreamType streamType, int32_t eventType, int32_t eventReason, std::string detail); + void OnDataReceived(DCStreamType streamType, std::vector>& buffers); + +private: + std::map> channels_; + std::map> listeners_; + std::map> dataProcess_; + std::map channelState_; + std::string devId_; + std::string dhId_; + std::shared_ptr eventBus_; + + bool isInit = false; + std::mutex inputMutex_; + bool isCapture_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.h new file mode 100644 index 00000000..98f8a510 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.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 OHOS_DCAMERA_SOURCE_INPUT_CHANNEL_LISTENER_H +#define OHOS_DCAMERA_SOURCE_INPUT_CHANNEL_LISTENER_H + +#include + +#include "icamera_channel_listener.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceInput; +class DCameraSourceInputChannelListener : public ICameraChannelListener { +public: + DCameraSourceInputChannelListener(std::shared_ptr& Input, DCStreamType streamType); + ~DCameraSourceInputChannelListener(); + void OnSessionState(int32_t state) override; + void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) override; + void OnDataReceived(std::vector>& buffers) override; + +private: + std::weak_ptr input_; + DCStreamType streamType_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process.h new file mode 100644 index 00000000..a9f37b50 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process.h @@ -0,0 +1,67 @@ +/* + * 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_STREAM_DATA_PROCESS_H +#define OHOS_DCAMERA_STREAM_DATA_PROCESS_H + +#include + +#include "data_buffer.h" +#include "icamera_source_data_process.h" +#include "idata_process_pipeline.h" +#include "image_common_type.h" +#include "types.h" + +#include "dcamera_stream_data_process_producer.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraStreamDataProcess : public std::enable_shared_from_this { +public: + DCameraStreamDataProcess(std::string devId, std::string dhId, DCStreamType streamType); + ~DCameraStreamDataProcess(); + void FeedStream(std::shared_ptr& buffer); + void ConfigStreams(std::shared_ptr& dstConfig, std::set& streamIds); + void ReleaseStreams(std::set& streamIds); + void StartCapture(std::shared_ptr& srcConfig, std::set& streamIds); + void StopCapture(); + void GetAllStreamIds(std::set& streamIds); + + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult); + void OnError(DataProcessErrorType errorType); + +private: + void FeedStreamToSnapShot(const std::shared_ptr& buffer); + void FeedStreamToContinue(const std::shared_ptr& buffer); + void CreatePipeline(); + void DestroyPipeline(); + VideoCodecType GetPipelineCodecType(DCEncodeType encodeType); + Videoformat GetPipelineFormat(int32_t format); + +private: + std::string devId_; + std::string dhId_; + DCStreamType streamType_; + + std::set streamIds_; + std::shared_ptr srcConfig_; + std::shared_ptr dstConfig_; + std::shared_ptr pipeline_; + std::shared_ptr listener_; + std::map> producers_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.h new file mode 100644 index 00000000..06c8bfa4 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.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 OHOS_DCAMERA_STREAM_DATA_PROCESS_PIPELINE_LISTENER_H +#define OHOS_DCAMERA_STREAM_DATA_PROCESS_PIPELINE_LISTENER_H + +#include + +#include "data_buffer.h" +#include "data_process_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraStreamDataProcess; +class DCameraStreamDataProcessPipelineListener : public DataProcessListener { +public: + DCameraStreamDataProcessPipelineListener(std::shared_ptr& process); + ~DCameraStreamDataProcessPipelineListener(); + + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult) override; + void OnError(DataProcessErrorType errorType) override; + +private: + std::weak_ptr process_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.h new file mode 100644 index 00000000..ceb2d27a --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.h @@ -0,0 +1,67 @@ +/* + * 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_ICAMERA_SOURCE_DATA_PROCESS_PRODUCER_H +#define OHOS_ICAMERA_SOURCE_DATA_PROCESS_PRODUCER_H + +#include +#include +#include +#include + +#include "data_buffer.h" +#include "event_handler.h" +#include "idistributed_camera_provider.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraStreamDataProcessProducer { +public: + typedef enum { + DCAMERA_PRODUCER_STATE_STOP = 0, + DCAMERA_PRODUCER_STATE_START = 1, + } DCameraProducerState; + + DCameraStreamDataProcessProducer(std::string devId, std::string dhId, int32_t streamId, DCStreamType streamType); + ~DCameraStreamDataProcessProducer(); + void Start(); + void Stop(); + void FeedStream(const std::shared_ptr& buffer); + void UpdateInterval(uint32_t fps); +private: + void LooperContinue(); + void LooperSnapShot(); + int32_t FeedStreamToDriver(const std::shared_ptr& dhBase, const std::shared_ptr& buffer); + + const uint32_t DCAMERA_PRODUCER_MAX_BUFFER_SIZE = 30; + const uint32_t DCAMERA_PRODUCER_RETRY_SLEEP_MS = 500; + +private: + std::string devId_; + std::string dhId_; + + std::thread producerThread_; + std::condition_variable producerCon_; + std::mutex producerMutex_; + std::queue> buffers_; + DCameraProducerState state_; + uint32_t interval_; + int32_t streamId_; + DCStreamType streamType_; + std::shared_ptr eventHandler_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.h new file mode 100644 index 00000000..51c7aac8 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.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 OHOS_DCAMERA_PROVIDER_CALLBACK_IMPL_H +#define OHOS_DCAMERA_PROVIDER_CALLBACK_IMPL_H + +#include "dcamera_provider_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceDev; +class DCameraProviderCallbackImpl : public DCameraProviderCallback { +public: + DCameraProviderCallbackImpl(std::string devId, std::string dhId, std::shared_ptr& sourceDev); + ~DCameraProviderCallbackImpl(); + + DCamRetCode OpenSession(const std::shared_ptr& dhBase) override; + DCamRetCode CloseSession(const std::shared_ptr& dhBase) override; + DCamRetCode ConfigureStreams(const std::shared_ptr& dhBase, + const std::vector>& streamInfos) override; + DCamRetCode ReleaseStreams(const std::shared_ptr& dhBase, const std::vector& streamIds) override; + DCamRetCode StartCapture(const std::shared_ptr& dhBase, + const std::vector>& captureInfos) override; + DCamRetCode StopCapture(const std::shared_ptr& dhBase) override; + DCamRetCode UpdateSettings(const std::shared_ptr& dhBase, + const std::vector>& settings) override; + +private: + std::string devId_; + std::string dhId_; + std::weak_ptr sourceDev_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_input.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_input.h new file mode 100644 index 00000000..13e65810 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_input.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 OHOS_ICAMERA_INPUT_H +#define OHOS_ICAMERA_INPUT_H + +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class ICameraInput { +public: + virtual ~ICameraInput() = default; + + virtual int32_t ConfigStreams(std::vector>& streamInfos) = 0; + virtual int32_t ReleaseStreams(std::vector& streamIds, bool& isAllRelease) = 0; + virtual int32_t ReleaseAllStreams() = 0; + virtual int32_t StartCapture(std::vector>& captureInfos) = 0; + virtual int32_t StopCapture() = 0; + virtual int32_t OpenChannel(std::vector& indexs) = 0; + virtual int32_t CloseChannel() = 0; + virtual int32_t Init() = 0; + virtual int32_t UnInit() = 0; + virtual int32_t UpdateSettings(std::vector>& settings) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_source_data_process.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_source_data_process.h new file mode 100644 index 00000000..5c19df20 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_source_data_process.h @@ -0,0 +1,67 @@ +/* + * 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_ICAMERA_SOURCE_DATA_PROCESS_H +#define OHOS_ICAMERA_SOURCE_DATA_PROCESS_H + +#include + +#include "data_buffer.h" +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraStreamConfig { +public: + DCameraStreamConfig(int32_t width, int32_t height, int32_t format, int32_t dataspace, + DCEncodeType encodeType, DCStreamType streamType) + : width_(width), height_(height), format_(format), dataspace_(dataspace), encodeType_(encodeType), + type_(streamType) + {} + ~DCameraStreamConfig() = default; + int32_t width_; + int32_t height_; + int32_t format_; + int32_t dataspace_; + DCEncodeType encodeType_; + DCStreamType type_; + + bool operator == (const DCameraStreamConfig& others) const + { + return this->width_ == others.width_ && this->height_ == others.height_ && this->format_ == others.format_ && + this->dataspace_ == others.dataspace_ && this->encodeType_ == others.encodeType_ && + this->type_ == others.type_; + } + + bool operator < (const DCameraStreamConfig& others) const + { + return (this->width_ < others.width_) || ((this->width_ == others.width_) && (this->height_ < this->height_)); + } +}; + +class ICameraSourceDataProcess { +public: + virtual ~ICameraSourceDataProcess() = default; + + virtual int32_t FeedStream(std::vector>& buffers) = 0; + virtual int32_t ConfigStreams(std::vector>& streamInos) = 0; + virtual int32_t ReleaseStreams(std::vector& streamIds) = 0; + virtual int32_t StartCapture(std::shared_ptr& captureInfo) = 0; + virtual int32_t StopCapture() = 0; + virtual void GetAllStreamIds(std::vector& streamIds) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_state_listener.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_state_listener.h new file mode 100644 index 00000000..613c2c26 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface/icamera_state_listener.h @@ -0,0 +1,34 @@ +/* + * 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_ICAMERA_STATE_LISTENER_H +#define OHOS_ICAMERA_STATE_LISTENER_H + +#include +#include + +namespace OHOS { +namespace DistributedHardware { +class ICameraStateListener { +public: + virtual ~ICameraStateListener() {} + virtual int32_t OnRegisterNotify(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) = 0; + virtual int32_t OnUnregisterNotify(const std::string& devId, const std::string& dhId, const std::string& reqId, + int32_t status, std::string& data) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_capture_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_capture_state.h new file mode 100644 index 00000000..b7ce816f --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_capture_state.h @@ -0,0 +1,52 @@ +/* + * 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_SOURCE_CAPTURE_STATE_H +#define OHOS_DCAMERA_SOURCE_CAPTURE_STATE_H + +#include +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceCaptureState : public DCameraSourceState { +public: + DCameraSourceCaptureState(std::shared_ptr& stateMachine); + ~DCameraSourceCaptureState() {} + + int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) override; + DCameraStateType GetStateType() override; + +private: + int32_t DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoStartCaptureTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoStopCaptureTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUpdateSettingsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoEventNofityTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + + using DCameraFunc = int32_t (DCameraSourceCaptureState::*)(std::shared_ptr& camDev, + DCameraSourceEvent& event); + +private: + std::weak_ptr stateMachine_; + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.h new file mode 100644 index 00000000..c50149d3 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.h @@ -0,0 +1,55 @@ +/* + * 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_SOURCE_CONFIG_STREAM_STATE_H +#define OHOS_DCAMERA_SOURCE_CONFIG_STREAM_STATE_H + +#include +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceConfigStreamState : public DCameraSourceState { +public: + DCameraSourceConfigStreamState(std::shared_ptr& stateMachine); + DCameraSourceConfigStreamState() {} + ~DCameraSourceConfigStreamState() {} + + int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) override; + DCameraStateType GetStateType() override; + +private: + int32_t DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoConfigStreamsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoReleaseStreamsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoStartCaptureTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoStopCaptureTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUpdateSettingsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoEventNofityTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + + using DCameraFunc = int32_t (DCameraSourceConfigStreamState::*)(std::shared_ptr& camDev, + DCameraSourceEvent& event); + +private: + std::weak_ptr stateMachine_; + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_init_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_init_state.h new file mode 100644 index 00000000..dc937779 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_init_state.h @@ -0,0 +1,46 @@ +/* + * 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_SOURCE_INIT_STATE_H +#define OHOS_DCAMERA_SOURCE_INIT_STATE_H + +#include +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceInitState : public DCameraSourceState { +public: + DCameraSourceInitState(std::shared_ptr& stateMachine); + ~DCameraSourceInitState() {} + + int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) override; + DCameraStateType GetStateType() override; + +private: + int32_t DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + + using DCameraFunc = int32_t (DCameraSourceInitState::*)(std::shared_ptr& camDev, + DCameraSourceEvent& event); + +private: + std::weak_ptr stateMachine_; + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_opened_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_opened_state.h new file mode 100644 index 00000000..b46b9e32 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_opened_state.h @@ -0,0 +1,52 @@ +/* + * 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_SOURCE_OPENED_STATE_H +#define OHOS_DCAMERA_SOURCE_OPENED_STATE_H + +#include +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceOpenedState : public DCameraSourceState { +public: + DCameraSourceOpenedState(std::shared_ptr& stateMachine); + ~DCameraSourceOpenedState() {} + + int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) override; + DCameraStateType GetStateType() override; + +private: + int32_t DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoConfigStreamsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoReleaseStreamsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUpdateSettingsTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoEventNofityTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + + using DCameraFunc = int32_t (DCameraSourceOpenedState::*)(std::shared_ptr& camDev, + DCameraSourceEvent& event); + +private: + std::weak_ptr stateMachine_; + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_regist_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_regist_state.h new file mode 100644 index 00000000..775cdc01 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_regist_state.h @@ -0,0 +1,49 @@ +/* + * 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_SOURCE_REGIST_STATE_H +#define OHOS_DCAMERA_SOURCE_REGIST_STATE_H + +#include +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceRegistState : public DCameraSourceState { +public: + DCameraSourceRegistState(std::shared_ptr& stateMachine); + ~DCameraSourceRegistState() {} + + int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) override; + DCameraStateType GetStateType() override; + +private: + int32_t DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + int32_t DoEventNofityTask(std::shared_ptr& camDev, DCameraSourceEvent& event); + + using DCameraFunc = int32_t (DCameraSourceRegistState::*)(std::shared_ptr& camDev, + DCameraSourceEvent& event); + +private: + std::weak_ptr stateMachine_; + std::map memberFuncMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state.h new file mode 100644 index 00000000..1e908c2a --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state.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_SOURCE_STATE_H +#define OHOS_DCAMERA_SOURCE_STATE_H +#include "dcamera_source_event.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_STATE_INIT = 0, + DCAMERA_STATE_REGIST = 1, + DCAMERA_STATE_OPENED = 2, + DCAMERA_STATE_CONFIG_STREAM = 3, + DCAMERA_STATE_CAPTURE = 4, +} DCameraStateType; + +class DCameraSourceDev; +class DCameraSourceStateMachine; +class DCameraSourceState { +public: + DCameraSourceState() {} + virtual ~DCameraSourceState() {} + + virtual int32_t Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) = 0; + virtual DCameraStateType GetStateType() = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_factory.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_factory.h new file mode 100644 index 00000000..44ddf0ad --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_factory.h @@ -0,0 +1,31 @@ +/* + * 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_SOURCE_STATE_FACTORY_H +#define OHOS_DCAMERA_SOURCE_STATE_FACTORY_H +#include "single_instance.h" +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceStateFactory { +DECLARE_SINGLE_INSTANCE(DCameraSourceStateFactory); +public: + std::shared_ptr CreateState(DCameraStateType stateType, + std::shared_ptr& stateMachine); +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_machine.h b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_machine.h new file mode 100644 index 00000000..030ed940 --- /dev/null +++ b/services/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate/dcamera_source_state_machine.h @@ -0,0 +1,37 @@ +/* + * 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_SOURCE_STATE_MACHINE_H +#define OHOS_DCAMERA_SOURCE_STATE_MACHINE_H +#include "dcamera_source_event.h" +#include "dcamera_source_state.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceDev; +class DCameraSourceStateMachine : public std::enable_shared_from_this { +public: + DCameraSourceStateMachine(std::shared_ptr& camDev); + ~DCameraSourceStateMachine(); + int32_t Execute(DCAMERA_EVENT eventType, DCameraSourceEvent& event); + void UpdateState(DCameraStateType stateType); + +private: + std::shared_ptr currentState_; + std::weak_ptr camDev_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcamera/dcamera_service_state_listener.cpp b/services/cameraservice/sourceservice/src/distributedcamera/dcamera_service_state_listener.cpp new file mode 100644 index 00000000..4eff7096 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcamera/dcamera_service_state_listener.cpp @@ -0,0 +1,92 @@ +/* + * 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_service_state_listener.h" + +#include + +#include "anonymous_string.h" +#include "dcamera_index.h" +#include "distributed_camera_errno.h" +#include "distributed_camera_source_service.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraServiceStateListener::DCameraServiceStateListener(sptr callback) + : callbackProxy_(callback) +{ + DHLOGI("DCameraServiceStateListener Create"); +} + +DCameraServiceStateListener::~DCameraServiceStateListener() +{ + DHLOGI("DCameraServiceStateListener Delete"); + callbackProxy_ = nullptr; +} + +int32_t DCameraServiceStateListener::OnRegisterNotify(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + DHLOGI("DCameraServiceStateListener OnRegisterNotify devId: %s, dhId: %s, status: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), status); + if (callbackProxy_ == nullptr) { + DHLOGE("DCameraServiceStateListener OnRegisterNotify callbackProxy_ is nullptr"); + return DCAMERA_BAD_VALUE; + } + + int32_t ret = callbackProxy_->OnNotifyRegResult(devId, dhId, reqId, status, data); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraServiceStateListener OnRegisterNotify OnNotifyRegResult failed: %d", ret); + } + if (status != DCAMERA_OK) { + std::thread([this, &devId, &dhId]() { + DHLOGI("DCameraServiceStateListener OnRegisterNotify thread delete devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + DCameraIndex camIndex(devId, dhId); + DistributedCameraSourceService::camerasMap_.erase(camIndex); + }).detach(); + } + return ret; +} + +int32_t DCameraServiceStateListener::OnUnregisterNotify(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + DHLOGI("DCameraServiceStateListener OnUnregisterNotify devId: %s, dhId: %s, status: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), status); + if (callbackProxy_ == nullptr) { + DHLOGE("DCameraServiceStateListener OnUnregisterNotify callbackProxy_ is nullptr"); + return DCAMERA_BAD_VALUE; + } + + int32_t ret = callbackProxy_->OnNotifyUnregResult(devId, dhId, reqId, status, data); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraServiceStateListener OnUnregisterNotify failed, ret: %d", ret); + } + + if (status == DCAMERA_OK) { + std::thread([this, &devId, &dhId]() { + DHLOGI("DCameraServiceStateListener OnUnregisterNotify thread delete devId: %s dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + DCameraIndex camIndex(devId, dhId); + DistributedCameraSourceService::camerasMap_.erase(camIndex); + }).detach(); + } + + return ret; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcamera/dcamera_source_callback_proxy.cpp b/services/cameraservice/sourceservice/src/distributedcamera/dcamera_source_callback_proxy.cpp new file mode 100644 index 00000000..2ce269d7 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcamera/dcamera_source_callback_proxy.cpp @@ -0,0 +1,78 @@ +/* + * 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_source_callback_proxy.h" + +#include "parcel.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraSourceCallbackProxy::OnNotifyRegResult(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DCameraSourceCallbackProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel req; + MessageParcel reply; + MessageOption option; + if (!req.WriteInterfaceToken(DCameraSourceCallbackProxy::GetDescriptor())) { + DHLOGE("DCameraSourceCallbackProxy OnNotifyRegResult write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!req.WriteString(devId) || !req.WriteString(dhId) || !req.WriteString(reqId) || + !req.WriteInt32(status) || !req.WriteString(data)) { + DHLOGE("DistributedCameraSourceProxy InitSource write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(NOTIFY_REG_RESULT, req, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} + +int32_t DCameraSourceCallbackProxy::OnNotifyUnregResult(const std::string& devId, const std::string& dhId, + const std::string& reqId, int32_t status, std::string& data) +{ + sptr remote = Remote(); + if (remote == nullptr) { + DHLOGE("DCameraSourceCallbackProxy remote service null"); + return DCAMERA_BAD_VALUE; + } + MessageParcel req; + MessageParcel reply; + MessageOption option; + if (!req.WriteInterfaceToken(DCameraSourceCallbackProxy::GetDescriptor())) { + DHLOGE("DCameraSourceCallbackProxy OnNotifyRegResult write token failed"); + return DCAMERA_BAD_VALUE; + } + + if (!req.WriteString(devId) || !req.WriteString(dhId) || !req.WriteString(reqId) || + !req.WriteInt32(status) || !req.WriteString(data)) { + DHLOGE("DistributedCameraSourceProxy InitSource write params failed"); + return DCAMERA_BAD_VALUE; + } + remote->SendRequest(NOTIFY_UNREG_RESULT, req, reply, option); + int32_t result = reply.ReadInt32(); + return result; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_service.cpp b/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_service.cpp new file mode 100644 index 00000000..fde25868 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_service.cpp @@ -0,0 +1,198 @@ +/* + * 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 "distributed_camera_source_service.h" + +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "anonymous_string.h" +#include "dcamera_service_state_listener.h" +#include "dcamera_source_service_ipc.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +REGISTER_SYSTEM_ABILITY_BY_ID(DistributedCameraSourceService, DISTRIBUTED_HARDWARE_CAMERA_SOURCE_SA_ID, true); + +std::map> DistributedCameraSourceService::camerasMap_; + +DistributedCameraSourceService::DistributedCameraSourceService(int32_t saId, bool runOnCreate) + : SystemAbility(saId, runOnCreate) +{ +} + +void DistributedCameraSourceService::OnStart() +{ + DHLOGI("DistributedCameraSourceService::OnStart"); + if (state_ == DCameraServiceState::DCAMERA_SRV_STATE_RUNNING) { + DHLOGI("DistributedCameraSourceService has already started."); + return; + } + + if (!Init()) { + DHLOGE("DistributedCameraSourceService init failed"); + return; + } + state_ = DCameraServiceState::DCAMERA_SRV_STATE_RUNNING; + DHLOGI("DCameraServiceState OnStart service success."); +} + +bool DistributedCameraSourceService::Init() +{ + DHLOGI("DistributedCameraSourceService start init"); + DCameraSourceServiceIpc::GetInstance().Init(); + if (!registerToService_) { + bool ret = Publish(this); + if (!ret) { + DHLOGE("DistributedCameraSourceService Publish service failed"); + return false; + } + registerToService_ = true; + } + DHLOGI("DistributedCameraSourceService init success"); + return true; +} + +void DistributedCameraSourceService::OnStop() +{ + DHLOGI("DistributedCameraSourceService OnStop service"); + state_ = DCameraServiceState::DCAMERA_SRV_STATE_NOT_START; + registerToService_ = false; + DCameraSourceServiceIpc::GetInstance().UnInit(); +} + +int32_t DistributedCameraSourceService::InitSource(const std::string& params, + const sptr& callback) +{ + DHLOGI("DistributedCameraSourceService InitSource param: %s", params.c_str()); + int32_t ret = LoadDCameraHDF(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService InitSource LoadHDF failed, ret: %d", ret); + return ret; + } + sourceVer_ = params; + callbackProxy_ = callback; + return DCAMERA_OK; +} + +int32_t DistributedCameraSourceService::ReleaseSource() +{ + DHLOGI("DistributedCameraSourceService ReleaseSource"); + int32_t ret = UnLoadCameraHDF(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService ReleaseSource UnLoadHDF failed, ret: %d", ret); + return ret; + } + callbackProxy_ = nullptr; + return DCAMERA_OK; +} + +int32_t DistributedCameraSourceService::RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const EnableParam& param) +{ + DHLOGI("DistributedCameraSourceService RegisterDistributedHardware devId: %s, dhId: %s, version: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), param.version.c_str()); + DCameraIndex camIndex(devId, dhId); + std::shared_ptr camDev = nullptr; + int32_t ret = DCAMERA_OK; + auto iter = camerasMap_.find(camIndex); + if (iter == camerasMap_.end()) { + DHLOGI("DistributedCameraSourceService RegisterDistributedHardware new dev devId: %s, dhId: %s, version: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), param.version.c_str()); + std::shared_ptr listener = std::make_shared(callbackProxy_); + camDev = std::make_shared(devId, dhId, listener); + if (camDev == nullptr) { + return DCAMERA_MEMORY_OPT_ERROR; + } + ret = camDev->InitDCameraSourceDev(); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService RegisterDistributedHardware failed %d InitDev devId: %s, dhId: %s", + ret, GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + camerasMap_.emplace(camIndex, camDev); + } else { + DHLOGI("DistributedCameraSourceService RegisterDistributedHardware exist devId: %s, dhId: %s, version: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), param.version.c_str()); + camDev = iter->second; + } + + ret = camDev->RegisterDistributedHardware(devId, dhId, reqId, param.version, param.attrs); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService RegisterDistributedHardware failed, ret: %d", ret); + camerasMap_.erase(camIndex); + } + DHLOGI("DistributedCameraSourceService RegisterDistributedHardware end devId: %s, dhId: %s, version: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), param.version.c_str()); + return ret; +} + +int32_t DistributedCameraSourceService::UnregisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId) +{ + DHLOGI("DistributedCameraSourceService UnregisterDistributedHardware devId: %s, dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + DCameraIndex camIndex(devId, dhId); + auto iter = camerasMap_.find(camIndex); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSourceService UnregisterDistributedHardware not found device"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr camDev = iter->second; + int32_t ret = camDev->UnRegisterDistributedHardware(devId, dhId, reqId); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService UnregisterDistributedHardware failed, ret: %d", ret); + } + return ret; +} + +int32_t DistributedCameraSourceService::DCameraNotify(const std::string& devId, const std::string& dhId, + std::string& events) +{ + DHLOGI("DistributedCameraSourceService DCameraNotify devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + DCameraIndex camIndex(devId, dhId); + auto iter = camerasMap_.find(camIndex); + if (iter == camerasMap_.end()) { + DHLOGE("DistributedCameraSourceService DCameraNotify not found device"); + return DCAMERA_NOT_FOUND; + } + + std::shared_ptr camDev = iter->second; + int32_t ret = camDev->DCameraNotify(events); + if (ret != DCAMERA_OK) { + DHLOGE("DistributedCameraSourceService DCameraNotify failed, ret: %d", ret); + } + return ret; +} + +int32_t DistributedCameraSourceService::LoadDCameraHDF() +{ + return DCAMERA_OK; +} + +int32_t DistributedCameraSourceService::UnLoadCameraHDF() +{ + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_stub.cpp b/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_stub.cpp new file mode 100644 index 00000000..dd45a32a --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcamera/distributed_camera_source_stub.cpp @@ -0,0 +1,135 @@ +/* + * 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 "distributed_camera_source_stub.h" + +#include "dcamera_source_callback_proxy.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DistributedCameraSourceStub::DistributedCameraSourceStub() +{ + memberFuncMap_[INIT_SOURCE] = &DistributedCameraSourceStub::InitSourceInner; + memberFuncMap_[RELEASE_SOURCE] = &DistributedCameraSourceStub::ReleaseSourceInner; + memberFuncMap_[REGISTER_DISTRIBUTED_HARDWARE] = &DistributedCameraSourceStub::RegisterDistributedHardwareInner; + memberFuncMap_[UNREGISTER_DISTRIBUTED_HARDWARE] = &DistributedCameraSourceStub::UnregisterDistributedHardwareInner; + memberFuncMap_[CAMERA_NOTIFY] = &DistributedCameraSourceStub::DCameraNotifyInner; +} + +DistributedCameraSourceStub::~DistributedCameraSourceStub() +{} + +int32_t DistributedCameraSourceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DistributedCameraSourceStub OnRemoteRequest code: %d", code); + std::u16string desc = DistributedCameraSourceStub::GetDescriptor(); + std::u16string remoteDesc = data.ReadInterfaceToken(); + if (desc != remoteDesc) { + DHLOGE("DistributedCameraSourceStub::OnRemoteRequest remoteDesc is invalid!"); + return ERR_INVALID_DATA; + } + auto itFunc = memberFuncMap_.find(code); + if (itFunc == memberFuncMap_.end()) { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + + auto memberFunc = itFunc->second; + return (this->*memberFunc)(data, reply); +} + +int32_t DistributedCameraSourceStub::InitSourceInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSourceStub InitSourceInner"); + int32_t ret = DCAMERA_OK; + do { + std::string params = data.ReadString(); + sptr remoteObj = data.ReadRemoteObject(); + if (remoteObj == nullptr) { + DHLOGE("DistributedCameraSourceStub initSource read object failed"); + ret = DCAMERA_BAD_VALUE; + break; + } + + sptr callbackProxy(new DCameraSourceCallbackProxy(remoteObj)); + if (callbackProxy == nullptr) { + DHLOGE("DistributedCameraSourceStub initSource get proxy failed"); + ret = DCAMERA_BAD_VALUE; + break; + } + + ret = InitSource(params, callbackProxy); + } while (0); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSourceStub::ReleaseSourceInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSourceStub ReleaseSourceInner"); + (void)data; + int32_t ret = ReleaseSource(); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSourceStub::RegisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSourceStub RegisterDistributedHardwareInner"); + int32_t ret = DCAMERA_OK; + do { + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + EnableParam params; + params.version = data.ReadString(); + params.attrs = data.ReadString(); + ret = RegisterDistributedHardware(devId, dhId, reqId, params); + DHLOGI("DistributedCameraSourceStub RegisterDistributedHardware %d", ret); + } while (0); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSourceStub::UnregisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply) +{ + DHLOGI("DistributedCameraSourceStub UnregisterDistributedHardwareInner"); + int32_t ret = DCAMERA_OK; + do { + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + ret = UnregisterDistributedHardware(devId, dhId, reqId); + } while (0); + reply.WriteInt32(ret); + return ret; +} + +int32_t DistributedCameraSourceStub::DCameraNotifyInner(MessageParcel &data, MessageParcel &reply) +{ + int32_t ret = DCAMERA_OK; + do { + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string events = data.ReadString(); + ret = DCameraNotify(devId, dhId, events); + } while (0); + reply.WriteInt32(ret); + return ret; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp new file mode 100644 index 00000000..59989035 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_dev.cpp @@ -0,0 +1,538 @@ +/* + * 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_source_dev.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "dcamera_channel_info_cmd.h" +#include "dcamera_info_cmd.h" +#include "dcamera_provider_callback_impl.h" +#include "dcamera_source_controller.h" +#include "dcamera_source_input.h" +#include "dcamera_utils_tools.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceDev::DCameraSourceDev(std::string devId, std::string dhId, + std::shared_ptr& stateLisener) : devId_(devId), dhId_(dhId), stateListener_(stateLisener) +{ + DHLOGI("DCameraSourceDev Construct devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceDev::NotifyRegisterResult; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceDev::NotifyUnregisterResult; + memberFuncMap_[DCAMERA_EVENT_OPEN] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_CLOSE] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_CONFIG_STREAMS] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_RELEASE_STREAMS] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_START_CAPTURE] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_STOP_CAPTURE] = &DCameraSourceDev::NotifyHalResult; + memberFuncMap_[DCAMERA_EVENT_UPDATE_SETTINGS] = &DCameraSourceDev::NotifyHalResult; + + eventResultMap_[DCAMERA_EVENT_OPEN] = DCAMERA_EVENT_OPEN_CHANNEL_ERROR; + eventResultMap_[DCAMERA_EVENT_CLOSE] = DCAMERA_EVENT_CLOSE_CHANNEL_ERROR; + eventResultMap_[DCAMERA_EVENT_CONFIG_STREAMS] = DCAMERA_EVENT_CONFIG_STREAMS_ERROR; + eventResultMap_[DCAMERA_EVENT_RELEASE_STREAMS] = DCAMERA_EVENT_RELEASE_STREAMS_ERROR; + eventResultMap_[DCAMERA_EVENT_START_CAPTURE] = DCAMERA_EVENT_START_CAPTURE_ERROR; + eventResultMap_[DCAMERA_EVENT_STOP_CAPTURE] = DCAMERA_EVENT_STOP_CAPTURE_ERROR; + eventResultMap_[DCAMERA_EVENT_UPDATE_SETTINGS] = DCAMERA_EVENT_UPDATE_SETTINGS_ERROR; +} + +DCameraSourceDev::~DCameraSourceDev() +{ + DHLOGI("DCameraSourceDev Delete devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); +} + +int32_t DCameraSourceDev::InitDCameraSourceDev() +{ + DHLOGI("DCameraSourceDev InitDCameraSourceDev devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + eventBus_ = std::make_shared(); + DCameraSourceEvent event(*this); + eventBus_->AddHandler(event.GetType(), *this); + auto cameraSourceDev = std::shared_ptr(shared_from_this()); + stateMachine_ = std::make_shared(cameraSourceDev); + stateMachine_->UpdateState(DCAMERA_STATE_INIT); + controller_ = std::make_shared(devId_, dhId_, stateMachine_, eventBus_); + input_ = std::make_shared(devId_, dhId_, eventBus_); + hdiCallback_ = new (std::nothrow) DCameraProviderCallbackImpl(devId_, dhId_, cameraSourceDev); + DHLOGI("DCameraSourceDev InitDCameraSourceDev end devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::RegisterDistributedHardware(const std::string& devId, const std::string& dhId, + const std::string& reqId, const std::string& ver, const std::string attrs) +{ + DHLOGI("DCameraSourceDev PostTask RegisterDistributedHardware devId %s dhId %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + version_ = ver; + DCameraIndex index(devId, dhId); + actualDevInfo_.insert(index); + + std::shared_ptr regParam = std::make_shared(devId, dhId, reqId, attrs); + DCameraSourceEvent event(*this, DCAMERA_EVENT_REGIST, regParam); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::UnRegisterDistributedHardware(const std::string devId, const std::string dhId, + const std::string reqId) +{ + DHLOGI("DCameraSourceDev PostTask UnRegisterDistributedHardware devId %s dhId %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + std::string param; + std::shared_ptr regParam = std::make_shared(devId, dhId, reqId, param); + DCameraSourceEvent event(*this, DCAMERA_EVENT_UNREGIST, regParam); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::DCameraNotify(std::string& eventStr) +{ + DHLOGI("DCameraSourceDev PostTask DCameraNotify devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraEventCmd cmd; + int32_t ret = cmd.Unmarshal(eventStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev DCameraNotify devId %s dhId %s marshal failed, ret: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), ret); + return ret; + } + + DCameraSourceEvent event(*this, DCAMERA_EVENT_NOFIFY, cmd.value_); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::OpenSession(DCameraIndex& camIndex) +{ + DHLOGI("DCameraSourceDev PostTask OpenSession devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_OPEN, camIndex); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::CloseSession(DCameraIndex& camIndex) +{ + DHLOGI("DCameraSourceDev PostTask CloseSession devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_CLOSE, camIndex); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ConfigStreams(const std::vector>& streamInfos) +{ + DHLOGI("DCameraSourceDev PostTask ConfigStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_CONFIG_STREAMS, streamInfos); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ReleaseStreams(const std::vector& streamIds) +{ + DHLOGI("DCameraSourceDev PostTask ReleaseStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_RELEASE_STREAMS, streamIds); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::StartCapture(const std::vector>& captureInfos) +{ + DHLOGI("DCameraSourceDev PostTask StartCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_START_CAPTURE, captureInfos); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::StopCapture() +{ + DHLOGI("DCameraSourceDev PostTask StopCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_STOP_CAPTURE); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::UpdateCameraSettings(const std::vector>& settings) +{ + DHLOGI("DCameraSourceDev PostTask UpdateCameraSettings devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + DCameraSourceEvent event(*this, DCAMERA_EVENT_UPDATE_SETTINGS, settings); + eventBus_->PostEvent(event); + return DCAMERA_OK; +} + +void DCameraSourceDev::OnEvent(DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceDev OnEvent devId %s dhId %s eventType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), event.GetEventType()); + int32_t ret = stateMachine_->Execute(event.GetEventType(), event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev OnEvent failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + NotifyResult(event.GetEventType(), event, ret); +} + +int32_t DCameraSourceDev::ExecuteRegister(std::shared_ptr& param) +{ + DHLOGI("DCameraSourceDev Execute Register devId: %s dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + std::vector actualDevInfo; + actualDevInfo.assign(actualDevInfo_.begin(), actualDevInfo_.end()); + int32_t ret = controller_->Init(actualDevInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute Register controller init failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + ret = input_->Init(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute Register input init failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + controller_->UnInit(); + return ret; + } + + sptr camHdiProvider = IDCameraProvider::Get(); + if (camHdiProvider == nullptr) { + DHLOGI("ExecuteRegister camHdiProvider is nullptr devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + controller_->UnInit(); + input_->UnInit(); + return DCAMERA_BAD_OPERATE; + } + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = param->devId_; + dhBase->dhId_ = param->dhId_; + DCamRetCode retHdi = camHdiProvider->EnableDCameraDevice(dhBase, param->param_, hdiCallback_); + DHLOGI("DCameraSourceDev Execute Register register hal, ret: %d, devId: %s dhId: %s", retHdi, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + if (retHdi != SUCCESS) { + controller_->UnInit(); + input_->UnInit(); + return DCAMERA_REGIST_HAL_FAILED; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteUnRegister(std::shared_ptr& param) +{ + DHLOGI("DCameraSourceDev Execute UnRegister devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = controller_->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute UnRegister controller uninit failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + + ret = input_->UnInit(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute UnRegister input uninit failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + + sptr camHdiProvider = IDCameraProvider::Get(); + if (camHdiProvider == nullptr) { + DHLOGI("ExecuteUnRegister camHdiProvider is nullptr devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + return DCAMERA_BAD_OPERATE; + } + + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = param->devId_; + dhBase->dhId_ = param->dhId_; + DCamRetCode retHdi = camHdiProvider->DisableDCameraDevice(dhBase); + DHLOGI("DCameraSourceDev Execute UnRegister unregister hal, ret: %d, devId: %s dhId: %s", retHdi, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + if (retHdi != SUCCESS) { + return DCAMERA_UNREGIST_HAL_FAILED; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteOpenCamera() +{ + DHLOGI("DCameraSourceDev Execute OpenCamera devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr openInfo = std::make_shared(); + int32_t ret = GetLocalDeviceNetworkId(openInfo->sourceDevId_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev getMyId failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + ret = controller_->OpenChannel(openInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute OpenCamera OpenChannel failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return DCAMERA_OPEN_CONFLICT; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteCloseCamera() +{ + DHLOGI("DCameraSourceDev Execute CloseCamera devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->CloseChannel(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute CloseCamera input CloseChannel failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + ret = controller_->CloseChannel(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute CloseCamera controller CloseChannel failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteConfigStreams(std::vector>& streamInfos) +{ + DHLOGI("DCameraSourceDev Execute ConfigStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->ConfigStreams(streamInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute ConfigStreams ConfigStreams failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + std::shared_ptr chanInfo = std::make_shared(); + ret = GetLocalDeviceNetworkId(chanInfo->sourceDevId_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev getMyId failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + DCameraChannelDetail continueChInfo(CONTINUE_SESSION_FLAG, CONTINUOUS_FRAME); + DCameraChannelDetail snapShotChInfo(SNAP_SHOT_SESSION_FLAG, SNAPSHOT_FRAME); + chanInfo->detail_.push_back(continueChInfo); + chanInfo->detail_.push_back(snapShotChInfo); + + ret = controller_->ChannelNeg(chanInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev ChannelNeg failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + std::vector actualDevInfo; + actualDevInfo.assign(actualDevInfo_.begin(), actualDevInfo_.end()); + ret = input_->OpenChannel(actualDevInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev ChannelNeg OpenChannel failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteReleaseStreams(std::vector& streamIds, bool& isAllRelease) +{ + DHLOGI("DCameraSourceDev Execute ReleaseStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->ReleaseStreams(streamIds, isAllRelease); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute ReleaseStreams failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteReleaseAllStreams() +{ + DHLOGI("DCameraSourceDev Execute ReleaseAllStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->ReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute ReleaseAllStreams failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteStartCapture(std::vector>& captureInfos) +{ + DHLOGI("DCameraSourceDev Execute StartCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->StartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev input StartCapture failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + std::vector> captures; + for (auto iter = captureInfos.begin(); iter != captureInfos.end(); iter++) { + std::shared_ptr capture = std::make_shared(); + capture->width_ = (*iter)->width_; + capture->height_ = (*iter)->height_; + capture->format_ = (*iter)->format_; + capture->dataspace_ = (*iter)->dataspace_; + capture->isCapture_ = (*iter)->isCapture_; + capture->encodeType_ = (*iter)->encodeType_; + capture->streamType_ = (*iter)->type_; + DHLOGI("ExecuteStartCapture devId %s dhId %s settings size: %d w: %d h: %d fmt: %d isC: %d enc: %d streamT: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), (*iter)->captureSettings_.size(), + capture->width_, capture->height_, capture->format_, capture->isCapture_ ? 1 : 0, capture->encodeType_, + capture->streamType_); + for (auto settingIter = (*iter)->captureSettings_.begin(); settingIter != (*iter)->captureSettings_.end(); + settingIter++) { + std::shared_ptr setting = std::make_shared(); + setting->type_ = (*settingIter)->type_; + setting->value_ = (*settingIter)->value_; + capture->captureSettings_.push_back(setting); + } + captures.push_back(capture); + } + + ret = controller_->StartCapture(captures); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute StartCapture StartCapture failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + return ret; +} + +int32_t DCameraSourceDev::ExecuteStopCapture() +{ + DHLOGI("DCameraSourceDev Execute StopCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute StopCapture input StopCapture failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + ret = controller_->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute StopCapture controller StopCapture failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteUpdateSettings(std::vector>& settings) +{ + DHLOGI("DCameraSourceDev Execute UpdateSettings devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = input_->UpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute UpdateSettings input UpdateSettings failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + ret = controller_->UpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute UpdateSettings controller UpdateSettings failed, ret: %d, devId: %s dhId: %s", + ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDev::ExecuteCameraEventNotify(std::shared_ptr& events) +{ + DHLOGI("DCameraSourceDev Execute CameraEventNotify devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = controller_->DCameraNotify(events); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceDev Execute CameraEventNotify DCameraNotify failed, ret: %d, devId: %s dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +void DCameraSourceDev::NotifyResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("Notify func map not find, execute %d notify, devId: %s dhId: %s", eventType, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return; + } + + auto memberFunc = itFunc->second; + (this->*memberFunc)(eventType, event, result); + return; +} + +void DCameraSourceDev::NotifyRegisterResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result) +{ + std::string data = ""; + std::shared_ptr param; + int32_t ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return; + } + + if (stateListener_ == nullptr) { + DHLOGE("DCameraSourceDev can not get listener"); + return; + } + stateListener_->OnRegisterNotify(param->devId_, param->dhId_, param->reqId_, result, data); +} + +void DCameraSourceDev::NotifyUnregisterResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result) +{ + std::string data = ""; + std::shared_ptr param; + int32_t ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return; + } + + if (stateListener_ == nullptr) { + DHLOGE("DCameraSourceDev can not get listener"); + return; + } + stateListener_->OnUnregisterNotify(param->devId_, param->dhId_, param->reqId_, result, data); +} + +void DCameraSourceDev::NotifyHalResult(DCAMERA_EVENT eventType, DCameraSourceEvent& event, int32_t result) +{ + DHLOGI("DCameraSourceDev NotifyHalResult eventType: %d, result: %d devId: %s dhId: %s", eventType, result, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + if (result == DCAMERA_OK) { + return; + } + + std::shared_ptr events = std::make_shared(); + events->eventType_ = DCAMERA_OPERATION; + auto iter = eventResultMap_.find(eventType); + if (iter == eventResultMap_.end()) { + return; + } + events->eventResult_ = iter->second; + ExecuteCameraEventNotify(events); + return; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_event.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_event.cpp new file mode 100644 index 00000000..fbcefe4c --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_event.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 "dcamera_source_event.h" + +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DCameraSourceEvent::GetDCameraIndex(DCameraIndex& index) +{ + auto indexPtr = std::get_if(&eventParam_); + if (indexPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if DCameraIndex"); + return DCAMERA_NOT_FOUND; + } + + index = *indexPtr; + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetDCameraRegistParam(std::shared_ptr& param) +{ + auto paramPtr = std::get_if>(&eventParam_); + if (paramPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if DCameraRegistParam"); + return DCAMERA_NOT_FOUND; + } + param = *paramPtr; + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetStreamInfos(std::vector>& streamInfos) +{ + auto streamInfosPtr = std::get_if>>(&eventParam_); + if (streamInfosPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if DCStreamInfo"); + return DCAMERA_NOT_FOUND; + } + streamInfos = std::move(*streamInfosPtr); + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetCaptureInfos(std::vector>& captureInfos) +{ + auto captureInfosPtr = std::get_if>>(&eventParam_); + if (captureInfosPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if DCCaptureInfo"); + return DCAMERA_NOT_FOUND; + } + captureInfos = std::move(*captureInfosPtr); + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetCameraSettings(std::vector>& settings) +{ + auto settingsPtr = std::get_if>>(&eventParam_); + if (settingsPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if DCameraSettings"); + return DCAMERA_NOT_FOUND; + } + settings = std::move(*settingsPtr); + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetStreamIds(std::vector& streamIds) +{ + auto streamIdsPtr = std::get_if>(&eventParam_); + if (streamIdsPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if streamIds"); + return DCAMERA_NOT_FOUND; + } + streamIds = std::move(*streamIdsPtr); + return DCAMERA_OK; +} + +int32_t DCameraSourceEvent::GetCameraEvent(std::shared_ptr& camEvent) +{ + auto camEventPtr = std::get_if>(&eventParam_); + if (camEventPtr == nullptr) { + DHLOGE("DCameraSourceEvent can not get_if camEventPtr"); + return DCAMERA_NOT_FOUND; + } + camEvent = *camEventPtr; + return DCAMERA_OK; +} + +DCAMERA_EVENT DCameraSourceEvent::GetEventType() +{ + return eventType_; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_service_ipc.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_service_ipc.cpp new file mode 100644 index 00000000..b49c0144 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamera_source_service_ipc.cpp @@ -0,0 +1,191 @@ +/* + * 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_source_service_ipc.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceServiceIpc::DCameraSourceServiceIpc() : isInit_(false) +{ + DHLOGI("DCameraSourceServiceIpc Create"); +} + +DCameraSourceServiceIpc::~DCameraSourceServiceIpc() +{ + DHLOGI("DCameraSourceServiceIpc Delete"); + UnInit(); +} + +IMPLEMENT_SINGLE_INSTANCE(DCameraSourceServiceIpc); + +void DCameraSourceServiceIpc::Init() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSourceServiceIpc Init Start"); + if (isInit_) { + DHLOGI("DCameraSourceServiceIpc has already init"); + return; + } + auto runner = AppExecFwk::EventRunner::Create("DCameraSourceServiceIpcHandler"); + serviceHandler_ = std::make_shared(runner); + sinkRemoteRecipient_ = new SinkRemoteRecipient(); + isInit_ = true; + DHLOGI("DCameraSourceServiceIpc Init End"); +} + +void DCameraSourceServiceIpc::UnInit() +{ + std::lock_guard autoLock(initDmsLock_); + DHLOGI("DCameraSourceServiceIpc UnInit Start"); + if (!isInit_) { + DHLOGI("DCameraSourceServiceIpc has already UnInit"); + return; + } + ClearSinkRemoteDhms(); + DHLOGI("DCameraSourceServiceIpc UnInit Start free servicehandle"); + serviceHandler_ = nullptr; + DHLOGI("DCameraSourceServiceIpc UnInit Start free recipient"); + sinkRemoteRecipient_ = nullptr; + isInit_ = false; + DHLOGI("DCameraSourceServiceIpc UnInit End"); +} + +sptr DCameraSourceServiceIpc::GetSinkRemoteDHMS(const std::string& deviceId) +{ + if (deviceId.empty()) { + DHLOGE("GetSinkRemoteDHMS deviceId is empty"); + return nullptr; + } + { + std::lock_guard autoLock(sinkRemoteDmsLock_); + auto iter = remoteSinks_.find(deviceId); + if (iter != remoteSinks_.end()) { + auto object = iter->second; + if (object != nullptr) { + DHLOGI("DCameraSourceServiceIpc GetSinkRemoteDHMS from cache devId: %s", + GetAnonyString(deviceId).c_str()); + return object; + } + } + } + DHLOGI("GetSinkRemoteDHMS remote deviceid is %s", GetAnonyString(deviceId).c_str()); + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + DHLOGE("GetSinkRemoteDHMS failed to connect to systemAbilityMgr!"); + return nullptr; + } + + auto object = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID, deviceId); + if (object == nullptr) { + DHLOGE("GetSinkRemoteDHMS failed get remote DHMS %s", GetAnonyString(deviceId).c_str()); + return nullptr; + } + int32_t ret = object->AddDeathRecipient(sinkRemoteRecipient_); + sptr remoteDmsObj = iface_cast(object); + if (remoteDmsObj == nullptr) { + DHLOGI("GetSinkRemoteDHMS failed, remoteDmsObj is null ret: %d", ret); + return nullptr; + } + { + std::lock_guard autoLock(sinkRemoteDmsLock_); + auto iter = remoteSinks_.find(deviceId); + if (iter != remoteSinks_.end()) { + iter->second->AsObject()->RemoveDeathRecipient(sinkRemoteRecipient_); + } + remoteSinks_[deviceId] = remoteDmsObj; + } + DHLOGI("GetSinkRemoteDHMS success, AddDeathRecipient ret: %d", ret); + return remoteDmsObj; +} + +void DCameraSourceServiceIpc::DeleteSinkRemoteDhms(const std::string& deviceId) +{ + DHLOGI("DeleteSinkRemoteDhms devId: %s", GetAnonyString(deviceId).c_str()); + std::lock_guard autoLock(sinkRemoteDmsLock_); + auto item = remoteSinks_.find(deviceId); + if (item == remoteSinks_.end()) { + DHLOGI("DeleteSinkRemoteDhms not found device: %s", GetAnonyString(deviceId).c_str()); + return; + } + + if (item->second != nullptr) { + item->second->AsObject()->RemoveDeathRecipient(sinkRemoteRecipient_); + } + remoteSinks_.erase(item); +} + +void DCameraSourceServiceIpc::ClearSinkRemoteDhms() +{ + DHLOGI("ClearSinkRemoteDhms Start"); + std::lock_guard autoLock(sinkRemoteDmsLock_); + for (auto iter = remoteSinks_.begin(); iter != remoteSinks_.end(); iter++) { + if (iter->second != nullptr) { + iter->second->AsObject()->RemoveDeathRecipient(sinkRemoteRecipient_); + } + } + remoteSinks_.clear(); + DHLOGI("ClearSinkRemoteDhms end"); +} + +void DCameraSourceServiceIpc::SinkRemoteRecipient::OnRemoteDied(const wptr& remote) +{ + DHLOGI("SinkRemoteRecipient OnRemoteDied received died notify!"); + DCameraSourceServiceIpc::GetInstance().OnSinkRemoteDmsDied(remote); +} + +void DCameraSourceServiceIpc::OnSinkRemoteDmsDied(const wptr& remote) +{ + sptr diedRemoted = remote.promote(); + if (diedRemoted == nullptr) { + DHLOGE("OnSinkRemoteDmsDied promote failed!"); + return; + } + DHLOGI("OnSinkRemoteDmsDied delete diedRemoted"); + auto remoteDmsDiedFunc = [this, diedRemoted]() { + OnSinkRemoteDmsDied(diedRemoted); + }; + if (serviceHandler_ != nullptr) { + serviceHandler_->PostTask(remoteDmsDiedFunc); + } +} + +void DCameraSourceServiceIpc::OnSinkRemoteDmsDied(const sptr& remote) +{ + std::lock_guard autoLock(sinkRemoteDmsLock_); + auto iter = std::find_if(remoteSinks_.begin(), remoteSinks_.end(), [&]( + const std::pair> &item)->bool { + return item.second->AsObject() == remote; + }); + if (iter == remoteSinks_.end()) { + DHLOGI("OnSinkRemoteDmsDied not found remote object"); + return; + } + + DHLOGI("OnSinkRemoteDmsDied remote.devId: %s", GetAnonyString(iter->first).c_str()); + if (iter->second != nullptr) { + iter->second->AsObject()->RemoveDeathRecipient(sinkRemoteRecipient_); + } + remoteSinks_.erase(iter); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp new file mode 100644 index 00000000..f993f583 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller.cpp @@ -0,0 +1,472 @@ +/* + * 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_source_controller.h" + +#include +#include "json/json.h" + +#include "dcamera_capture_info_cmd.h" +#include "dcamera_channel_source_impl.h" +#include "dcamera_metadata_setting_cmd.h" +#include "dcamera_protocol.h" +#include "dcamera_source_controller_channel_listener.h" +#include "dcamera_source_service_ipc.h" +#include "dcamera_utils_tools.h" + +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" +#include "idistributed_camera_sink.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceController::DCameraSourceController(std::string devId, std::string dhId, + std::shared_ptr& stateMachine, std::shared_ptr& eventBus) + : devId_(devId), dhId_(dhId), stateMachine_(stateMachine), eventBus_(eventBus), + channelState_(DCAMERA_CHANNEL_STATE_DISCONNECTED) +{ + DHLOGI("DCameraSourceController create devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + isInit = false; +} + +DCameraSourceController::~DCameraSourceController() +{ + DHLOGI("DCameraSourceController delete devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (isInit) { + UnInit(); + } +} + +int32_t DCameraSourceController::StartCapture(std::vector>& captureInfos) +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController StartCapture not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController StartCapture devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + DCameraCaptureInfoCmd cmd; + cmd.type_ = DCAMERA_PROTOCOL_TYPE_OPERATION; + cmd.dhId_ = dhId; + cmd.command_ = DCAMERA_PROTOCOL_CMD_CAPTURE; + cmd.value_.assign(captureInfos.begin(), captureInfos.end()); + std::string jsonStr; + int32_t ret = cmd.Marshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController StartCapture Marshal faied %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DHLOGI("DCameraSourceController StartCapture devId: %s, dhId: %s captureJson: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str(), jsonStr.c_str()); + std::shared_ptr buffer = std::make_shared(jsonStr.length() + 1); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), (uint8_t *)jsonStr.c_str(), jsonStr.length()); + if (ret != EOK) { + DHLOGE("DCameraSourceController StartCapture memcpy_s failed %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + ret = channel_->SendData(buffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController StartCapture SendData failed %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DHLOGI("DCameraSourceController StartCapture devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceController::StopCapture() +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController StopCapture not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController StopCapture devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteDHMS(devId); + if (camSinkSrv == nullptr) { + DHLOGE("DCameraSourceController StopCapture can not get service, devId: %s", GetAnonyString(devId).c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = camSinkSrv->StopCapture(dhId); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController StopCapture failed: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return DCAMERA_BAD_OPERATE; + } + DHLOGI("DCameraSourceController StopCapture devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceController::ChannelNeg(std::shared_ptr& info) +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController ChannelNeg not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController ChannelNeg devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteDHMS(devId); + if (camSinkSrv == nullptr) { + DHLOGE("DCameraSourceController ChannelNeg can not get service, devId: %s", GetAnonyString(devId).c_str()); + return DCAMERA_BAD_OPERATE; + } + DCameraChannelInfoCmd cmd; + cmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE; + cmd.dhId_ = dhId; + cmd.command_ = DCAMERA_PROTOCOL_CMD_CHAN_NEG; + cmd.value_ = info; + std::string jsonStr; + int32_t ret = cmd.Marshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController ChannelNeg Marshal failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DHLOGD("DCameraSourceController ChannelNeg devId: %s, dhId: %s channelNegJson: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str(), jsonStr.c_str()); + ret = camSinkSrv->ChannelNeg(dhId, jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController ChannelNeg rpc failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DHLOGD("DCameraSourceController ChannelNeg devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceController::DCameraNotify(std::shared_ptr& events) +{ + sptr camHdiProvider = IDCameraProvider::Get(); + if (camHdiProvider == nullptr) { + DHLOGI("DCameraNotify camHdiProvider is nullptr devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + return DCAMERA_BAD_OPERATE; + } + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = devId_; + dhBase->dhId_ = dhId_; + std::shared_ptr hdiEvent = std::make_shared(); + hdiEvent->type_ = events->eventType_; + hdiEvent->result_ = events->eventResult_; + hdiEvent->content_ = events->eventContent_; + DCamRetCode retHdi = camHdiProvider->Notify(dhBase, hdiEvent); + DHLOGI("Nofify hal, ret: %d, devId: %s dhId: %s, type: %d, result: %d, content: %s", retHdi, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), events->eventType_, events->eventResult_, + events->eventContent_.c_str()); + if (retHdi != SUCCESS) { + return DCAMERA_BAD_OPERATE; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceController::UpdateSettings(std::vector>& settings) +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController UpdateSettings not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController UpdateSettings devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + DCameraMetadataSettingCmd cmd; + cmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE; + cmd.dhId_ = dhId; + cmd.command_ = DCAMERA_PROTOCOL_CMD_UPDATE_METADATA; + cmd.value_.assign(settings.begin(), settings.end()); + std::string jsonStr; + int32_t ret = cmd.Marshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController UpdateSettings Marshal faied %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + std::shared_ptr buffer = std::make_shared(jsonStr.length() + 1); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), (uint8_t *)jsonStr.c_str(), jsonStr.length()); + if (ret != EOK) { + DHLOGE("DCameraSourceController UpdateSettings memcpy_s failed %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + ret = channel_->SendData(buffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController UpdateSettings SendData failed %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DHLOGI("DCameraSourceController UpdateSettings devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceController::GetCameraInfo(std::shared_ptr& camInfo) +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController GetCameraInfo not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController GetCameraInfo devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteDHMS(devId); + if (camSinkSrv == nullptr) { + DHLOGE("DCameraSourceController GetCameraInfo can not get service, devId: %s", GetAnonyString(devId).c_str()); + return DCAMERA_BAD_OPERATE; + } + std::string camInfoJson; + int32_t ret = camSinkSrv->GetCameraInfo(dhId, camInfoJson); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController GetCameraInfo GetCameraInfo failed: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ret; + } + DCameraInfoCmd cmd; + ret = cmd.Unmarshal(camInfoJson); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController GetCameraInfo DCameraInfoCmd Unmarshal failed: %d", ret); + return ret; + } + camInfo = cmd.value_; + return DCAMERA_OK; +} + +int32_t DCameraSourceController::OpenChannel(std::shared_ptr& openInfo) +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController OpenChannel not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController OpenChannel devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteDHMS(devId); + if (camSinkSrv == nullptr) { + DHLOGE("DCameraSourceController can not get service, devId: %s", GetAnonyString(devId).c_str()); + return DCAMERA_BAD_OPERATE; + } + + DCameraOpenInfoCmd cmd; + cmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE; + cmd.dhId_ = dhId; + cmd.command_ = DCAMERA_PROTOCOL_CMD_OPEN_CHANNEL; + cmd.value_ = openInfo; + std::string jsonStr; + int32_t ret = cmd.Marshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController Marshal OpenInfo failed %d", ret); + return ret; + } + DHLOGD("DCameraSourceController OpenChannel devId: %s, dhId: %s openJson: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str(), jsonStr.c_str()); + ret = camSinkSrv->OpenChannel(dhId, jsonStr); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController SA OpenChannel failed %d", ret); + return ret; + } + DHLOGD("DCameraSourceController OpenChannel devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str(), jsonStr.c_str()); + + std::vector indexs; + indexs.push_back(DCameraIndex(devId, dhId)); + ret = channel_->CreateSession(indexs, SESSION_FLAG, DCAMERA_SESSION_MODE_CTRL, listener_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController CreateSession failed %d", ret); + return ret; + } + ret = channel_->OpenSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController OpenChannel OpenChannel failed %d", ret); + return ret; + } + + return DCAMERA_OK; +} + +int32_t DCameraSourceController::CloseChannel() +{ + if (indexs_.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController CloseChannel not support operate %d camera", indexs_.size()); + return DCAMERA_BAD_OPERATE; + } + + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + DHLOGI("DCameraSourceController CloseChannel devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + int32_t ret = channel_->CloseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController CloseChannel CloseSession failed %d", ret); + } + DHLOGI("DCameraSourceController CloseChannel devId: %s, dhId: %s success", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + channelState_ = DCAMERA_CHANNEL_STATE_DISCONNECTED; + ret = channel_->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController CloseChannel ReleaseSession failed %d", ret); + } + sptr camSinkSrv = DCameraSourceServiceIpc::GetInstance().GetSinkRemoteDHMS(devId); + if (camSinkSrv != nullptr) { + ret = camSinkSrv->CloseChannel(dhId); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceController SA CloseChannel failed %d", ret); + } + DCameraSourceServiceIpc::GetInstance().DeleteSinkRemoteDhms(devId); + } + return ret; +} + +int32_t DCameraSourceController::Init(std::vector& indexs) +{ + DHLOGI("DCameraSourceController Init"); + if (indexs.size() > DCAMERA_MAX_NUM) { + DHLOGE("DCameraSourceController init error"); + return DCAMERA_INIT_ERR; + } + indexs_.assign(indexs.begin(), indexs.end()); + std::string dhId = indexs_.begin()->dhId_; + std::string devId = indexs_.begin()->devId_; + auto controller = std::shared_ptr(shared_from_this()); + listener_ = std::make_shared(controller); + channel_ = std::make_shared(); + DHLOGI("DCameraSourceController Init GetProvider end devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + isInit = true; + return DCAMERA_OK; +} + +int32_t DCameraSourceController::UnInit() +{ + DHLOGI("DCameraSourceController UnInit"); + indexs_.clear(); + isInit = false; + return DCAMERA_OK; +} + +void DCameraSourceController::OnSessionState(int32_t state) +{ + DHLOGI("DCameraSourceController OnSessionState state %d", state); + channelState_ = state; + switch (state) { + case DCAMERA_CHANNEL_STATE_CONNECTED: { + stateMachine_->UpdateState(DCAMERA_STATE_OPENED); + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_CONNECTED; + DCameraSourceEvent event(*this, DCAMERA_EVENT_NOFIFY, camEvent); + eventBus_->PostEvent(event); + break; + } + case DCAMERA_CHANNEL_STATE_DISCONNECTED: { + DHLOGI("DCameraSourceDev PostTask Controller CloseSession OnClose devId %s dhId %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + DCameraIndex camIndex(devId_, dhId_); + DCameraSourceEvent event(*this, DCAMERA_EVENT_CLOSE, camIndex); + eventBus_->PostEvent(event); + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_DISCONNECTED; + DCameraSourceEvent eventNotify(*this, DCAMERA_EVENT_NOFIFY, camEvent); + eventBus_->PostEvent(eventNotify); + break; + } + default: { + break; + } + } +} + +void DCameraSourceController::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + DHLOGI("DCameraSourceController OnSessionError devId: %s, dhId: %s, eventType: %d, eventReason: %d, detail %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), eventType, eventReason, detail.c_str()); + return; +} + +void DCameraSourceController::OnDataReceived(std::vector>& buffers) +{ + if (buffers.empty()) { + DHLOGI("DCameraSourceController OnDataReceived empty, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + return; + } + std::shared_ptr buffer = *(buffers.begin()); + std::string jsonStr((char *)buffer->Data()); + JSONCPP_STRING errs; + Json::CharReaderBuilder readerBuilder; + Json::Value rootValue; + + std::unique_ptr const jsonReader(readerBuilder.newCharReader()); + if (!jsonReader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.length(), &rootValue, &errs) || + !rootValue.isObject()) { + return; + } + + if (!rootValue.isMember("Command") || !rootValue["Command"].isString()) { + return; + } + std::string command = rootValue["Command"].asString(); + if (command == DCAMERA_PROTOCOL_CMD_METADATA_RESULT) { + HandleMetaDataResult(jsonStr); + } + return; +} + +void DCameraSourceController::HandleMetaDataResult(std::string& jsonStr) +{ + sptr camHdiProvider = IDCameraProvider::Get(); + if (camHdiProvider == nullptr) { + DHLOGI("DCameraSourceController HandleMetaDataResult camHdiProvider is null, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return; + } + DCameraMetadataSettingCmd cmd; + int32_t ret = cmd.Unmarshal(jsonStr); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSourceController HandleMetaDataResult failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return; + } + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = devId_; + dhBase->dhId_ = dhId_; + for (auto iter = cmd.value_.begin(); iter != cmd.value_.end(); iter++) { + DCamRetCode retHdi = camHdiProvider->OnSettingsResult(dhBase, (*iter)); + DHLOGI("OnSettingsResult hal, ret: %d, devId: %s dhId: %s, type: %d, result: %d, content: %s", retHdi, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.cpp new file mode 100644 index 00000000..e0792381 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameracontrol/dcamera_source_controller_channel_listener.cpp @@ -0,0 +1,67 @@ +/* + * 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_source_controller_channel_listener.h" + +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "dcamera_source_controller.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceControllerChannelListener::DCameraSourceControllerChannelListener( + std::shared_ptr& controller) : controller_(controller) +{ +} + +DCameraSourceControllerChannelListener::~DCameraSourceControllerChannelListener() +{ +} + +void DCameraSourceControllerChannelListener::OnSessionState(int32_t state) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSourceController OnSessionState not found controller"); + return; + } + + controller->OnSessionState(state); +} + +void DCameraSourceControllerChannelListener::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSourceController OnSessionError not found controller"); + return; + } + + controller->OnSessionError(eventType, eventReason, detail); +} + +void DCameraSourceControllerChannelListener::OnDataReceived(std::vector>& buffers) +{ + std::shared_ptr controller = controller_.lock(); + if (controller == nullptr) { + DHLOGE("DCameraSourceController OnDataReceived not found controller"); + return; + } + + controller->OnDataReceived(buffers); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_data_process.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_data_process.cpp new file mode 100644 index 00000000..c383f37d --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_data_process.cpp @@ -0,0 +1,165 @@ +/* + * 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_source_data_process.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceDataProcess::DCameraSourceDataProcess(std::string devId, std::string dhId, DCStreamType streamType) + : devId_(devId), dhId_(dhId), streamType_(streamType) +{ + DHLOGI("DCameraSourceDataProcess Constructor devId %s dhId %s streamType %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamType_); +} + +DCameraSourceDataProcess::~DCameraSourceDataProcess() +{ + DHLOGI("DCameraSourceDataProcess Destructor devId %s dhId %s streamType %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamType_); + streamProcess_.clear(); + streamIds_.clear(); +} + +int32_t DCameraSourceDataProcess::FeedStream(std::vector>& buffers) +{ + if (buffers.size() > DCAMERA_MAX_NUM) { + DHLOGI("DCameraSourceDataProcess FeedStream devId %s dhId %s size: %d over flow", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), buffers.size()); + return DCAMERA_BAD_VALUE; + } + + auto buffer = *(buffers.begin()); + DHLOGD("DCameraSourceDataProcess FeedStream devId %s dhId %s streamType %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + for (auto iter = streamProcess_.begin(); iter != streamProcess_.end(); iter++) { + (*iter)->FeedStream(buffer); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDataProcess::ConfigStreams(std::vector>& streamInfos) +{ + DHLOGI("DCameraSourceDataProcess ConfigStreams devId %s dhId %s streamType %d size %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamInfos.size()); + if (streamInfos.empty()) { + DHLOGI("DCameraSourceDataProcess ConfigStreams is empty"); + return DCAMERA_OK; + } + std::map> streamConfigs; + for (auto iter = streamInfos.begin(); iter != streamInfos.end(); iter++) { + std::shared_ptr streamInfo = *iter; + DCameraStreamConfig streamConfig(streamInfo->width_, streamInfo->height_, streamInfo->format_, + streamInfo->dataspace_, streamInfo->encodeType_, streamInfo->type_); + DHLOGI("DCameraSourceDataProcess ConfigStreams devId %s dhId %s, streamId: %d info: width: %d, height: %d," + + "format: %d, dataspace: %d, encodeType: %d streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamInfo->streamId_, streamConfig.width_, streamConfig.height_, + streamConfig.format_, streamConfig.dataspace_, streamConfig.encodeType_, streamConfig.type_); + if (streamConfigs.find(streamConfig) == streamConfigs.end()) { + std::set streamIdSet; + streamConfigs.emplace(streamConfig, streamIdSet); + } + streamConfigs[streamConfig].insert(streamInfo->streamId_); + streamIds_.insert(streamInfo->streamId_); + } + + for (auto iter = streamConfigs.begin(); iter != streamConfigs.end(); iter++) { + DHLOGI("DCameraSourceDataProcess ConfigStreams devId %s dhId %s, info: width: %d, height: %d, format: %d," + + "dataspace: %d, encodeType: %d streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), iter->first.width_, iter->first.height_, iter->first.format_, + iter->first.dataspace_, iter->first.encodeType_, iter->first.type_); + + std::shared_ptr streamProcess = + std::make_shared(devId_, dhId_, streamType_); + std::shared_ptr streamConfig = + std::make_shared(iter->first.width_, iter->first.height_, iter->first.format_, + iter->first.dataspace_, iter->first.encodeType_, iter->first.type_); + streamProcess->ConfigStreams(streamConfig, iter->second); + + streamProcess_.push_back(streamProcess); + } + + return DCAMERA_OK; +} + +int32_t DCameraSourceDataProcess::ReleaseStreams(std::vector& streamIds) +{ + DHLOGI("DCameraSourceDataProcess ReleaseStreams devId %s dhId %s streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamType_); + std::set streamIdSet(streamIds.begin(), streamIds.end()); + auto iter = streamProcess_.begin(); + while (iter != streamProcess_.end()) { + (*iter)->ReleaseStreams(streamIdSet); + std::set processStreamIds; + (*iter)->GetAllStreamIds(processStreamIds); + if (processStreamIds.empty()) { + iter = streamProcess_.erase(iter); + } else { + iter++; + } + } + + std::string strStreams; + for (auto iterSet = streamIdSet.begin(); iterSet != streamIdSet.end(); iterSet++) { + strStreams += (std::to_string(*iterSet) + std::string(" ")); + streamIds_.erase(*iterSet); + } + DHLOGI("DCameraSourceDataProcess ReleaseStreams devId %s dhId %s streamType: %d streamProcessSize: %d streams: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamProcess_.size(), + strStreams.c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceDataProcess::StartCapture(std::shared_ptr& captureInfo) +{ + DHLOGI("DCameraSourceDataProcess StartCapture devId %s dhId %s, info: width: %d, height: %d, format: %d,\ + dataspace: %d, encodeType: %d streamType: %d", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), + captureInfo->width_, captureInfo->height_, captureInfo->format_, captureInfo->dataspace_, + captureInfo->encodeType_, captureInfo->type_); + + std::shared_ptr streamConfig = + std::make_shared(captureInfo->width_, captureInfo->height_, captureInfo->format_, + captureInfo->dataspace_, captureInfo->encodeType_, captureInfo->type_); + std::set streamIds(captureInfo->streamIds_.begin(), captureInfo->streamIds_.end()); + for (auto iterSet = streamIds.begin(); iterSet != streamIds.end(); iterSet++) { + DHLOGI("DCameraSourceDataProcess StartCapture devId %s dhId %s StartCapture id: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), *iterSet); + } + for (auto iter = streamProcess_.begin(); iter != streamProcess_.end(); iter++) { + (*iter)->StartCapture(streamConfig, streamIds); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceDataProcess::StopCapture() +{ + DHLOGI("DCameraSourceDataProcess StopCapture devId %s dhId %s streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamType_); + for (auto iter = streamProcess_.begin(); iter != streamProcess_.end(); iter++) { + (*iter)->StopCapture(); + } + return DCAMERA_OK; +} + +void DCameraSourceDataProcess::GetAllStreamIds(std::vector& streamIds) +{ + streamIds.assign(streamIds_.begin(), streamIds_.end()); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp new file mode 100644 index 00000000..93d97013 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input.cpp @@ -0,0 +1,377 @@ +/* + * 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_source_input.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "dcamera_channel_source_impl.h" +#include "dcamera_source_data_process.h" +#include "dcamera_source_event.h" +#include "dcamera_source_input_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceInput::DCameraSourceInput(std::string devId, std::string dhId, std::shared_ptr& eventBus) + : devId_(devId), dhId_(dhId), eventBus_(eventBus), isInit(false), isCapture_(false) +{ + DHLOGI("DCameraSourceInput Constructor devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); +} + +DCameraSourceInput::~DCameraSourceInput() +{ + DHLOGI("DCameraSourceInput Destructor devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (isInit) { + UnInit(); + } +} + +int32_t DCameraSourceInput::ConfigStreams(std::vector>& streamInfos) +{ + DHLOGI("DCameraSourceInput ConfigStreams devId %s dhId %s, size: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamInfos.size()); + int32_t ret = ReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ConfigStreams ReleaseAllStreams failed %d devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + if (streamInfos.empty()) { + return DCAMERA_OK; + } + + std::vector> snapStreams; + std::vector> continueStreams; + for (auto iter = streamInfos.begin(); iter != streamInfos.end(); iter++) { + std::shared_ptr streamInfo = *iter; + DHLOGI("DCameraSourceInput ConfigStreams devId: %s, dhId: %s, streamId: %d, width: %d, height: %d," + + "format: %d, dataspace: %d, encodeType:%d streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamInfo->streamId_, streamInfo->width_, streamInfo->height_, + streamInfo->format_, streamInfo->dataspace_, streamInfo->encodeType_, streamInfo->type_); + switch (streamInfo->type_) { + case CONTINUOUS_FRAME: { + continueStreams.push_back(streamInfo); + break; + } + case SNAPSHOT_FRAME: { + snapStreams.push_back(streamInfo); + break; + } + default: + break; + } + } + + do { + ret = dataProcess_[CONTINUOUS_FRAME]->ConfigStreams(continueStreams); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ConfigStreams continue failed %d devId %s dhId %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + break; + } + ret = dataProcess_[SNAPSHOT_FRAME]->ConfigStreams(snapStreams); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ConfigStreams snapshot failed %d devId %s dhId %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + break; + } + } while (0); + + if (ret != DCAMERA_OK) { + ReleaseAllStreams(); + } + return ret; +} + +int32_t DCameraSourceInput::ReleaseStreams(std::vector& streamIds, bool& isAllRelease) +{ + DHLOGI("DCameraSourceInput ReleaseStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = dataProcess_[CONTINUOUS_FRAME]->ReleaseStreams(streamIds); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ReleaseStreams continue stream ReleaseStreams ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + ret = dataProcess_[SNAPSHOT_FRAME]->ReleaseStreams(streamIds); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ReleaseStreams snapshot stream ReleaseStreams ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + std::vector continueStreamIds; + dataProcess_[CONTINUOUS_FRAME]->GetAllStreamIds(continueStreamIds); + std::vector snapStreamIds; + dataProcess_[CONTINUOUS_FRAME]->GetAllStreamIds(snapStreamIds); + if (continueStreamIds.empty() && snapStreamIds.empty()) { + isAllRelease = true; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::StartCapture(std::vector>& captureInfos) +{ + DHLOGI("DCameraSourceInput StartCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + int32_t ret = DCAMERA_OK; + for (auto iter = captureInfos.begin(); iter != captureInfos.end(); iter++) { + for (auto iterSet = (*iter)->streamIds_.begin(); iterSet != (*iter)->streamIds_.end(); iterSet++) { + DHLOGI("DCameraSourceInput StartCapture devId %s dhId %s StartCapture id: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), *iterSet); + } + DHLOGI("DCameraSourceInput StartCapture Inner devId %s dhId %s streamType: %d idSize: %d isCap: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), (*iter)->type_, (*iter)->streamIds_.size(), + (*iter)->isCapture_ ? 1 : 0); + ret = dataProcess_[(*iter)->type_]->StartCapture(*iter); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput StartCapture ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + } + std::lock_guard autoLock(inputMutex_); + isCapture_ = true; + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::StopCapture() +{ + DHLOGI("DCameraSourceInput StopCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::lock_guard autoLock(inputMutex_); + isCapture_ = false; + int32_t ret = dataProcess_[CONTINUOUS_FRAME]->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput StopCapture continue ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + ret = dataProcess_[SNAPSHOT_FRAME]->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput StopCapture snapshot ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::OpenChannel(std::vector& indexs) +{ + DHLOGI("DCameraSourceInput OpenChannel devId %s dhId %s continue state: %d, snapshot state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), channelState_[CONTINUOUS_FRAME], + channelState_[SNAPSHOT_FRAME]); + int32_t ret = DCAMERA_OK; + if (channelState_[CONTINUOUS_FRAME] == DCAMERA_CHANNEL_STATE_DISCONNECTED) { + ret = channels_[CONTINUOUS_FRAME]->CreateSession(indexs, CONTINUE_SESSION_FLAG, DCAMERA_SESSION_MODE_VIDEO, + listeners_[CONTINUOUS_FRAME]); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput CreateSession continue failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + ret = channels_[CONTINUOUS_FRAME]->OpenSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput OpenChannel continue stream failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + } + + if (channelState_[SNAPSHOT_FRAME] == DCAMERA_CHANNEL_STATE_DISCONNECTED) { + ret = channels_[SNAPSHOT_FRAME]->CreateSession(indexs, SNAP_SHOT_SESSION_FLAG, DCAMERA_SESSION_MODE_JPEG, + listeners_[SNAPSHOT_FRAME]); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput Init CreateSession snapshot failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + ret = channels_[SNAPSHOT_FRAME]->OpenSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput OpenChannel snapshot stream failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + } + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::CloseChannel() +{ + DHLOGI("DCameraSourceInput CloseChannel devId %s dhId %s continue state: %d, snapshot state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), channelState_[CONTINUOUS_FRAME], + channelState_[SNAPSHOT_FRAME]); + int32_t ret = DCAMERA_OK; + if (channelState_[CONTINUOUS_FRAME] != DCAMERA_CHANNEL_STATE_DISCONNECTED) { + ret = channels_[CONTINUOUS_FRAME]->CloseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput CloseChannel continue stream failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + channelState_[CONTINUOUS_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED; + + ret = channels_[CONTINUOUS_FRAME]->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSourceInput release continue session failed: %d devId %s dhId %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + } + + if (channelState_[SNAPSHOT_FRAME] != DCAMERA_CHANNEL_STATE_DISCONNECTED) { + ret = channels_[SNAPSHOT_FRAME]->CloseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput CloseChannel snapshot stream failed ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + channelState_[SNAPSHOT_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED; + + ret = channels_[SNAPSHOT_FRAME]->ReleaseSession(); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSourceInput release snapshot session failed: %d devId %s dhId %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } + } + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::Init() +{ + DHLOGI("DCameraSourceInput Init devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + auto input = std::shared_ptr(shared_from_this()); + std::shared_ptr conDataProcess = std::make_shared(devId_, dhId_, + CONTINUOUS_FRAME); + std::shared_ptr continueCh = std::make_shared(); + std::shared_ptr conListener = + std::make_shared(input, CONTINUOUS_FRAME); + channels_.emplace(CONTINUOUS_FRAME, continueCh); + listeners_.emplace(CONTINUOUS_FRAME, conListener); + dataProcess_.emplace(CONTINUOUS_FRAME, conDataProcess); + channelState_.emplace(CONTINUOUS_FRAME, DCAMERA_CHANNEL_STATE_DISCONNECTED); + + std::shared_ptr snapDataProcess = std::make_shared(devId_, + dhId_, SNAPSHOT_FRAME); + std::shared_ptr snapShotCh = std::make_shared(); + std::shared_ptr snapListener = + std::make_shared(input, SNAPSHOT_FRAME); + channels_.emplace(SNAPSHOT_FRAME, snapShotCh); + listeners_.emplace(SNAPSHOT_FRAME, snapListener); + dataProcess_.emplace(SNAPSHOT_FRAME, snapDataProcess); + channelState_.emplace(SNAPSHOT_FRAME, DCAMERA_CHANNEL_STATE_DISCONNECTED); + isInit = true; + DHLOGI("DCameraSourceInput Init devId end %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::UnInit() +{ + DHLOGI("DCameraSourceInput UnInit devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + channels_.clear(); + listeners_.clear(); + dataProcess_.clear(); + channelState_.clear(); + isInit = false; + return DCAMERA_OK; +} + +int32_t DCameraSourceInput::UpdateSettings(std::vector>& settings) +{ + return DCAMERA_OK; +} + +void DCameraSourceInput::OnSessionState(DCStreamType streamType, int32_t state) +{ + DHLOGI("DCameraSourceInput OnSessionState devId: %s, dhId: %s, streamType: %d, state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType, state); + channelState_[streamType] = (DCameraChannelState)state; + switch (state) { + case DCAMERA_CHANNEL_STATE_DISCONNECTED: { + DHLOGI("DCameraSourceDev PostTask CloseSession Input OnClose devId %s dhId %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + DCameraIndex camIndex(devId_, dhId_); + DCameraSourceEvent event(*this, DCAMERA_EVENT_CLOSE, camIndex); + eventBus_->PostEvent(event); + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_DISCONNECTED; + DCameraSourceEvent srcEvent(*this, DCAMERA_EVENT_NOFIFY, camEvent); + eventBus_->PostEvent(srcEvent); + break; + } + default: { + DHLOGI("DCameraSourceInput OnSessionState state %d", state); + break; + } + } +} + +void DCameraSourceInput::OnSessionError(DCStreamType streamType, int32_t eventType, int32_t eventReason, + std::string detail) +{ + DHLOGI("DCameraSourceInput OnSessionError devId: %s, dhId: %s, eventType: %d, eventReason: %d, detail %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), eventType, eventReason, detail.c_str()); +} + +void DCameraSourceInput::OnDataReceived(DCStreamType streamType, std::vector>& buffers) +{ + std::lock_guard autoLock(inputMutex_); + if (!isCapture_) { + DHLOGE("DCameraSourceInput OnDataReceived FeedStream %d stream capture stop, devId: %s, dhId: %s", streamType, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return; + } + int32_t ret = dataProcess_[streamType]->FeedStream(buffers); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput OnDataReceived FeedStream %d stream failed ret: %d, devId: %s, dhId: %s", streamType, + ret, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + } +} + +int32_t DCameraSourceInput::ReleaseAllStreams() +{ + DHLOGI("DCameraSourceInput ReleaseAllStreams devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::vector continueStreamIds; + dataProcess_[CONTINUOUS_FRAME]->GetAllStreamIds(continueStreamIds); + int32_t ret = dataProcess_[CONTINUOUS_FRAME]->ReleaseStreams(continueStreamIds); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ReleaseAllStreams continue stream ReleaseStreams ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + + std::vector snapStreamIds; + dataProcess_[SNAPSHOT_FRAME]->GetAllStreamIds(snapStreamIds); + ret = dataProcess_[SNAPSHOT_FRAME]->ReleaseStreams(snapStreamIds); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInput ReleaseAllStreams snapshot stream ReleaseStreams ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return ret; + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.cpp new file mode 100644 index 00000000..3bbcf886 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_source_input_channel_listener.cpp @@ -0,0 +1,67 @@ +/* + * 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_source_input_channel_listener.h" + +#include "dcamera_source_input.h" + +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceInputChannelListener::DCameraSourceInputChannelListener(std::shared_ptr& input, + DCStreamType streamType) : input_(input), streamType_(streamType) +{ +} + +DCameraSourceInputChannelListener::~DCameraSourceInputChannelListener() +{ +} + +void DCameraSourceInputChannelListener::OnSessionState(int32_t state) +{ + std::shared_ptr input = input_.lock(); + if (input == nullptr) { + DHLOGE("DCameraSourceInput OnSessionState not found input"); + return; + } + + input->OnSessionState(streamType_, state); +} + +void DCameraSourceInputChannelListener::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) +{ + std::shared_ptr input = input_.lock(); + if (input == nullptr) { + DHLOGE("DCameraSourceInput OnSessionError not found input"); + return; + } + + input->OnSessionError(streamType_, eventType, eventReason, detail); +} + +void DCameraSourceInputChannelListener::OnDataReceived(std::vector>& buffers) +{ + std::shared_ptr input = input_.lock(); + if (input == nullptr) { + DHLOGE("DCameraSourceInput OnDataReceived not found input"); + return; + } + + input->OnDataReceived(streamType_, buffers); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process.cpp new file mode 100644 index 00000000..8bf016f5 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process.cpp @@ -0,0 +1,229 @@ +/* + * 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_data_process.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "dcamera_pipeline_source.h" +#include "dcamera_stream_data_process_pipeline_listener.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraStreamDataProcess::DCameraStreamDataProcess(std::string devId, std::string dhId, DCStreamType streamType) + : devId_(devId), dhId_(dhId), streamType_(streamType) +{ + DHLOGI("DCameraSourceDataProcess Constructor devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + pipeline_ = nullptr; + listener_ = nullptr; +} + +DCameraStreamDataProcess::~DCameraStreamDataProcess() +{ + DHLOGI("DCameraStreamDataProcess Destructor devId %s dhId %s streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamType_); + streamIds_.clear(); + producers_.clear(); + if (pipeline_ != nullptr) { + pipeline_->DestroyDataProcessPipeline(); + } +} + +void DCameraStreamDataProcess::FeedStream(std::shared_ptr& buffer) +{ + DHLOGD("DCameraStreamDataProcess FeedStream devId %s dhId %s streamType %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + switch (streamType_) { + case SNAPSHOT_FRAME: { + FeedStreamToSnapShot(buffer); + break; + } + case CONTINUOUS_FRAME: { + FeedStreamToContinue(buffer); + break; + } + default: + break; + } +} + +void DCameraStreamDataProcess::ConfigStreams(std::shared_ptr& dstConfig, + std::set& streamIds) +{ + DHLOGI("DCameraStreamDataProcess ConfigStreams devId %s dhId %s streamType: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_); + dstConfig_ = dstConfig; + streamIds_ = streamIds; +} + +void DCameraStreamDataProcess::ReleaseStreams(std::set& streamIds) +{ + for (auto iter = streamIds.begin(); iter != streamIds.end(); iter++) { + int32_t streamId = *iter; + DHLOGI("DCameraStreamDataProcess ReleaseStreams devId %s dhId %s streamId: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), streamId); + streamIds_.erase(streamId); + auto producerIter = producers_.find(streamId); + if (producerIter == producers_.end()) { + continue; + } + producerIter->second->Stop(); + producers_.erase(streamId); + } +} + +void DCameraStreamDataProcess::StartCapture(std::shared_ptr& srcConfig, + std::set& streamIds) +{ + srcConfig_ = srcConfig; + if (streamType_ == CONTINUOUS_FRAME) { + CreatePipeline(); + } + for (auto iter = streamIds_.begin(); iter != streamIds_.end(); iter++) { + uint32_t streamId = *iter; + DHLOGI("DCameraStreamDataProcess StartCapture devId %s dhId %s streamType: %d streamId: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId); + if (streamIds.find(streamId) == streamIds.end()) { + continue; + } + + DHLOGI("DCameraStreamDataProcess StartCapture findProducer devId %s dhId %s streamType: %d streamId: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId); + auto producerIter = producers_.find(streamId); + if (producerIter != producers_.end()) { + continue; + } + DHLOGI("DCameraStreamDataProcess StartCapture CreateProducer devId %s dhId %s streamType: %d streamId: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId); + producers_[streamId] = std::make_shared(devId_, dhId_, streamId, streamType_); + producers_[streamId]->Start(); + } +} + +void DCameraStreamDataProcess::StopCapture() +{ + DHLOGI("DCameraStreamDataProcess StopCapture devId %s dhId %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (streamType_ == CONTINUOUS_FRAME) { + DestroyPipeline(); + } + auto iter = producers_.begin(); + while (iter != producers_.end()) { + iter->second->Stop(); + iter = producers_.erase(iter); + } +} + +void DCameraStreamDataProcess::GetAllStreamIds(std::set& streamIds) +{ + streamIds = streamIds_; +} + +void DCameraStreamDataProcess::FeedStreamToSnapShot(const std::shared_ptr& buffer) +{ + DHLOGD("DCameraStreamDataProcess FeedStreamToSnapShot devId %s dhId %s streamType %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + for (auto iter = producers_.begin(); iter != producers_.end(); iter++) { + iter->second->FeedStream(buffer); + } +} + +void DCameraStreamDataProcess::FeedStreamToContinue(const std::shared_ptr& buffer) +{ + DHLOGD("DCameraStreamDataProcess FeedStreamToContinue devId %s dhId %s streamType %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + std::vector> buffers; + buffers.push_back(buffer); + if (pipeline_ == nullptr) { + DHLOGE("DCameraStreamDataProcess FeedStreamToContinue pipeline null devId %s dhId %s type: %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + return; + } + int32_t ret = pipeline_->ProcessData(buffers); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraStreamDataProcess FeedStreamToContinue pipeline ProcessData failed, ret: %d", ret); + } +} + +void DCameraStreamDataProcess::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + DHLOGI("DCameraStreamDataProcess OnProcessedVideoBuffer devId %s dhId %s streamType: %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, videoResult->Size()); + for (auto iter = producers_.begin(); iter != producers_.end(); iter++) { + iter->second->FeedStream(videoResult); + } +} + +void DCameraStreamDataProcess::OnError(DataProcessErrorType errorType) +{ + DHLOGE("DCameraStreamDataProcess OnError pipeline errorType: %d", errorType); +} + +void DCameraStreamDataProcess::CreatePipeline() +{ + if (pipeline_ != nullptr) { + DHLOGI("DCameraStreamDataProcess CreatePipeline already exist, devId %s dhId %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return; + } + pipeline_ = std::make_shared(); + auto process = std::shared_ptr(shared_from_this()); + listener_ = std::make_shared(process); + VideoConfigParams srcParams(GetPipelineCodecType(srcConfig_->encodeType_), GetPipelineFormat(srcConfig_->format_), + DCAMERA_PRODUCER_FPS_DEFAULT, srcConfig_->width_, srcConfig_->height_); + VideoConfigParams dstParams(GetPipelineCodecType(dstConfig_->encodeType_), GetPipelineFormat(dstConfig_->format_), + DCAMERA_PRODUCER_FPS_DEFAULT, dstConfig_->width_, dstConfig_->height_); + int32_t ret = pipeline_->CreateDataProcessPipeline(PipelineType::VIDEO, srcParams, dstParams, listener_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraStreamDataProcess CreateDataProcessPipeline type: %d failed, ret: %d", PipelineType::VIDEO, ret); + } +} + +void DCameraStreamDataProcess::DestroyPipeline() +{ + if (pipeline_ == nullptr) { + return; + } + pipeline_->DestroyDataProcessPipeline(); + pipeline_ = nullptr; +} + +VideoCodecType DCameraStreamDataProcess::GetPipelineCodecType(DCEncodeType encodeType) +{ + VideoCodecType codecType; + switch (encodeType) { + case ENCODE_TYPE_H264: + codecType = VideoCodecType::CODEC_H264; + break; + case ENCODE_TYPE_H265: + codecType = VideoCodecType::CODEC_H265; + break; + default: + codecType = VideoCodecType::NO_CODEC; + break; + } + return codecType; +} + +Videoformat DCameraStreamDataProcess::GetPipelineFormat(int32_t format) +{ + return Videoformat::NV21; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.cpp new file mode 100644 index 00000000..0151a8fd --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_pipeline_listener.cpp @@ -0,0 +1,55 @@ +/* + * 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_data_process_pipeline_listener.h" + +#include "dcamera_stream_data_process.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraStreamDataProcessPipelineListener::DCameraStreamDataProcessPipelineListener( + std::shared_ptr& process) : process_(process) +{ +} + +DCameraStreamDataProcessPipelineListener::~DCameraStreamDataProcessPipelineListener() +{ +} + +void DCameraStreamDataProcessPipelineListener::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + std::shared_ptr process = process_.lock(); + if (process == nullptr) { + DHLOGE("DCameraStreamDataProcessPipelineListener OnProcessedVideoBuffer not found process"); + return; + } + process->OnProcessedVideoBuffer(videoResult); +} + +void DCameraStreamDataProcessPipelineListener::OnError(DataProcessErrorType errorType) +{ + std::shared_ptr process = process_.lock(); + if (process == nullptr) { + DHLOGE("DCameraStreamDataProcessPipelineListener OnProcessedVideoBuffer not found process"); + return; + } + process->OnError(errorType); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.cpp new file mode 100644 index 00000000..902a2c13 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcameradata/dcamera_stream_data_process_producer.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_stream_data_process_producer.h" + +#include +#include + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraStreamDataProcessProducer::DCameraStreamDataProcessProducer(std::string devId, std::string dhId, + int32_t streamId, DCStreamType streamType) + : devId_(devId), dhId_(dhId), streamId_(streamId), streamType_(streamType) +{ + DHLOGI("DCameraStreamDataProcessProducer Constructor devId %s dhId %s streamType: %d streamId: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_); + state_ = DCAMERA_PRODUCER_STATE_STOP; + interval_ = DCAMERA_PRODUCER_ONE_MINUTE_MS / DCAMERA_PRODUCER_FPS_DEFAULT; +} + +DCameraStreamDataProcessProducer::~DCameraStreamDataProcessProducer() +{ + DHLOGI("DCameraStreamDataProcessProducer Destructor devId %s dhId %s state: %d streamType: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), state_, streamType_); + if (state_ == DCAMERA_PRODUCER_STATE_START) { + Stop(); + } +} + +void DCameraStreamDataProcessProducer::Start() +{ + DHLOGI("DCameraStreamDataProcessProducer Start producer devId: %s dhId: %s streamType: %d streamId: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_); + state_ = DCAMERA_PRODUCER_STATE_START; + if (streamType_ == CONTINUOUS_FRAME) { + producerThread_ = std::thread(&DCameraStreamDataProcessProducer::LooperContinue, this); + std::string threadName = "DCameraProducer_" + std::to_string(streamType_) + "_" + std::to_string(streamId_); + auto runner = AppExecFwk::EventRunner::Create(threadName); + eventHandler_ = std::make_shared(runner); + } else { + producerThread_ = std::thread(&DCameraStreamDataProcessProducer::LooperSnapShot, this); + } +} + +void DCameraStreamDataProcessProducer::Stop() +{ + DHLOGI("DCameraStreamDataProcessProducer Stop devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); + state_ = DCAMERA_PRODUCER_STATE_STOP; + producerCon_.notify_one(); + producerThread_.join(); + eventHandler_ = nullptr; + DHLOGI("DCameraStreamDataProcessProducer Stop end devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); +} + +void DCameraStreamDataProcessProducer::FeedStream(const std::shared_ptr& buffer) +{ + DHLOGD("DCameraStreamDataProcessProducer FeedStream devId %s dhId %s streamType: %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + std::unique_lock lock(producerMutex_); + if (buffers_.size() >= DCAMERA_PRODUCER_MAX_BUFFER_SIZE) { + DHLOGD("DCameraStreamDataProcessProducer FeedStream OverSize devId %s dhId %s streamType: %d streamSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, buffer->Size()); + buffers_.pop(); + } + buffers_.push(buffer); + if (streamType_ == SNAPSHOT_FRAME) { + producerCon_.notify_one(); + } +} + +void DCameraStreamDataProcessProducer::LooperContinue() +{ + DHLOGI("LooperContinue producer devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = devId_; + dhBase->dhId_ = dhId_; + + while (state_ == DCAMERA_PRODUCER_STATE_START) { + std::shared_ptr buffer = nullptr; + { + std::unique_lock lock(producerMutex_); + producerCon_.wait_for(lock, std::chrono::milliseconds(interval_), [this] { + return (this->state_ == DCAMERA_PRODUCER_STATE_STOP); + }); + if (state_ == DCAMERA_PRODUCER_STATE_STOP || buffers_.empty()) { + continue; + } + + buffer = buffers_.front(); + if (buffers_.size() > 1) { + buffers_.pop(); + DHLOGD("common devId %s dhId %s streamSize: %d bufferSize: %d streamType: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), buffer->Size(), buffers_.size(), + streamType_); + } else { + DHLOGD("repeat devId %s dhId %s streamSize: %d bufferSize: %d streamType: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), buffer->Size(), buffers_.size(), + streamType_); + } + } + + auto feedFunc = [this, dhBase, buffer]() { + FeedStreamToDriver(dhBase, buffer); + }; + if (eventHandler_ != nullptr) { + eventHandler_->PostTask(feedFunc); + } + } + DHLOGI("LooperContinue producer end devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); +} + +void DCameraStreamDataProcessProducer::LooperSnapShot() +{ + DHLOGI("LooperSnapShot producer devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); + std::shared_ptr dhBase = std::make_shared(); + dhBase->deviceId_ = devId_; + dhBase->dhId_ = dhId_; + + while (state_ == DCAMERA_PRODUCER_STATE_START) { + std::shared_ptr buffer = nullptr; + { + std::unique_lock lock(producerMutex_); + producerCon_.wait(lock, [this] { + return (!buffers_.empty() || state_ == DCAMERA_PRODUCER_STATE_STOP); + }); + if (state_ == DCAMERA_PRODUCER_STATE_STOP) { + continue; + } + + if (!buffers_.empty()) { + DHLOGI("LooperSnapShot producer get buffer devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); + buffer = buffers_.front(); + } + } + + if (buffer == nullptr) { + DHLOGI("LooperSnapShot producer get buffer failed devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); + continue; + } + int32_t ret = FeedStreamToDriver(dhBase, buffer); + if (ret != DCAMERA_OK) { + std::this_thread::sleep_for(std::chrono::milliseconds(DCAMERA_PRODUCER_RETRY_SLEEP_MS)); + continue; + } + { + std::unique_lock lock(producerMutex_); + buffers_.pop(); + } + } + DHLOGI("LooperSnapShot producer end devId: %s dhId: %s streamType: %d streamId: %d state: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamType_, streamId_, state_); +} + +int32_t DCameraStreamDataProcessProducer::FeedStreamToDriver(const std::shared_ptr& dhBase, + const std::shared_ptr& buffer) +{ + DHLOGD("LooperFeed devId %s dhId %s streamSize: %d streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), buffer->Size(), streamType_); + sptr camHdiProvider = IDCameraProvider::Get(); + if (camHdiProvider == nullptr) { + DHLOGI("camHdiProvider is nullptr"); + return DCAMERA_BAD_VALUE; + } + std::shared_ptr sharedMemory; + DCamRetCode retHdi = camHdiProvider->AcquireBuffer(dhBase, streamId_, sharedMemory); + if (retHdi != SUCCESS) { + DHLOGE("AcquireBuffer devId: %s dhId: %s streamId: %d ret: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamId_, retHdi); + return DCAMERA_BAD_OPERATE; + } + + int32_t ret = DCAMERA_OK; + do { + if (sharedMemory == nullptr) { + DHLOGE("sharedMemory devId: %s dhId: %s streamId: %d, sharedMemory is null", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamId_); + ret = DCAMERA_MEMORY_OPT_ERROR; + break; + } + + if (buffer->Size() > sharedMemory->size_) { + DHLOGE("sharedMemory devId: %s dhId: %s streamId: %d bufSize: %d, addressSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamId_, buffer->Size(), + sharedMemory->size_); + ret = DCAMERA_MEMORY_OPT_ERROR; + break; + } + int32_t ret = memcpy_s(sharedMemory->bufferHandle_->virAddr, sharedMemory->size_, buffer->Data(), + buffer->Size()); + if (ret != EOK) { + DHLOGE("memcpy_s devId: %s dhId: %s streamId: %d bufSize: %d, addressSize: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamId_, buffer->Size(), + sharedMemory->size_); + ret = DCAMERA_MEMORY_OPT_ERROR; + break; + } + sharedMemory->size_ = buffer->Size(); + } while (0); + + retHdi = camHdiProvider->ShutterBuffer(dhBase, streamId_, sharedMemory); + if (retHdi != SUCCESS) { + DHLOGE("ShutterBuffer devId: %s dhId: %s streamId: %d ret: %d", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(), streamId_, retHdi); + return DCAMERA_BAD_OPERATE; + } + DHLOGD("LooperFeed end devId %s dhId %s streamSize: %d streamType: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), buffer->Size(), streamType_); + return ret; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.cpp new file mode 100644 index 00000000..768f41c4 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerahdf/dcamera_provider_callback_impl.cpp @@ -0,0 +1,181 @@ +/* + * 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_callback_impl.h" + +#include "dcamera_index.h" +#include "dcamera_source_dev.h" + +#include "anonymous_string.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +#include "types.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraProviderCallbackImpl::DCameraProviderCallbackImpl(std::string devId, std::string dhId, + std::shared_ptr& sourceDev) : devId_(devId), dhId_(dhId), sourceDev_(sourceDev) +{ + DHLOGI("DCameraProviderCallbackImpl create devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); +} + +DCameraProviderCallbackImpl::~DCameraProviderCallbackImpl() +{ + DHLOGI("DCameraProviderCallbackImpl delete devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); +} + +DCamRetCode DCameraProviderCallbackImpl::OpenSession(const std::shared_ptr& dhBase) +{ + DHLOGI("DCameraProviderCallbackImpl OpenSession devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl OpenSession failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + DCameraIndex camIndex(devId_, dhId_); + int32_t ret = sourceDev->OpenSession(camIndex); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl OpenSession failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::CloseSession(const std::shared_ptr& dhBase) +{ + DHLOGI("DCameraProviderCallbackImpl CloseSession devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl CloseSession failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + DCameraIndex camIndex(devId_, dhId_); + int32_t ret = sourceDev->CloseSession(camIndex); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl CloseSession failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::ConfigureStreams(const std::shared_ptr& dhBase, + const std::vector>& streamInfos) +{ + DHLOGI("DCameraProviderCallbackImpl ConfigStreams devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl ConfigStreams failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + int32_t ret = sourceDev->ConfigStreams(streamInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl CloseSession failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::ReleaseStreams(const std::shared_ptr& dhBase, + const std::vector& streamIds) +{ + DHLOGI("DCameraProviderCallbackImpl ReleaseStreams devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl ReleaseStreams failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + int32_t ret = sourceDev->ReleaseStreams(streamIds); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl ReleaseStreams failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::StartCapture(const std::shared_ptr& dhBase, + const std::vector>& captureInfos) +{ + DHLOGI("DCameraProviderCallbackImpl StartCapture devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl StartCapture failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + int32_t ret = sourceDev->StartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl StartCapture failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::StopCapture(const std::shared_ptr& dhBase) +{ + DHLOGI("DCameraProviderCallbackImpl StopCapture devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl StopCapture failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + int32_t ret = sourceDev->StopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl StopCapture failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} + +DCamRetCode DCameraProviderCallbackImpl::UpdateSettings(const std::shared_ptr& dhBase, + const std::vector>& settings) +{ + DHLOGI("DCameraProviderCallbackImpl UpdateSettings devId: %s dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + std::shared_ptr sourceDev = sourceDev_.lock(); + if (sourceDev == nullptr) { + DHLOGE("DCameraProviderCallbackImpl UpdateSettings failed, can not get device, devId: %s, dhId: %s", + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + int32_t ret = sourceDev->UpdateCameraSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraProviderCallbackImpl UpdateSettings failed, ret: %d, devId: %s, dhId: %s", ret, + GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + return FAILED; + } + return SUCCESS; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_capture_state.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_capture_state.cpp new file mode 100644 index 00000000..0b6e3072 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_capture_state.cpp @@ -0,0 +1,217 @@ +/* + * 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_source_capture_state.h" + +#include "dcamera_source_dev.h" +#include "dcamera_source_state_machine.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceCaptureState::DCameraSourceCaptureState(std::shared_ptr& stateMachine) + : stateMachine_(stateMachine) +{ + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceCaptureState::DoRegisterTask; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceCaptureState::DoUnregisterTask; + memberFuncMap_[DCAMERA_EVENT_OPEN] = &DCameraSourceCaptureState::DoOpenTask; + memberFuncMap_[DCAMERA_EVENT_CLOSE] = &DCameraSourceCaptureState::DoCloseTask; + memberFuncMap_[DCAMERA_EVENT_START_CAPTURE] = &DCameraSourceCaptureState::DoStartCaptureTask; + memberFuncMap_[DCAMERA_EVENT_STOP_CAPTURE] = &DCameraSourceCaptureState::DoStopCaptureTask; + memberFuncMap_[DCAMERA_EVENT_UPDATE_SETTINGS] = &DCameraSourceCaptureState::DoUpdateSettingsTask; + memberFuncMap_[DCAMERA_EVENT_NOFIFY] = &DCameraSourceCaptureState::DoEventNofityTask; +} + +int32_t DCameraSourceCaptureState::Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("DCameraSourceCaptureState execute %d in wrong state", eventType); + return DCAMERA_WRONG_STATE; + } + + auto memberFunc = itFunc->second; + int32_t ret = (this->*memberFunc)(camDev, event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState execute %d failed, ret: %d", eventType, ret); + } + return ret; +} + +DCameraStateType DCameraSourceCaptureState::GetStateType() +{ + return DCAMERA_STATE_CAPTURE; +} + +int32_t DCameraSourceCaptureState::DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceCaptureState DoRegisterTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoUnregisterTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_DISCONNECTED; + int32_t ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask ExecuteCameraEventNotify failed: %d", ret); + return ret; + } + + ret = camDev->ExecuteStopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask ExecuteStopCapture failed: %d", ret); + return ret; + } + + ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask ExecuteCloseCamera failed, ret: %d", ret); + return ret; + } + + ret = camDev->ExecuteReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask ExecuteReleaseAllStreams failed, ret: %d", ret); + return ret; + } + + std::shared_ptr param; + ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return ret; + } + ret = camDev->ExecuteUnRegister(param); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask ExecuteUnRegister failed: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceCaptureState DoUnregisterTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_INIT); + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceCaptureState DoOpenTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + int32_t ret = camDev->ExecuteStopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteStopCapture failed, ret: %d", ret); + return ret; + } + + ret = camDev->ExecuteReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteReleaseAllStreams failed, ret: %d", ret); + return ret; + } + + ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteCloseCamera failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceCaptureState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_REGIST); + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoStartCaptureTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> captureInfos; + int32_t ret = event.GetCaptureInfos(captureInfos); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteStartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState DoStartCaptureTask failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoStopCaptureTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + int32_t ret = camDev->ExecuteStopCapture(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteStopCapture failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceCaptureState DoStopCaptureTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_CONFIG_STREAM); + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoUpdateSettingsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> settings; + int32_t ret = event.GetCameraSettings(settings); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteUpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteUpdateSettings failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceCaptureState::DoEventNofityTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent; + int32_t ret = event.GetCameraEvent(camEvent); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceCaptureState ExecuteCameraEventNotify failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.cpp new file mode 100644 index 00000000..654b4125 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_config_stream_state.cpp @@ -0,0 +1,258 @@ +/* + * 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_source_config_stream_state.h" + +#include "dcamera_source_dev.h" +#include "dcamera_source_state_machine.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceConfigStreamState::DCameraSourceConfigStreamState(std::shared_ptr& stateMachine) + : stateMachine_(stateMachine) +{ + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceConfigStreamState::DoRegisterTask; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceConfigStreamState::DoUnregisterTask; + memberFuncMap_[DCAMERA_EVENT_OPEN] = &DCameraSourceConfigStreamState::DoOpenTask; + memberFuncMap_[DCAMERA_EVENT_CLOSE] = &DCameraSourceConfigStreamState::DoCloseTask; + memberFuncMap_[DCAMERA_EVENT_CONFIG_STREAMS] = &DCameraSourceConfigStreamState::DoConfigStreamsTask; + memberFuncMap_[DCAMERA_EVENT_RELEASE_STREAMS] = &DCameraSourceConfigStreamState::DoReleaseStreamsTask; + memberFuncMap_[DCAMERA_EVENT_START_CAPTURE] = &DCameraSourceConfigStreamState::DoStartCaptureTask; + memberFuncMap_[DCAMERA_EVENT_STOP_CAPTURE] = &DCameraSourceConfigStreamState::DoStopCaptureTask; + memberFuncMap_[DCAMERA_EVENT_UPDATE_SETTINGS] = &DCameraSourceConfigStreamState::DoUpdateSettingsTask; + memberFuncMap_[DCAMERA_EVENT_NOFIFY] = &DCameraSourceConfigStreamState::DoEventNofityTask; +} + +int32_t DCameraSourceConfigStreamState::Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("DCameraSourceConfigStreamState execute %d in wrong state", eventType); + return DCAMERA_WRONG_STATE; + } + + auto memberFunc = itFunc->second; + int32_t ret = (this->*memberFunc)(camDev, event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState execute %d failed, ret: %d", eventType, ret); + } + return ret; +} + +DCameraStateType DCameraSourceConfigStreamState::GetStateType() +{ + return DCAMERA_STATE_CONFIG_STREAM; +} + +int32_t DCameraSourceConfigStreamState::DoRegisterTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceConfigStreamState DoRegisterTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoUnregisterTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_DISCONNECTED; + int32_t ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState DoUnregisterTask ExecuteCameraEventNotify failed: %d", ret); + return ret; + } + + ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState DoUnregisterTask ExecuteCloseCamera failed, ret: %d", ret); + return ret; + } + + ret = camDev->ExecuteReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState DoUnregisterTask ExecuteReleaseAllStreams failed, ret: %d", ret); + return ret; + } + + std::shared_ptr param; + ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return ret; + } + ret = camDev->ExecuteUnRegister(param); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState DoUnregisterTask ExecuteUnRegister failed: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceConfigStreamState DoUnregisterTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_INIT); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceConfigStreamState DoOpenTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoCloseTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + int32_t ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteCloseCamera failed, ret: %d", ret); + return ret; + } + + ret = camDev->ExecuteReleaseAllStreams(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteReleaseAllStreams failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceConfigStreamState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_REGIST); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoConfigStreamsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> streamInfos; + int32_t ret = event.GetStreamInfos(streamInfos); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteConfigStreams(streamInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteConfigStreams failed, ret: %d", ret); + return ret; + } + + if (streamInfos.empty()) { + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceConfigStreamState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_OPENED); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoReleaseStreamsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector streamIds; + int32_t ret = event.GetStreamIds(streamIds); + if (ret != DCAMERA_OK) { + return ret; + } + + bool isAllRelease = false; + ret = camDev->ExecuteReleaseStreams(streamIds, isAllRelease); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteConfigStreams failed, ret: %d", ret); + return ret; + } + + if (isAllRelease) { + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceConfigStreamState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_OPENED); + } + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoStartCaptureTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> captureInfos; + int32_t ret = event.GetCaptureInfos(captureInfos); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteStartCapture(captureInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteStartCapture failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceConfigStreamState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_CAPTURE); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoStopCaptureTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceConfigStreamState DoStopCaptureTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoUpdateSettingsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> settings; + int32_t ret = event.GetCameraSettings(settings); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteUpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteConfigStreams failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceConfigStreamState::DoEventNofityTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent; + int32_t ret = event.GetCameraEvent(camEvent); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceConfigStreamState ExecuteCameraEventNotify failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_init_state.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_init_state.cpp new file mode 100644 index 00000000..da582aa8 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_init_state.cpp @@ -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. + */ + +#include "dcamera_source_init_state.h" + +#include "dcamera_source_dev.h" +#include "dcamera_source_state_machine.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceInitState::DCameraSourceInitState(std::shared_ptr& stateMachine) + : stateMachine_(stateMachine) +{ + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceInitState::DoRegisterTask; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceInitState::DoUnregisterTask; +} + +int32_t DCameraSourceInitState::Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("DCameraSourceInitState execute %d in wrong state", eventType); + return DCAMERA_WRONG_STATE; + } + + auto memberFunc = itFunc->second; + int32_t ret = (this->*memberFunc)(camDev, event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceInitState execute %d failed, ret: %d", eventType, ret); + } + return ret; +} + +DCameraStateType DCameraSourceInitState::GetStateType() +{ + return DCAMERA_STATE_INIT; +} + +int32_t DCameraSourceInitState::DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + std::shared_ptr param; + int32_t ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return ret; + } + ret = camDev->ExecuteRegister(param); + if (ret != DCAMERA_OK) { + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceInitState can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_REGIST); + return DCAMERA_OK; +} + +int32_t DCameraSourceInitState::DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceInitState DoUnregisterTask Idempotent"); + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_opened_state.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_opened_state.cpp new file mode 100644 index 00000000..975a302a --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_opened_state.cpp @@ -0,0 +1,188 @@ +/* + * 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_source_opened_state.h" + +#include "dcamera_source_dev.h" +#include "dcamera_source_state_machine.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceOpenedState::DCameraSourceOpenedState(std::shared_ptr& stateMachine) + : stateMachine_(stateMachine) +{ + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceOpenedState::DoRegisterTask; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceOpenedState::DoUnregisterTask; + memberFuncMap_[DCAMERA_EVENT_OPEN] = &DCameraSourceOpenedState::DoOpenTask; + memberFuncMap_[DCAMERA_EVENT_CLOSE] = &DCameraSourceOpenedState::DoCloseTask; + memberFuncMap_[DCAMERA_EVENT_CONFIG_STREAMS] = &DCameraSourceOpenedState::DoConfigStreamsTask; + memberFuncMap_[DCAMERA_EVENT_RELEASE_STREAMS] = &DCameraSourceOpenedState::DoReleaseStreamsTask; + memberFuncMap_[DCAMERA_EVENT_UPDATE_SETTINGS] = &DCameraSourceOpenedState::DoUpdateSettingsTask; + memberFuncMap_[DCAMERA_EVENT_NOFIFY] = &DCameraSourceOpenedState::DoEventNofityTask; +} + +int32_t DCameraSourceOpenedState::Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("DCameraSourceOpenedState execute %d in wrong state", eventType); + return DCAMERA_WRONG_STATE; + } + + auto memberFunc = itFunc->second; + int32_t ret = (this->*memberFunc)(camDev, event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState execute %d failed, ret: %d", eventType, ret); + } + return ret; +} + +DCameraStateType DCameraSourceOpenedState::GetStateType() +{ + return DCAMERA_STATE_OPENED; +} + +int32_t DCameraSourceOpenedState::DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceOpenedState DoRegisterTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + std::shared_ptr camEvent = std::make_shared(); + camEvent->eventType_ = DCAMERA_MESSAGE; + camEvent->eventResult_ = DCAMERA_EVENT_CHANNEL_DISCONNECTED; + int32_t ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState DoUnregisterTask ExecuteCameraEventNotify failed: %d", ret); + return ret; + } + + ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState DoUnregisterTask ExecuteCloseCamera failed: %d", ret); + return ret; + } + + std::shared_ptr param; + ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return ret; + } + ret = camDev->ExecuteUnRegister(param); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState DoUnregisterTask ExecuteUnRegister failed: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceOpenedState DoUnregisterTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_INIT); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoConfigStreamsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> streamInfos; + int32_t ret = event.GetStreamInfos(streamInfos); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteConfigStreams(streamInfos); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState ExecuteConfigStreams failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceOpenedState DoConfigStreamsTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_CONFIG_STREAM); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoReleaseStreamsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceOpenedState DoReleaseStreamsTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoUpdateSettingsTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::vector> settings; + int32_t ret = event.GetCameraSettings(settings); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteUpdateSettings(settings); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState ExecuteConfigStreams failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceOpenedState DoOpenTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + int32_t ret = camDev->ExecuteCloseCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState DoOpenTask ExecuteCloseCamera failed, ret: %d", ret); + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceOpenedState DoOpenTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_REGIST); + return DCAMERA_OK; +} + +int32_t DCameraSourceOpenedState::DoEventNofityTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent; + int32_t ret = event.GetCameraEvent(camEvent); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceOpenedState DoEventNofityTask ExecuteCameraEventNotify failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_regist_state.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_regist_state.cpp new file mode 100644 index 00000000..0f6b9095 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_regist_state.cpp @@ -0,0 +1,117 @@ +/* + * 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_source_regist_state.h" + +#include "dcamera_source_dev.h" +#include "dcamera_source_state_machine.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceRegistState::DCameraSourceRegistState(std::shared_ptr& stateMachine) + : stateMachine_(stateMachine) +{ + memberFuncMap_[DCAMERA_EVENT_REGIST] = &DCameraSourceRegistState::DoRegisterTask; + memberFuncMap_[DCAMERA_EVENT_UNREGIST] = &DCameraSourceRegistState::DoUnregisterTask; + memberFuncMap_[DCAMERA_EVENT_OPEN] = &DCameraSourceRegistState::DoOpenTask; + memberFuncMap_[DCAMERA_EVENT_CLOSE] = &DCameraSourceRegistState::DoCloseTask; + memberFuncMap_[DCAMERA_EVENT_NOFIFY] = &DCameraSourceRegistState::DoEventNofityTask; +} + +int32_t DCameraSourceRegistState::Execute(std::shared_ptr& camDev, DCAMERA_EVENT eventType, + DCameraSourceEvent& event) +{ + auto itFunc = memberFuncMap_.find(eventType); + if (itFunc == memberFuncMap_.end()) { + DHLOGE("DCameraSourceRegistState execute %d in wrong state", eventType); + return DCAMERA_WRONG_STATE; + } + + auto memberFunc = itFunc->second; + int32_t ret = (this->*memberFunc)(camDev, event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceRegistState execute %d failed, ret: %d", eventType, ret); + } + return ret; +} + +DCameraStateType DCameraSourceRegistState::GetStateType() +{ + return DCAMERA_STATE_REGIST; +} + +int32_t DCameraSourceRegistState::DoRegisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceRegistState DoRegisterTask Idempotent"); + return DCAMERA_OK; +} + + +int32_t DCameraSourceRegistState::DoUnregisterTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + std::shared_ptr param; + int32_t ret = event.GetDCameraRegistParam(param); + if (ret != DCAMERA_OK) { + return ret; + } + ret = camDev->ExecuteUnRegister(param); + if (ret != DCAMERA_OK) { + return ret; + } + std::shared_ptr stateMachine = stateMachine_.lock(); + if (stateMachine == nullptr) { + DHLOGE("DCameraSourceRegistState DoUnregisterTask can not get stateMachine"); + return DCAMERA_BAD_VALUE; + } + stateMachine->UpdateState(DCAMERA_STATE_INIT); + return DCAMERA_OK; +} + +int32_t DCameraSourceRegistState::DoOpenTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + int32_t ret = camDev->ExecuteOpenCamera(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceRegistState ExecuteOpenCamera failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} + +int32_t DCameraSourceRegistState::DoCloseTask(std::shared_ptr& camDev, DCameraSourceEvent& event) +{ + DHLOGI("DCameraSourceRegistState DoCloseTask Idempotent"); + return DCAMERA_OK; +} + +int32_t DCameraSourceRegistState::DoEventNofityTask(std::shared_ptr& camDev, + DCameraSourceEvent& event) +{ + std::shared_ptr camEvent; + int32_t ret = event.GetCameraEvent(camEvent); + if (ret != DCAMERA_OK) { + return ret; + } + + ret = camDev->ExecuteCameraEventNotify(camEvent); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceRegistState DoEventNofityTask ExecuteCameraEventNotify failed, ret: %d", ret); + return ret; + } + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_factory.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_factory.cpp new file mode 100644 index 00000000..d43f8aed --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_factory.cpp @@ -0,0 +1,65 @@ +/* + * 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_source_state_factory.h" + +#include "dcamera_source_capture_state.h" +#include "dcamera_source_config_stream_state.h" +#include "dcamera_source_init_state.h" +#include "dcamera_source_opened_state.h" +#include "dcamera_source_regist_state.h" + +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DCameraSourceStateFactory); + +std::shared_ptr DCameraSourceStateFactory::CreateState(DCameraStateType stateType, + std::shared_ptr& stateMachine) +{ + std::shared_ptr state = nullptr; + switch (stateType) { + case DCAMERA_STATE_INIT: { + state = std::make_shared(stateMachine); + break; + } + case DCAMERA_STATE_REGIST: { + state = std::make_shared(stateMachine); + break; + } + case DCAMERA_STATE_OPENED: { + state = std::make_shared(stateMachine); + break; + } + case DCAMERA_STATE_CONFIG_STREAM: { + state = std::make_shared(stateMachine); + break; + } + case DCAMERA_STATE_CAPTURE: { + state = std::make_shared(stateMachine); + break; + } + default: { + DHLOGE("DCameraSourceStateFactory create state failed, wrong type %d", stateType); + return nullptr; + } + } + + return state; +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_machine.cpp b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_machine.cpp new file mode 100644 index 00000000..95c0fab6 --- /dev/null +++ b/services/cameraservice/sourceservice/src/distributedcameramgr/dcamerastate/dcamera_source_state_machine.cpp @@ -0,0 +1,63 @@ +/* + * 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_source_state_machine.h" + +#include + +#include "dcamera_source_state_factory.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSourceStateMachine::DCameraSourceStateMachine(std::shared_ptr& camDev) : camDev_(camDev) +{ + DHLOGI("DCameraSourceStateMachine Create"); +} + +DCameraSourceStateMachine::~DCameraSourceStateMachine() +{ + DHLOGI("DCameraSourceStateMachine Delete"); +} + +int32_t DCameraSourceStateMachine::Execute(DCAMERA_EVENT eventType, DCameraSourceEvent& event) +{ + DHLOGI("In state %d execute event %d", currentState_->GetStateType(), eventType); + std::shared_ptr camDev = camDev_.lock(); + if (camDev == nullptr) { + DHLOGE("DCameraSourceStateMachine execute failed, camDev is nullptr"); + return DCAMERA_BAD_VALUE; + } + int32_t ret = currentState_->Execute(camDev, event.GetEventType(), event); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSourceStateMachine currentState_: %d execute event: %d failed", currentState_->GetStateType(), + event.GetEventType()); + } + return ret; +} + +void DCameraSourceStateMachine::UpdateState(DCameraStateType stateType) +{ + if (stateType != DCAMERA_STATE_INIT) { + DHLOGI("DCameraSourceStateMachine update state from %d to %d", currentState_->GetStateType(), stateType); + } else { + DHLOGI("DCameraSourceStateMachine update state %d", stateType); + } + auto stateMachine = std::shared_ptr(shared_from_this()); + currentState_ = DCameraSourceStateFactory::GetInstance().CreateState(stateType, stateMachine); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/test/unittest/BUILD.gn b/services/cameraservice/sourceservice/test/unittest/BUILD.gn new file mode 100644 index 00000000..b4ed56ba --- /dev/null +++ b/services/cameraservice/sourceservice/test/unittest/BUILD.gn @@ -0,0 +1,19 @@ +# 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. + +group("source_service_test") { + testonly = true + deps = [ + "common/distributedcameramgr:dcamera_mgr_test", + ] +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/BUILD.gn b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/BUILD.gn new file mode 100644 index 00000000..5401e17c --- /dev/null +++ b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/BUILD.gn @@ -0,0 +1,93 @@ +# 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/test.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") +module_out_path = "distributedcamera/dcamera_source_mgr_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "${services_path}/cameraservice/sourceservice/include/distributedcamera", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr/dcameracontrol", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr/dcameradata", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr/dcamerahdf", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr/dcamerainterface", + "${services_path}/cameraservice/sourceservice/include/distributedcameramgr/dcamerastate", + "${services_path}/cameraservice/cameraoperator/client/include", + "${services_path}/cameraservice/base/include", + "${services_path}/channel/include", + "${services_path}/data_process/include/pipeline", + "${services_path}/data_process/include/interfaces", + "${services_path}/data_process/include/utils", + "${services_path}/data_process/include/eventbus", + "${common_path}/include/constants", + "${common_path}/include/utils", + + "${innerkits_path}/native_cpp/camera_source/include", + "${innerkits_path}/native_cpp/camera_source/include/callback", + "${innerkits_path}/native_cpp/camera_sink/include", + + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + "${fwk_utils_path}/include/eventbus", + "${fwk_common_path}/utils/include", + "${fwk_common_path}/log/include", + "${distributedcamera_hdf_path}/interfaces/include", + "${distributedcamera_hdf_path}/interfaces/hdi_ipc/client/provider", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//third_party/jsoncpp/include", + "//drivers/peripheral/base/", + ] +} + +ohos_unittest("DCameraSourceMgrTest") { + module_out_path = module_out_path + + sources = [ + "dcamera_source_state_machine_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "${services_path}/cameraservice/sourceservice:distributed_camera_source", + "${services_path}/channel:distributed_camera_channel", + "${common_path}:distributed_camera_utils", + "//third_party/jsoncpp:jsoncpp", + "//utils/native/base:utils", + "${fwk_utils_path}:distributedhardwareutils", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ + "ipc:ipc_core", + "eventhandler:libeventhandler", + + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DCameraSourceMgrTest\"", + "LOG_DOMAIN=0xD004100", + ] +} + +group("dcamera_mgr_test") { + testonly = true + deps = [ ":DCameraSourceMgrTest" ] +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_state_machine_test.cpp b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_state_machine_test.cpp new file mode 100644 index 00000000..493b1e56 --- /dev/null +++ b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/dcamera_source_state_machine_test.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 +#include +#define private public +#include "dcamera_source_state.h" +#undef private + +#include "dcamera_source_capture_state.h" +#include "dcamera_source_config_stream_state.h" +#include "dcamera_source_init_state.h" +#include "dcamera_source_opened_state.h" +#include "dcamera_source_regist_state.h" +#include "dcamera_source_state_factory.h" +#include "dcamera_source_state_machine.h" +#include "mock_dcamera_source_dev.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +class DCameraSourceStateMachineTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr camDev_; + std::shared_ptr stateMachine_; + +private: + static void SetStreamInfos(); + static void SetCaptureInfos(); +}; + +namespace { +const std::string TEST_DEVICE_ID = "bb536a637105409e904d4da83790a4a7"; +const std::string TEST_CAMERA_DH_ID_0 = "camera_0"; +const std::string TEST_REQID = "0xFFFF"; +const std::string TEST_PARAM = "0xFFFF"; +const int32_t TEST_WIDTH = 1920; +const int32_t TEST_HEIGTH = 1080; +const int32_t TEST_STREAMID = 2; +} + +std::vector> g_streamInfosSnap; +std::vector> g_captureInfoSnap; +std::vector> g_cameraSettingSnap; +std::vector g_streamIdSnap; +std::shared_ptr g_camEvent; +std::shared_ptr g_registParam; +DCameraIndex g_camIndex; + +void DCameraSourceStateMachineTest::SetUpTestCase(void) +{ + SetStreamInfos(); + SetCaptureInfos(); +} + +void DCameraSourceStateMachineTest::SetStreamInfos() +{ + g_camIndex.devId_ = TEST_DEVICE_ID; + g_camIndex.dhId_ = TEST_CAMERA_DH_ID_0; + g_camEvent = std::make_shared(); + std::shared_ptr streamInfo1 = std::make_shared(); + streamInfo1->streamId_ = 1; + streamInfo1->width_ = TEST_WIDTH; + streamInfo1->height_ = TEST_HEIGTH; + streamInfo1->stride_ = 1; + streamInfo1->format_ = 1; + streamInfo1->dataspace_ = 1; + streamInfo1->encodeType_ = ENCODE_TYPE_JPEG; + streamInfo1->type_ = SNAPSHOT_FRAME; + + std::shared_ptr streamInfo2 = std::make_shared(); + streamInfo2->streamId_ = TEST_STREAMID; + streamInfo2->width_ = TEST_WIDTH; + streamInfo2->height_ = TEST_HEIGTH; + streamInfo2->stride_ = 1; + streamInfo2->format_ = 1; + streamInfo2->dataspace_ = 1; + streamInfo2->encodeType_ = ENCODE_TYPE_JPEG; + streamInfo2->type_ = SNAPSHOT_FRAME; + g_streamInfosSnap.push_back(streamInfo1); + g_streamInfosSnap.push_back(streamInfo2); +} + +void DCameraSourceStateMachineTest::SetCaptureInfos() +{ + std::shared_ptr captureInfo1 = std::make_shared(); + captureInfo1->streamIds_.push_back(1); + captureInfo1->width_ = TEST_WIDTH; + captureInfo1->height_ = TEST_HEIGTH; + captureInfo1->stride_ = 1; + captureInfo1->format_ = 1; + captureInfo1->dataspace_ = 1; + captureInfo1->encodeType_ = ENCODE_TYPE_H265; + captureInfo1->type_ = CONTINUOUS_FRAME; + + std::shared_ptr captureInfo2 = std::make_shared(); + captureInfo2->streamIds_.push_back(1); + captureInfo2->width_ = TEST_WIDTH; + captureInfo2->height_ = TEST_HEIGTH; + captureInfo2->stride_ = 1; + captureInfo2->format_ = 1; + captureInfo2->dataspace_ = 1; + captureInfo2->encodeType_ = ENCODE_TYPE_H265; + captureInfo2->type_ = CONTINUOUS_FRAME; + g_captureInfoSnap.push_back(captureInfo1); + g_captureInfoSnap.push_back(captureInfo2); + + std::shared_ptr camSettings1 = std::make_shared(); + camSettings1->type_ = UPDATE_METADATA; + camSettings1->value_ = "SettingValue"; + + std::shared_ptr camSettings2 = std::make_shared(); + camSettings2->type_ = ENABLE_METADATA; + camSettings2->value_ = "SettingValue"; + g_cameraSettingSnap.push_back(camSettings1); + g_cameraSettingSnap.push_back(camSettings2); + + g_streamIdSnap.push_back(1); + g_streamIdSnap.push_back(TEST_STREAMID); + + g_registParam = std::make_shared(TEST_DEVICE_ID, TEST_CAMERA_DH_ID_0, TEST_REQID, TEST_PARAM); +} + +void DCameraSourceStateMachineTest::TearDownTestCase(void) +{ +} + +void DCameraSourceStateMachineTest::SetUp(void) +{ + camDev_ = std::make_shared(TEST_DEVICE_ID, TEST_CAMERA_DH_ID_0); + stateMachine_ = std::make_shared(camDev_); +} + +void DCameraSourceStateMachineTest::TearDown(void) +{ + stateMachine_ = nullptr; + camDev_ = nullptr; +} + +/** + * @tc.name: dcamera_source_state_machine_test_001 + * @tc.desc: Verify source init state. + * @tc.type: FUNC + * @tc.require: AR000GK6MC + */ +HWTEST_F(DCameraSourceStateMachineTest, dcamera_source_state_machine_test_001, TestSize.Level1) +{ + DCameraSourceEvent event0(*camDev_, DCAMERA_EVENT_REGIST, g_registParam); + DCameraSourceEvent event1(*camDev_, DCAMERA_EVENT_UNREGIST, g_registParam); + stateMachine_ ->UpdateState(DCAMERA_STATE_INIT); + int32_t ret = stateMachine_ ->Execute(DCAMERA_EVENT_REGIST, event0); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UNREGIST, event1); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_source_state_machine_test_002 + * @tc.desc: Verify source regist state. + * @tc.type: FUNC + * @tc.require: AR000GK6MC + */ +HWTEST_F(DCameraSourceStateMachineTest, dcamera_source_state_machine_test_002, TestSize.Level1) +{ + DCameraSourceEvent event0(*camDev_, DCAMERA_EVENT_REGIST, g_registParam); + DCameraSourceEvent event1(*camDev_, DCAMERA_EVENT_UNREGIST, g_registParam); + DCameraSourceEvent event2(*camDev_, DCAMERA_EVENT_OPEN, g_camIndex); + DCameraSourceEvent event3(*camDev_, DCAMERA_EVENT_CLOSE, g_camIndex); + DCameraSourceEvent event9(*camDev_, DCAMERA_EVENT_NOFIFY, g_camEvent); + stateMachine_ ->UpdateState(DCAMERA_STATE_INIT); + stateMachine_ ->UpdateState(DCAMERA_STATE_REGIST); + int32_t ret = stateMachine_ ->Execute(DCAMERA_EVENT_REGIST, event0); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_OPEN, event2); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CLOSE, event3); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_NOFIFY, event9); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UNREGIST, event1); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_source_state_machine_test_003 + * @tc.desc: Verify source open state. + * @tc.type: FUNC + * @tc.require: AR000GK6MD + */ +HWTEST_F(DCameraSourceStateMachineTest, dcamera_source_state_machine_test_003, TestSize.Level1) +{ + DCameraSourceEvent event0(*camDev_, DCAMERA_EVENT_REGIST, g_registParam); + DCameraSourceEvent event1(*camDev_, DCAMERA_EVENT_UNREGIST, g_registParam); + DCameraSourceEvent event2(*camDev_, DCAMERA_EVENT_OPEN, g_camIndex); + DCameraSourceEvent event3(*camDev_, DCAMERA_EVENT_CLOSE, g_camIndex); + DCameraSourceEvent event4(*camDev_, DCAMERA_EVENT_CONFIG_STREAMS, g_streamInfosSnap); + DCameraSourceEvent event5(*camDev_, DCAMERA_EVENT_RELEASE_STREAMS, g_streamIdSnap); + DCameraSourceEvent event8(*camDev_, DCAMERA_EVENT_UPDATE_SETTINGS, g_cameraSettingSnap); + DCameraSourceEvent event9(*camDev_, DCAMERA_EVENT_NOFIFY, g_camEvent); + stateMachine_ ->UpdateState(DCAMERA_STATE_INIT); + stateMachine_ ->UpdateState(DCAMERA_STATE_REGIST); + stateMachine_ ->UpdateState(DCAMERA_STATE_OPENED); + int32_t ret = stateMachine_ ->Execute(DCAMERA_EVENT_REGIST, event0); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_OPEN, event2); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CONFIG_STREAMS, event4); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_RELEASE_STREAMS, event5); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_NOFIFY, event9); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UPDATE_SETTINGS, event8); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CLOSE, event3); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UNREGIST, event1); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_source_state_machine_test_004 + * @tc.desc: Verify source config Stream state. + * @tc.type: FUNC + * @tc.require: AR000GK6ME + */ +HWTEST_F(DCameraSourceStateMachineTest, dcamera_source_state_machine_test_004, TestSize.Level1) +{ + DCameraSourceEvent event0(*camDev_, DCAMERA_EVENT_REGIST, g_registParam); + DCameraSourceEvent event1(*camDev_, DCAMERA_EVENT_UNREGIST, g_registParam); + DCameraSourceEvent event2(*camDev_, DCAMERA_EVENT_OPEN, g_camIndex); + DCameraSourceEvent event3(*camDev_, DCAMERA_EVENT_CLOSE, g_camIndex); + DCameraSourceEvent event4(*camDev_, DCAMERA_EVENT_CONFIG_STREAMS, g_streamInfosSnap); + DCameraSourceEvent event5(*camDev_, DCAMERA_EVENT_RELEASE_STREAMS, g_streamIdSnap); + DCameraSourceEvent event6(*camDev_, DCAMERA_EVENT_START_CAPTURE, g_captureInfoSnap); + DCameraSourceEvent event7(*camDev_, DCAMERA_EVENT_STOP_CAPTURE); + DCameraSourceEvent event8(*camDev_, DCAMERA_EVENT_UPDATE_SETTINGS, g_cameraSettingSnap); + DCameraSourceEvent event9(*camDev_, DCAMERA_EVENT_NOFIFY, g_camEvent); + stateMachine_ ->UpdateState(DCAMERA_STATE_INIT); + stateMachine_ ->UpdateState(DCAMERA_STATE_REGIST); + stateMachine_ ->UpdateState(DCAMERA_STATE_OPENED); + stateMachine_ ->UpdateState(DCAMERA_STATE_CONFIG_STREAM); + int32_t ret = stateMachine_ ->Execute(DCAMERA_EVENT_REGIST, event0); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_OPEN, event2); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CONFIG_STREAMS, event4); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_START_CAPTURE, event6); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_NOFIFY, event9); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UPDATE_SETTINGS, event8); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_STOP_CAPTURE, event7); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_RELEASE_STREAMS, event5); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CLOSE, event3); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UNREGIST, event1); + EXPECT_EQ(DCAMERA_OK, ret); +} + +/** + * @tc.name: dcamera_source_state_machine_test_005 + * @tc.desc: Verify source capture state. + * @tc.type: FUNC + * @tc.require: AR000GK6ME + */ +HWTEST_F(DCameraSourceStateMachineTest, dcamera_source_state_machine_test_005, TestSize.Level1) +{ + DCameraSourceEvent event0(*camDev_, DCAMERA_EVENT_REGIST, g_registParam); + DCameraSourceEvent event1(*camDev_, DCAMERA_EVENT_UNREGIST, g_registParam); + DCameraSourceEvent event2(*camDev_, DCAMERA_EVENT_OPEN, g_camIndex); + DCameraSourceEvent event3(*camDev_, DCAMERA_EVENT_CLOSE, g_camIndex); + DCameraSourceEvent event6(*camDev_, DCAMERA_EVENT_START_CAPTURE, g_captureInfoSnap); + DCameraSourceEvent event7(*camDev_, DCAMERA_EVENT_STOP_CAPTURE); + DCameraSourceEvent event8(*camDev_, DCAMERA_EVENT_UPDATE_SETTINGS, g_cameraSettingSnap); + DCameraSourceEvent event9(*camDev_, DCAMERA_EVENT_NOFIFY, g_camEvent); + stateMachine_ ->UpdateState(DCAMERA_STATE_INIT); + stateMachine_ ->UpdateState(DCAMERA_STATE_REGIST); + stateMachine_ ->UpdateState(DCAMERA_STATE_OPENED); + stateMachine_ ->UpdateState(DCAMERA_STATE_CONFIG_STREAM); + stateMachine_ ->UpdateState(DCAMERA_STATE_CAPTURE); + int32_t ret = stateMachine_ ->Execute(DCAMERA_EVENT_REGIST, event0); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_OPEN, event2); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_START_CAPTURE, event6); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_NOFIFY, event9); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UPDATE_SETTINGS, event8); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_STOP_CAPTURE, event7); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_CLOSE, event3); + EXPECT_EQ(DCAMERA_OK, ret); + + ret = stateMachine_ ->Execute(DCAMERA_EVENT_UNREGIST, event1); + EXPECT_EQ(DCAMERA_OK, ret); +} +} +} \ No newline at end of file diff --git a/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/mock_dcamera_source_dev.h b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/mock_dcamera_source_dev.h new file mode 100644 index 00000000..d59341c0 --- /dev/null +++ b/services/cameraservice/sourceservice/test/unittest/common/distributedcameramgr/mock_dcamera_source_dev.h @@ -0,0 +1,84 @@ +/* + * 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_DISTRIBUTED_CAMERA_MOCKSOURCE_DEV_H +#define OHOS_DISTRIBUTED_CAMERA_MOCKSOURCE_DEV_H + +#include "dcamera_source_dev.h" + +#include "distributed_camera_errno.h" +#include "idistributed_camera_source.h" + +namespace OHOS { +namespace DistributedHardware { +class MockDCameraSourceDev : public DCameraSourceDev { +public: + MockDCameraSourceDev(std::string devId, std::string dhId) : DCameraSourceDev(devId, dhId, stateLisener_) {}; + ~MockDCameraSourceDev() = default; + + int32_t ExecuteRegister(std::shared_ptr& param) + { + return DCAMERA_OK; + } + int32_t ExecuteUnRegister(std::shared_ptr& param) + { + return DCAMERA_OK; + } + int32_t ExecuteOpenCamera() + { + return DCAMERA_OK; + } + int32_t ExecuteCloseCamera() + { + return DCAMERA_OK; + } + int32_t ExecuteConfigStreams(std::vector>& streamInfos) + { + return DCAMERA_OK; + } + int32_t ExecuteReleaseStreams(std::vector& streamIds, bool& isAllRelease) + { + return DCAMERA_OK; + } + int32_t ExecuteReleaseAllStreams() + { + return DCAMERA_OK; + } + int32_t ExecuteStartCapture(std::vector>& captureInfos) + { + return DCAMERA_OK; + } + int32_t ExecuteStopCapture() + { + return DCAMERA_OK; + } + int32_t ExecuteUpdateSettings(std::vector>& settings) + { + return DCAMERA_OK; + } + int32_t ExecuteCameraEventNotify(std::shared_ptr& events) + { + return DCAMERA_OK; + } + +private: + std::string devId_; + std::string dhId_; + std::shared_ptr stateLisener_ = nullptr; +}; +} // namespace DistributedHardware +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/channel/BUILD.gn b/services/channel/BUILD.gn new file mode 100644 index 00000000..fa955e46 --- /dev/null +++ b/services/channel/BUILD.gn @@ -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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_channel") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "include", + "${common_path}/include/constants", + "${common_path}/include/utils", + ] + + sources = [ + "src/dcamera_channel_sink_impl.cpp", + "src/dcamera_channel_source_impl.cpp", + "src/dcamera_softbus_adapter.cpp", + "src/dcamera_softbus_session.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcamerachannel\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "eventhandler:libeventhandler", + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/channel/include/dcamera_channel_sink_impl.h b/services/channel/include/dcamera_channel_sink_impl.h new file mode 100644 index 00000000..d276d119 --- /dev/null +++ b/services/channel/include/dcamera_channel_sink_impl.h @@ -0,0 +1,46 @@ +/* + * 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_CHANNEL_SINK_IMPL_H +#define OHOS_DCAMERA_CHANNEL_SINK_IMPL_H + +#include "icamera_channel.h" + +#include "dcamera_softbus_session.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraChannelSinkImpl : public ICameraChannel { +public: + DCameraChannelSinkImpl(); + ~DCameraChannelSinkImpl(); + int32_t OpenSession() override; + int32_t CloseSession() override; + int32_t CreateSession(std::vector& camIndexs, std::string sessionFlag, DCameraSessionMode sessionMode, + std::shared_ptr& listener) override; + int32_t ReleaseSession() override; + int32_t SendData(std::shared_ptr& buffer) override; + +private: + std::shared_ptr listener_; + std::vector camIndexs_; + std::shared_ptr softbusSession_; + std::string mySessionName_; + DCameraSessionMode mode_; + const std::string SESSION_HEAD = "DBinder.ohos.dhardware.dcamera_"; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/include/dcamera_channel_source_impl.h b/services/channel/include/dcamera_channel_source_impl.h new file mode 100644 index 00000000..f12b5309 --- /dev/null +++ b/services/channel/include/dcamera_channel_source_impl.h @@ -0,0 +1,46 @@ +/* + * 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_CHANNEL_SOURCE_IMPL_H +#define OHOS_DCAMERA_CHANNEL_SOURCE_IMPL_H + +#include "icamera_channel.h" + +#include "dcamera_softbus_session.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraChannelSourceImpl : public ICameraChannel { +public: + DCameraChannelSourceImpl(); + ~DCameraChannelSourceImpl(); + int32_t OpenSession() override; + int32_t CloseSession() override; + int32_t CreateSession(std::vector& camIndexs, std::string sessionFlag, DCameraSessionMode sessionMode, + std::shared_ptr& listener) override; + int32_t ReleaseSession() override; + int32_t SendData(std::shared_ptr& buffer) override; + +private: + std::shared_ptr listener_; + std::vector camIndexs_; + std::vector> softbusSessions_; + std::string mySessionName_; + DCameraSessionMode mode_; + const std::string SESSION_HEAD = "DBinder.ohos.dhardware.dcamera_"; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/include/dcamera_softbus_adapter.h b/services/channel/include/dcamera_softbus_adapter.h new file mode 100644 index 00000000..79c39604 --- /dev/null +++ b/services/channel/include/dcamera_softbus_adapter.h @@ -0,0 +1,86 @@ +/* + * 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_SOFTBUS_ADAPTER_H +#define OHOS_DCAMERA_SOFTBUS_ADAPTER_H + +#include +#include +#include + +#include "session.h" +#include "single_instance.h" + +#include "dcamera_softbus_session.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_CHANNLE_ROLE_SOURCE = 0, + DCAMERA_CHANNLE_ROLE_SINK = 1, +} DCAMERA_CHANNEL_ROLE; + +class DCameraSoftbusAdapter { +DECLARE_SINGLE_INSTANCE_BASE(DCameraSoftbusAdapter); +public: + int32_t CreateSoftbusSessionServer(std::string sessionName, DCAMERA_CHANNEL_ROLE role); + int32_t DestroySoftbusSessionServer(std::string sessionName); + int32_t OpenSoftbusSession(std::string mySessName, std::string peerSessName, int32_t sessionMode, + std::string peerDevId); + int32_t CloseSoftbusSession(int32_t sessionId); + int32_t SendSofbusBytes(int32_t sessionId, std::shared_ptr& buffer); + int32_t SendSofbusStream(int32_t sessionId, std::shared_ptr& buffer); + int32_t GetLocalNetworkId(std::string& myDevId); + + int32_t OnSourceSessionOpened(int32_t sessionId, int32_t result); + void OnSourceSessionClosed(int32_t sessionId); + void OnSourceBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen); + void OnSourceMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen); + void OnSourceStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param); + + int32_t OnSinkSessionOpened(int32_t sessionId, int32_t result); + void OnSinkSessionClosed(int32_t sessionId); + void OnSinkBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen); + void OnSinkMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen); + void OnSinkStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param); + +public: + std::map> sourceSessions_; + std::map> sinkSessions_; + +private: + DCameraSoftbusAdapter(); + ~DCameraSoftbusAdapter(); + + int32_t DCameraSoftbusSourceGetSession(int32_t sessionId, std::shared_ptr& session); + int32_t DCameraSoftbusSinkGetSession(int32_t sessionId, std::shared_ptr& session); + int32_t DCameraSoftbusGetSessionById(int32_t sessionId, std::shared_ptr& session); + +private: + std::mutex optLock_; + const string PKG_NAME = "DBinderBus_" + std::to_string(getpid()); + static const uint32_t DCAMERA_SESSION_NAME_MAX_LEN = 128; + map sessListeners_; + std::map sessionTotal_; + static const uint32_t DCAMERA_LINK_TYPE_MAX = 4; + static const uint32_t DCAMERA_LINK_TYPE_INDEX_2 = 2; + std::mutex idMapLock_; + std::map> sessionIdMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/include/dcamera_softbus_session.h b/services/channel/include/dcamera_softbus_session.h new file mode 100644 index 00000000..7d0934b0 --- /dev/null +++ b/services/channel/include/dcamera_softbus_session.h @@ -0,0 +1,120 @@ +/* + * 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_SOFTBUS_SESSION_H +#define OHOS_DCAMERA_SOFTBUS_SESSION_H + +#include "event_handler.h" +#include + +#include "icamera_channel.h" +#include "icamera_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_SOFTBUS_STATE_CLOSED = 0, + DCAMERA_SOFTBUS_STATE_OPENED = 1, +} DCameraSofbutState; + +class DCameraSoftbusSession { +public: + DCameraSoftbusSession(); + DCameraSoftbusSession(std::string myDevId, std::string mySessionName, std::string peerDevId, + std::string peerSessionName, std::shared_ptr listener, DCameraSessionMode mode); + ~DCameraSoftbusSession(); + int32_t OpenSession(); + int32_t CloseSession(); + int32_t OnSessionOpend(int32_t sessionId, int32_t result); + int32_t OnSessionClose(int32_t sessionId); + int32_t OnDataReceived(std::shared_ptr& buffer); + int32_t SendData(DCameraSessionMode mode, std::shared_ptr& buffer); + std::string GetPeerDevId(); + std::string GetPeerSessionName(); + std::string GetMySessionName(); + +private: + struct SessionDataHeader { + uint16_t version; + uint8_t fragFlag; + uint32_t dataType; + uint32_t seqNum; + uint32_t totalLen; + uint16_t subSeq; + uint32_t dataLen; + }; + + using DCameraSendFuc = int32_t (DCameraSoftbusSession::*)(std::shared_ptr& buffer); + int32_t SendBytes(std::shared_ptr& buffer); + int32_t SendStream(std::shared_ptr& buffer); + void DealRecvData(std::shared_ptr& buffer); + void PackRecvData(std::shared_ptr& buffer); + void AssembleNoFrag(std::shared_ptr& buffer, SessionDataHeader& headerPara); + void AssembleFrag(std::shared_ptr& buffer, SessionDataHeader& headerPara); + int32_t CheckUnPackBuffer(SessionDataHeader& headerPara); + void GetFragDataLen(uint8_t *ptrPacket, SessionDataHeader& headerPara); + int32_t UnPackSendData(std::shared_ptr& buffer, DCameraSendFuc memberFunc); + void MakeFragDataHeader(const SessionDataHeader& headPara, uint8_t *header, uint32_t len); + void PostData(std::shared_ptr& buffer); + uint16_t U16Get(const uint8_t *ptr); + uint32_t U32Get(const uint8_t *ptr); + void ResetAssembleFrag(); + + enum { + FRAG_NULL = 0, + FRAG_START, + FRAG_MID, + FRAG_END, + FRAG_START_END, + }; + + static const uint32_t BINARY_DATA_MAX_TOTAL_LEN = 100 * 1024 * 1024; + static const uint32_t BINARY_DATA_MAX_LEN = 1000 * 1024; + static const uint32_t BINARY_DATA_PACKET_MAX_LEN = 62 * 1024; + static const uint16_t PROTOCOL_VERSION = 1; + static const uint16_t HEADER_UINT8_NUM = 1; + static const uint16_t HEADER_UINT16_NUM = 2; + static const uint16_t HEADER_UINT32_NUM = 4; + static const uint16_t BINARY_HEADER_FRAG_LEN = 21; + + static const uint32_t BINARY_HEADER_FRAG_OFFSET = 2; + static const uint32_t BINARY_HEADER_DATATYPE_OFFSET = 3; + static const uint32_t BINARY_HEADER_SEQNUM_OFFSET = 7; + static const uint32_t BINARY_HEADER_TOTALLEN_OFFSET = 11; + static const uint32_t BINARY_HEADER_SUBSEQ_OFFSET = 15; + static const uint32_t BINARY_HEADER_DATALEN_OFFSET = 17; + + std::shared_ptr packBuffer_; + bool isWaiting_; + uint32_t nowSeq_; + uint32_t nowSubSeq_; + uint32_t offset_; + uint32_t totalLen_; + +private: + std::string myDevId_; + std::string mySessionName_; + std::string peerDevId_; + std::string peerSessionName_; + std::shared_ptr listener_; + int32_t sessionId_; + DCameraSofbutState state_; + DCameraSessionMode mode_; + std::map sendFuncMap_; + std::shared_ptr eventHandler_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/include/icamera_channel.h b/services/channel/include/icamera_channel.h new file mode 100644 index 00000000..e05b7a9c --- /dev/null +++ b/services/channel/include/icamera_channel.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 OHOS_ICAMERA_CHANNEL_H +#define OHOS_ICAMERA_CHANNEL_H + +#include "icamera_channel_listener.h" +#include "data_buffer.h" +#include "dcamera_index.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_SESSION_MODE_CTRL = 0, + DCAMERA_SESSION_MODE_VIDEO = 1, + DCAMERA_SESSION_MODE_JPEG = 2, +} DCameraSessionMode; + +class ICameraChannel { +public: + virtual ~ICameraChannel() = default; + + virtual int32_t OpenSession() = 0; + virtual int32_t CloseSession() = 0; + virtual int32_t CreateSession(std::vector& camIndexs, std::string sessionFlag, + DCameraSessionMode sessionMode, std::shared_ptr& listener) = 0; + virtual int32_t ReleaseSession(); + virtual int32_t SendData(std::shared_ptr& buffer) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/include/icamera_channel_listener.h b/services/channel/include/icamera_channel_listener.h new file mode 100644 index 00000000..a1cd2254 --- /dev/null +++ b/services/channel/include/icamera_channel_listener.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_ICAMERA_CHANNEL_LISTENER_H +#define OHOS_ICAMERA_CHANNEL_LISTENER_H + +#include +#include +#include + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DCAMERA_CHANNEL_STATE_DISCONNECTED = 0, + DCAMERA_CHANNEL_STATE_CONNECTING = 1, + DCAMERA_CHANNEL_STATE_CONNECTED = 2, +} DCameraChannelState; + +class ICameraChannelListener { +public: + virtual ~ICameraChannelListener() = default; + + virtual void OnSessionState(int32_t state) = 0; + virtual void OnSessionError(int32_t eventType, int32_t eventReason, std::string detail) = 0; + virtual void OnDataReceived(std::vector>& buffers) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/channel/src/dcamera_channel_sink_impl.cpp b/services/channel/src/dcamera_channel_sink_impl.cpp new file mode 100644 index 00000000..565c5473 --- /dev/null +++ b/services/channel/src/dcamera_channel_sink_impl.cpp @@ -0,0 +1,126 @@ +/* + * 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_channel_sink_impl.h" + +#include "dcamera_softbus_adapter.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraChannelSinkImpl::DCameraChannelSinkImpl() +{ + softbusSession_ = nullptr; +} + +DCameraChannelSinkImpl::~DCameraChannelSinkImpl() +{ +} + +int32_t DCameraChannelSinkImpl::OpenSession() +{ + DHLOGI("DCameraChannelSinkImpl OpenSession name: %s", mySessionName_.c_str()); + if (softbusSession_ == nullptr) { + DHLOGE("DCameraChannelSinkImpl OpenSession %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = softbusSession_->OpenSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSinkImpl OpenSession %s ret: %d", mySessionName_.c_str(), ret); + } + + return ret; +} + +int32_t DCameraChannelSinkImpl::CloseSession() +{ + DHLOGI("DCameraChannelSinkImpl CloseSession name: %s", mySessionName_.c_str()); + if (softbusSession_ == nullptr) { + DHLOGE("DCameraChannelSinkImpl CloseSession %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = softbusSession_->CloseSession(); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSinkImpl CloseSession %s ret: %d", mySessionName_.c_str(), ret); + } + + return ret; +} + +int32_t DCameraChannelSinkImpl::CreateSession(std::vector& camIndexs, std::string sessionFlag, + DCameraSessionMode sessionMode, std::shared_ptr& listener) +{ + if (camIndexs.size() > DCAMERA_MAX_NUM || listener == nullptr) { + return DCAMERA_BAD_VALUE; + } + if (softbusSession_ != nullptr) { + DHLOGI("DCameraChannelSinkImpl session has already create %s", sessionFlag.c_str()); + return DCAMERA_OK; + } + camIndexs_.assign(camIndexs.begin(), camIndexs.end()); + listener_ = listener; + mySessionName_ = SESSION_HEAD + camIndexs[0].dhId_ + std::string("_") + sessionFlag; + mode_ = sessionMode; + std::string myDevId; + DCameraSoftbusAdapter::GetInstance().GetLocalNetworkId(myDevId); + DHLOGI("DCameraChannelSinkImpl session create name: %s devId: %s", mySessionName_.c_str(), + GetAnonyString(myDevId).c_str()); + int32_t ret = DCameraSoftbusAdapter::GetInstance().CreateSoftbusSessionServer(mySessionName_, + DCAMERA_CHANNLE_ROLE_SINK); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSinkImpl CreateSession %s failed, ret: %d", mySessionName_.c_str(), ret); + return ret; + } + std::string peerDevId = camIndexs[0].devId_; + std::string peerSessionName = SESSION_HEAD + sessionFlag; + softbusSession_ = std::make_shared(myDevId, mySessionName_, peerDevId, peerSessionName, + listener, sessionMode); + DCameraSoftbusAdapter::GetInstance().sinkSessions_[mySessionName_] = softbusSession_; + return DCAMERA_OK; +} + +int32_t DCameraChannelSinkImpl::ReleaseSession() +{ + DHLOGI("DCameraChannelSinkImpl ReleaseSession name: %s", mySessionName_.c_str()); + if (softbusSession_ == nullptr) { + return DCAMERA_OK; + } + DCameraSoftbusAdapter::GetInstance().sourceSessions_.erase(softbusSession_->GetMySessionName()); + int32_t ret = DCameraSoftbusAdapter::GetInstance().DestroySoftbusSessionServer(softbusSession_->GetMySessionName()); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSinkImpl ReleaseSession %s failed, ret: %d", mySessionName_.c_str(), ret); + } + softbusSession_ = nullptr; + return ret; +} + +int32_t DCameraChannelSinkImpl::SendData(std::shared_ptr& buffer) +{ + if (softbusSession_ == nullptr) { + DHLOGE("DCameraChannelSinkImpl SendData %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = softbusSession_->SendData(mode_, buffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSinkImpl SendData %s failed, ret: %d", mySessionName_.c_str(), ret); + } + return ret; +} +} +} \ No newline at end of file diff --git a/services/channel/src/dcamera_channel_source_impl.cpp b/services/channel/src/dcamera_channel_source_impl.cpp new file mode 100644 index 00000000..f3fb7115 --- /dev/null +++ b/services/channel/src/dcamera_channel_source_impl.cpp @@ -0,0 +1,145 @@ +/* + * 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_channel_source_impl.h" + +#include "dcamera_softbus_adapter.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraChannelSourceImpl::DCameraChannelSourceImpl() +{ +} + +DCameraChannelSourceImpl::~DCameraChannelSourceImpl() +{ +} + +int32_t DCameraChannelSourceImpl::OpenSession() +{ + DHLOGI("DCameraChannelSourceImpl OpenSession name: %s", mySessionName_.c_str()); + if (softbusSessions_.empty()) { + DHLOGE("DCameraChannelSourceImpl OpenSession %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = DCAMERA_OK; + for (auto iter = softbusSessions_.begin(); iter != softbusSessions_.end(); iter++) { + int32_t retOpen = (*iter)->OpenSession(); + if (retOpen != DCAMERA_OK) { + DHLOGE("DCameraChannelSourceImpl OpenSession %s failed, ret: %d", mySessionName_.c_str(), retOpen); + ret = DCAMERA_BAD_OPERATE; + break; + } + } + + if (ret != DCAMERA_OK) { + CloseSession(); + } + + return ret; +} + +int32_t DCameraChannelSourceImpl::CloseSession() +{ + DHLOGI("DCameraChannelSourceImpl CloseSession name: %s", mySessionName_.c_str()); + if (softbusSessions_.empty()) { + DHLOGE("DCameraChannelSourceImpl CloseSession %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = DCAMERA_OK; + for (auto iter = softbusSessions_.begin(); iter != softbusSessions_.end(); iter++) { + int32_t retOpen = (*iter)->CloseSession(); + if (retOpen != DCAMERA_OK) { + DHLOGE("DCameraChannelSourceImpl CloseSession %s failed, ret: %d", mySessionName_.c_str(), retOpen); + ret = DCAMERA_BAD_OPERATE; + } + } + + return ret; +} + +int32_t DCameraChannelSourceImpl::CreateSession(std::vector& camIndexs, std::string sessionFlag, + DCameraSessionMode sessionMode, std::shared_ptr& listener) +{ + if (camIndexs.size() > DCAMERA_MAX_NUM || listener == nullptr) { + return DCAMERA_BAD_VALUE; + } + if (!softbusSessions_.empty()) { + DHLOGI("DCameraChannelSourceImpl session has already create %s", sessionFlag.c_str()); + return DCAMERA_OK; + } + camIndexs_.assign(camIndexs.begin(), camIndexs.end()); + listener_ = listener; + mySessionName_ = SESSION_HEAD + sessionFlag; + mode_ = sessionMode; + std::string myDevId; + DCameraSoftbusAdapter::GetInstance().GetLocalNetworkId(myDevId); + DHLOGI("DCameraChannelSourceImpl session create name: %s devId: %s", mySessionName_.c_str(), + GetAnonyString(myDevId).c_str()); + int32_t ret = DCameraSoftbusAdapter::GetInstance().CreateSoftbusSessionServer(mySessionName_, + DCAMERA_CHANNLE_ROLE_SOURCE); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSourceImpl CreateSession %s failed, ret: %d", mySessionName_.c_str(), ret); + return ret; + } + for (auto iter = camIndexs.begin(); iter != camIndexs.end(); iter++) { + std::string peerDevId = (*iter).devId_; + std::string peerSessionName = SESSION_HEAD + (*iter).dhId_ + std::string("_") + sessionFlag; + std::shared_ptr softbusSess = std::make_shared(myDevId, + mySessionName_, peerDevId, peerSessionName, listener, sessionMode); + softbusSessions_.push_back(softbusSess); + DCameraSoftbusAdapter::GetInstance().sourceSessions_[peerDevId + peerSessionName] = softbusSess; + } + return DCAMERA_OK; +} + +int32_t DCameraChannelSourceImpl::ReleaseSession() +{ + DHLOGI("DCameraChannelSourceImpl ReleaseSession name: %s", mySessionName_.c_str()); + for (auto iter = softbusSessions_.begin(); iter != softbusSessions_.end(); iter++) { + std::string sessKey = (*iter)->GetPeerDevId() + (*iter)->GetPeerSessionName(); + DCameraSoftbusAdapter::GetInstance().sourceSessions_.erase(sessKey); + } + std::vector>().swap(softbusSessions_); + int32_t ret = DCameraSoftbusAdapter::GetInstance().DestroySoftbusSessionServer(mySessionName_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraChannelSourceImpl ReleaseSession %s failed, ret: %d", mySessionName_.c_str(), ret); + } + return ret; +} + +int32_t DCameraChannelSourceImpl::SendData(std::shared_ptr& buffer) +{ + if (softbusSessions_.empty()) { + DHLOGE("DCameraChannelSourceImpl SendData %s failed", mySessionName_.c_str()); + return DCAMERA_BAD_OPERATE; + } + int32_t ret = DCAMERA_OK; + for (auto iter = softbusSessions_.begin(); iter != softbusSessions_.end(); iter++) { + int32_t retSend = (*iter)->SendData(mode_, buffer); + if (retSend != DCAMERA_OK) { + DHLOGE("DCameraChannelSourceImpl SendData %s failed, ret: %d", mySessionName_.c_str(), retSend); + ret = DCAMERA_BAD_OPERATE; + } + } + return ret; +} +} +} \ No newline at end of file diff --git a/services/channel/src/dcamera_softbus_adapter.cpp b/services/channel/src/dcamera_softbus_adapter.cpp new file mode 100644 index 00000000..f7bf7963 --- /dev/null +++ b/services/channel/src/dcamera_softbus_adapter.cpp @@ -0,0 +1,488 @@ +/* + * 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_softbus_adapter.h" + +#include + +#include "softbus_bus_center.h" +#include "softbus_common.h" + +#include "anonymous_string.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DCameraSoftbusAdapter); + +static int32_t DCameraSourceOnSessionOpend(int32_t sessionId, int32_t result) +{ + return DCameraSoftbusAdapter::GetInstance().OnSourceSessionOpened(sessionId, result); +} + +static void DCameraSourceOnSessionClosed(int32_t sessionId) +{ + DCameraSoftbusAdapter::GetInstance().OnSourceSessionClosed(sessionId); + return; +} + +static void DCameraSourceOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + DCameraSoftbusAdapter::GetInstance().OnSourceBytesReceived(sessionId, data, dataLen); + return; +} + +static void DCameraSourceOnMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + DCameraSoftbusAdapter::GetInstance().OnSourceMessageReceived(sessionId, data, dataLen); + return; +} + +static void DCameraSourceOnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + DCameraSoftbusAdapter::GetInstance().OnSourceStreamReceived(sessionId, data, ext, param); + return; +} + +static int32_t DCameraSinkOnSessionOpend(int32_t sessionId, int32_t result) +{ + return DCameraSoftbusAdapter::GetInstance().OnSinkSessionOpened(sessionId, result); +} + +static void DCameraSinkOnSessionClosed(int32_t sessionId) +{ + DCameraSoftbusAdapter::GetInstance().OnSinkSessionClosed(sessionId); + return; +} + +static void DCameraSinkOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + DCameraSoftbusAdapter::GetInstance().OnSinkBytesReceived(sessionId, data, dataLen); + return; +} + +static void DCameraSinkOnMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + DCameraSoftbusAdapter::GetInstance().OnSinkMessageReceived(sessionId, data, dataLen); + return; +} + +static void DCameraSinkOnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + DCameraSoftbusAdapter::GetInstance().OnSinkStreamReceived(sessionId, data, ext, param); + return; +} + +DCameraSoftbusAdapter::DCameraSoftbusAdapter() +{ + ISessionListener sourceListener; + sourceListener.OnSessionOpened = DCameraSourceOnSessionOpend; + sourceListener.OnSessionClosed = DCameraSourceOnSessionClosed; + sourceListener.OnBytesReceived = DCameraSourceOnBytesReceived; + sourceListener.OnMessageReceived = DCameraSourceOnMessageReceived; + sourceListener.OnStreamReceived = DCameraSourceOnStreamReceived; + sessListeners_[DCAMERA_CHANNLE_ROLE_SOURCE] = sourceListener; + + ISessionListener sinkListener; + sinkListener.OnSessionOpened = DCameraSinkOnSessionOpend; + sinkListener.OnSessionClosed = DCameraSinkOnSessionClosed; + sinkListener.OnBytesReceived = DCameraSinkOnBytesReceived; + sinkListener.OnMessageReceived = DCameraSinkOnMessageReceived; + sinkListener.OnStreamReceived = DCameraSinkOnStreamReceived; + sessListeners_[DCAMERA_CHANNLE_ROLE_SINK] = sinkListener; +} + +DCameraSoftbusAdapter::~DCameraSoftbusAdapter() +{ +} + +int32_t DCameraSoftbusAdapter::CreateSoftbusSessionServer(std::string sessionName, DCAMERA_CHANNEL_ROLE role) +{ + std::lock_guard autoLock(optLock_); + if (sessionTotal_.find(sessionName) != sessionTotal_.end()) { + sessionTotal_[sessionName]++; + DHLOGI("DCameraSoftbusAdapter sessionName already exist %s totalnum: %d", sessionName.c_str(), + sessionTotal_[sessionName]); + return DCAMERA_OK; + } + + int32_t ret = CreateSessionServer(PKG_NAME.c_str(), sessionName.c_str(), &sessListeners_[role]); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter CreateSessionServer failed, ret: %d", ret); + return ret; + } + sessionTotal_[sessionName]++; + DHLOGI("DCameraSoftbusAdapter sessionName create %s totalnum: %d", sessionName.c_str(), + sessionTotal_[sessionName]); + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::DestroySoftbusSessionServer(std::string sessionName) +{ + std::lock_guard autoLock(optLock_); + if (sessionTotal_.find(sessionName) == sessionTotal_.end()) { + DHLOGI("DCameraSoftbusAdapter sessionName already destroy %s", sessionName.c_str()); + return DCAMERA_OK; + } + + sessionTotal_[sessionName]--; + DHLOGI("DCameraSoftbusAdapter sessionName destroy %s totalnum: %d", sessionName.c_str(), + sessionTotal_[sessionName]); + uint32_t total_ = sessionTotal_[sessionName]; + if (total_ == 0) { + RemoveSessionServer(PKG_NAME.c_str(), sessionName.c_str()); + sessionTotal_.erase(sessionName); + } + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::OpenSoftbusSession(std::string mySessName, std::string peerSessName, + int32_t sessionMode, std::string peerDevId) +{ + uint32_t dataType = TYPE_STREAM; + uint32_t streamType = -1; + switch (sessionMode) { + case DCAMERA_SESSION_MODE_CTRL: { + dataType = TYPE_BYTES; + streamType = -1; + break; + } + case DCAMERA_SESSION_MODE_VIDEO: + case DCAMERA_SESSION_MODE_JPEG: { + dataType = TYPE_STREAM; + streamType = RAW_STREAM; + break; + } + default: + DHLOGE("DCameraSoftbusAdapter OpenSoftbusSession bad sessionMode %d", sessionMode); + return DCAMERA_BAD_VALUE; + } + SessionAttribute attr = { 0 }; + attr.dataType = static_cast(dataType); + attr.linkTypeNum = DCAMERA_LINK_TYPE_MAX; + LinkType linkTypeList[DCAMERA_LINK_TYPE_MAX] = { + LINK_TYPE_WIFI_P2P, + LINK_TYPE_WIFI_WLAN_5G, + LINK_TYPE_WIFI_WLAN_2G, + LINK_TYPE_BR, + }; + + if (dataType == TYPE_BYTES) { + linkTypeList[0] = LINK_TYPE_WIFI_WLAN_2G; + linkTypeList[DCAMERA_LINK_TYPE_INDEX_2] = LINK_TYPE_WIFI_P2P; + } + int32_t ret = memcpy_s(attr.linkType, DCAMERA_LINK_TYPE_MAX * sizeof(LinkType), linkTypeList, + DCAMERA_LINK_TYPE_MAX * sizeof(LinkType)); + if (ret != EOK) { + DHLOGE("DCameraSoftbusAdapter OpenSoftbusSession memcpy_s failed %d", ret); + return DCAMERA_BAD_VALUE; + } + attr.attr.streamAttr.streamType = (StreamType)streamType; + int32_t sessionId = OpenSession(mySessName.c_str(), peerSessName.c_str(), peerDevId.c_str(), "0", &attr); + if (sessionId < 0) { + DHLOGE("DCameraSoftbusAdapter OpenSoftbusSession failed %d", sessionId); + return DCAMERA_BAD_OPERATE; + } + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::CloseSoftbusSession(int32_t sessionId) +{ + DHLOGI("close softbus sessionId: %d", sessionId); + CloseSession(sessionId); + { + std::lock_guard autoLock(idMapLock_); + sessionIdMap_.erase(sessionId); + } + DHLOGI("close softbus sessionId: %d end", sessionId); + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::SendSofbusBytes(int32_t sessionId, std::shared_ptr& buffer) +{ + return SendBytes(sessionId, buffer->Data(), buffer->Size()); +} + +int32_t DCameraSoftbusAdapter::SendSofbusStream(int32_t sessionId, std::shared_ptr& buffer) +{ + StreamData streamData = { (char *)buffer->Data(), buffer->Size() }; + StreamData ext = { 0 }; + StreamFrameInfo param = { 0 }; + return SendStream(sessionId, &streamData, &ext, ¶m); +} + +int32_t DCameraSoftbusAdapter::DCameraSoftbusGetSessionById(int32_t sessionId, + std::shared_ptr& session) +{ + DHLOGI("get softbus session by sessionId: %d", sessionId); + std::lock_guard autoLock(idMapLock_); + auto iter = sessionIdMap_.find(sessionId); + if (iter == sessionIdMap_.end()) { + DHLOGE("get softbus session by id not find session %d", sessionId); + return DCAMERA_NOT_FOUND; + } + session = iter->second; + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::DCameraSoftbusSourceGetSession(int32_t sessionId, + std::shared_ptr& session) +{ + char peerSessionName[DCAMERA_SESSION_NAME_MAX_LEN] = ""; + char peerDevId[NETWORK_ID_BUF_LEN] = ""; + int32_t ret = GetPeerSessionName(sessionId, peerSessionName, sizeof(peerSessionName)); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSoftbusAdapter DCameraSoftbusSourceGetSession sessionId: %d GetPeerSessionName failed: %d", + sessionId, ret); + return ret; + } + + ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSoftbusAdapter DCameraSoftbusSourceGetSession sessionId: %d GetPeerDeviceId failed: %d", + sessionId, ret); + return ret; + } + + auto iter = sourceSessions_.find(std::string(peerDevId) + std::string(peerSessionName)); + if (iter == sourceSessions_.end()) { + DHLOGE("DCameraSoftbusAdapter DCameraSoftbusSourceGetSession not find session %d", sessionId); + return DCAMERA_NOT_FOUND; + } + session = iter->second; + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::OnSourceSessionOpened(int32_t sessionId, int32_t result) +{ + DHLOGI("DCameraSoftbusAdapter OnSourceSessionOpened sessionId: %d, result: %d", sessionId, result); + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSourceGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSourceSessionOpened not find session %d", sessionId); + return DCAMERA_NOT_FOUND; + } + + ret = session->OnSessionOpend(sessionId, result); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSourceSessionOpened failed %d sessionId: %d", ret, sessionId); + } else { + std::lock_guard autoLock(idMapLock_); + sessionIdMap_.emplace(sessionId, session); + } + DHLOGI("DCameraSoftbusAdapter OnSourceSessionOpened sessionId: %d, result: %d end", sessionId, result); + return ret; +} + +void DCameraSoftbusAdapter::OnSourceSessionClosed(int32_t sessionId) +{ + DHLOGI("DCameraSoftbusAdapter OnSourceSessionClosed sessionId: %d", sessionId); + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusGetSessionById(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSourceSessionClosed not find session %d", sessionId); + return; + } + { + std::lock_guard autoLock(idMapLock_); + sessionIdMap_.erase(sessionId); + } + session->OnSessionClose(sessionId); + DHLOGI("DCameraSoftbusAdapter OnSourceSessionClosed sessionId: %d end", sessionId); + return; +} + +void DCameraSoftbusAdapter::OnSourceBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + if (dataLen == 0 || dataLen > DCAMERA_MAX_RECV_DATA_LEN || data == nullptr) { + DHLOGE("DCameraSoftbusAdapter OnSourceBytesReceived dataLen: %d, sessionId: %d", dataLen, sessionId); + return; + } + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSourceGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSourceBytesReceived not find session %d", sessionId); + return; + } + + std::shared_ptr buffer = std::make_shared(dataLen); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), data, dataLen); + if (ret != EOK) { + DHLOGE("DCameraSoftbusAdapter OnSourceBytesReceived memcpy_s failed ret: %d", ret); + return; + } + session->OnDataReceived(buffer); + return; +} + +void DCameraSoftbusAdapter::OnSourceMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + return; +} + +void DCameraSoftbusAdapter::OnSourceStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + int32_t dataLen = data->bufLen; + if (dataLen <= 0 || dataLen > (int32_t)DCAMERA_MAX_RECV_DATA_LEN || data == nullptr) { + DHLOGE("DCameraSoftbusAdapter OnSourceStreamReceived dataLen: %d, sessionId: %d", dataLen, sessionId); + return; + } + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSourceGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSourceStreamReceived not find session %d", sessionId); + return; + } + + std::shared_ptr buffer = std::make_shared(data->bufLen); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), (uint8_t *)data->buf, data->bufLen); + if (ret != EOK) { + DHLOGE("DCameraSoftbusAdapter OnSourceStreamReceived memcpy_s failed ret: %d", ret); + return; + } + session->OnDataReceived(buffer); + return; +} + +int32_t DCameraSoftbusAdapter::DCameraSoftbusSinkGetSession(int32_t sessionId, + std::shared_ptr& session) +{ + char mySessionName[DCAMERA_SESSION_NAME_MAX_LEN] = ""; + int ret = GetMySessionName(sessionId, mySessionName, sizeof(mySessionName)); + if (ret != DCAMERA_OK) { + DHLOGI("DCameraSoftbusAdapter DCameraSoftbusSinkGetSession sessionId: %d GetPeerSessionName failed: %d", + sessionId, ret); + return ret; + } + + auto iter = sinkSessions_.find(std::string(mySessionName)); + if (iter == sinkSessions_.end()) { + DHLOGE("DCameraSoftbusAdapter DCameraSoftbusSinkGetSession not find session %d", sessionId); + return DCAMERA_NOT_FOUND; + } + session = iter->second; + return DCAMERA_OK; +} + +int32_t DCameraSoftbusAdapter::OnSinkSessionOpened(int32_t sessionId, int32_t result) +{ + DHLOGI("DCameraSoftbusAdapter OnSinkSessionOpened sessionId: %d, result: %d", sessionId, result); + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSinkGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSinkSessionOpened not find session %d", sessionId); + return DCAMERA_NOT_FOUND; + } + + ret = session->OnSessionOpend(sessionId, result); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSinkSessionOpened not find session %d", sessionId); + } else { + std::lock_guard autoLock(idMapLock_); + sessionIdMap_.emplace(sessionId, session); + } + DHLOGI("DCameraSoftbusAdapter OnSinkSessionOpened sessionId: %d, result: %d end", sessionId, result); + return ret; +} + +void DCameraSoftbusAdapter::OnSinkSessionClosed(int32_t sessionId) +{ + DHLOGI("DCameraSoftbusAdapter OnSinkSessionClosed sessionId: %d", sessionId); + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusGetSessionById(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSinkSessionClosed not find session %d", sessionId); + return; + } + { + std::lock_guard autoLock(idMapLock_); + sessionIdMap_.erase(sessionId); + } + session->OnSessionClose(sessionId); + return; +} + +void DCameraSoftbusAdapter::OnSinkBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + if (dataLen == 0 || dataLen > DCAMERA_MAX_RECV_DATA_LEN || data == nullptr) { + DHLOGE("DCameraSoftbusAdapter OnSinkBytesReceived dataLen: %d, sessionId: %d", dataLen, sessionId); + return; + } + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSinkGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSinkBytesReceived not find session %d", sessionId); + return; + } + + std::shared_ptr buffer = std::make_shared(dataLen); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), data, dataLen); + if (ret != EOK) { + DHLOGE("DCameraSoftbusAdapter OnSinkBytesReceived memcpy_s failed ret: %d", ret); + return; + } + session->OnDataReceived(buffer); + return; +} + +void DCameraSoftbusAdapter::OnSinkMessageReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + return; +} + +void DCameraSoftbusAdapter::OnSinkStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + int32_t dataLen = data->bufLen; + if (dataLen <= 0 || dataLen > (int32_t)DCAMERA_MAX_RECV_DATA_LEN || data == nullptr) { + DHLOGE("DCameraSoftbusAdapter OnSinkStreamReceived dataLen: %d sessionId: %d", dataLen, sessionId); + return; + } + std::shared_ptr session = nullptr; + int32_t ret = DCameraSoftbusSinkGetSession(sessionId, session); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter OnSinkStreamReceived not find session %d", sessionId); + return; + } + + std::shared_ptr buffer = std::make_shared(data->bufLen); + ret = memcpy_s(buffer->Data(), buffer->Capacity(), (uint8_t *)data->buf, data->bufLen); + if (ret != EOK) { + DHLOGE("DCameraSoftbusAdapter OnSinkStreamReceived memcpy_s failed ret: %d", ret); + return; + } + session->OnDataReceived(buffer); + return; +} + +int32_t DCameraSoftbusAdapter::GetLocalNetworkId(std::string& myDevId) +{ + NodeBasicInfo basicInfo = { { 0 } }; + int32_t ret = GetLocalNodeDeviceInfo(PKG_NAME.c_str(), &basicInfo); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusAdapter GetLocalNodeDeviceInfo failed ret: %d", ret); + return ret; + } + + myDevId = std::string(basicInfo.networkId); + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/channel/src/dcamera_softbus_session.cpp b/services/channel/src/dcamera_softbus_session.cpp new file mode 100644 index 00000000..e4a562f4 --- /dev/null +++ b/services/channel/src/dcamera_softbus_session.cpp @@ -0,0 +1,451 @@ +/* + * 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_softbus_session.h" + +#include + +#include "anonymous_string.h" +#include "dcamera_softbus_adapter.h" +#include "distributed_camera_constants.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +DCameraSoftbusSession::DCameraSoftbusSession() +{ + sessionId_ = -1; + state_ = DCAMERA_SOFTBUS_STATE_CLOSED; + mode_ = DCAMERA_SESSION_MODE_CTRL; + ResetAssembleFrag(); +} + +DCameraSoftbusSession::DCameraSoftbusSession(std::string myDevId, std::string mySessionName, std::string peerDevId, + std::string peerSessionName, std::shared_ptr listener, DCameraSessionMode mode) + : myDevId_(myDevId), mySessionName_(mySessionName), peerDevId_(peerDevId), peerSessionName_(peerSessionName), + listener_(listener), sessionId_(-1), state_(DCAMERA_SOFTBUS_STATE_CLOSED), mode_(mode) +{ + sendFuncMap_[DCAMERA_SESSION_MODE_CTRL] = &DCameraSoftbusSession::SendBytes; + sendFuncMap_[DCAMERA_SESSION_MODE_VIDEO] = &DCameraSoftbusSession::SendStream; + sendFuncMap_[DCAMERA_SESSION_MODE_JPEG] = &DCameraSoftbusSession::SendStream; + auto runner = AppExecFwk::EventRunner::Create(mySessionName); + eventHandler_ = std::make_shared(runner); + ResetAssembleFrag(); +} + +DCameraSoftbusSession::~DCameraSoftbusSession() +{ + if (sessionId_ != -1) { + int32_t ret = DCameraSoftbusAdapter::GetInstance().CloseSoftbusSession(sessionId_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession delete failed, ret: %d, sessId: %d peerDevId: %s peerSessionName: %s", ret, + sessionId_, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + } + } + sendFuncMap_.clear(); + eventHandler_ = nullptr; +} + +int32_t DCameraSoftbusSession::OpenSession() +{ + DHLOGI("DCameraSoftbusSession OpenSession peerDevId: %s peerSessionName: %s", + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + int32_t ret = DCameraSoftbusAdapter::GetInstance().OpenSoftbusSession(mySessionName_, peerSessionName_, mode_, + peerDevId_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession OpenSession failed, ret: %d, peerDevId: %s peerSessionName: %s", ret, + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + return ret; + } + + listener_->OnSessionState(DCAMERA_CHANNEL_STATE_CONNECTING); + return DCAMERA_OK; +} + +int32_t DCameraSoftbusSession::CloseSession() +{ + DHLOGI("DCameraSoftbusSession CloseSession sessionId: %d peerDevId: %s peerSessionName: %s", sessionId_, + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + if (sessionId_ == -1) { + DHLOGI("DCameraSoftbusSession CloseSession has already close peerDevId: %s peerSessionName: %s", + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + return DCAMERA_OK; + } + int32_t ret = DCameraSoftbusAdapter::GetInstance().CloseSoftbusSession(sessionId_); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession CloseSession failed, ret: %d, peerDevId: %s peerSessionName: %s", ret, + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + return ret; + } + + sessionId_ = -1; + state_ = DCAMERA_SOFTBUS_STATE_CLOSED; + return DCAMERA_OK; +} + +int32_t DCameraSoftbusSession::OnSessionOpend(int32_t sessionId, int32_t result) +{ + DHLOGI("DCameraSoftbusSession OnSessionOpend sessionId: %d result: %d peerDevId: %s peerSessionName: %s", + sessionId, result, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + if (result != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession OnSessionOpend sessionId: %d result: %d peerDevId: %s peerSessionName: %s", + sessionId_, result, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + listener_->OnSessionState(DCAMERA_CHANNEL_STATE_DISCONNECTED); + listener_->OnSessionError(DCAMERA_MESSAGE, DCAMERA_EVENT_OPEN_CHANNEL_ERROR, + std::string("softbus internal error")); + return result; + } + + sessionId_ = sessionId; + state_ = DCAMERA_SOFTBUS_STATE_OPENED; + listener_->OnSessionState(DCAMERA_CHANNEL_STATE_CONNECTED); + return DCAMERA_OK; +} + +int32_t DCameraSoftbusSession::OnSessionClose(int32_t sessionId) +{ + DHLOGI("DCameraSoftbusSession OnSessionClose sessionId: %d peerDevId: %s peerSessionName: %s", sessionId, + GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + sessionId_ = -1; + state_ = DCAMERA_SOFTBUS_STATE_CLOSED; + listener_->OnSessionState(DCAMERA_CHANNEL_STATE_DISCONNECTED); + return DCAMERA_OK; +} + +int32_t DCameraSoftbusSession::OnDataReceived(std::shared_ptr& buffer) +{ + auto recvDataFunc = [this, buffer]() mutable { + DealRecvData(buffer); + }; + if (eventHandler_ != nullptr) { + eventHandler_->PostTask(recvDataFunc); + } + return DCAMERA_OK; +} + +void DCameraSoftbusSession::DealRecvData(std::shared_ptr& buffer) +{ + if (mode_ == DCAMERA_SESSION_MODE_VIDEO) { + PostData(buffer); + return; + } + PackRecvData(buffer); + return; +} + +void DCameraSoftbusSession::PackRecvData(std::shared_ptr& buffer) +{ + if (buffer->Size() < BINARY_HEADER_FRAG_LEN) { + DHLOGE("DCameraSoftbusSession PackRecvData failed, size: %d, sess: %s peerSess: %s", + buffer->Size(), mySessionName_.c_str(), peerSessionName_.c_str()); + return; + } + uint8_t *ptrPacket = buffer->Data(); + SessionDataHeader headerPara; + GetFragDataLen(ptrPacket, headerPara); + if (buffer->Size() != (headerPara.dataLen + BINARY_HEADER_FRAG_LEN) || headerPara.dataLen > headerPara.totalLen || + headerPara.dataLen > BINARY_DATA_MAX_LEN || headerPara.totalLen > BINARY_DATA_MAX_TOTAL_LEN) { + DHLOGE("DCameraSoftbusSession PackRecvData failed, size: %d, dataLen: %d, totalLen: %d sess: %s peerSess: %s", + buffer->Size(), headerPara.dataLen, headerPara.totalLen, mySessionName_.c_str(), peerSessionName_.c_str()); + return; + } + + DHLOGD("DCameraSoftbusSession PackRecvData Assemble, size: %d, dataLen: %d, totalLen: %d sess: %s peerSess: %s", + buffer->Size(), headerPara.dataLen, headerPara.totalLen, mySessionName_.c_str(), peerSessionName_.c_str()); + if (headerPara.fragFlag == FRAG_START_END) { + AssembleNoFrag(buffer, headerPara); + } else { + AssembleFrag(buffer, headerPara); + } +} + +void DCameraSoftbusSession::AssembleNoFrag(std::shared_ptr& buffer, SessionDataHeader& headerPara) +{ + if (headerPara.dataLen != headerPara.totalLen) { + DHLOGE("DCameraSoftbusSession PackRecvData failed, dataLen: %d, totalLen: %d, sess: %s peerSess: %s", + headerPara.dataLen, headerPara.totalLen, mySessionName_.c_str(), peerSessionName_.c_str()); + return; + } + std::shared_ptr postData = std::make_shared(headerPara.dataLen); + int32_t ret = memcpy_s(postData->Data(), postData->Size(), buffer->Data() + BINARY_HEADER_FRAG_LEN, + buffer->Size() - BINARY_HEADER_FRAG_LEN); + if (ret != EOK) { + DHLOGE("DCameraSoftbusSession PackRecvData failed, ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + return; + } + PostData(postData); +} + +void DCameraSoftbusSession::AssembleFrag(std::shared_ptr& buffer, SessionDataHeader& headerPara) +{ + if (headerPara.fragFlag == FRAG_START) { + isWaiting_ = true; + nowSeq_ = headerPara.seqNum; + nowSubSeq_ = headerPara.subSeq; + offset_ = 0; + totalLen_ = headerPara.totalLen; + packBuffer_ = std::make_shared(headerPara.totalLen); + int32_t ret = memcpy_s(packBuffer_->Data(), packBuffer_->Size(), buffer->Data() + BINARY_HEADER_FRAG_LEN, + buffer->Size() - BINARY_HEADER_FRAG_LEN); + if (ret != EOK) { + DHLOGE("DCameraSoftbusSession AssembleFrag failed, ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + ResetAssembleFrag(); + return; + } + offset_ += headerPara.dataLen; + } + + if (headerPara.fragFlag == FRAG_MID || headerPara.fragFlag == FRAG_END) { + int32_t ret = CheckUnPackBuffer(headerPara); + if (ret != DCAMERA_OK) { + return; + } + + nowSubSeq_ = headerPara.subSeq; + ret = memcpy_s(packBuffer_->Data() + offset_, packBuffer_->Size() - offset_, + buffer->Data() + BINARY_HEADER_FRAG_LEN, buffer->Size() - BINARY_HEADER_FRAG_LEN); + if (ret != EOK) { + DHLOGE("DCameraSoftbusSession AssembleFrag failed, memcpy_s ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + ResetAssembleFrag(); + return; + } + offset_ += headerPara.dataLen; + } + + if (headerPara.fragFlag == FRAG_END) { + PostData(packBuffer_); + ResetAssembleFrag(); + } +} + +int32_t DCameraSoftbusSession::CheckUnPackBuffer(SessionDataHeader& headerPara) +{ + if (!isWaiting_) { + DHLOGE("DCameraSoftbusSession AssembleFrag failed, not start one, sess: %s peerSess: %s", + mySessionName_.c_str(), peerSessionName_.c_str()); + return DCAMERA_BAD_VALUE; + } + + if (nowSeq_ != headerPara.seqNum) { + DHLOGE("DCameraSoftbusSession AssembleFrag seq error nowSeq: %d actualSeq: %d, sess: %s peerSess: %s", + nowSeq_, headerPara.seqNum, mySessionName_.c_str(), peerSessionName_.c_str()); + return DCAMERA_BAD_VALUE; + } + + if (nowSubSeq_ + 1 != headerPara.subSeq) { + DHLOGE("DCameraSoftbusSession AssembleFrag subSeq error nowSeq: %d actualSeq: %d, sess: %s peerSess: %s", + nowSubSeq_, headerPara.subSeq, mySessionName_.c_str(), peerSessionName_.c_str()); + return DCAMERA_BAD_VALUE; + } + + if (totalLen_ < headerPara.dataLen + offset_) { + DHLOGE("DCameraSoftbusSession AssembleFrag len error cap: %d size: %d, dataLen: %d sess: %s peerSess: %s", + totalLen_, offset_, headerPara.dataLen, mySessionName_.c_str(), + peerSessionName_.c_str()); + return DCAMERA_BAD_VALUE; + } + return DCAMERA_OK; +} + +void DCameraSoftbusSession::ResetAssembleFrag() +{ + isWaiting_ = false; + nowSeq_ = 0; + nowSubSeq_ = 0; + offset_ = 0; + totalLen_ = 0; + packBuffer_ = nullptr; +} + +void DCameraSoftbusSession::PostData(std::shared_ptr& buffer) +{ + std::vector> buffers; + buffers.push_back(buffer); + listener_->OnDataReceived(buffers); +} + +void DCameraSoftbusSession::GetFragDataLen(uint8_t *ptrPacket, SessionDataHeader& headerPara) +{ + headerPara.version = U16Get(ptrPacket); + headerPara.fragFlag = ptrPacket[static_cast(BINARY_HEADER_FRAG_OFFSET)]; + headerPara.dataType = U32Get(ptrPacket + BINARY_HEADER_DATATYPE_OFFSET); + headerPara.seqNum = U32Get(ptrPacket + BINARY_HEADER_SEQNUM_OFFSET); + headerPara.totalLen = U32Get(ptrPacket + BINARY_HEADER_TOTALLEN_OFFSET); + headerPara.subSeq = U16Get(ptrPacket + BINARY_HEADER_SUBSEQ_OFFSET); + headerPara.dataLen = U32Get(ptrPacket + BINARY_HEADER_DATALEN_OFFSET); +} + +uint16_t DCameraSoftbusSession::U16Get(const uint8_t *ptr) +{ + return (ptr[0] << DCAMERA_SHIFT_8) | ptr[1]; +} + +uint32_t DCameraSoftbusSession::U32Get(const uint8_t *ptr) +{ + return (ptr[0] << DCAMERA_SHIFT_24) | (ptr[1] << DCAMERA_SHIFT_16) | (ptr[2] << DCAMERA_SHIFT_8) | ptr[3]; +} + +int32_t DCameraSoftbusSession::SendData(DCameraSessionMode mode, std::shared_ptr& buffer) +{ + auto itFunc = sendFuncMap_.find(mode); + if (itFunc == sendFuncMap_.end()) { + return DCAMERA_NOT_FOUND; + } + auto memberFunc = itFunc->second; + if (mode == DCAMERA_SESSION_MODE_VIDEO) { + return (this->*memberFunc)(buffer); + } + + return UnPackSendData(buffer, memberFunc); +} + +int32_t DCameraSoftbusSession::UnPackSendData(std::shared_ptr& buffer, DCameraSendFuc memberFunc) +{ + uint16_t subSeq = 0; + uint32_t seq = 0; + uint32_t totalLen = buffer->Size(); + SessionDataHeader headPara = { PROTOCOL_VERSION, FRAG_START, mode_, seq, totalLen, subSeq }; + + if (buffer->Size() <= BINARY_DATA_PACKET_MAX_LEN) { + headPara.fragFlag = FRAG_START_END; + headPara.dataLen = buffer->Size(); + std::shared_ptr unpackData = std::make_shared(buffer->Size() + BINARY_HEADER_FRAG_LEN); + MakeFragDataHeader(headPara, unpackData->Data(), BINARY_HEADER_FRAG_LEN); + int32_t ret = memcpy_s(unpackData->Data() + BINARY_HEADER_FRAG_LEN, unpackData->Size() - BINARY_HEADER_FRAG_LEN, + buffer->Data(), buffer->Size()); + if (ret != EOK) { + DHLOGE("DCameraSoftbusSession UnPackSendData START_END memcpy_s failed, ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + return ret; + } + return (this->*memberFunc)(unpackData); + } + + uint32_t offset = 0; + while (totalLen > offset) { + if (totalLen - offset > BINARY_DATA_PACKET_MAX_LEN) { + headPara.dataLen = BINARY_DATA_PACKET_MAX_LEN; + } else { + headPara.fragFlag = FRAG_END; + headPara.dataLen = totalLen - offset; + } + + std::shared_ptr unpackData = + std::make_shared(headPara.dataLen + BINARY_HEADER_FRAG_LEN); + MakeFragDataHeader(headPara, unpackData->Data(), BINARY_HEADER_FRAG_LEN); + int ret = memcpy_s(unpackData->Data() + BINARY_HEADER_FRAG_LEN, unpackData->Size() - BINARY_HEADER_FRAG_LEN, + buffer->Data() + offset, headPara.dataLen); + if (ret != EOK) { + DHLOGE("DCameraSoftbusSession UnPackSendData memcpy_s failed, ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + return ret; + } + ret = (this->*memberFunc)(unpackData); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession sendData failed, ret: %d, sess: %s peerSess: %s", + ret, mySessionName_.c_str(), peerSessionName_.c_str()); + return ret; + } + headPara.subSeq++; + headPara.fragFlag = FRAG_MID; + offset += headPara.dataLen; + } + return DCAMERA_OK; +} + +void DCameraSoftbusSession::MakeFragDataHeader(const SessionDataHeader& headPara, uint8_t *header, uint32_t len) +{ + uint32_t headerLen = sizeof(uint8_t) * HEADER_UINT8_NUM + sizeof(uint16_t) * HEADER_UINT16_NUM + + sizeof(uint32_t) * HEADER_UINT32_NUM; + if (headerLen > len) { + DHLOGE("MakeFragDataHeader %d over len %d", headerLen, len); + return; + } + uint32_t i = 0; + header[i++] = headPara.version >> DCAMERA_SHIFT_8; + header[i++] = headPara.version & UINT16_SHIFT_MASK_0; + header[i++] = headPara.fragFlag; + header[i++] = (headPara.dataType & UINT32_SHIFT_MASK_24) >> DCAMERA_SHIFT_24; + header[i++] = (headPara.dataType & UINT32_SHIFT_MASK_16) >> DCAMERA_SHIFT_16; + header[i++] = (headPara.dataType & UINT32_SHIFT_MASK_8) >> DCAMERA_SHIFT_8; + header[i++] = (headPara.dataType & UINT32_SHIFT_MASK_0); + header[i++] = (headPara.seqNum & UINT32_SHIFT_MASK_24) >> DCAMERA_SHIFT_24; + header[i++] = (headPara.seqNum & UINT32_SHIFT_MASK_16) >> DCAMERA_SHIFT_16; + header[i++] = (headPara.seqNum & UINT32_SHIFT_MASK_8) >> DCAMERA_SHIFT_8; + header[i++] = (headPara.seqNum & UINT32_SHIFT_MASK_0); + header[i++] = (headPara.totalLen & UINT32_SHIFT_MASK_24) >> DCAMERA_SHIFT_24; + header[i++] = (headPara.totalLen & UINT32_SHIFT_MASK_16) >> DCAMERA_SHIFT_16; + header[i++] = (headPara.totalLen & UINT32_SHIFT_MASK_8) >> DCAMERA_SHIFT_8; + header[i++] = (headPara.totalLen & UINT32_SHIFT_MASK_0); + header[i++] = headPara.subSeq >> DCAMERA_SHIFT_8; + header[i++] = headPara.subSeq & UINT16_SHIFT_MASK_0; + header[i++] = (headPara.dataLen & UINT32_SHIFT_MASK_24) >> DCAMERA_SHIFT_24; + header[i++] = (headPara.dataLen & UINT32_SHIFT_MASK_16) >> DCAMERA_SHIFT_16; + header[i++] = (headPara.dataLen & UINT32_SHIFT_MASK_8) >> DCAMERA_SHIFT_8; + header[i++] = (headPara.dataLen & UINT32_SHIFT_MASK_0); +} + +int32_t DCameraSoftbusSession::SendBytes(std::shared_ptr& buffer) +{ + if (state_ != DCAMERA_SOFTBUS_STATE_OPENED) { + DHLOGE("DCameraSoftbusSession SendBytes session state %d is not opened sessionId: %d peerDev: %s peerName: %s", + state_, sessionId_, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + return DCAMERA_WRONG_STATE; + } + + int32_t ret = DCameraSoftbusAdapter::GetInstance().SendSofbusBytes(sessionId_, buffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession SendBytes sessionId: %d failed: %d peerDevId: %s peerSessionName: %s", sessionId_, + ret, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + } + return ret; +} + +int32_t DCameraSoftbusSession::SendStream(std::shared_ptr& buffer) +{ + if (state_ != DCAMERA_SOFTBUS_STATE_OPENED) { + DHLOGE("DCameraSoftbusSession SendStream session state %d is not opened sessionId: %d peerDev: %s peerName: %s", + state_, sessionId_, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + return DCAMERA_WRONG_STATE; + } + + int32_t ret = DCameraSoftbusAdapter::GetInstance().SendSofbusStream(sessionId_, buffer); + if (ret != DCAMERA_OK) { + DHLOGE("DCameraSoftbusSession SendStream sessionId: %d failed: %d peerDevId: %s peerSessionName: %s", + sessionId_, ret, GetAnonyString(peerDevId_).c_str(), GetAnonyString(peerSessionName_).c_str()); + } + return ret; +} + +std::string DCameraSoftbusSession::GetPeerDevId() +{ + return peerDevId_; +} + +std::string DCameraSoftbusSession::GetPeerSessionName() +{ + return peerSessionName_; +} + +std::string DCameraSoftbusSession::GetMySessionName() +{ + return mySessionName_; +} +} +} \ No newline at end of file diff --git a/services/data_process/BUILD.gn b/services/data_process/BUILD.gn new file mode 100644 index 00000000..a4aa82d7 --- /dev/null +++ b/services/data_process/BUILD.gn @@ -0,0 +1,81 @@ +# 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("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedcamera/distributedcamera.gni") + +ohos_shared_library("distributed_camera_data_process") { + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//foundation/graphic/standard/interfaces/innerkits/common", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "//drivers/peripheral/display/interfaces/include", + "//foundation/multimedia/media_standard/interfaces/innerkits/native/media/include", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + "${fwk_utils_path}/include/eventbus", + "${fwk_utils_path}/include", + ] + + include_dirs += [ + "include/interfaces", + "include/eventbus", + "include/pipeline", + "include/utils", + "include/pipeline_node/multimedia_codec", + "include/pipeline_node/colorspace_conversion", + "include/pipeline_node/fpscontroller", + "${common_path}/include/constants", + "${common_path}/include/utils", + "${innerkits_path}/native_cpp/camera_source/include", + ] + + sources = [ + "src/pipeline/dcamera_pipeline_sink.cpp", + "src/pipeline/dcamera_pipeline_source.cpp", + "src/pipeline/abstract_data_process.cpp", + "src/utils/image_common_type.cpp", + "src/pipeline_node/multimedia_codec/decode_data_process.cpp", + "src/pipeline_node/multimedia_codec/decode_video_callback.cpp", + "src/pipeline_node/multimedia_codec/encode_data_process.cpp", + "src/pipeline_node/multimedia_codec/encode_video_callback.cpp", + "src/pipeline_node/fpscontroller/fps_controller_process.cpp", + "src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp", + ] + + deps = [ + "${fwk_utils_path}:distributedhardwareutils", + "${common_path}:distributed_camera_utils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dcameradataproc\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "eventhandler:libeventhandler", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_camera" +} \ No newline at end of file diff --git a/services/data_process/include/eventbus/dcamera_codec_event.h b/services/data_process/include/eventbus/dcamera_codec_event.h new file mode 100644 index 00000000..3cb83d27 --- /dev/null +++ b/services/data_process/include/eventbus/dcamera_codec_event.h @@ -0,0 +1,90 @@ +/* + * 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_CODEC_EVENT_H +#define OHOS_DCAMERA_CODEC_EVENT_H + +#include + +#include "event.h" +#include "data_buffer.h" +#include "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +enum class VideoCodecAction : int32_t { + NO_ACTION = 0, + ACTION_ONCE_AGAIN = 1, +}; + +class CodecPacket { +public: + CodecPacket() : videoCodec_(VideoCodecType::NO_CODEC) {} + CodecPacket(VideoCodecType videoCodec, const std::vector>& multiDataBuffers) + : videoCodec_(videoCodec), multiDataBuffers_(multiDataBuffers) {} + ~CodecPacket() = default; + + void SetVideoCodecType(VideoCodecType videoCodec) + { + videoCodec_ = videoCodec; + } + + VideoCodecType GetVideoCodecType() const + { + return videoCodec_; + } + + void SetDataBuffers(std::vector>& multiDataBuffers) + { + multiDataBuffers_ = multiDataBuffers; + } + + std::vector> GetDataBuffers() const + { + return multiDataBuffers_; + } + +private: + VideoCodecType videoCodec_; + std::vector> multiDataBuffers_; +}; + +class DCameraCodecEvent : public Event { + TYPEINDENT(DCameraCodecEvent) +public: + DCameraCodecEvent(EventSender& sender, const std::shared_ptr& codecPacket) + : Event(sender), codecPacket_(codecPacket), action_(VideoCodecAction::NO_ACTION) {} + DCameraCodecEvent(EventSender& sender, const std::shared_ptr& codecPacket, + VideoCodecAction otherAction) + : Event(sender), codecPacket_(codecPacket), action_(otherAction) {} + ~DCameraCodecEvent() {} + + std::shared_ptr GetCodecPacket() const + { + return codecPacket_; + } + + VideoCodecAction GetAction() const + { + return action_; + } + +private: + std::shared_ptr codecPacket_; + VideoCodecAction action_; +}; +} +} +#endif diff --git a/services/data_process/include/eventbus/dcamera_pipeline_event.h b/services/data_process/include/eventbus/dcamera_pipeline_event.h new file mode 100644 index 00000000..f01126f7 --- /dev/null +++ b/services/data_process/include/eventbus/dcamera_pipeline_event.h @@ -0,0 +1,101 @@ +/* + * 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_PIPELINE_EVENT_H +#define OHOS_DCAMERA_PIPELINE_EVENT_H + +#include + +#include "event.h" +#include "data_buffer.h" +#include "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +enum class PipelineAction : int32_t { + NO_ACTION = 0, +}; + +class PipelineConfig { +public: + PipelineConfig() : pipelineType_(PipelineType::VIDEO) {} + PipelineConfig(PipelineType pipelineType, const std::string& pipelineOwner, + const std::vector>& multiDataBuffers) + : pipelineType_(pipelineType), pipelineOwner_(pipelineOwner), multiDataBuffers_(multiDataBuffers) {} + ~PipelineConfig() = default; + + void SetPipelineType(PipelineType pipelineType) + { + pipelineType_ = pipelineType; + } + + PipelineType GetPipelineType() const + { + return pipelineType_; + } + + void SetPipelineOwner(std::string pipelineOwner) + { + pipelineOwner_ = pipelineOwner; + } + + std::string GetPipelineOwner() const + { + return pipelineOwner_; + } + + void SetDataBuffers(std::vector>& multiDataBuffers) + { + multiDataBuffers_ = multiDataBuffers; + } + + std::vector> GetDataBuffers() const + { + return multiDataBuffers_; + } + +private: + PipelineType pipelineType_; + std::string pipelineOwner_; + std::vector> multiDataBuffers_; +}; + +class DCameraPipelineEvent : public Event { + TYPEINDENT(DCameraPipelineEvent) +public: + DCameraPipelineEvent(EventSender& sender, const std::shared_ptr& pipelineConfig) + : Event(sender), pipelineConfig_(pipelineConfig), action_(PipelineAction::NO_ACTION) {} + DCameraPipelineEvent(EventSender& sender, const std::shared_ptr& pipelineConfig, + PipelineAction otherAction) + : Event(sender), pipelineConfig_(pipelineConfig), action_(otherAction) {} + ~DCameraPipelineEvent() = default; + + std::shared_ptr GetPipelineConfig() const + { + return pipelineConfig_; + } + + PipelineAction GetAction() const + { + return action_; + } + +private: + std::shared_ptr pipelineConfig_ = nullptr; + PipelineAction action_; +}; +} +} +#endif diff --git a/services/data_process/include/interfaces/data_process_listener.h b/services/data_process/include/interfaces/data_process_listener.h new file mode 100644 index 00000000..15de4e72 --- /dev/null +++ b/services/data_process/include/interfaces/data_process_listener.h @@ -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. + */ + +#ifndef OHOS_DATA_PROCESS_LISTENER_H +#define OHOS_DATA_PROCESS_LISTENER_H + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +enum DataProcessErrorType : int32_t { + ERROR_PIPELINE_ENCODER = 0, + ERROR_PIPELINE_DECODER = -1, + ERROR_PIPELINE_EVENTBUS = -2, + ERROR_DISABLE_PROCESS = -3, +}; + +class DataProcessListener { +public: + virtual ~DataProcessListener() = default; + virtual void OnProcessedVideoBuffer(const std::shared_ptr& videoResult) = 0; + virtual void OnError(DataProcessErrorType errorType) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/interfaces/idata_process_pipeline.h b/services/data_process/include/interfaces/idata_process_pipeline.h new file mode 100644 index 00000000..9355c695 --- /dev/null +++ b/services/data_process/include/interfaces/idata_process_pipeline.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 OHOS_IDATA_PROCESS_PIPELINE_H +#define OHOS_IDATA_PROCESS_PIPELINE_H + +#include +#include + +#include "data_buffer.h" +#include "image_common_type.h" +#include "distributed_camera_errno.h" +#include "data_process_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class IDataProcessPipeline { +public: + virtual ~IDataProcessPipeline() = default; + + virtual int32_t CreateDataProcessPipeline(PipelineType piplineType, const VideoConfigParams& sourceConfig, + const VideoConfigParams& targetConfig, const std::shared_ptr& listener) = 0; + virtual int32_t ProcessData(std::vector>& dataBuffers) = 0; + virtual void DestroyDataProcessPipeline() = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline/abstract_data_process.h b/services/data_process/include/pipeline/abstract_data_process.h new file mode 100644 index 00000000..beed1821 --- /dev/null +++ b/services/data_process/include/pipeline/abstract_data_process.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 OHOS_ABSTRACT_DATA_PROCESS_H +#define OHOS_ABSTRACT_DATA_PROCESS_H + +#include +#include + +#include "data_buffer.h" +#include "image_common_type.h" +#include "distributed_camera_errno.h" + +namespace OHOS { +namespace DistributedHardware { +class AbstractDataProcess { +public: + virtual ~AbstractDataProcess() = default; + int32_t SetNextNode(std::shared_ptr& nextDataProcess); + void SetNodeRank(size_t curNodeRank); + + virtual int32_t InitNode() = 0; + virtual int32_t ProcessData(std::vector>& inputBuffers) = 0; + virtual void ReleaseProcessNode() = 0; + +protected: + std::shared_ptr nextDataProcess_ = nullptr; + size_t nodeRank_; +}; +} +} +#endif diff --git a/services/data_process/include/pipeline/dcamera_pipeline_sink.h b/services/data_process/include/pipeline/dcamera_pipeline_sink.h new file mode 100644 index 00000000..b23e0870 --- /dev/null +++ b/services/data_process/include/pipeline/dcamera_pipeline_sink.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 OHOS_DCAMERA_PIPELINE_SINK_H +#define OHOS_DCAMERA_PIPELINE_SINK_H + +#include +#include + +#include "event.h" +#include "event_bus.h" +#include "event_sender.h" +#include "eventbus_handler.h" + +#include "data_buffer.h" +#include "image_common_type.h" +#include "distributed_camera_errno.h" +#include "dcamera_pipeline_event.h" +#include "idata_process_pipeline.h" +#include "abstract_data_process.h" +#include "data_process_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class EncodeDataProcess; + +class DCameraPipelineSink : public IDataProcessPipeline, public std::enable_shared_from_this { +public: + ~DCameraPipelineSink(); + + int32_t CreateDataProcessPipeline(PipelineType piplineType, const VideoConfigParams& sourceConfig, + const VideoConfigParams& targetConfig, const std::shared_ptr& listener) override; + int32_t ProcessData(std::vector>& dataBuffers) override; + void DestroyDataProcessPipeline() override; + + void OnError(DataProcessErrorType errorType); + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult); + +private: + bool IsInRange(const VideoConfigParams& curConfig); + int32_t InitDCameraPipNodes(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + +private: + const static std::string PIPELINE_OWNER; + const static uint32_t MAX_FRAME_RATE = 30; + const static uint32_t MIN_VIDEO_WIDTH = 320; + const static uint32_t MIN_VIDEO_HEIGHT = 240; + const static uint32_t MAX_VIDEO_WIDTH = 1920; + const static uint32_t MAX_VIDEO_HEIGHT = 1080; + + std::shared_ptr processListener_ = nullptr; + std::shared_ptr pipelineHead_ = nullptr; + + bool isProcess_ = false; + PipelineType piplineType_ = PipelineType::VIDEO; + std::vector> pipNodeRanks_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline/dcamera_pipeline_source.h b/services/data_process/include/pipeline/dcamera_pipeline_source.h new file mode 100644 index 00000000..a8065f86 --- /dev/null +++ b/services/data_process/include/pipeline/dcamera_pipeline_source.h @@ -0,0 +1,76 @@ +/* + * 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_PIPELINE_SOURCE_H +#define OHOS_DCAMERA_PIPELINE_SOURCE_H + +#include +#include + +#include "event.h" +#include "event_bus.h" +#include "event_sender.h" +#include "eventbus_handler.h" + +#include "data_buffer.h" +#include "image_common_type.h" +#include "distributed_camera_errno.h" +#include "dcamera_pipeline_event.h" +#include "idata_process_pipeline.h" +#include "abstract_data_process.h" +#include "data_process_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class DecodeDataProcess; + +class DCameraPipelineSource : public EventSender, public EventBusHandler, + public IDataProcessPipeline, public std::enable_shared_from_this { +public: + ~DCameraPipelineSource(); + + int32_t CreateDataProcessPipeline(PipelineType piplineType, const VideoConfigParams& sourceConfig, + const VideoConfigParams& targetConfig, const std::shared_ptr& listener) override; + int32_t ProcessData(std::vector>& dataBuffers) override; + void DestroyDataProcessPipeline() override; + void OnEvent(DCameraPipelineEvent& ev) override; + + void OnError(DataProcessErrorType errorType); + void OnProcessedVideoBuffer(const std::shared_ptr& videoResult); + +private: + bool IsInRange(const VideoConfigParams& curConfig); + void InitDCameraPipEvent(); + int32_t InitDCameraPipNodes(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + +private: + const static std::string PIPELINE_OWNER; + const static uint32_t MAX_FRAME_RATE = 30; + const static uint32_t MIN_VIDEO_WIDTH = 320; + const static uint32_t MIN_VIDEO_HEIGHT = 240; + const static uint32_t MAX_VIDEO_WIDTH = 1920; + const static uint32_t MAX_VIDEO_HEIGHT = 1080; + + std::shared_ptr processListener_ = nullptr; + std::shared_ptr pipelineHead_ = nullptr; + std::shared_ptr eventBusSource_ = nullptr; + + bool isProcess_ = false; + PipelineType piplineType_ = PipelineType::VIDEO; + std::vector> pipNodeRanks_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.h b/services/data_process/include/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.h new file mode 100644 index 00000000..bd0eba5b --- /dev/null +++ b/services/data_process/include/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.h @@ -0,0 +1,48 @@ +/* + * 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_CONVERT_NV12TONV21_H +#define OHOS_CONVERT_NV12TONV21_H + +#include "securec.h" +#include "data_buffer.h" +#include "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +class ConvertNV12ToNV21 { +public: + ConvertNV12ToNV21() = default; + ~ConvertNV12ToNV21() = default; + std::shared_ptr ProcessData(const std::shared_ptr& srcBuf, + const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + +private: + bool IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + int32_t GetImageUnitInfo(ImageUnitInfo& imgInfo, const std::shared_ptr& imgBuf); + bool IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo); + int32_t CheckColorConvertInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + void SeparateUVPlaneByRow(const uint8_t *srcUVPlane, uint8_t *dstUPlane, uint8_t *dstVPlane, + int32_t srcHalfWidth); + int32_t SeparateNV12UVPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + void CombineUVPlaneByRow(const uint8_t *srcUPlane, const uint8_t *srcVPlane, uint8_t *dstUVPlane, + int32_t dstHalfWidth); + int32_t CombineNV12UVPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + int32_t CopyYPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + int32_t ColorConvertNV12ToNV21(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/fpscontroller/fps_controller_process.h b/services/data_process/include/pipeline_node/fpscontroller/fps_controller_process.h new file mode 100644 index 00000000..9e9fbbeb --- /dev/null +++ b/services/data_process/include/pipeline_node/fpscontroller/fps_controller_process.h @@ -0,0 +1,79 @@ +/* + * 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_FPS_CONTROLLER_PROCESS_H +#define OHOS_FPS_CONTROLLER_PROCESS_H + +#include +#include + +#include "abstract_data_process.h" +#include "dcamera_pipeline_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPipelineSource; + +class FpsControllerProcess : public AbstractDataProcess { +public: + FpsControllerProcess(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig, + const std::weak_ptr& callbackPipSource) + : sourceConfig_(sourceConfig), targetConfig_(targetConfig), callbackPipelineSource_(callbackPipSource) {} + ~FpsControllerProcess(); + + int32_t InitNode() override; + int32_t ProcessData(std::vector>& inputBuffers) override; + void ReleaseProcessNode() override; + +private: + void UpdateFPSControllerInfo(int64_t nowMs); + void UpdateFrameRateCorrectionFactor(int64_t nowMs); + void UpdateIncomingFrameTimes(int64_t nowMs); + float CalculateFrameRate(int64_t nowMs); + bool IsDropFrame(float incomingFps); + bool ReduceFrameRateByUniformStrategy(int32_t incomingFps); + int32_t FpsControllerDone(std::vector> outputBuffers); + +private: + const static uint32_t MAX_TARGET_FRAME_RATE = 30; + const static int32_t VIDEO_FRAME_DROP_INTERVAL = 4; + const static int32_t MIN_INCOME_FRAME_NUM_COEFFICIENT = 3; + const static int32_t INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE = 60; + /* Receive video frame detect time windows */ + const static int32_t FRAME_HISTORY_TIME_WINDOWS_MS = 2000; + const static int64_t FRMAE_MAX_INTERVAL_TIME_WINDOW_MS = 700; + const static int32_t OVERSHOOT_MODIFY_COEFFICIENT = 3; + const static int32_t DOUBLE_MULTIPLE = 2; + + std::mutex mtx; + VideoConfigParams sourceConfig_; + VideoConfigParams targetConfig_; + std::weak_ptr callbackPipelineSource_; + bool isFpsControllerProcess_ = false; + bool isFirstFrame_ = false; + uint32_t targetFrameRate_ = 0; + int64_t lastFrameIncomeTimeMs_ = 0; + /* the time span between current and last frame */ + int64_t recentFrameTimeSpanMs_ = -1; + int32_t keepCorrectionCount_ = 0; + int32_t keepLessThanDoubleCount_ = 0; + int32_t keepMoreThanDoubleCount_ = 0; + float frameRateCorrectionFactor_ = 0.0; + /* modify the frame rate controller argument */ + int32_t frameRateOvershootMdf_ = 0; + int64_t incomingFrameTimesMs_[INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE]; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h b/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h new file mode 100644 index 00000000..cfd051f8 --- /dev/null +++ b/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h @@ -0,0 +1,145 @@ +/* + * 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_DECODE_DATA_PROCESS_H +#define OHOS_DECODE_DATA_PROCESS_H + +#include "securec.h" +#include +#include +#include +#include +#include + +#include "surface.h" +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" +#include "avsharedmemory.h" +#include "avcodec_video_decoder.h" +#include "event.h" +#include "event_bus.h" +#include "event_sender.h" +#include "eventbus_handler.h" +#include "event_registration.h" + +#include "data_buffer.h" +#include "distributed_camera_errno.h" +#include "image_common_type.h" +#include "dcamera_codec_event.h" +#include "abstract_data_process.h" +#include "dcamera_pipeline_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPipelineSource; +class DecodeVideoCallback; + +class DecodeDataProcess : public EventSender, public EventBusHandler, public AbstractDataProcess, + public std::enable_shared_from_this { +public: + DecodeDataProcess(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig, + const std::shared_ptr& eventBusPipeline, + const std::weak_ptr& callbackPipSource) + : sourceConfig_(sourceConfig), targetConfig_(targetConfig), eventBusPipeline_(eventBusPipeline), + callbackPipelineSource_(callbackPipSource) {} + ~DecodeDataProcess(); + + int32_t InitNode() override; + int32_t ProcessData(std::vector>& inputBuffers) override; + void ReleaseProcessNode() override; + void OnEvent(DCameraCodecEvent& ev) override; + + void OnError(); + void OnInputBufferAvailable(uint32_t index); + void OnOutputFormatChanged(const Media::Format &format); + void OnOutputBufferAvailable(uint32_t index, const Media::AVCodecBufferInfo& info, + const Media::AVCodecBufferFlag& flag); + void GetDecoderOutputBuffer(const sptr& surface); + VideoConfigParams GetSourceConfig() const; + VideoConfigParams GetTargetConfig() const; + +private: + bool IsInDecoderRange(const VideoConfigParams& curConfig); + bool IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + void InitCodecEvent(); + int32_t InitDecoder(); + int32_t InitDecoderMetadataFormat(); + int32_t SetDecoderOutputSurface(); + void ReleaseDecoder(); + int32_t FeedDecoderInputBuffer(); + int64_t GetDecoderTimeStamp(); + int32_t GetAlignedHeight(); + void CopyDecodedImage(const sptr& surBuf, int64_t timeStampUs, int32_t alignedWidth, + int32_t alignedHeight); + int32_t CopyYUVPlaneByRow(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + int32_t CheckCopyImageInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo); + bool IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo); + void PostOutputDataBuffers(std::shared_ptr& outputBuffer); + int32_t DecodeDone(std::vector> outputBuffers); + +private: + const static int32_t VIDEO_DECODER_QUEUE_MAX = 1000; + const static int32_t MAX_YUV420_BUFFER_SIZE = 1920 * 1080 * 3 / 2 * 2; + const static uint32_t MAX_FRAME_RATE = 30; + const static uint32_t MIN_VIDEO_WIDTH = 320; + const static uint32_t MIN_VIDEO_HEIGHT = 240; + const static uint32_t MAX_VIDEO_WIDTH = 1920; + const static uint32_t MAX_VIDEO_HEIGHT = 1080; + + std::mutex mtxDecoderState_; + std::mutex mtxHoldCount_; + VideoConfigParams sourceConfig_; + VideoConfigParams targetConfig_; + std::shared_ptr eventBusPipeline_; + std::weak_ptr callbackPipelineSource_; + std::shared_ptr eventBusDecode_ = nullptr; + std::shared_ptr eventBusRegHandleDecode_ = nullptr; + std::shared_ptr eventBusRegHandlePipeline2Decode_ = nullptr; + std::shared_ptr videoDecoder_ = nullptr; + std::shared_ptr decodeVideoCallback_ = nullptr; + sptr decodeConsumerSurface_ = nullptr; + sptr decodeProducerSurface_ = nullptr; + + bool isDecoderProcess_ = false; + int32_t waitDecoderOutputCount_ = 0; + int32_t alignedHeight_ = 0; + int64_t lastFeedDecoderInputBufferTimeUs_ = 0; + int64_t outputTimeStampUs_ = 0; + std::string processType_; + Media::Format metadataFormat_; + Media::Format decodeOutputFormat_; + Media::AVCodecBufferInfo outputInfo_; + std::queue> inputBuffersQueue_; + std::queue availableInputIndexsQueue_; +}; + +class DecodeSurfaceListener : public IBufferConsumerListener { +public: + DecodeSurfaceListener(sptr surface, std::weak_ptr decodeVideoNode) + : surface_(surface), decodeVideoNode_(decodeVideoNode) {} + ~DecodeSurfaceListener() = default; + + void OnBufferAvailable() override; + void SetSurface(const sptr& surface); + void SetDecodeVideoNode(const std::weak_ptr& decodeVideoNode); + +private: + sptr surface_; + std::weak_ptr decodeVideoNode_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/multimedia_codec/decode_video_callback.h b/services/data_process/include/pipeline_node/multimedia_codec/decode_video_callback.h new file mode 100644 index 00000000..4749a8c8 --- /dev/null +++ b/services/data_process/include/pipeline_node/multimedia_codec/decode_video_callback.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 OHOS_DECODE_VIDEO_CALLBACK_H +#define OHOS_DECODE_VIDEO_CALLBACK_H + +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" + +#include "decode_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +class DecodeDataProcess; + +class DecodeVideoCallback : public Media::AVCodecCallback { +public: + explicit DecodeVideoCallback(const std::weak_ptr& decodeVideoNode) + : decodeVideoNode_(decodeVideoNode) {} + ~DecodeVideoCallback() = default; + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode) override; + void OnInputBufferAvailable(uint32_t index) override; + void OnOutputFormatChanged(const Media::Format &format) override; + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) override; +private: + std::weak_ptr decodeVideoNode_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h b/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h new file mode 100644 index 00000000..89899e98 --- /dev/null +++ b/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h @@ -0,0 +1,123 @@ +/* + * 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_ENCODE_DATA_PROCESS_H +#define OHOS_ENCODE_DATA_PROCESS_H + +#include "securec.h" +#include +#include +#include + +#include "surface.h" +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" +#include "avsharedmemory.h" +#include "avcodec_video_encoder.h" + +#include "data_buffer.h" +#include "distributed_camera_errno.h" +#include "image_common_type.h" +#include "abstract_data_process.h" +#include "dcamera_pipeline_sink.h" + +namespace OHOS { +namespace DistributedHardware { +class DCameraPipelineSink; +class EncodeVideoCallback; + +class EncodeDataProcess : public AbstractDataProcess, public std::enable_shared_from_this { +public: + EncodeDataProcess(const VideoConfigParams &sourceConfig, const VideoConfigParams &targetConfig, + const std::weak_ptr& callbackPipSink) + : sourceConfig_(sourceConfig), targetConfig_(targetConfig), callbackPipelineSink_(callbackPipSink) {} + ~EncodeDataProcess(); + + int32_t InitNode() override; + int32_t ProcessData(std::vector>& inputBuffers) override; + void ReleaseProcessNode() override; + + void OnError(); + void OnInputBufferAvailable(uint32_t index); + void OnOutputFormatChanged(const Media::Format &format); + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag); + VideoConfigParams GetSourceConfig() const; + VideoConfigParams GetTargetConfig() const; + +private: + bool IsInEncoderRange(const VideoConfigParams& curConfig); + bool IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig); + int32_t InitEncoder(); + int32_t InitEncoderMetadataFormat(); + int32_t InitEncoderBitrateFormat(); + int32_t FeedEncoderInputBuffer(std::shared_ptr& inputBuffer); + sptr GetEncoderInputSurfaceBuffer(); + int64_t GetEncoderTimeStamp(); + int32_t GetEncoderOutputBuffer(uint32_t index, Media::AVCodecBufferInfo info); + int32_t EncodeDone(std::vector> outputBuffers); + +private: + const static int32_t ENCODER_STRIDE_ALIGNMENT = 8; + const static int64_t NORM_YUV420_BUFFER_SIZE = 1920 * 1080 * 3 / 2; + const static uint32_t MAX_FRAME_RATE = 30; + const static uint32_t MIN_VIDEO_WIDTH = 320; + const static uint32_t MIN_VIDEO_HEIGHT = 240; + const static uint32_t MAX_VIDEO_WIDTH = 1920; + const static uint32_t MAX_VIDEO_HEIGHT = 1080; + const static int32_t IDR_FRAME_INTERVAL_MS = 300; + + const static int64_t WIDTH_320_HEIGHT_240 = 320 * 240; + const static int64_t WIDTH_480_HEIGHT_360 = 480 * 360; + const static int64_t WIDTH_640_HEIGHT_360 = 640 * 360; + const static int64_t WIDTH_640_HEIGHT_480 = 640 * 480; + const static int64_t WIDTH_720_HEIGHT_540 = 720 * 540; + const static int64_t WIDTH_960_HEIGHT_540 = 960 * 540; + const static int64_t WIDTH_960_HEIGHT_720 = 960 * 720; + const static int64_t WIDTH_1280_HEIGHT_720 = 1280 * 720; + const static int64_t WIDTH_1440_HEIGHT_1080 = 1440 * 1080; + const static int64_t WIDTH_1920_HEIGHT_1080 = 1920 * 1080; + const static int32_t BITRATE_500000 = 500000; + const static int32_t BITRATE_1110000 = 1110000; + const static int32_t BITRATE_1500000 = 1500000; + const static int32_t BITRATE_1800000 = 1800000; + const static int32_t BITRATE_2100000 = 2100000; + const static int32_t BITRATE_2300000 = 2300000; + const static int32_t BITRATE_2800000 = 2800000; + const static int32_t BITRATE_3400000 = 3400000; + const static int32_t BITRATE_5000000 = 5000000; + const static int32_t BITRATE_6000000 = 6000000; + const static std::map ENCODER_BITRATE_TABLE; + + std::mutex mtxEncoderState_; + std::mutex mtxHoldCount_; + VideoConfigParams sourceConfig_; + VideoConfigParams targetConfig_; + std::weak_ptr callbackPipelineSink_; + std::shared_ptr videoEncoder_ = nullptr; + std::shared_ptr encodeVideoCallback_ = nullptr; + sptr encodeProducerSurface_ = nullptr; + + bool isEncoderProcess_ = false; + int32_t waitEncoderOutputCount_ = 0; + int64_t lastFeedEncoderInputBufferTimeUs_ = 0; + int64_t inputTimeStampUs_ = 0; + std::string processType_; + Media::Format metadataFormat_; + Media::Format encodeOutputFormat_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/pipeline_node/multimedia_codec/encode_video_callback.h b/services/data_process/include/pipeline_node/multimedia_codec/encode_video_callback.h new file mode 100644 index 00000000..c91055cc --- /dev/null +++ b/services/data_process/include/pipeline_node/multimedia_codec/encode_video_callback.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 OHOS_DECODE_VIDEO_CALLBACK_H +#define OHOS_DECODE_VIDEO_CALLBACK_H + +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" + +#include "encode_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +class EncodeDataProcess; + +class EncodeVideoCallback : public Media::AVCodecCallback { +public: + explicit EncodeVideoCallback(const std::weak_ptr& encodeVideoNode) + : encodeVideoNode_(encodeVideoNode) {} + ~EncodeVideoCallback() = default; + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode) override; + void OnInputBufferAvailable(uint32_t index) override; + void OnOutputFormatChanged(const Media::Format &format) override; + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) override; +private: + std::weak_ptr encodeVideoNode_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/include/utils/image_common_type.h b/services/data_process/include/utils/image_common_type.h new file mode 100644 index 00000000..9f692ea8 --- /dev/null +++ b/services/data_process/include/utils/image_common_type.h @@ -0,0 +1,78 @@ +/* + * 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_IMAGE_COMMON_TYPE_H +#define OHOS_IMAGE_COMMON_TYPE_H + +#include + +namespace OHOS { +namespace DistributedHardware { +enum class PipelineType : int32_t { + VIDEO = 0, + PHOTO_JPEG, +}; + +enum class VideoCodecType : int32_t { + NO_CODEC = 0, + CODEC_H264, + CODEC_H265, +}; + +enum class Videoformat : int32_t { + YUVI420 = 0, + NV12, + NV21, +}; + +class VideoConfigParams { +public: + VideoConfigParams(VideoCodecType videoCodec, Videoformat pixelFormat, uint32_t frameRate, uint32_t width, + uint32_t height) + : videoCodec_(videoCodec), pixelFormat_(pixelFormat), frameRate_(frameRate), width_ (width), height_(height) + {} + ~VideoConfigParams() = default; + + void SetVideoCodecType(VideoCodecType videoCodec); + void SetVideoformat(Videoformat pixelFormat); + void SetFrameRate(uint32_t frameRate); + void SetWidthAndHeight(uint32_t width, uint32_t height); + VideoCodecType GetVideoCodecType() const; + Videoformat GetVideoformat() const; + uint32_t GetFrameRate() const; + uint32_t GetWidth() const; + uint32_t GetHeight() const; + +private: + VideoCodecType videoCodec_; + Videoformat pixelFormat_; + uint32_t frameRate_; + uint32_t width_; + uint32_t height_; +}; + +struct ImageUnitInfo { + Videoformat colorFormat; + int32_t width; + int32_t height; + int32_t alignedWidth; + int32_t alignedHeight; + size_t chromaOffset; + size_t imgSize; + uint8_t *imgData; +}; +} +} +#endif \ No newline at end of file diff --git a/services/data_process/src/pipeline/abstract_data_process.cpp b/services/data_process/src/pipeline/abstract_data_process.cpp new file mode 100644 index 00000000..bfc7b793 --- /dev/null +++ b/services/data_process/src/pipeline/abstract_data_process.cpp @@ -0,0 +1,37 @@ +/* + * 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 "abstract_data_process.h" + +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t AbstractDataProcess::SetNextNode(std::shared_ptr& nextDataProcess) +{ + if (nextDataProcess == nullptr) { + DHLOGE("Next data process is invalid."); + return DCAMERA_BAD_VALUE; + } + nextDataProcess_ = nextDataProcess; + return DCAMERA_OK; +} + +void AbstractDataProcess::SetNodeRank(size_t curNodeRank) +{ + nodeRank_ = curNodeRank; +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline/dcamera_pipeline_sink.cpp b/services/data_process/src/pipeline/dcamera_pipeline_sink.cpp new file mode 100644 index 00000000..bda1da7f --- /dev/null +++ b/services/data_process/src/pipeline/dcamera_pipeline_sink.cpp @@ -0,0 +1,176 @@ +/* + * 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_pipeline_sink.h" + +#include "distributed_hardware_log.h" + +#include "encode_data_process.h" + +namespace OHOS { +namespace DistributedHardware { +const std::string DCameraPipelineSink::PIPELINE_OWNER = "Sink"; + +DCameraPipelineSink::~DCameraPipelineSink() +{ + if (isProcess_) { + DHLOGD("~DCameraPipelineSink : Destroy sink data process pipeline."); + DestroyDataProcessPipeline(); + } +} + +int32_t DCameraPipelineSink::CreateDataProcessPipeline(PipelineType piplineType, + const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig, + const std::shared_ptr& listener) +{ + DHLOGD("Create sink data process pipeline."); + switch (piplineType) { + case PipelineType::VIDEO: + if (!(IsInRange(sourceConfig) && IsInRange(targetConfig))) { + DHLOGE("Source config or target config of sink pipeline are invalid."); + return DCAMERA_BAD_VALUE; + } + break; + default: + DHLOGE("JPEG or other pipeline type are not supported in sink pipeline."); + return DCAMERA_NOT_FOUND; + } + if (listener == nullptr) { + DHLOGE("The process listener of sink pipeline is empty."); + return DCAMERA_BAD_VALUE; + } + if (pipelineHead_ != nullptr) { + DHLOGD("The sink pipeline already exists."); + return DCAMERA_OK; + } + + int32_t err = InitDCameraPipNodes(sourceConfig, targetConfig); + if (err != DCAMERA_OK) { + DestroyDataProcessPipeline(); + return err; + } + piplineType_ = piplineType; + processListener_ = listener; + isProcess_ = true; + return DCAMERA_OK; +} + +bool DCameraPipelineSink::IsInRange(const VideoConfigParams& curConfig) +{ + return (curConfig.GetFrameRate() <= MAX_FRAME_RATE || curConfig.GetWidth() >= MIN_VIDEO_WIDTH || + curConfig.GetWidth() <= MAX_VIDEO_WIDTH || curConfig.GetHeight() >= MIN_VIDEO_HEIGHT || + curConfig.GetHeight() <= MAX_VIDEO_HEIGHT); +} + +int32_t DCameraPipelineSink::InitDCameraPipNodes(const VideoConfigParams& sourceConfig, + const VideoConfigParams& targetConfig) +{ + DHLOGD("Init sink DCamera pipeline Nodes."); + if (piplineType_ == PipelineType::PHOTO_JPEG) { + DHLOGE("JPEG data process is not supported."); + return DCAMERA_NOT_FOUND; + } + + pipNodeRanks_.push_back(std::make_shared(sourceConfig, targetConfig, shared_from_this())); + if (pipNodeRanks_.size() == 0) { + DHLOGD("Creating an empty sink pipeline."); + pipelineHead_ = nullptr; + return DCAMERA_BAD_VALUE; + } + for (size_t i = 0; i < pipNodeRanks_.size(); i++) { + pipNodeRanks_[i]->SetNodeRank(i); + int32_t err = pipNodeRanks_[i]->InitNode(); + if (err != DCAMERA_OK) { + DHLOGE("Init sink DCamera pipeline Node [%d] failed.", i); + return DCAMERA_INIT_ERR; + } + if (i == 0) { + continue; + } + err = pipNodeRanks_[i - 1]->SetNextNode(pipNodeRanks_[i]); + if (err != DCAMERA_OK) { + DHLOGE("Set the next node of Node [%d] failed in sink pipeline.", i - 1); + return DCAMERA_INIT_ERR; + } + } + DHLOGD("All nodes have been linked in sink pipeline."); + pipelineHead_ = pipNodeRanks_[0]; + return DCAMERA_OK; +} + +int32_t DCameraPipelineSink::ProcessData(std::vector>& dataBuffers) +{ + DHLOGD("Process data buffers in sink pipeline."); + if (piplineType_ == PipelineType::PHOTO_JPEG) { + DHLOGE("JPEG data process is not supported in sink pipeline."); + return DCAMERA_NOT_FOUND; + } + if (pipelineHead_ == nullptr) { + DHLOGE("The current sink pipeline node is empty. Processing failed."); + return DCAMERA_INIT_ERR; + } + if (dataBuffers.empty()) { + DHLOGE("Sink Pipeline Input Data buffers is null."); + return DCAMERA_BAD_VALUE; + } + if (!isProcess_) { + DHLOGE("Sink pipeline node occurred error or start destroy."); + return DCAMERA_DISABLE_PROCESS; + } + + int32_t err = pipelineHead_->ProcessData(dataBuffers); + if (err != DCAMERA_OK) { + DHLOGE("Sink plpeline process data buffers fail."); + } + return err; +} + +void DCameraPipelineSink::DestroyDataProcessPipeline() +{ + DHLOGD("Destroy sink data process pipeline start."); + isProcess_ = false; + if (pipelineHead_ != nullptr) { + pipelineHead_->ReleaseProcessNode(); + pipelineHead_ = nullptr; + } + + pipNodeRanks_.clear(); + piplineType_ = PipelineType::VIDEO; + processListener_ = nullptr; + DHLOGD("Destroy sink data process pipeline end."); +} + +void DCameraPipelineSink::OnError(DataProcessErrorType errorType) +{ + DHLOGE("A runtime error occurred in sink pipeline."); + isProcess_ = false; + if (processListener_ == nullptr) { + DHLOGE("The process listener of sink pipeline is empty."); + return; + } + processListener_->OnError(errorType); +} + +void DCameraPipelineSink::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + DHLOGD("Sink pipeline output the processed video buffer."); + if (processListener_ == nullptr) { + DHLOGE("The process listener of sink pipeline is empty."); + return; + } + processListener_->OnProcessedVideoBuffer(videoResult); +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline/dcamera_pipeline_source.cpp b/services/data_process/src/pipeline/dcamera_pipeline_source.cpp new file mode 100644 index 00000000..5aa728f9 --- /dev/null +++ b/services/data_process/src/pipeline/dcamera_pipeline_source.cpp @@ -0,0 +1,209 @@ +/* + * 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_pipeline_source.h" + +#include "distributed_hardware_log.h" + +#include "decode_data_process.h" +#include "fps_controller_process.h" + +namespace OHOS { +namespace DistributedHardware { +const std::string DCameraPipelineSource::PIPELINE_OWNER = "Source"; + +DCameraPipelineSource::~DCameraPipelineSource() +{ + if (isProcess_) { + DHLOGD("~DCameraPipelineSource : Destroy source data process pipeline."); + DestroyDataProcessPipeline(); + } +} + +int32_t DCameraPipelineSource::CreateDataProcessPipeline(PipelineType piplineType, + const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig, + const std::shared_ptr& listener) +{ + DHLOGD("Create source data process pipeline."); + switch (piplineType) { + case PipelineType::VIDEO: + if (!(IsInRange(sourceConfig) && IsInRange(targetConfig))) { + DHLOGE("Source config or target config of source pipeline are invalid."); + return DCAMERA_BAD_VALUE; + } + break; + default: + DHLOGE("JPEG or other pipeline type are not supported in source pipeline."); + return DCAMERA_NOT_FOUND; + } + if (listener == nullptr) { + DHLOGE("The process listener of source pipeline is empty."); + return DCAMERA_BAD_VALUE; + } + + if (pipelineHead_ != nullptr) { + DHLOGD("The source pipeline already exists."); + return DCAMERA_OK; + } + + InitDCameraPipEvent(); + int32_t err = InitDCameraPipNodes(sourceConfig, targetConfig); + if (err != DCAMERA_OK) { + DestroyDataProcessPipeline(); + return err; + } + piplineType_ = piplineType; + processListener_ = listener; + isProcess_ = true; + return DCAMERA_OK; +} + +bool DCameraPipelineSource::IsInRange(const VideoConfigParams& curConfig) +{ + return (curConfig.GetFrameRate() <= MAX_FRAME_RATE || curConfig.GetWidth() >= MIN_VIDEO_WIDTH || + curConfig.GetWidth() <= MAX_VIDEO_WIDTH || curConfig.GetHeight() >= MIN_VIDEO_HEIGHT || + curConfig.GetHeight() <= MAX_VIDEO_HEIGHT); +} + +void DCameraPipelineSource::InitDCameraPipEvent() +{ + DHLOGD("Init source DCamera pipeline event to asynchronously process data."); + eventBusSource_ = std::make_shared(); + DCameraPipelineEvent pipelineEvent(*this, std::make_shared()); + eventBusSource_->AddHandler(pipelineEvent.GetType(), *this); +} + +int32_t DCameraPipelineSource::InitDCameraPipNodes(const VideoConfigParams& sourceConfig, + const VideoConfigParams& targetConfig) +{ + DHLOGD("Init source DCamera pipeline Nodes."); + if (piplineType_ == PipelineType::PHOTO_JPEG) { + DHLOGE("JPEG data process is not supported."); + return DCAMERA_NOT_FOUND; + } + if (eventBusSource_ == nullptr) { + DHLOGE("eventBusSource is nullptr."); + return DCAMERA_BAD_VALUE; + } + pipNodeRanks_.push_back(std::make_shared(sourceConfig, targetConfig, + eventBusSource_, shared_from_this())); + if (pipNodeRanks_.size() == 0) { + DHLOGD("Creating an empty source pipeline."); + pipelineHead_ = nullptr; + return DCAMERA_BAD_VALUE; + } + for (size_t i = 0; i < pipNodeRanks_.size(); i++) { + pipNodeRanks_[i]->SetNodeRank(i); + int32_t err = pipNodeRanks_[i]->InitNode(); + if (err != DCAMERA_OK) { + DHLOGE("Init source DCamera pipeline Node [%d] failed.", i); + return DCAMERA_INIT_ERR; + } + if (i == 0) { + continue; + } + err = pipNodeRanks_[i - 1]->SetNextNode(pipNodeRanks_[i]); + if (err != DCAMERA_OK) { + DHLOGE("Set the next node of Node [%d] failed in source pipeline.", i - 1); + return DCAMERA_INIT_ERR; + } + } + DHLOGD("All nodes have been linked in source pipeline."); + pipelineHead_ = pipNodeRanks_[0]; + return DCAMERA_OK; +} + +int32_t DCameraPipelineSource::ProcessData(std::vector>& dataBuffers) +{ + DHLOGD("Process data buffers in source pipeline."); + if (piplineType_ == PipelineType::PHOTO_JPEG) { + DHLOGE("JPEG data process is not supported in source pipeline."); + return DCAMERA_NOT_FOUND; + } + if (pipelineHead_ == nullptr) { + DHLOGE("The current source pipeline node is empty. Processing failed."); + return DCAMERA_INIT_ERR; + } + if (dataBuffers.empty()) { + DHLOGE("Source Pipeline Input data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + if (!isProcess_) { + DHLOGE("Source Pipeline node occurred error or start destroy."); + return DCAMERA_DISABLE_PROCESS; + } + + DHLOGD("Send asynchronous event to process data in source pipeline."); + std::shared_ptr pipConfigSource = std::make_shared(piplineType_, + PIPELINE_OWNER, dataBuffers); + DCameraPipelineEvent dCamPipelineEvent(*this, pipConfigSource); + if (eventBusSource_ == nullptr) { + DHLOGE("eventBusSource_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + eventBusSource_->PostEvent(dCamPipelineEvent, POSTMODE::POST_ASYNC); + return DCAMERA_OK; +} + +void DCameraPipelineSource::DestroyDataProcessPipeline() +{ + DHLOGD("Destroy source data process pipeline start."); + isProcess_ = false; + if (pipelineHead_ != nullptr) { + pipelineHead_->ReleaseProcessNode(); + pipelineHead_ = nullptr; + } + eventBusSource_ = nullptr; + processListener_ = nullptr; + pipNodeRanks_.clear(); + piplineType_ = PipelineType::VIDEO; + DHLOGD("Destroy source data process pipeline end."); +} + +void DCameraPipelineSource::OnEvent(DCameraPipelineEvent& ev) +{ + DHLOGD("Receive asynchronous event then start process data in source pipeline."); + std::shared_ptr pipelineConfig = ev.GetPipelineConfig(); + std::vector> inputBuffers = pipelineConfig->GetDataBuffers(); + if (inputBuffers.empty()) { + DHLOGE("Receiving process data buffers is empty in source pipeline."); + OnError(ERROR_PIPELINE_EVENTBUS); + return; + } + pipelineHead_->ProcessData(inputBuffers); +} + +void DCameraPipelineSource::OnError(DataProcessErrorType errorType) +{ + DHLOGE("A runtime error occurred in the source pipeline."); + isProcess_ = false; + if (processListener_ == nullptr) { + DHLOGE("The process listener of source pipeline is empty."); + return; + } + processListener_->OnError(errorType); +} + +void DCameraPipelineSource::OnProcessedVideoBuffer(const std::shared_ptr& videoResult) +{ + DHLOGD("Source pipeline output the processed video buffer."); + if (processListener_ == nullptr) { + DHLOGE("The process listener of source pipeline is empty."); + return; + } + processListener_->OnProcessedVideoBuffer(videoResult); +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp b/services/data_process/src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp new file mode 100644 index 00000000..b7908312 --- /dev/null +++ b/services/data_process/src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp @@ -0,0 +1,364 @@ +/* + * 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 "convert_nv12_to_nv21.h" + +#include "distributed_hardware_log.h" + +#include "distributed_camera_errno.h" + +namespace OHOS { +namespace DistributedHardware { +bool ConvertNV12ToNV21::IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig) +{ + return (sourceConfig.GetVideoformat() == Videoformat::NV12 && targetConfig.GetVideoformat() == Videoformat::NV21 && + sourceConfig.GetWidth() == targetConfig.GetWidth() && sourceConfig.GetHeight() == targetConfig.GetHeight()); +} + +int32_t ConvertNV12ToNV21::GetImageUnitInfo(ImageUnitInfo& imgInfo, const std::shared_ptr& imgBuf) +{ + if (imgBuf == nullptr) { + DHLOGE("GetImageUnitInfo failed, imgBuf is nullptr."); + return DCAMERA_BAD_VALUE; + } + + bool findErr = true; + int32_t colorFormat = 0; + findErr = findErr && imgBuf->FindInt32("Videoformat", colorFormat); + if (!findErr) { + DHLOGE("GetImageUnitInfo failed, Videoformat is null."); + return DCAMERA_NOT_FOUND; + } + if (colorFormat != static_cast(Videoformat::YUVI420) && + colorFormat != static_cast(Videoformat::NV12) && + colorFormat != static_cast(Videoformat::NV21)) { + DHLOGE("GetImageUnitInfo failed, colorFormat %d are not supported.", colorFormat); + return DCAMERA_NOT_FOUND; + } + imgInfo.colorFormat = static_cast(colorFormat); + findErr = findErr && imgBuf->FindInt32("width", imgInfo.width); + findErr = findErr && imgBuf->FindInt32("height", imgInfo.height); + findErr = findErr && imgBuf->FindInt32("alignedWidth", imgInfo.alignedWidth); + findErr = findErr && imgBuf->FindInt32("alignedHeight", imgInfo.alignedHeight); + if (!findErr) { + DHLOGE("GetImageUnitInfo failed, width %d, height %d, alignedWidth %d, alignedHeight %d.", + imgInfo.width, imgInfo.height, imgInfo.alignedWidth, imgInfo.alignedHeight); + return DCAMERA_NOT_FOUND; + } + + imgInfo.chromaOffset = static_cast(imgInfo.alignedWidth * imgInfo.alignedHeight); + imgInfo.imgSize = imgBuf->Size(); + imgInfo.imgData = imgBuf->Data(); + if (imgInfo.imgData == nullptr) { + DHLOGE("Get the imgData of the imgBuf failed."); + return DCAMERA_BAD_VALUE; + } + DHLOGD("imgBuf info : Videoformat %d, alignedWidth %d, alignedHeight %d, width %d, height %d, chromaOffset %d, " + + "imgSize %d.", imgInfo.colorFormat, imgInfo.width, imgInfo.height, imgInfo.alignedWidth, + imgInfo.alignedHeight, imgInfo.chromaOffset, imgInfo.imgSize); + return DCAMERA_OK; +} + +bool ConvertNV12ToNV21::IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo) +{ + int32_t y2UvRatio = 2; + int32_t bytesPerPixel = 3; + size_t expectedImgSize = static_cast(imgInfo.alignedWidth * imgInfo.alignedHeight * + bytesPerPixel / y2UvRatio); + size_t expectedChromaOffset = static_cast(imgInfo.alignedWidth * imgInfo.alignedHeight); + return (imgInfo.width <= imgInfo.alignedWidth && imgInfo.height <= imgInfo.alignedHeight && + imgInfo.imgSize >= expectedImgSize && imgInfo.chromaOffset == expectedChromaOffset); +} + +int32_t ConvertNV12ToNV21::CheckColorConvertInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + if (srcImgInfo.imgData == nullptr || dstImgInfo.imgData == nullptr) { + DHLOGE("The imgData of srcImgInfo or the imgData of dstImgInfo are null!"); + return DCAMERA_BAD_VALUE; + } + if (srcImgInfo.colorFormat != Videoformat::NV12 && dstImgInfo.colorFormat != Videoformat::NV21) { + DHLOGE("CopyInfo error : srcImgInfo colorFormat %d, dstImgInfo colorFormat %d.", + srcImgInfo.colorFormat, dstImgInfo.colorFormat); + return DCAMERA_BAD_VALUE; + } + + if (!IsCorrectImageUnitInfo(srcImgInfo)) { + DHLOGE("srcImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " + + "imgSize %lld.", srcImgInfo.width, srcImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight, + srcImgInfo.chromaOffset, srcImgInfo.imgSize); + return DCAMERA_BAD_VALUE; + } + if (!IsCorrectImageUnitInfo(dstImgInfo)) { + DHLOGE("dstImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " + + "imgSize %lld.", dstImgInfo.width, dstImgInfo.height, dstImgInfo.alignedWidth, dstImgInfo.alignedHeight, + dstImgInfo.chromaOffset, dstImgInfo.imgSize); + return DCAMERA_BAD_VALUE; + } + + if (dstImgInfo.width > srcImgInfo.alignedWidth || dstImgInfo.height > srcImgInfo.alignedHeight) { + DHLOGE("Comparison ImgInfo fail: dstwidth %d, dstheight %d, srcAlignedWidth %d, srcAlignedHeight %d.", + dstImgInfo.width, dstImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight); + return DCAMERA_BAD_VALUE; + } + return DCAMERA_OK; +} + +/** +* @brief Separate a row of srcUVPlane into half a row of dstUPlane and half a row of dstVPlane. For example, +* converts the UVPlane memory arrangement of NV12 to the UV memory arrangement of YUVI420. Note that the +* stride and width of the dstImage must be the same. +*/ +void ConvertNV12ToNV21::SeparateUVPlaneByRow(const uint8_t *srcUVPlane, uint8_t *dstUPlane, uint8_t *dstVPlane, + int32_t srcHalfWidth) +{ + int32_t memoryOffset0 = 0; + int32_t memoryOffset1 = 1; + int32_t memoryOffset2 = 2; + int32_t memoryOffset3 = 3; + int32_t perSeparatebytes = 4; + for (int32_t x = 0; x < srcHalfWidth - 1; x += memoryOffset2) { + dstUPlane[x] = srcUVPlane[memoryOffset0]; + dstUPlane[x + memoryOffset1] = srcUVPlane[memoryOffset2]; + dstVPlane[x] = srcUVPlane[memoryOffset1]; + dstVPlane[x + memoryOffset1] = srcUVPlane[memoryOffset3]; + srcUVPlane += perSeparatebytes; + } + if (static_cast(srcHalfWidth) & 1) { + dstUPlane[srcHalfWidth - 1] = srcUVPlane[memoryOffset0]; + dstVPlane[srcHalfWidth - 1] = srcUVPlane[memoryOffset1]; + } +} + +int32_t ConvertNV12ToNV21::SeparateNV12UVPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + int32_t ret = CheckColorConvertInfo(srcImgInfo, dstImgInfo); + if (ret != DCAMERA_OK) { + DHLOGE("ColorConvert : CheckColorConvertInfo failed."); + return ret; + } + + int32_t y2UvRatio = 2; + uint8_t *srcUVPlane = srcImgInfo.imgData + srcImgInfo.chromaOffset; + int32_t srcUVStride = srcImgInfo.alignedWidth; + uint8_t *dstUPlane = dstImgInfo.imgData + dstImgInfo.chromaOffset; + int32_t dstUStride = dstImgInfo.alignedWidth / y2UvRatio; + uint8_t *dstVPlane = dstUPlane + (dstImgInfo.chromaOffset / y2UvRatio) / y2UvRatio; + int32_t dstVStride = dstImgInfo.alignedWidth / y2UvRatio; + int32_t width = srcImgInfo.width / y2UvRatio; + int32_t height = srcImgInfo.height / y2UvRatio; + DHLOGD("srcUVStride %d, dstUStride %d, dstVStride %d, src half width %d, src half height %d.", + srcUVStride, dstUStride, dstVStride, width, height); + + /* Negative height means invert the image. */ + if (height < 0) { + height = -height; + dstUPlane = dstUPlane + (height - 1) * dstUStride; + dstVPlane = dstVPlane + (height - 1) * dstVStride; + dstUStride = -dstUStride; + dstVStride = -dstVStride; + } + /* No black border of srcImage and dstImage, and the strides of srcImage and dstImage are equal. */ + if (srcUVStride == width * y2UvRatio && dstUStride == width && dstVStride == width) { + SeparateUVPlaneByRow(srcUVPlane, dstUPlane, dstVPlane, width * height); + return DCAMERA_OK; + } + /* Black borders exist in srcImage or dstImage. */ + for (int32_t y = 0; y < height; ++y) { + SeparateUVPlaneByRow(srcUVPlane, dstUPlane, dstVPlane, width); + dstUPlane += dstUStride; + dstVPlane += dstVStride; + srcUVPlane += srcUVStride; + } + return DCAMERA_OK; +} + +/** +* @brief Combine half a row of srcUPlane and half a row of srcVPlane into a row of dstUVPlane. For example, +* converts the UVPlane memory arrangement of YUVI420 to the UV memory arrangement of NV12. Note that the +* stride and width of the srcImage must be the same. +*/ +void ConvertNV12ToNV21::CombineUVPlaneByRow(const uint8_t *srcUPlane, const uint8_t *srcVPlane, uint8_t *dstUVPlane, + int32_t dstHalfWidth) +{ + int32_t memoryOffset0 = 0; + int32_t memoryOffset1 = 1; + int32_t memoryOffset2 = 2; + int32_t memoryOffset3 = 3; + int32_t perCombinebytes = 4; + for (int32_t x = 0; x < dstHalfWidth - 1; x += memoryOffset2) { + dstUVPlane[memoryOffset0] = srcUPlane[x]; + dstUVPlane[memoryOffset1] = srcVPlane[x]; + dstUVPlane[memoryOffset2] = srcUPlane[x + memoryOffset1]; + dstUVPlane[memoryOffset3] = srcVPlane[x + memoryOffset1]; + dstUVPlane += perCombinebytes; + } + if (static_cast(dstHalfWidth) & 1) { + dstUVPlane[memoryOffset0] = srcUPlane[dstHalfWidth - 1]; + dstUVPlane[memoryOffset1] = srcVPlane[dstHalfWidth - 1]; + } +} + +int32_t ConvertNV12ToNV21::CombineNV12UVPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + int32_t ret = CheckColorConvertInfo(srcImgInfo, dstImgInfo); + if (ret != DCAMERA_OK) { + DHLOGE("ColorConvert : CheckColorConvertInfo failed."); + return ret; + } + + int32_t y2UvRatio = 2; + uint8_t *srcVPlane = srcImgInfo.imgData + srcImgInfo.chromaOffset; + int32_t srcVStride = srcImgInfo.alignedWidth / y2UvRatio; + uint8_t *srcUPlane = srcVPlane + (srcImgInfo.chromaOffset / y2UvRatio) / y2UvRatio; + int32_t srcUStride = srcImgInfo.alignedWidth / y2UvRatio; + uint8_t *dstUVPlane = dstImgInfo.imgData + dstImgInfo.chromaOffset; + int32_t dstUVStride = dstImgInfo.alignedWidth; + int32_t width = dstImgInfo.width / y2UvRatio; + int32_t height = dstImgInfo.height / y2UvRatio; + DHLOGD("srcUStride %d, srcVStride %d, dstUVStride %d, dst half width %d, dst half height %d.", + srcUStride, srcVStride, dstUVStride, width, height); + + /* Negative height means invert the image. */ + if (height < 0) { + height = -height; + dstUVPlane = dstUVPlane + (height - 1) * dstUVStride; + dstUVStride = -dstUVStride; + } + /* No black border of srcImage and dstImage, and the strides of srcImage and dstImage are equal. */ + if (srcUStride == width && srcVStride == width && dstUVStride == width * y2UvRatio) { + CombineUVPlaneByRow(srcUPlane, srcVPlane, dstUVPlane, width * height); + return DCAMERA_OK; + } + /* Black borders exist in srcImage or dstImage. */ + for (int32_t y = 0; y < height; ++y) { + CombineUVPlaneByRow(srcUPlane, srcVPlane, dstUVPlane, width); + srcUPlane += srcUStride; + srcVPlane += srcVStride; + dstUVPlane += dstUVStride; + } + return DCAMERA_OK; +} + +int32_t ConvertNV12ToNV21::CopyYPlane(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + int32_t ret = CheckColorConvertInfo(srcImgInfo, dstImgInfo); + if (ret != DCAMERA_OK) { + DHLOGE("ColorConvert : CheckColorConvertInfo failed."); + return ret; + } + + errno_t err = EOK; + size_t totalCopyYPlaneSize = dstImgInfo.alignedWidth * dstImgInfo.height; + if (srcImgInfo.alignedWidth == dstImgInfo.width && dstImgInfo.alignedWidth == dstImgInfo.width) { + /* No black border of srcImage and dstImage, and the strides of srcImage and dstImage are equal. */ + err = memcpy_s(dstImgInfo.imgData, totalCopyYPlaneSize, srcImgInfo.imgData, totalCopyYPlaneSize); + if (err != EOK) { + DHLOGE("ColorConvert : memcpy_s CopyYPlaner failed by Coalesce rows."); + return DCAMERA_MEMORY_OPT_ERROR; + } + } else { + /* Black borders exist in srcImage or dstImage. */ + int32_t srcDataOffset = 0; + int32_t dstDataOffset = 0; + for (int32_t yh = 0; yh < dstImgInfo.height; yh++) { + DHLOGE("ColorConvert : memcpy_s Line[%d] source buffer failed.", yh); + err = memcpy_s(dstImgInfo.imgData + dstDataOffset, totalCopyYPlaneSize - dstDataOffset, + srcImgInfo.imgData + srcDataOffset, dstImgInfo.width); + if (err != EOK) { + DHLOGE("memcpy_s YPlane in line[%d] failed.", yh); + return DCAMERA_MEMORY_OPT_ERROR; + } + dstDataOffset += dstImgInfo.alignedWidth; + srcDataOffset += srcImgInfo.alignedWidth; + } + DHLOGD("ColorConvert :get valid yplane OK, srcImgInfo: alignedWidth %d, width %d, height %d. " + + "dstImgInfo: alignedWidth %d, width %d, height %d. dstDataOffset %d, srcDataOffset %d.", + srcImgInfo.alignedWidth, srcImgInfo.width, srcImgInfo.height, dstImgInfo.alignedWidth, + dstImgInfo.width, dstImgInfo.height, dstDataOffset, srcDataOffset); + } + return DCAMERA_OK; +} + +int32_t ConvertNV12ToNV21::ColorConvertNV12ToNV21(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + int32_t err = CheckColorConvertInfo(srcImgInfo, dstImgInfo); + if (err != DCAMERA_OK) { + DHLOGE("ColorConvertNV12ToNV21 : CheckColorConvertInfo failed."); + return err; + } + err = CopyYPlane(srcImgInfo, dstImgInfo); + if (err != DCAMERA_OK) { + DHLOGE("ColorConvertNV12ToNV21 : CopyYPlane failed."); + return err; + } + + std::shared_ptr tempPlaneYUV = std::make_shared(dstImgInfo.imgSize); + ImageUnitInfo tempImgInfo = dstImgInfo; + tempImgInfo.imgData = tempPlaneYUV->Data(); + SeparateNV12UVPlane(srcImgInfo, tempImgInfo); + CombineNV12UVPlane(tempImgInfo, dstImgInfo); + return DCAMERA_OK; +} + +std::shared_ptr ConvertNV12ToNV21::ProcessData(const std::shared_ptr& srcBuf, + const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig) +{ + if (srcBuf == nullptr) { + DHLOGE("ColorConvertProcessData : srcBuf is null."); + return nullptr; + } + if (!IsConvertible(sourceConfig, targetConfig)) { + DHLOGE("ColorConvertProcessData : Only supported convert videoformat NV12 to NV21."); + DHLOGE("sourceConfig: Videoformat %d Width %d, Height %d, targetConfig: Videoformat %d Width %d, Height %d.", + sourceConfig.GetVideoformat(), sourceConfig.GetWidth(), sourceConfig.GetHeight(), + targetConfig.GetVideoformat(), targetConfig.GetWidth(), targetConfig.GetHeight()); + return nullptr; + } + int64_t timeStamp = 0; + if (!(srcBuf->FindInt64("timeUs", timeStamp))) { + DHLOGE("ColorConvertProcessData : Find srcBuf timeStamp failed."); + return nullptr; + } + + ImageUnitInfo srcImgInfo {Videoformat::YUVI420, 0, 0, 0, 0, 0, 0, nullptr}; + if (GetImageUnitInfo(srcImgInfo, srcBuf) != DCAMERA_OK) { + DHLOGE("ColorConvertProcessData : Get srcImgInfo failed."); + return nullptr; + } + int32_t y2UvRatio = 2; + int32_t bytesPerPixel = 3; + size_t dstBufsize = sourceConfig.GetWidth() * sourceConfig.GetHeight() * bytesPerPixel / y2UvRatio; + std::shared_ptr dstBuf = std::make_shared(dstBufsize); + ImageUnitInfo dstImgInfo = { targetConfig.GetVideoformat(), static_cast(sourceConfig.GetWidth()), + static_cast(sourceConfig.GetHeight()), static_cast(sourceConfig.GetWidth()), + static_cast(sourceConfig.GetHeight()), sourceConfig.GetWidth() * sourceConfig.GetHeight(), + dstBuf->Size(), dstBuf->Data() }; + int32_t err = ColorConvertNV12ToNV21(srcImgInfo, dstImgInfo); + if (err != DCAMERA_OK) { + return nullptr; + } + dstBuf->SetInt64("timeUs", timeStamp); + dstBuf->SetInt32("Videoformat", static_cast(targetConfig.GetVideoformat())); + dstBuf->SetInt32("alignedWidth", static_cast(sourceConfig.GetWidth())); + dstBuf->SetInt32("alignedHeight", static_cast(sourceConfig.GetHeight())); + dstBuf->SetInt32("width", static_cast(sourceConfig.GetWidth())); + dstBuf->SetInt32("height", static_cast(sourceConfig.GetHeight())); + DHLOGD("ColorConvert end, dstBuf Videoformat %d, width %d, height %d, alignedWidth %d, alignedHeight %d, " + + "ImgSize%d, timeUs %lld.", targetConfig.GetVideoformat(), sourceConfig.GetWidth(), sourceConfig.GetHeight(), + sourceConfig.GetWidth(), sourceConfig.GetHeight(), dstBuf->Size(), timeStamp); + return dstBuf; +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/fpscontroller/fps_controller_process.cpp b/services/data_process/src/pipeline_node/fpscontroller/fps_controller_process.cpp new file mode 100644 index 00000000..090aa045 --- /dev/null +++ b/services/data_process/src/pipeline_node/fpscontroller/fps_controller_process.cpp @@ -0,0 +1,331 @@ +/* + * 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 "fps_controller_process.h" + +#include "dcamera_utils_tools.h" +#include "distributed_camera_errno.h" +#include "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +FpsControllerProcess::~FpsControllerProcess() +{ + if (isFpsControllerProcess_) { + DHLOGD("~DecodeDataProcess : ReleaseProcessNode."); + ReleaseProcessNode(); + } +} + +int32_t FpsControllerProcess::InitNode() +{ + if (targetConfig_.GetFrameRate() > MAX_TARGET_FRAME_RATE) { + DHLOGE("The target framerate : %d is greater than the max framerate : %d.", + targetConfig_.GetFrameRate(), MAX_TARGET_FRAME_RATE); + return DCAMERA_BAD_TYPE; + } + targetFrameRate_ = targetConfig_.GetFrameRate(); + isFpsControllerProcess_ = true; + return DCAMERA_OK; +} + +void FpsControllerProcess::ReleaseProcessNode() +{ + DHLOGD("Start release [%d] node : FPS controller.", nodeRank_); + if (nextDataProcess_ != nullptr) { + nextDataProcess_->ReleaseProcessNode(); + } + + isFpsControllerProcess_ = false; + isFirstFrame_ = false; + targetFrameRate_ = 0; + lastFrameIncomeTimeMs_ = 0; + recentFrameTimeSpanMs_ = -1; + keepCorrectionCount_ = 0; + keepLessThanDoubleCount_ = 0; + keepMoreThanDoubleCount_ = 0; + frameRateCorrectionFactor_ = 0.0; + frameRateOvershootMdf_ = 0; + for (int i = 0; i < INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE; i++) { + incomingFrameTimesMs_[i] = 0; + } +} + +int32_t FpsControllerProcess::ProcessData(std::vector>& inputBuffers) +{ + if (inputBuffers.empty()) { + DHLOGE("Data buffers is null."); + return DCAMERA_BAD_TYPE; + } + if (!isFpsControllerProcess_) { + DHLOGE("Decoder node occurred error."); + return DCAMERA_DISABLE_PROCESS; + } + int64_t timeStampUs = 0; + if (!inputBuffers[0]->FindInt64("timeUs", timeStampUs)) { + DHLOGE("Find decoder output timestamp fail."); + return DCAMERA_BAD_TYPE; + } + + std::lock_guard lck (mtx); + int64_t nowTimeMs = GetNowTimeStampMs(); + UpdateFPSControllerInfo(nowTimeMs); + + float curFrameRate = CalculateFrameRate(nowTimeMs); + if (IsDropFrame(curFrameRate)) { + DHLOGD("frame control, currect frameRate %u, targetRate %u, drop it", curFrameRate, targetFrameRate_); + return DCAMERA_OK; + } + + DHLOGD("frame control render PushVideoFrame, frame info width %d height %d, timeStampUs %lld, fps %d", + sourceConfig_.GetWidth(), sourceConfig_.GetHeight(), (long long)timeStampUs, curFrameRate); + return FpsControllerDone(inputBuffers); +} + +void FpsControllerProcess::UpdateFPSControllerInfo(int64_t nowMs) +{ + DHLOGD("Frame control, update control info."); + if (targetFrameRate_ <= 0) { + DHLOGD("Frame control, targetFrameRate_ : %d", targetFrameRate_); + return; + } + + isFirstFrame_ = false; + if (lastFrameIncomeTimeMs_ == 0) { + DHLOGD("Frame control, income fisrt frame."); + isFirstFrame_ = true; + } + lastFrameIncomeTimeMs_ = nowMs; + recentFrameTimeSpanMs_ = nowMs - lastFrameIncomeTimeMs_; + DHLOGD("Frame control, lastFrameIncomeTimeMs_ %lld, receive Frame after last frame(ms): %lld", + (long long)lastFrameIncomeTimeMs_, (long long)recentFrameTimeSpanMs_); + UpdateIncomingFrameTimes(nowMs); + UpdateFrameRateCorrectionFactor(nowMs); + return; +} + +void FpsControllerProcess::UpdateFrameRateCorrectionFactor(int64_t nowMs) +{ + DHLOGD("Frame control, update FPS correction factor."); + if (targetFrameRate_ <= 0) { + DHLOGD("Frame control, targetFrameRate_ : %d", targetFrameRate_); + return; + } + if (isFirstFrame_) { + DHLOGD("No frame rate correction factor when the first frame."); + return; + } + + const float minDropFrmValue = 0.5; + const float maxDropFrmValue = 1.0; + const float msPerSecond = 1000; + const float maxInstantaneousFrameRateCoefficient = 1.1; + float maxInstantaneousFrameRateThreshold = targetFrameRate_ * maxInstantaneousFrameRateCoefficient; + float instantaneousFrameRate = msPerSecond / recentFrameTimeSpanMs_; + if (instantaneousFrameRate < 0) { + instantaneousFrameRate = -instantaneousFrameRate; + } + if (instantaneousFrameRate <= maxInstantaneousFrameRateThreshold) { + frameRateCorrectionFactor_ = minDropFrmValue; + } else { + if (keepCorrectionCount_ >= VIDEO_FRAME_DROP_INTERVAL) { + frameRateCorrectionFactor_ = maxDropFrmValue; + keepCorrectionCount_ = 0; + } else { + frameRateCorrectionFactor_ = 0; + keepCorrectionCount_++; + } + DHLOGD("Frame control, instantaneousFrameRate %.3f is more than maxInstantaneousFrameRateThreshold %.3f, " + + "keepCorrectionCount %d", instantaneousFrameRate, maxInstantaneousFrameRateThreshold, + keepCorrectionCount_); + } + + DHLOGD("Frame control, targetFramerate %d, maxInstantaneousFrameRateThreshold %.3f," + + "instantaneousFrameRate %.3f, frameRateCorrectionFactor %.3f", targetFrameRate_, + maxInstantaneousFrameRateThreshold, instantaneousFrameRate, frameRateCorrectionFactor_); + return; +} + +void FpsControllerProcess::UpdateIncomingFrameTimes(int64_t nowMs) +{ + DHLOGD("Frame control, update incoming frame times array."); + if (targetFrameRate_ <= 0) { + DHLOGD("Frame control, targetFrameRate_ : %d", targetFrameRate_); + return; + } + if (isFirstFrame_) { + incomingFrameTimesMs_[0] = nowMs; + return; + } + + int64_t intervalNewAndFirst = nowMs - incomingFrameTimesMs_[0]; + if (intervalNewAndFirst < 0) { + intervalNewAndFirst = -intervalNewAndFirst; + } + if (intervalNewAndFirst > FRMAE_MAX_INTERVAL_TIME_WINDOW_MS) { + DHLOGD("frame control, nowMs: %lld mIncomingFrameT[0]: %lld intervalNewAndFirst: %lld", + (long long)nowMs, (long long)incomingFrameTimesMs_[0], (long long)intervalNewAndFirst); + for (int i = 0; i < INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE; i++) { + incomingFrameTimesMs_[i] = 0; + } + } else { + DHLOGD("frame control shift, nowMs: %lld mIncomingFrameT[0]: %lld intervalNewAndFirst: %lld", + (long long)nowMs, (long long)incomingFrameTimesMs_[0], (long long)intervalNewAndFirst); + const int32_t windowLeftNum = 2; + for (int i = (INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE - windowLeftNum); i >= 0; --i) { + incomingFrameTimesMs_[i + 1] = incomingFrameTimesMs_[i]; + } + } + incomingFrameTimesMs_[0] = nowMs; + return; +} + +float FpsControllerProcess::CalculateFrameRate(int64_t nowMs) +{ + DHLOGD("Frame control, calculate frame rate."); + if (targetFrameRate_ <= 0) { + DHLOGE("Frame control, targetFrameRate_ : %d", targetFrameRate_); + return 0.0; + } + + int32_t num = 0; + int32_t validFramesNumber = 0; + if (nowMs < 0) { + nowMs = -nowMs; + } + for (; num < INCOME_FRAME_TIME_HISTORY_WINDOWS_SIZE; num++) { + if (incomingFrameTimesMs_[num] <= 0 || nowMs - incomingFrameTimesMs_[num] > FRAME_HISTORY_TIME_WINDOWS_MS) { + break; + } else { + validFramesNumber++; + } + } + + const float msPerSecond = 1000; + const int32_t minValidCalculatedFrameRatesNum = 2; + int32_t minIncomingFrameNum = static_cast(targetFrameRate_) / MIN_INCOME_FRAME_NUM_COEFFICIENT; + if (validFramesNumber > minIncomingFrameNum && validFramesNumber > minValidCalculatedFrameRatesNum) { + int64_t validTotalTimeDifference = (nowMs - incomingFrameTimesMs_[num - 1]); + if (validTotalTimeDifference < 0) { + validTotalTimeDifference = -validTotalTimeDifference; + } + if (validTotalTimeDifference > 0) { + return validFramesNumber * msPerSecond / validTotalTimeDifference + frameRateCorrectionFactor_; + } + } + return static_cast(validFramesNumber); +} + +bool FpsControllerProcess::IsDropFrame(float incomingFps) +{ + DHLOGD("Frame control, IsDropFrame"); + if (targetFrameRate_ == 0) { + DHLOGD("target fps is 0, drop all frame."); + return true; + } + if (incomingFps <= 0) { + DHLOGD("incoming fps not more than 0, not drop"); + return false; + } + const int32_t incomingFrmRate = static_cast(incomingFps); + if (incomingFrmRate > static_cast(targetFrameRate_)) { + DHLOGD("incoming fps not more than targetFrameRate_, not drop"); + return false; + } + bool isDrop = ReduceFrameRateByUniformStrategy(incomingFrmRate); + DHLOGD("drop frame result: %s", isDrop ? "drop" : "no drop"); + return isDrop; +} + +bool FpsControllerProcess::ReduceFrameRateByUniformStrategy(int32_t incomingFrmRate) +{ + DHLOGD("Frame control, reduce frame rate by uniform rate strategy"); + if (incomingFrmRate > static_cast(targetFrameRate_)) { + DHLOGD("incoming fps not more than targetFrameRate_, not drop"); + return false; + } + + /* + * When the actual incoming frame rate correction value is greater than the target frame + * rate, the incoming frames are reduced uniformly. + */ + bool isDrop = false; + int32_t overshoot = frameRateOvershootMdf_ + (incomingFrmRate - targetFrameRate_); + if (overshoot < 0) { + overshoot = 0; + frameRateOvershootMdf_ = 0; + } + if (overshoot && DOUBLE_MULTIPLE * overshoot < incomingFrmRate) { + /* + * When the actual input frame rate is less than or equal to twice the target frame rate, + * one frame is droped every (incomingFrmRate / overshoot) frames. + */ + if (keepMoreThanDoubleCount_) { + keepMoreThanDoubleCount_ = 0; + return true; + } + const int32_t dropVar = incomingFrmRate / overshoot; + if (keepLessThanDoubleCount_ >= dropVar) { + isDrop = true; + frameRateOvershootMdf_ = -(incomingFrmRate % overshoot) / OVERSHOOT_MODIFY_COEFFICIENT; + keepLessThanDoubleCount_ = 1; + } else { + keepLessThanDoubleCount_++; + } + } else { + /* + * When the actual frame rate is more than twice the target frame rate or the overshoot is + * equal to 0, one frame is reserved every (overshoot / targetFrameRate_) frames. + */ + keepLessThanDoubleCount_ = 0; + const int32_t dropVar = overshoot / targetFrameRate_; + if (keepMoreThanDoubleCount_ < dropVar) { + isDrop = true; + keepMoreThanDoubleCount_++; + } else { + frameRateOvershootMdf_ = overshoot % static_cast(targetFrameRate_); + isDrop = false; + keepMoreThanDoubleCount_ = 0; + } + } + return isDrop; +} + +int32_t FpsControllerProcess::FpsControllerDone(std::vector> outputBuffers) +{ + if (outputBuffers.empty()) { + DHLOGE("The received data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + + if (nextDataProcess_ != nullptr) { + DHLOGD("Send to the next node of the FpsController for processing."); + int32_t err = nextDataProcess_->ProcessData(outputBuffers); + if (err != DCAMERA_OK) { + DHLOGE("Someone node after the FpsController processes fail."); + } + return err; + } + DHLOGD("The current node is the last node, and Output the processed video buffer"); + std::shared_ptr targetPipelineSource = callbackPipelineSource_.lock(); + if (targetPipelineSource == nullptr) { + DHLOGE("callbackPipelineSource_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + targetPipelineSource->OnProcessedVideoBuffer(outputBuffers[0]); + return DCAMERA_OK; +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp new file mode 100644 index 00000000..6e69982c --- /dev/null +++ b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp @@ -0,0 +1,701 @@ +/* + * 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 "decode_data_process.h" + +#include "distributed_hardware_log.h" +#include "graphic_common_c.h" + +#include "convert_nv12_to_nv21.h" +#include "dcamera_utils_tools.h" +#include "decode_video_callback.h" + +namespace OHOS { +namespace DistributedHardware { +DecodeDataProcess::~DecodeDataProcess() +{ + if (isDecoderProcess_) { + DHLOGD("~DecodeDataProcess : ReleaseProcessNode."); + ReleaseProcessNode(); + } +} + +int32_t DecodeDataProcess::InitNode() +{ + DHLOGD("Init DCamera DecodeNode start."); + if (!(IsInDecoderRange(sourceConfig_) && IsInDecoderRange(targetConfig_))) { + DHLOGE("Source config or target config are invalid."); + return DCAMERA_BAD_VALUE; + } + if (!IsConvertible(sourceConfig_, targetConfig_)) { + DHLOGE("The DecodeNode can't convert %d to %d.", sourceConfig_.GetVideoCodecType(), + targetConfig_.GetVideoCodecType()); + return DCAMERA_BAD_TYPE; + } + if (sourceConfig_.GetVideoCodecType() == targetConfig_.GetVideoCodecType()) { + DHLOGD("Disable DecodeNode. The target video codec type %d is the same as the source video codec type %d.", + sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); + return DCAMERA_OK; + } + + InitCodecEvent(); + int32_t err = InitDecoder(); + if (err != DCAMERA_OK) { + DHLOGE("Init video decoder fail."); + ReleaseProcessNode(); + return err; + } + alignedHeight_ = GetAlignedHeight(); + isDecoderProcess_ = true; + return DCAMERA_OK; +} + +int32_t DecodeDataProcess::GetAlignedHeight() +{ + int32_t alignedBits = 32; + int32_t alignedHeight = static_cast(sourceConfig_.GetHeight()); + if (alignedHeight % alignedBits != 0) { + alignedHeight = ((alignedHeight / alignedBits) + 1) * alignedBits; + } + return alignedHeight; +} + +bool DecodeDataProcess::IsInDecoderRange(const VideoConfigParams& curConfig) +{ + return (curConfig.GetWidth() >= MIN_VIDEO_WIDTH || curConfig.GetWidth() <= MAX_VIDEO_WIDTH || + curConfig.GetHeight() >= MIN_VIDEO_HEIGHT || curConfig.GetHeight() <= MAX_VIDEO_HEIGHT || + curConfig.GetFrameRate() <= MAX_FRAME_RATE); +} + +bool DecodeDataProcess::IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig) +{ + return (sourceConfig.GetVideoCodecType() == targetConfig.GetVideoCodecType() || + targetConfig.GetVideoCodecType() == VideoCodecType::NO_CODEC); +} + +void DecodeDataProcess::InitCodecEvent() +{ + DHLOGD("Init DecodeNode eventBus, and add handler for it."); + eventBusDecode_ = std::make_shared(); + DCameraCodecEvent codecEvent(*this, std::make_shared()); + eventBusRegHandleDecode_ = eventBusDecode_->AddHandler(codecEvent.GetType(), *this); + + DHLOGD("Add handler for DCamera pipeline eventBus."); + eventBusRegHandlePipeline2Decode_ = eventBusPipeline_->AddHandler(codecEvent.GetType(), *this); +} + +int32_t DecodeDataProcess::InitDecoder() +{ + DHLOGD("Init video decoder."); + int32_t err = InitDecoderMetadataFormat(); + if (err != DCAMERA_OK) { + DHLOGE("Init video decoder metadata format fail."); + return err; + } + + videoDecoder_ = Media::VideoDecoderFactory::CreateByName("OMX_hisi_video_decoder_avc"); + if (videoDecoder_ == nullptr) { + DHLOGE("Create video decoder failed."); + return DCAMERA_INIT_ERR; + } + decodeVideoCallback_ = std::make_shared(shared_from_this()); + int32_t retVal = videoDecoder_->SetCallback(decodeVideoCallback_); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Set video decoder callback failed."); + return DCAMERA_INIT_ERR; + } + retVal = videoDecoder_->Configure(metadataFormat_); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Set video decoder metadata format failed."); + return DCAMERA_INIT_ERR; + } + retVal = SetDecoderOutputSurface(); + if (retVal != DCAMERA_OK) { + DHLOGE("Set decoder output surface fail."); + return retVal; + } + + retVal = videoDecoder_->Prepare(); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Video decoder prepare failed."); + return DCAMERA_INIT_ERR; + } + retVal = videoDecoder_->Start(); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Video decoder start failed."); + return DCAMERA_INIT_ERR; + } + return DCAMERA_OK; +} + +int32_t DecodeDataProcess::InitDecoderMetadataFormat() +{ + DHLOGD("Init video decoder metadata format."); + switch (sourceConfig_.GetVideoCodecType()) { + case VideoCodecType::CODEC_H264: + processType_ = "video/avc"; + metadataFormat_.PutStringValue("codec_mime", processType_); + break; + case VideoCodecType::CODEC_H265: + processType_ = "video/hevc"; + metadataFormat_.PutStringValue("codec_mime", processType_); + break; + default: + DHLOGE("The current codec type does not support decoding."); + return DCAMERA_NOT_FOUND; + } + metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12); + metadataFormat_.PutIntValue("max_input_size", MAX_YUV420_BUFFER_SIZE); + metadataFormat_.PutIntValue("width", (int32_t)sourceConfig_.GetWidth()); + metadataFormat_.PutIntValue("height", (int32_t)sourceConfig_.GetHeight()); + metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE); + return DCAMERA_OK; +} + +int32_t DecodeDataProcess::SetDecoderOutputSurface() +{ + DHLOGD("Set the video decoder output surface."); + if (videoDecoder_ == nullptr) { + DHLOGE("The video decoder is null."); + return DCAMERA_BAD_VALUE; + } + + decodeConsumerSurface_ = Surface::CreateSurfaceAsConsumer(); + if (decodeConsumerSurface_ == nullptr) { + DHLOGE("Creat the decode consumer surface fail."); + return DCAMERA_INIT_ERR; + } + decodeConsumerSurface_->SetDefaultWidthAndHeight((int32_t)sourceConfig_.GetWidth(), + (int32_t)sourceConfig_.GetHeight()); + sptr decodeSurfaceListener_ = new DecodeSurfaceListener(decodeConsumerSurface_, + shared_from_this()); + if (decodeConsumerSurface_->RegisterConsumerListener(decodeSurfaceListener_) != + SURFACE_ERROR_OK) { + DHLOGE("Register consumer listener fail."); + return DCAMERA_INIT_ERR; + } + + sptr surfaceProducer = decodeConsumerSurface_->GetProducer(); + if (surfaceProducer == nullptr) { + DHLOGE("Get the surface producer of the decode consumer surface fail."); + return DCAMERA_INIT_ERR; + } + decodeProducerSurface_ = Surface::CreateSurfaceAsProducer(surfaceProducer); + if (decodeProducerSurface_ == nullptr) { + DHLOGE("Creat the decode producer surface of the decode consumer surface fail."); + return DCAMERA_INIT_ERR; + } + + DHLOGD("Set the producer surface to video decoder output surface."); + int32_t err = videoDecoder_->SetOutputSurface(decodeProducerSurface_); + if (err != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Set decoder output surface fail."); + return DCAMERA_INIT_ERR; + } + return DCAMERA_OK; +} + +void DecodeDataProcess::ReleaseProcessNode() +{ + DHLOGD("Start release [%d] node : DecodeNode.", nodeRank_); + isDecoderProcess_ = false; + if (nextDataProcess_ != nullptr) { + nextDataProcess_->ReleaseProcessNode(); + } + if (eventBusDecode_ != nullptr && eventBusPipeline_ != nullptr) { + DHLOGD("Start release DecodeNode eventBusDecode_ and eventBusPipeline_."); + DCameraCodecEvent codecEvent(*this, std::make_shared()); + eventBusDecode_->RemoveHandler(codecEvent.GetType(), eventBusRegHandleDecode_); + eventBusDecode_ = nullptr; + eventBusPipeline_->RemoveHandler(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_); + eventBusPipeline_ = nullptr; + } + + { + std::lock_guard lck(mtxDecoderState_); + if (videoDecoder_ != nullptr) { + DHLOGD("Start release videoDecoder."); + videoDecoder_->Flush(); + videoDecoder_->Stop(); + videoDecoder_->Release(); + decodeConsumerSurface_ = nullptr; + decodeProducerSurface_ = nullptr; + videoDecoder_ = nullptr; + decodeVideoCallback_ = nullptr; + } + } + + processType_ = ""; + std::queue> emptyBuffersQueue; + inputBuffersQueue_.swap(emptyBuffersQueue); + std::queue emptyIndexsQueue; + availableInputIndexsQueue_.swap(emptyIndexsQueue); + waitDecoderOutputCount_ = 0; + lastFeedDecoderInputBufferTimeUs_ = 0; + outputTimeStampUs_ = 0; + alignedHeight_ = 0; + DHLOGD("Release [%d] node : DecodeNode end.", nodeRank_); +} + +int32_t DecodeDataProcess::ProcessData(std::vector>& inputBuffers) +{ + DHLOGD("Process data in DecodeDataProcess."); + if (inputBuffers.empty()) { + DHLOGE("The input data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + if (sourceConfig_.GetVideoCodecType() == targetConfig_.GetVideoCodecType()) { + DHLOGD("The target VideoCodecType : %d is the same as the source VideoCodecType : %d.", + sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); + return DecodeDone(inputBuffers); + } + + if (videoDecoder_ == nullptr) { + DHLOGE("The video decoder does not exist before decoding data."); + return DCAMERA_INIT_ERR; + } + if (inputBuffersQueue_.size() > VIDEO_DECODER_QUEUE_MAX) { + DHLOGE("video decoder input buffers queue over flow."); + return DCAMERA_INDEX_OVERFLOW; + } + if (inputBuffers[0]->Size() > MAX_YUV420_BUFFER_SIZE) { + DHLOGE("DecodeNode input buffer size %d error.", inputBuffers[0]->Size()); + return DCAMERA_MEMORY_OPT_ERROR; + } + if (!isDecoderProcess_) { + DHLOGE("Decoder node occurred error or start release."); + return DCAMERA_DISABLE_PROCESS; + } + inputBuffersQueue_.push(inputBuffers[0]); + DHLOGD("Push inputBuffer sucess. BufSize %d, QueueSize %d.", inputBuffers[0]->Size(), inputBuffersQueue_.size()); + int32_t err = FeedDecoderInputBuffer(); + if (err != DCAMERA_OK) { + int32_t sleepTimeUs = 5000; + std::this_thread::sleep_for(std::chrono::microseconds(sleepTimeUs)); + DHLOGD("Feed decoder input buffer fail. Try FeedDecoderInputBuffer again."); + std::shared_ptr reFeedInputPacket = std::make_shared(); + reFeedInputPacket->SetVideoCodecType(sourceConfig_.GetVideoCodecType()); + DCameraCodecEvent dCamCodecEv(*this, reFeedInputPacket, VideoCodecAction::ACTION_ONCE_AGAIN); + if (eventBusPipeline_ == nullptr) { + DHLOGE("eventBusPipeline_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + eventBusPipeline_->PostEvent(dCamCodecEv, POSTMODE::POST_ASYNC); + } + return DCAMERA_OK; +} + +int32_t DecodeDataProcess::FeedDecoderInputBuffer() +{ + DHLOGD("Feed decoder input buffer."); + while ((!inputBuffersQueue_.empty()) && (isDecoderProcess_)) { + std::shared_ptr buffer = inputBuffersQueue_.front(); + if (buffer == nullptr || availableInputIndexsQueue_.empty()) { + DHLOGE("inputBuffersQueue size %d, availableInputIndexsQueue size %d.", + inputBuffersQueue_.size(), availableInputIndexsQueue_.size()); + return DCAMERA_BAD_VALUE; + } + + { + std::lock_guard lck(mtxDecoderState_); + if (videoDecoder_ == nullptr) { + DHLOGE("The video decoder does not exist before GetInputBuffer."); + return DCAMERA_OK; + } + uint32_t index = availableInputIndexsQueue_.front(); + std::shared_ptr sharedMemoryInput = videoDecoder_->GetInputBuffer(index); + if (sharedMemoryInput == nullptr) { + DHLOGE("Failed to obtain the input shared memory corresponding to the [%d] index.", index); + return DCAMERA_BAD_VALUE; + } + size_t inputMemoDataSize = static_cast(sharedMemoryInput->GetSize()); + errno_t err = memcpy_s(sharedMemoryInput->GetBase(), inputMemoDataSize, buffer->Data(), buffer->Size()); + if (err != EOK) { + DHLOGE("memcpy_s buffer failed."); + return DCAMERA_MEMORY_OPT_ERROR; + } + int64_t timeUs = GetDecoderTimeStamp(); + DHLOGD("Decoder input buffer size %d, timeStamp %lld.", buffer->Size(), (long long)timeUs); + Media::AVCodecBufferInfo bufferInfo {timeUs, static_cast(buffer->Size()), 0}; + int32_t ret = videoDecoder_->QueueInputBuffer(index, bufferInfo, + Media::AVCODEC_BUFFER_FLAG_NONE); + if (ret != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("queue Input buffer failed."); + return DCAMERA_BAD_OPERATE; + } + } + + inputBuffersQueue_.pop(); + DHLOGD("Push inputBuffer sucess. inputBuffersQueue size is %d.", inputBuffersQueue_.size()); + + { + std::lock_guard lck(mtxHoldCount_); + availableInputIndexsQueue_.pop(); + waitDecoderOutputCount_++; + DHLOGD("Wait decoder output frames number is %d.", waitDecoderOutputCount_); + } + } + return DCAMERA_OK; +} + +int64_t DecodeDataProcess::GetDecoderTimeStamp() +{ + int64_t TimeDifferenceStampUs = 0; + int64_t nowTimeUs = GetNowTimeStampUs(); + if (lastFeedDecoderInputBufferTimeUs_ == 0) { + lastFeedDecoderInputBufferTimeUs_ = nowTimeUs; + return TimeDifferenceStampUs; + } + TimeDifferenceStampUs = nowTimeUs - lastFeedDecoderInputBufferTimeUs_; + lastFeedDecoderInputBufferTimeUs_ = nowTimeUs; + return TimeDifferenceStampUs; +} + +void DecodeDataProcess::GetDecoderOutputBuffer(const sptr& surface) +{ + DHLOGD("Get decoder output buffer."); + if (surface == nullptr) { + DHLOGE("Get decode consumer surface failed."); + return; + } + Rect damage = {0, 0, 0, 0}; + int32_t acquireFence = 0; + int64_t timeStampUs = 0; + sptr surfaceBuffer = nullptr; + GSError ret = surface->AcquireBuffer(surfaceBuffer, acquireFence, timeStampUs, damage); + if (ret != GSERROR_OK || surfaceBuffer == nullptr) { + DHLOGE("Acquire surface buffer failed!"); + return; + } + int32_t alignedWidth = surfaceBuffer->GetStride(); + int32_t alignedHeight = alignedHeight_; + DHLOGD("OutputBuffer alignedWidth %d, alignedHeight %d, TimeUs %lld.", alignedWidth, alignedHeight, timeStampUs); + CopyDecodedImage(surfaceBuffer, timeStampUs, alignedWidth, alignedHeight); + surface->ReleaseBuffer(surfaceBuffer, -1); + outputTimeStampUs_ = timeStampUs; + { + std::lock_guard lck(mtxHoldCount_); + if (waitDecoderOutputCount_ <= 0) { + DHLOGE("The waitDecoderOutputCount_ = %d.", waitDecoderOutputCount_); + } + int32_t firstFrameInputNum = 2; + if (outputTimeStampUs_ == 0) { + waitDecoderOutputCount_ -= firstFrameInputNum; + } else { + waitDecoderOutputCount_--; + } + DHLOGD("Wait decoder output frames number is %d.", waitDecoderOutputCount_); + } +} + +void DecodeDataProcess::CopyDecodedImage(const sptr& surBuf, int64_t timeStampUs, int32_t alignedWidth, + int32_t alignedHeight) +{ + if (surBuf == nullptr) { + DHLOGE("surface buffer is null!"); + return; + } + int32_t y2UvRatio = 2; + int32_t bytesPerPixel = 3; + size_t validDecodedImageAlignedSize = static_cast(alignedWidth * alignedHeight * + bytesPerPixel / y2UvRatio); + size_t validDecodedImageSize = static_cast(sourceConfig_.GetWidth() * sourceConfig_.GetHeight() * + bytesPerPixel / y2UvRatio); + size_t surfaceBufSize = static_cast(surBuf->GetSize()); + if (validDecodedImageAlignedSize > surfaceBufSize || validDecodedImageAlignedSize < validDecodedImageSize) { + DHLOGE("Buffer size error, validDecodedImageSize %d, validDecodedImageAlignedSize %d, surBufSize %d.", + validDecodedImageSize, validDecodedImageAlignedSize, surBuf->GetSize()); + return; + } + std::shared_ptr bufferOutput = std::make_shared(validDecodedImageSize); + uint8_t *addr = static_cast(surBuf->GetVirAddr()); + if (alignedWidth == static_cast(sourceConfig_.GetWidth()) && + alignedHeight == static_cast(sourceConfig_.GetHeight())) { + errno_t err = memcpy_s(bufferOutput->Data(), bufferOutput->Size(), addr, validDecodedImageSize); + if (err != EOK) { + DHLOGE("memcpy_s surface buffer failed."); + return; + } + } else { + ImageUnitInfo srcImgInfo = { sourceConfig_.GetVideoformat(), static_cast(sourceConfig_.GetWidth()), + static_cast(sourceConfig_.GetHeight()), alignedWidth, alignedHeight, + static_cast(alignedWidth * alignedHeight), surfaceBufSize, addr }; + ImageUnitInfo dstImgInfo = { sourceConfig_.GetVideoformat(), static_cast(sourceConfig_.GetWidth()), + static_cast(sourceConfig_.GetHeight()), static_cast(sourceConfig_.GetWidth()), + static_cast(sourceConfig_.GetHeight()), sourceConfig_.GetWidth() * sourceConfig_.GetHeight(), + bufferOutput->Size(), bufferOutput->Data() }; + int32_t retRow = CopyYUVPlaneByRow(srcImgInfo, dstImgInfo); + if (retRow != DCAMERA_OK) { + DHLOGE("memcpy_s surface buffer failed."); + return; + } + } + bufferOutput->SetInt64("timeUs", timeStampUs); + bufferOutput->SetInt32("Videoformat", static_cast(sourceConfig_.GetVideoformat())); + bufferOutput->SetInt32("alignedWidth", static_cast(sourceConfig_.GetWidth())); + bufferOutput->SetInt32("alignedHeight", static_cast(sourceConfig_.GetHeight())); + bufferOutput->SetInt32("width", static_cast(sourceConfig_.GetWidth())); + bufferOutput->SetInt32("height", static_cast(sourceConfig_.GetHeight())); + PostOutputDataBuffers(bufferOutput); +} + +int32_t DecodeDataProcess::CopyYUVPlaneByRow(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + int32_t ret = CheckCopyImageInfo(srcImgInfo, dstImgInfo); + if (ret != DCAMERA_OK) { + DHLOGE("Check CopyImageUnitInfo failed."); + return ret; + } + errno_t err = EOK; + int32_t srcDataOffset = 0; + int32_t dstDataOffset = 0; + for (int32_t yh = 0; yh < dstImgInfo.height; yh++) { + err = memcpy_s(dstImgInfo.imgData + dstDataOffset, dstImgInfo.chromaOffset - dstDataOffset, + srcImgInfo.imgData + srcDataOffset, dstImgInfo.width); + if (err != EOK) { + DHLOGE("memcpy_s YPlane in line[%d] failed.", yh); + return DCAMERA_MEMORY_OPT_ERROR; + } + dstDataOffset += dstImgInfo.alignedWidth; + srcDataOffset += srcImgInfo.alignedWidth; + } + DHLOGD("Copy Yplane end, dstDataOffset %d, srcDataOffset %d, validYPlaneSize %d.", + dstDataOffset, srcDataOffset, dstImgInfo.chromaOffset); + + int32_t y2UvRatio = 2; + dstDataOffset = dstImgInfo.chromaOffset; + srcDataOffset = srcImgInfo.chromaOffset; + for (int32_t uvh = 0; uvh < dstImgInfo.height / y2UvRatio; uvh++) { + err = memcpy_s(dstImgInfo.imgData + dstDataOffset, dstImgInfo.imgSize - dstDataOffset, + srcImgInfo.imgData + srcDataOffset, dstImgInfo.width); + if (err != EOK) { + DHLOGE("memcpy_s UVPlane in line[%d] failed.", uvh); + return DCAMERA_MEMORY_OPT_ERROR; + } + dstDataOffset += dstImgInfo.alignedWidth; + srcDataOffset += srcImgInfo.alignedWidth; + } + DHLOGD("Copy UVplane end, dstDataOffset %d, srcDataOffset %d.", dstDataOffset, srcDataOffset); + return DCAMERA_OK; +} + +int32_t DecodeDataProcess::CheckCopyImageInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo) +{ + if (srcImgInfo.imgData == nullptr || dstImgInfo.imgData == nullptr) { + DHLOGE("The imgData of srcImgInfo or the imgData of dstImgInfo are null!"); + return DCAMERA_BAD_VALUE; + } + if (srcImgInfo.colorFormat != dstImgInfo.colorFormat) { + DHLOGE("CopyInfo error : srcImgInfo colorFormat %d, dstImgInfo colorFormat %d.", + srcImgInfo.colorFormat, dstImgInfo.colorFormat); + return DCAMERA_BAD_VALUE; + } + + if (!IsCorrectImageUnitInfo(srcImgInfo)) { + DHLOGE("srcImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " + + "imgSize %lld.", srcImgInfo.width, srcImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight, + srcImgInfo.chromaOffset, srcImgInfo.imgSize); + return DCAMERA_BAD_VALUE; + } + if (!IsCorrectImageUnitInfo(dstImgInfo)) { + DHLOGE("dstImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " + + "imgSize %lld.", dstImgInfo.width, dstImgInfo.height, dstImgInfo.alignedWidth, dstImgInfo.alignedHeight, + dstImgInfo.chromaOffset, dstImgInfo.imgSize); + return DCAMERA_BAD_VALUE; + } + + if (dstImgInfo.width > srcImgInfo.alignedWidth || dstImgInfo.height > srcImgInfo.alignedHeight) { + DHLOGE("Comparison ImgInfo fail: dstwidth %d, dstheight %d, srcAlignedWidth %d, srcAlignedHeight %d.", + dstImgInfo.width, dstImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight); + return DCAMERA_BAD_VALUE; + } + return DCAMERA_OK; +} + +bool DecodeDataProcess::IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo) +{ + int32_t y2UvRatio = 2; + int32_t bytesPerPixel = 3; + size_t expectedImgSize = static_cast(imgInfo.alignedWidth * imgInfo.alignedHeight * + bytesPerPixel / y2UvRatio); + size_t expectedChromaOffset = static_cast(imgInfo.alignedWidth * imgInfo.alignedHeight); + return (imgInfo.width <= imgInfo.alignedWidth && imgInfo.height <= imgInfo.alignedHeight && + imgInfo.imgSize >= expectedImgSize && imgInfo.chromaOffset == expectedChromaOffset); +} + +void DecodeDataProcess::PostOutputDataBuffers(std::shared_ptr& outputBuffer) +{ + if (eventBusDecode_ == nullptr || outputBuffer == nullptr) { + DHLOGE("eventBusDecode_ or outputBuffer is null."); + return; + } + std::vector> multiDataBuffers; + multiDataBuffers.push_back(outputBuffer); + std::shared_ptr transNextNodePacket = std::make_shared(VideoCodecType::NO_CODEC, + multiDataBuffers); + DCameraCodecEvent dCamCodecEv(*this, transNextNodePacket, VideoCodecAction::NO_ACTION); + eventBusDecode_->PostEvent(dCamCodecEv, POSTMODE::POST_ASYNC); + DHLOGD("Send video decoder output asynchronous DCameraCodecEvents success."); +} + +int32_t DecodeDataProcess::DecodeDone(std::vector> outputBuffers) +{ + DHLOGD("Decoder Done."); + if (outputBuffers.empty()) { + DHLOGE("The received data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + + if (nextDataProcess_ != nullptr) { + DHLOGD("Send to the next node of the decoder for processing."); + int32_t err = nextDataProcess_->ProcessData(outputBuffers); + if (err != DCAMERA_OK) { + DHLOGE("Someone node after the decoder processes fail."); + } + return err; + } + DHLOGD("The current node is the last node, and Output the processed video buffer"); + std::shared_ptr targetPipelineSource = callbackPipelineSource_.lock(); + if (targetPipelineSource == nullptr) { + DHLOGE("callbackPipelineSource_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + targetPipelineSource->OnProcessedVideoBuffer(outputBuffers[0]); + return DCAMERA_OK; +} + +void DecodeDataProcess::OnEvent(DCameraCodecEvent& ev) +{ + DHLOGD("Receiving asynchronous DCameraCodecEvents."); + std::shared_ptr receivedCodecPacket = ev.GetCodecPacket(); + VideoCodecAction action = ev.GetAction(); + switch (action) { + case VideoCodecAction::NO_ACTION: { + if (receivedCodecPacket == nullptr) { + DHLOGE("the received codecPacket of action [%d] is null.", action); + OnError(); + return; + } + + std::shared_ptr colorConverter = std::make_shared(); + VideoConfigParams decodedConfig(VideoCodecType::NO_CODEC, Videoformat::NV12, sourceConfig_.GetFrameRate(), + sourceConfig_.GetWidth(), sourceConfig_.GetHeight()); + std::vector> nv21DataBuffers; + std::shared_ptr nv21Image = colorConverter->ProcessData( + receivedCodecPacket->GetDataBuffers()[0], decodedConfig, targetConfig_); + nv21DataBuffers.push_back(nv21Image); + + DecodeDone(nv21DataBuffers); + break; + } + case VideoCodecAction::ACTION_ONCE_AGAIN: + DHLOGD("Try FeedDecoderInputBuffer again."); + FeedDecoderInputBuffer(); + return; + default: + DHLOGD("The action : %d is not supported.", action); + return; + } +} + +void DecodeDataProcess::OnError() +{ + DHLOGD("DecodeDataProcess : OnError."); + isDecoderProcess_ = false; + videoDecoder_->Stop(); + std::shared_ptr targetPipelineSource = callbackPipelineSource_.lock(); + if (targetPipelineSource == nullptr) { + DHLOGE("callbackPipelineSource_ is nullptr."); + return; + } + targetPipelineSource->OnError(DataProcessErrorType::ERROR_PIPELINE_DECODER); +} + +void DecodeDataProcess::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("DecodeDataProcess::OnInputBufferAvailable"); + std::lock_guard lck(mtxHoldCount_); + if (availableInputIndexsQueue_.size() > VIDEO_DECODER_QUEUE_MAX) { + DHLOGE("Video decoder available indexs queue overflow."); + return; + } + DHLOGD("Video decoder available indexs queue push index [%d].", index); + availableInputIndexsQueue_.push(index); +} + +void DecodeDataProcess::OnOutputFormatChanged(const Media::Format &format) +{ + if (decodeOutputFormat_.GetFormatMap().empty()) { + DHLOGE("The first changed video decoder output format is null."); + return; + } + decodeOutputFormat_ = format; +} + +void DecodeDataProcess::OnOutputBufferAvailable(uint32_t index, const Media::AVCodecBufferInfo& info, + const Media::AVCodecBufferFlag& flag) +{ + if (!isDecoderProcess_) { + DHLOGE("Decoder node occurred error or start release."); + return; + } + DHLOGD("Video decode buffer info: presentation TimeUs %lld, size %d, offset %d, flag %d", + info.presentationTimeUs, info.size, info.offset, flag); + outputInfo_ = info; + { + std::lock_guard lck(mtxDecoderState_); + if (videoDecoder_ == nullptr) { + DHLOGE("The video decoder does not exist before decoding data."); + return; + } + int32_t errRelease = videoDecoder_->ReleaseOutputBuffer(index, true); + if (errRelease != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("The video decoder output decoded data to surface fail, index : [%d].", index); + } + } +} + +VideoConfigParams DecodeDataProcess::GetSourceConfig() const +{ + return sourceConfig_; +} + +VideoConfigParams DecodeDataProcess::GetTargetConfig() const +{ + return targetConfig_; +} + +void DecodeSurfaceListener::OnBufferAvailable() +{ + DHLOGD("DecodeSurfaceListener : OnBufferAvailable."); + std::shared_ptr targetDecoderNode = decodeVideoNode_.lock(); + if (targetDecoderNode == nullptr) { + DHLOGE("decodeVideoNode_ is nullptr."); + return; + } + targetDecoderNode->GetDecoderOutputBuffer(surface_); +} + +void DecodeSurfaceListener::SetSurface(const sptr& surface) +{ + surface_ = surface; +} + +void DecodeSurfaceListener::SetDecodeVideoNode(const std::weak_ptr& decodeVideoNode) +{ + decodeVideoNode_ = decodeVideoNode; +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/multimedia_codec/decode_video_callback.cpp b/services/data_process/src/pipeline_node/multimedia_codec/decode_video_callback.cpp new file mode 100644 index 00000000..401f3672 --- /dev/null +++ b/services/data_process/src/pipeline_node/multimedia_codec/decode_video_callback.cpp @@ -0,0 +1,67 @@ +/* + * 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 "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void DecodeVideoCallback::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGE("DecodeVideoCallback : OnError. Error type: %d . Error code: %d ", errorType, errorCode); + std::shared_ptr targetDecoderNode = decodeVideoNode_.lock(); + if (targetDecoderNode == nullptr) { + DHLOGE("decodeVideoNode_ is nullptr."); + return; + } + targetDecoderNode->OnError(); +} + +void DecodeVideoCallback::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("DecodeVideoCallback : OnInputBufferAvailable."); + std::shared_ptr targetDecoderNode = decodeVideoNode_.lock(); + if (targetDecoderNode == nullptr) { + DHLOGE("decodeVideoNode_ is nullptr."); + return; + } + targetDecoderNode->OnInputBufferAvailable(index); +} + +void DecodeVideoCallback::OnOutputFormatChanged(const Media::Format &format) +{ + DHLOGD("DecodeVideoCallback : OnOutputFormatChanged."); + std::shared_ptr targetDecoderNode = decodeVideoNode_.lock(); + if (targetDecoderNode == nullptr) { + DHLOGE("decodeVideoNode_ is nullptr."); + return; + } + targetDecoderNode->OnOutputFormatChanged(format); +} + +void DecodeVideoCallback::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGD("DecodeVideoCallback : OnOutputBufferAvailable. Only relaese buffer when using surface output."); + std::shared_ptr targetDecoderNode = decodeVideoNode_.lock(); + if (targetDecoderNode == nullptr) { + DHLOGE("decodeVideoNode_ is nullptr."); + return; + } + targetDecoderNode->OnOutputBufferAvailable(index, info, flag); +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp new file mode 100644 index 00000000..df634660 --- /dev/null +++ b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp @@ -0,0 +1,499 @@ +/* + * 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 "encode_data_process.h" + +#include + +#include "display_type.h" +#include "distributed_hardware_log.h" +#include "graphic_common_c.h" + +#include "dcamera_utils_tools.h" +#include "encode_video_callback.h" + +#ifndef DH_LOG_TAG +#define DH_LOG_TAG "DCDP_NODE_ENCODEC" +#endif + +namespace OHOS { +namespace DistributedHardware { +const std::map EncodeDataProcess::ENCODER_BITRATE_TABLE = { + std::map::value_type(WIDTH_320_HEIGHT_240, BITRATE_500000), + std::map::value_type(WIDTH_480_HEIGHT_360, BITRATE_1110000), + std::map::value_type(WIDTH_640_HEIGHT_360, BITRATE_1500000), + std::map::value_type(WIDTH_640_HEIGHT_480, BITRATE_1800000), + std::map::value_type(WIDTH_720_HEIGHT_540, BITRATE_2100000), + std::map::value_type(WIDTH_960_HEIGHT_540, BITRATE_2300000), + std::map::value_type(WIDTH_960_HEIGHT_720, BITRATE_2800000), + std::map::value_type(WIDTH_1280_HEIGHT_720, BITRATE_3400000), + std::map::value_type(WIDTH_1440_HEIGHT_1080, BITRATE_5000000), + std::map::value_type(WIDTH_1920_HEIGHT_1080, BITRATE_6000000), +}; + +EncodeDataProcess::~EncodeDataProcess() +{ + if (isEncoderProcess_) { + DHLOGD("~EncodeDataProcess : ReleaseProcessNode."); + ReleaseProcessNode(); + } +} + +int32_t EncodeDataProcess::InitNode() +{ + DHLOGD("Init DCamera EncodeNode start."); + if (!(IsInEncoderRange(sourceConfig_) && IsInEncoderRange(targetConfig_))) { + DHLOGE("Source config or target config are invalid."); + return DCAMERA_BAD_VALUE; + } + if (!IsConvertible(sourceConfig_, targetConfig_)) { + DHLOGE("The EncodeNode cannot convert source VideoCodecType %d to target VideoCodecType %d.", + sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); + return DCAMERA_BAD_TYPE; + } + if (sourceConfig_.GetVideoCodecType() == targetConfig_.GetVideoCodecType()) { + DHLOGD("Disable EncodeNode. The target VideoCodecType %d is the same as the source VideoCodecType %d.", + sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); + return DCAMERA_OK; + } + + int32_t err = InitEncoder(); + if (err != DCAMERA_OK) { + DHLOGE("Init video encoder fail."); + ReleaseProcessNode(); + return err; + } + isEncoderProcess_ = true; + return DCAMERA_OK; +} + +bool EncodeDataProcess::IsInEncoderRange(const VideoConfigParams& curConfig) +{ + return (curConfig.GetWidth() >= MIN_VIDEO_WIDTH || curConfig.GetWidth() <= MAX_VIDEO_WIDTH || + curConfig.GetHeight() >= MIN_VIDEO_HEIGHT || curConfig.GetHeight() <= MAX_VIDEO_HEIGHT || + curConfig.GetFrameRate() <= MAX_FRAME_RATE); +} + +bool EncodeDataProcess::IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig) +{ + return (sourceConfig.GetVideoCodecType() == targetConfig.GetVideoCodecType() || + sourceConfig.GetVideoCodecType() == VideoCodecType::NO_CODEC); +} + +int32_t EncodeDataProcess::InitEncoder() +{ + DHLOGD("Init video encoder."); + int32_t err = InitEncoderMetadataFormat(); + if (err != DCAMERA_OK) { + DHLOGE("Init video encoder metadata format fail."); + return err; + } + err = InitEncoderBitrateFormat(); + if (err != DCAMERA_OK) { + DHLOGE("Init video encoder bitrate format fail."); + return err; + } + + videoEncoder_ = Media::VideoEncoderFactory::CreateByMime(processType_); + if (videoEncoder_ == nullptr) { + DHLOGE("Create video encoder failed."); + return DCAMERA_INIT_ERR; + } + encodeVideoCallback_ = std::make_shared(shared_from_this()); + int32_t retVal = videoEncoder_->SetCallback(encodeVideoCallback_); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Set video encoder callback failed."); + return DCAMERA_INIT_ERR; + } + retVal = videoEncoder_->Configure(metadataFormat_); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Set video encoder metadata format failed."); + return DCAMERA_INIT_ERR; + } + encodeProducerSurface_ = videoEncoder_->CreateInputSurface(); + if (encodeProducerSurface_ == nullptr) { + DHLOGE("Get video encoder producer surface failed."); + return DCAMERA_INIT_ERR; + } + retVal = videoEncoder_->Prepare(); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Video encoder prepare failed."); + return DCAMERA_INIT_ERR; + } + retVal = videoEncoder_->Start(); + if (retVal != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("Video encoder start failed."); + return DCAMERA_INIT_ERR; + } + return DCAMERA_OK; +} + +int32_t EncodeDataProcess::InitEncoderMetadataFormat() +{ + DHLOGD("Init video encoder metadata format."); + switch (targetConfig_.GetVideoCodecType()) { + case VideoCodecType::CODEC_H264: + processType_ = "video/avc"; + metadataFormat_.PutStringValue("codec_mime", processType_); + metadataFormat_.PutIntValue("codec_profile", Media::AVCProfile::AVC_PROFILE_BASELINE); + break; + case VideoCodecType::CODEC_H265: + processType_ = "video/hevc"; + metadataFormat_.PutStringValue("codec_mime", processType_); + metadataFormat_.PutIntValue("codec_profile", Media::HEVCProfile::HEVC_PROFILE_MAIN); + break; + default: + DHLOGE("The current codec type does not support encoding."); + return DCAMERA_NOT_FOUND; + } + switch (sourceConfig_.GetVideoformat()) { + case Videoformat::YUVI420: + metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::YUVI420); + break; + case Videoformat::NV12: + metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12); + break; + case Videoformat::NV21: + metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV21); + break; + default: + DHLOGE("The current pixel format does not support encoding."); + return DCAMERA_NOT_FOUND; + } + + metadataFormat_.PutLongValue("max_input_size", NORM_YUV420_BUFFER_SIZE); + metadataFormat_.PutIntValue("width", (int32_t)sourceConfig_.GetWidth()); + metadataFormat_.PutIntValue("height", (int32_t)sourceConfig_.GetHeight()); + metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE); + return DCAMERA_OK; +} + +int32_t EncodeDataProcess::InitEncoderBitrateFormat() +{ + DHLOGD("Init video encoder bitrate format."); + if (!(IsInEncoderRange(sourceConfig_) && IsInEncoderRange(targetConfig_))) { + DHLOGE("Source config or target config are invalid."); + return DCAMERA_BAD_VALUE; + } + metadataFormat_.PutIntValue("i_frame_interval", IDR_FRAME_INTERVAL_MS); + metadataFormat_.PutIntValue("video_encode_bitrate_mode", Media::VideoEncodeBitrateMode::VBR); + + if (ENCODER_BITRATE_TABLE.empty()) { + DHLOGD("ENCODER_BITRATE_TABLE is null, use the default bitrate of the encoder."); + return DCAMERA_OK; + } + int64_t pixelformat = static_cast(sourceConfig_.GetWidth() * sourceConfig_.GetHeight()); + int32_t matchedBitrate = BITRATE_6000000; + int64_t minPixelformatDiff = WIDTH_1920_HEIGHT_1080 - pixelformat; + for (auto it = ENCODER_BITRATE_TABLE.begin(); it != ENCODER_BITRATE_TABLE.end(); it++) { + int64_t pixelformatDiff = abs(pixelformat - it->first); + if (pixelformatDiff == 0) { + matchedBitrate = it->second; + break; + } + if (minPixelformatDiff >= pixelformatDiff) { + minPixelformatDiff = pixelformatDiff; + matchedBitrate = it->second; + } + } + DHLOGD("Source config: width : %d, height : %d, matched bitrate %d.", sourceConfig_.GetWidth(), + sourceConfig_.GetHeight(), matchedBitrate); + metadataFormat_.PutIntValue("bitrate", matchedBitrate); + return DCAMERA_OK; +} + +void EncodeDataProcess::ReleaseProcessNode() +{ + DHLOGD("Start release [%d] node : EncodeNode.", nodeRank_); + isEncoderProcess_ = false; + if (nextDataProcess_ != nullptr) { + nextDataProcess_->ReleaseProcessNode(); + } + + { + std::lock_guard lck(mtxEncoderState_); + if (videoEncoder_ != nullptr) { + DHLOGD("Start release videoEncoder."); + videoEncoder_->Flush(); + videoEncoder_->Stop(); + videoEncoder_->Release(); + encodeProducerSurface_ = nullptr; + videoEncoder_ = nullptr; + encodeVideoCallback_ = nullptr; + } + } + + waitEncoderOutputCount_ = 0; + lastFeedEncoderInputBufferTimeUs_ = 0; + inputTimeStampUs_ = 0; + processType_ = ""; + DHLOGD("Release [%d] node : EncodeNode end.", nodeRank_); +} + +int32_t EncodeDataProcess::ProcessData(std::vector>& inputBuffers) +{ + DHLOGD("Process data in EncodeDataProcess."); + if (inputBuffers.empty()) { + DHLOGE("The input data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + if (sourceConfig_.GetVideoCodecType() == targetConfig_.GetVideoCodecType()) { + DHLOGD("The target VideoCodecType : %d is the same as the source VideoCodecType : %d.", + sourceConfig_.GetVideoCodecType(), targetConfig_.GetVideoCodecType()); + return EncodeDone(inputBuffers); + } + + if (videoEncoder_ == nullptr) { + DHLOGE("The video encoder does not exist before encoding data."); + return DCAMERA_INIT_ERR; + } + if (inputBuffers[0]->Size() > NORM_YUV420_BUFFER_SIZE) { + DHLOGE("EncodeNode input buffer size %d error.", inputBuffers[0]->Size()); + return DCAMERA_MEMORY_OPT_ERROR; + } + if (!isEncoderProcess_) { + DHLOGE("EncodeNode occurred error or start release."); + return DCAMERA_DISABLE_PROCESS; + } + int32_t err = FeedEncoderInputBuffer(inputBuffers[0]); + if (err != DCAMERA_OK) { + DHLOGE("Feed encoder input Buffer fail."); + return err; + } + { + std::lock_guard lck(mtxHoldCount_); + int32_t firstFrameOutputNum = 2; + if (inputTimeStampUs_ == 0) { + waitEncoderOutputCount_ += firstFrameOutputNum; + } else { + waitEncoderOutputCount_++; + } + DHLOGD("Wait encoder output frames number is %d.", waitEncoderOutputCount_); + } + return DCAMERA_OK; +} + +int32_t EncodeDataProcess::FeedEncoderInputBuffer(std::shared_ptr& inputBuffer) +{ + std::lock_guard lck(mtxEncoderState_); + DHLOGD("Feed encoder input buffer, buffer size %d.", inputBuffer->Size()); + if (encodeProducerSurface_ == nullptr) { + DHLOGE("Get encoder input producer surface failed."); + return DCAMERA_INIT_ERR; + } + sptr surfacebuffer = GetEncoderInputSurfaceBuffer(); + if (surfacebuffer == nullptr) { + DHLOGE("Get encoder input producer surface buffer failed."); + return DCAMERA_BAD_OPERATE; + } + uint8_t *addr = static_cast(surfacebuffer->GetVirAddr()); + if (addr == nullptr) { + DHLOGE("SurfaceBuffer address is nullptr"); + encodeProducerSurface_->CancelBuffer(surfacebuffer); + return DCAMERA_BAD_OPERATE; + } + size_t size = static_cast(surfacebuffer->GetSize()); + errno_t err = memcpy_s(addr, size, inputBuffer->Data(), inputBuffer->Size()); + if (err != EOK) { + DHLOGE("memcpy_s encoder input producer surface buffer failed."); + return DCAMERA_MEMORY_OPT_ERROR; + } + inputTimeStampUs_ = GetEncoderTimeStamp(); + DHLOGD("Encoder input buffer size %d, timeStamp %lld.", inputBuffer->Size(), (long long)inputTimeStampUs_); + surfacebuffer->ExtraSet("timeStamp", inputTimeStampUs_); + BufferFlushConfig flushConfig = { {0, 0, sourceConfig_.GetWidth(), sourceConfig_.GetHeight()}, 0}; + SurfaceError ret = encodeProducerSurface_->FlushBuffer(surfacebuffer, -1, flushConfig); + if (ret != SURFACE_ERROR_OK) { + DHLOGE("Flush encoder input producer surface buffer failed."); + return DCAMERA_BAD_OPERATE; + } + return DCAMERA_OK; +} + +sptr EncodeDataProcess::GetEncoderInputSurfaceBuffer() +{ + BufferRequestConfig requestConfig; + requestConfig.width = static_cast(sourceConfig_.GetWidth()); + requestConfig.height = static_cast(sourceConfig_.GetHeight()); + requestConfig.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA; + requestConfig.timeout = 0; + requestConfig.strideAlignment = ENCODER_STRIDE_ALIGNMENT; + switch (sourceConfig_.GetVideoformat()) { + case Videoformat::YUVI420: + requestConfig.format = PixelFormat::PIXEL_FMT_YCBCR_420_P; + break; + case Videoformat::NV12: + requestConfig.format = PixelFormat::PIXEL_FMT_YCBCR_420_SP; + break; + case Videoformat::NV21: + requestConfig.format = PixelFormat::PIXEL_FMT_YCRCB_420_SP; + break; + default: + DHLOGE("The current pixel format does not support encoding."); + return nullptr; + } + sptr surfacebuffer = nullptr; + int32_t flushFence = -1; + GSError err = encodeProducerSurface_->RequestBuffer(surfacebuffer, flushFence, requestConfig); + if (err != GSERROR_OK || surfacebuffer == nullptr) { + DHLOGE("Request encoder input producer surface buffer failed, error code: %d.", err); + } + return surfacebuffer; +} + +int64_t EncodeDataProcess::GetEncoderTimeStamp() +{ + int64_t TimeDifferenceStampUs = 0; + const int64_t nsPerUs = 1000L; + int64_t nowTimeUs = GetNowTimeStampUs() * nsPerUs; + if (lastFeedEncoderInputBufferTimeUs_ == 0) { + lastFeedEncoderInputBufferTimeUs_ = nowTimeUs; + return TimeDifferenceStampUs; + } + TimeDifferenceStampUs = nowTimeUs - lastFeedEncoderInputBufferTimeUs_; + lastFeedEncoderInputBufferTimeUs_ = nowTimeUs; + return TimeDifferenceStampUs; +} + +int32_t EncodeDataProcess::GetEncoderOutputBuffer(uint32_t index, Media::AVCodecBufferInfo info) +{ + DHLOGD("Get encoder output buffer."); + if (videoEncoder_ == nullptr) { + DHLOGE("The video encoder does not exist before output encoded data."); + return DCAMERA_BAD_VALUE; + } + std::shared_ptr sharedMemoryOutput = videoEncoder_->GetOutputBuffer(index); + if (sharedMemoryOutput == nullptr) { + DHLOGE("Failed to get the output shared memory, index : %d", index); + return DCAMERA_BAD_OPERATE; + } + + if (info.size <= 0) { + DHLOGE("AVCodecBufferInfo error, buffer size : %d", info.size); + return DCAMERA_BAD_VALUE; + } + + size_t outputMemoDataSize = static_cast(info.size); + DHLOGD("Encoder output buffer size : %d", outputMemoDataSize); + std::shared_ptr bufferOutput = std::make_shared(outputMemoDataSize); + errno_t err = memcpy_s(bufferOutput->Data(), bufferOutput->Size(), + sharedMemoryOutput->GetBase(), outputMemoDataSize); + if (err != EOK) { + DHLOGE("memcpy_s buffer failed."); + return DCAMERA_MEMORY_OPT_ERROR; + } + bufferOutput->SetInt64("timeUs", info.presentationTimeUs); + + std::vector> nextInputBuffers; + nextInputBuffers.push_back(bufferOutput); + return EncodeDone(nextInputBuffers); +} + +int32_t EncodeDataProcess::EncodeDone(std::vector> outputBuffers) +{ + DHLOGD("Encoder done."); + if (outputBuffers.empty()) { + DHLOGE("The received data buffers is empty."); + return DCAMERA_BAD_VALUE; + } + + if (nextDataProcess_ != nullptr) { + DHLOGD("Send to the next node of the encoder for processing."); + int32_t err = nextDataProcess_->ProcessData(outputBuffers); + if (err != DCAMERA_OK) { + DHLOGE("Someone node after the encoder processes fail."); + } + return err; + } + DHLOGD("The current node is the last node, and Output the processed video buffer"); + std::shared_ptr targetPipelineSink = callbackPipelineSink_.lock(); + if (targetPipelineSink == nullptr) { + DHLOGE("callbackPipelineSink_ is nullptr."); + return DCAMERA_BAD_VALUE; + } + targetPipelineSink->OnProcessedVideoBuffer(outputBuffers[0]); + return DCAMERA_OK; +} + +void EncodeDataProcess::OnError() +{ + DHLOGD("EncodeDataProcess : OnError."); + isEncoderProcess_ = false; + videoEncoder_->Flush(); + videoEncoder_->Stop(); + std::shared_ptr targetPipelineSink = callbackPipelineSink_.lock(); + if (targetPipelineSink == nullptr) { + DHLOGE("callbackPipelineSink_ is nullptr."); + return; + } + targetPipelineSink->OnError(DataProcessErrorType::ERROR_PIPELINE_ENCODER); +} + +void EncodeDataProcess::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("The available input buffer index : %d. No operation when using surface input.", index); +} + +void EncodeDataProcess::OnOutputFormatChanged(const Media::Format &format) +{ + if (encodeOutputFormat_.GetFormatMap().empty()) { + DHLOGE("The first changed video encoder output format is null."); + return; + } + encodeOutputFormat_ = format; +} + +void EncodeDataProcess::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + if (!isEncoderProcess_) { + DHLOGE("EncodeNode occurred error or start release."); + return; + } + DHLOGD("Video encode buffer info: presentation TimeUs %lld, size %d, offset %d, flag %d", + info.presentationTimeUs, info.size, info.offset, flag); + int32_t err = GetEncoderOutputBuffer(index, info); + if (err != DCAMERA_OK) { + DHLOGE("Get encode output Buffer fail."); + return; + } + { + std::lock_guard lck(mtxHoldCount_); + if (waitEncoderOutputCount_ <= 0) { + DHLOGE("The waitEncoderOutputCount_ = %d.", waitEncoderOutputCount_); + } + waitEncoderOutputCount_--; + DHLOGD("Wait encoder output frames number is %d.", waitEncoderOutputCount_); + } + if (videoEncoder_ == nullptr) { + DHLOGE("The video encoder does not exist before release output buffer index."); + return; + } + int32_t errRelease = videoEncoder_->ReleaseOutputBuffer(index); + if (errRelease != Media::MediaServiceErrCode::MSERR_OK) { + DHLOGE("The video encoder release output buffer fail, index : [%d].", index); + } +} +VideoConfigParams EncodeDataProcess::GetSourceConfig() const +{ + return sourceConfig_; +} + +VideoConfigParams EncodeDataProcess::GetTargetConfig() const +{ + return targetConfig_; +} +} +} \ No newline at end of file diff --git a/services/data_process/src/pipeline_node/multimedia_codec/encode_video_callback.cpp b/services/data_process/src/pipeline_node/multimedia_codec/encode_video_callback.cpp new file mode 100644 index 00000000..27b05a22 --- /dev/null +++ b/services/data_process/src/pipeline_node/multimedia_codec/encode_video_callback.cpp @@ -0,0 +1,66 @@ +/* + * 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 "distributed_hardware_log.h" + +namespace OHOS { +namespace DistributedHardware { +void EncodeVideoCallback::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGD("EncodeVideoCallback : OnError. Error type: %d . Error code: %d ", errorType, errorCode); + std::shared_ptr targetEncoderNode = encodeVideoNode_.lock(); + if (targetEncoderNode == nullptr) { + DHLOGE("encodeVideoNode_ is nullptr."); + return; + } + targetEncoderNode->OnError(); +} + +void EncodeVideoCallback::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("EncodeVideoCallback : OnInputBufferAvailable. No operation when using surface input."); + std::shared_ptr targetEncoderNode = encodeVideoNode_.lock(); + if (targetEncoderNode == nullptr) { + DHLOGE("encodeVideoNode_ is nullptr."); + return; + } + targetEncoderNode->OnInputBufferAvailable(index); +} + +void EncodeVideoCallback::OnOutputFormatChanged(const Media::Format &format) +{ + DHLOGD("EncodeVideoCallback : OnOutputFormatChanged."); + std::shared_ptr targetEncoderNode = encodeVideoNode_.lock(); + if (targetEncoderNode == nullptr) { + DHLOGE("encodeVideoNode_ is nullptr."); + return; + } + targetEncoderNode->OnOutputFormatChanged(format); +} + +void EncodeVideoCallback::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGD("EncodeVideoCallback : OnOutputBufferAvailable."); + std::shared_ptr targetEncoderNode = encodeVideoNode_.lock(); + if (targetEncoderNode == nullptr) { + DHLOGE("encodeVideoNode_ is nullptr."); + return; + } + targetEncoderNode->OnOutputBufferAvailable(index, info, flag); +} +} +} \ No newline at end of file diff --git a/services/data_process/src/utils/image_common_type.cpp b/services/data_process/src/utils/image_common_type.cpp new file mode 100644 index 00000000..4c96dee4 --- /dev/null +++ b/services/data_process/src/utils/image_common_type.cpp @@ -0,0 +1,66 @@ +/* + * 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 "image_common_type.h" + +namespace OHOS { +namespace DistributedHardware { +void VideoConfigParams::SetVideoCodecType(VideoCodecType videoCodec) +{ + videoCodec_ = videoCodec; +} + +void VideoConfigParams::SetVideoformat(Videoformat pixelFormat) +{ + pixelFormat_ = pixelFormat; +} + +void VideoConfigParams::SetFrameRate(uint32_t frameRate) +{ + frameRate_ = frameRate; +} + +void VideoConfigParams::SetWidthAndHeight(uint32_t width, uint32_t height) +{ + width_ = width; + height_ = height; +} + +VideoCodecType VideoConfigParams::GetVideoCodecType() const +{ + return videoCodec_; +} + +Videoformat VideoConfigParams::GetVideoformat() const +{ + return pixelFormat_; +} + +uint32_t VideoConfigParams::GetFrameRate() const +{ + return frameRate_; +} + +uint32_t VideoConfigParams::GetWidth() const +{ + return width_; +} + +uint32_t VideoConfigParams::GetHeight() const +{ + return height_; +} +} +} \ No newline at end of file -- Gitee From 91009acb0fdfe04eb225f937dcb51c273ef1ae05 Mon Sep 17 00:00:00 2001 From: hobbycao Date: Wed, 9 Mar 2022 15:13:43 +0800 Subject: [PATCH 2/4] distributedcamera code codex --- .../hdi_impl/src/dcamera_device/dmetadata_processor.cpp | 2 +- camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp | 2 +- .../hdi_ipc/client/operator/dstream_operator_proxy.cpp | 3 +-- .../interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp | 1 - .../hdi_ipc/server/provider/dcamera_provider_stub.cpp | 1 - common/src/utils/dcamera_utils_tools.cpp | 4 ++-- .../pipeline_node/multimedia_codec/decode_data_process.cpp | 2 +- .../pipeline_node/multimedia_codec/encode_data_process.cpp | 2 +- 8 files changed, 7 insertions(+), 10 deletions(-) diff --git a/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp b/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp index 2b53f17f..c8602c36 100644 --- a/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp +++ b/camera_hdf/hdi_impl/src/dcamera_device/dmetadata_processor.cpp @@ -531,7 +531,7 @@ std::map> DMetadataProcessor::GetDCameraSupported } uint32_t width = static_cast(std::atoi(reso[0].c_str())); uint32_t height = static_cast(std::atoi(reso[1].c_str())); - if (height <= 0 || width <= 0 || + 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))) { diff --git a/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp b/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp index 7b6823ad..362fa246 100644 --- a/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp +++ b/camera_hdf/hdi_impl/src/dstream_operator/dstream_operator.cpp @@ -420,7 +420,7 @@ DCamRetCode DStreamOperator::InitOutputConfigurations(const std::shared_ptr(std::atoi(reso[0].c_str())); uint32_t height = static_cast(std::atoi(reso[1].c_str())); - if (height <= 0 || width <= 0 || + 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))) { diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp index 5915a125..feff8748 100644 --- a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp @@ -103,10 +103,9 @@ CamRetCode DStreamOperatorProxy::CreateStreams(const std::vector streamInfo = streamInfos.at(i); - bRet = IpcDataUtils::EncodeStreamInfo(streamInfo, data); + bool bRet bRet = IpcDataUtils::EncodeStreamInfo(streamInfo, data); if (!bRet) { DHLOGE("Write streamInfo failed. index = %d", i); return CamRetCode::INVALID_ARGUMENT; diff --git a/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp index d561e83d..5c11b712 100644 --- a/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp +++ b/camera_hdf/interfaces/hdi_ipc/server/host/dcamera_host_stub.cpp @@ -230,7 +230,6 @@ void *DCameraHostStubInstance() void DestroyDCameraHostStub(void *stubObj) { delete reinterpret_cast(stubObj); - stubObj = nullptr; } int32_t DCHostServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) diff --git a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp index 9bb5d24b..cb1245a9 100644 --- a/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp +++ b/camera_hdf/interfaces/hdi_ipc/server/provider/dcamera_provider_stub.cpp @@ -266,7 +266,6 @@ void *DCameraProviderStubInstance() void DestroyDCameraProviderStub(void *stubObj) { delete reinterpret_cast(stubObj); - stubObj = nullptr; } int32_t DCProviderServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) diff --git a/common/src/utils/dcamera_utils_tools.cpp b/common/src/utils/dcamera_utils_tools.cpp index 9040ef91..62513dcf 100644 --- a/common/src/utils/dcamera_utils_tools.cpp +++ b/common/src/utils/dcamera_utils_tools.cpp @@ -61,7 +61,6 @@ std::string Base64Encode(const unsigned char *toEncode, unsigned int len) { std::string ret; uint32_t i = 0; - uint32_t j = 0; unsigned char charArray3[3]; unsigned char charArray4[4]; @@ -82,6 +81,7 @@ std::string Base64Encode(const unsigned char *toEncode, unsigned int len) } if (i) { + uint32_t j = 0; for (j = i; j < sizeof(charArray3); j++) { charArray3[j] = '\0'; } @@ -105,7 +105,6 @@ std::string Base64Decode(const std::string& basicString) { std::string ret; uint32_t i = 0; - uint32_t j = 0; int index = 0; int len = static_cast(basicString.size()); unsigned char charArray3[3]; @@ -131,6 +130,7 @@ std::string Base64Decode(const std::string& basicString) } if (i) { + uint32_t j = 0; for (j = i; j < sizeof(charArray4); j++) { charArray4[j] = 0; } diff --git a/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp index 6e69982c..38763e3e 100644 --- a/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp +++ b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp @@ -390,8 +390,8 @@ void DecodeDataProcess::GetDecoderOutputBuffer(const sptr& surface) if (waitDecoderOutputCount_ <= 0) { DHLOGE("The waitDecoderOutputCount_ = %d.", waitDecoderOutputCount_); } - int32_t firstFrameInputNum = 2; if (outputTimeStampUs_ == 0) { + int32_t firstFrameInputNum = 2; waitDecoderOutputCount_ -= firstFrameInputNum; } else { waitDecoderOutputCount_--; diff --git a/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp index df634660..ca2136e6 100644 --- a/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp +++ b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp @@ -274,8 +274,8 @@ int32_t EncodeDataProcess::ProcessData(std::vector>& } { std::lock_guard lck(mtxHoldCount_); - int32_t firstFrameOutputNum = 2; if (inputTimeStampUs_ == 0) { + int32_t firstFrameOutputNum = 2; waitEncoderOutputCount_ += firstFrameOutputNum; } else { waitEncoderOutputCount_++; -- Gitee From f7e1301c0f99c9266752c5d023481f4c86274201 Mon Sep 17 00:00:00 2001 From: hobbycao Date: Wed, 9 Mar 2022 15:28:42 +0800 Subject: [PATCH 3/4] bugfix --- .../hdi_ipc/client/operator/dstream_operator_proxy.cpp | 2 +- .../pipeline_node/multimedia_codec/decode_data_process.h | 1 + .../pipeline_node/multimedia_codec/encode_data_process.h | 1 + .../src/pipeline_node/multimedia_codec/decode_data_process.cpp | 3 +-- .../src/pipeline_node/multimedia_codec/encode_data_process.cpp | 3 +-- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp index feff8748..e5937f82 100644 --- a/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp +++ b/camera_hdf/interfaces/hdi_ipc/client/operator/dstream_operator_proxy.cpp @@ -105,7 +105,7 @@ CamRetCode DStreamOperatorProxy::CreateStreams(const std::vector streamInfo = streamInfos.at(i); - bool bRet bRet = IpcDataUtils::EncodeStreamInfo(streamInfo, data); + bool bRet = IpcDataUtils::EncodeStreamInfo(streamInfo, data); if (!bRet) { DHLOGE("Write streamInfo failed. index = %d", i); return CamRetCode::INVALID_ARGUMENT; diff --git a/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h b/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h index cfd051f8..8843eaad 100644 --- a/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h +++ b/services/data_process/include/pipeline_node/multimedia_codec/decode_data_process.h @@ -98,6 +98,7 @@ private: const static uint32_t MIN_VIDEO_HEIGHT = 240; const static uint32_t MAX_VIDEO_WIDTH = 1920; const static uint32_t MAX_VIDEO_HEIGHT = 1080; + const static int32_t FIRST_FRAME_INPUT_NUM = 2; std::mutex mtxDecoderState_; std::mutex mtxHoldCount_; diff --git a/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h b/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h index 89899e98..ba265fa5 100644 --- a/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h +++ b/services/data_process/include/pipeline_node/multimedia_codec/encode_data_process.h @@ -78,6 +78,7 @@ private: const static uint32_t MAX_VIDEO_WIDTH = 1920; const static uint32_t MAX_VIDEO_HEIGHT = 1080; const static int32_t IDR_FRAME_INTERVAL_MS = 300; + const static int32_t FIRST_FRAME_OUTPUT_NUM = 2; const static int64_t WIDTH_320_HEIGHT_240 = 320 * 240; const static int64_t WIDTH_480_HEIGHT_360 = 480 * 360; diff --git a/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp index 38763e3e..488dec5b 100644 --- a/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp +++ b/services/data_process/src/pipeline_node/multimedia_codec/decode_data_process.cpp @@ -391,8 +391,7 @@ void DecodeDataProcess::GetDecoderOutputBuffer(const sptr& surface) DHLOGE("The waitDecoderOutputCount_ = %d.", waitDecoderOutputCount_); } if (outputTimeStampUs_ == 0) { - int32_t firstFrameInputNum = 2; - waitDecoderOutputCount_ -= firstFrameInputNum; + waitDecoderOutputCount_ -= FIRST_FRAME_INPUT_NUM; } else { waitDecoderOutputCount_--; } diff --git a/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp index ca2136e6..f5d9c92a 100644 --- a/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp +++ b/services/data_process/src/pipeline_node/multimedia_codec/encode_data_process.cpp @@ -275,8 +275,7 @@ int32_t EncodeDataProcess::ProcessData(std::vector>& { std::lock_guard lck(mtxHoldCount_); if (inputTimeStampUs_ == 0) { - int32_t firstFrameOutputNum = 2; - waitEncoderOutputCount_ += firstFrameOutputNum; + waitEncoderOutputCount_ += FIRST_FRAME_OUTPUT_NUM; } else { waitEncoderOutputCount_++; } -- Gitee From b034ab2dcc4e28bc883bc085cbb8d5dc9c60bb6f Mon Sep 17 00:00:00 2001 From: hobbycao Date: Wed, 9 Mar 2022 15:32:25 +0800 Subject: [PATCH 4/4] picture update --- figures/distributedcamera_arch.png | Bin 99835 -> 101997 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/figures/distributedcamera_arch.png b/figures/distributedcamera_arch.png index c2097be48adb30e27303a408e0a713257f56ad18..ed769ce56875747c86851dd4157fd82745eb8f26 100644 GIT binary patch delta 18355 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 delta 16176 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 -- Gitee