From 224446bcad3e3d42c8c3de5bec690216b1fb944f Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 23 Aug 2023 21:50:30 +0000 Subject: [PATCH] Add EVS Video Emulated Camera Class Test: Build Bug: 277861838 Change-Id: Ic9ce648b857eddefccc24065397af5b2056426c7 --- .../aidl/impl/default/include/EvsAllCameras.h | 20 ++ .../default/include/EvsVideoEmulatedCamera.h | 108 ++++++++++ .../aidl/impl/default/src/EvsEnumerator.cpp | 6 +- .../default/src/EvsVideoEmulatedCamera.cpp | 198 ++++++++++++++++++ 4 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 automotive/evs/aidl/impl/default/include/EvsAllCameras.h create mode 100644 automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h create mode 100644 automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp diff --git a/automotive/evs/aidl/impl/default/include/EvsAllCameras.h b/automotive/evs/aidl/impl/default/include/EvsAllCameras.h new file mode 100644 index 0000000000..a76501d758 --- /dev/null +++ b/automotive/evs/aidl/impl/default/include/EvsAllCameras.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "EvsMockCamera.h" +#include "EvsVideoEmulatedCamera.h" diff --git a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h new file mode 100644 index 0000000000..356a42ae36 --- /dev/null +++ b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ConfigManager.h" +#include "EvsCamera.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace aidl::android::hardware::automotive::evs::implementation { + +class EvsVideoEmulatedCamera : public EvsCamera { + public: + EvsVideoEmulatedCamera(Sigil sigil, const char* deviceName, + std::unique_ptr& camInfo); + + ~EvsVideoEmulatedCamera() override; + + // Methods from ::android::hardware::automotive::evs::IEvsCamera follow. + ndk::ScopedAStatus forcePrimaryClient( + const std::shared_ptr& display) override; + ndk::ScopedAStatus getCameraInfo(evs::CameraDesc* _aidl_return) override; + ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier, + std::vector* value) override; + ndk::ScopedAStatus getIntParameter(evs::CameraParam id, std::vector* value) override; + ndk::ScopedAStatus getIntParameterRange(evs::CameraParam id, + evs::ParameterRange* _aidl_return) override; + ndk::ScopedAStatus getParameterList(std::vector* _aidl_return) override; + ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId, + evs::CameraDesc* _aidl_return) override; + ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier, + const std::vector& opaqueValue) override; + ndk::ScopedAStatus setIntParameter(evs::CameraParam id, int32_t value, + std::vector* effectiveValue) override; + ndk::ScopedAStatus setPrimaryClient() override; + ndk::ScopedAStatus unsetPrimaryClient() override; + + const evs::CameraDesc& getDesc() { return mDescription; } + + static std::shared_ptr Create(const char* deviceName); + static std::shared_ptr Create( + const char* deviceName, std::unique_ptr& camInfo, + const evs::Stream* streamCfg = nullptr); + + private: + // For the camera parameters. + struct CameraParameterDesc { + CameraParameterDesc(int min = 0, int max = 0, int step = 0, int value = 0) { + this->range.min = min; + this->range.max = max; + this->range.step = step; + this->value = value; + } + + ParameterRange range; + int32_t value; + }; + + void initializeParameters(); + + ::android::status_t allocateOneFrame(buffer_handle_t* handle) override; + + bool startVideoStreamImpl_locked(const std::shared_ptr& receiver, + ndk::ScopedAStatus& status, + std::unique_lock& lck) override; + + bool stopVideoStreamImpl_locked(ndk::ScopedAStatus& status, + std::unique_lock& lck) override; + + // The properties of this camera. + CameraDesc mDescription = {}; + + // Camera parameters. + std::unordered_map> mParams; + + // Static camera module information + std::unique_ptr& mCameraInfo; + + // For the extended info + std::unordered_map> mExtInfo; +}; + +} // namespace aidl::android::hardware::automotive::evs::implementation diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp index ec4b18f906..80e72a73b5 100644 --- a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp +++ b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp @@ -17,9 +17,9 @@ #include "EvsEnumerator.h" #include "ConfigManager.h" +#include "EvsAllCameras.h" #include "EvsCameraBase.h" #include "EvsGlDisplay.h" -#include "EvsMockCamera.h" #include #include @@ -264,6 +264,10 @@ ScopedAStatus EvsEnumerator::openCamera(const std::string& id, const Stream& cfg pActiveCamera = EvsMockCamera::Create(id.data(), cameraInfo, &cfg); break; + case DeviceType::VIDEO: + pActiveCamera = EvsVideoEmulatedCamera::Create(id.data(), cameraInfo, &cfg); + break; + default: LOG(ERROR) << __func__ << ": camera device type " << static_cast(cameraInfo->deviceType) diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp new file mode 100644 index 0000000000..f198a64e5b --- /dev/null +++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "EvsVideoEmulatedCamera.h" + +#include + +#include + +#include +#include + +namespace aidl::android::hardware::automotive::evs::implementation { + +EvsVideoEmulatedCamera::EvsVideoEmulatedCamera(Sigil, const char* deviceName, + std::unique_ptr& camInfo) + : mCameraInfo(camInfo) { + mDescription.id = deviceName; + + /* set camera metadata */ + if (camInfo) { + uint8_t* ptr = reinterpret_cast(camInfo->characteristics); + const size_t len = get_camera_metadata_size(camInfo->characteristics); + mDescription.metadata.insert(mDescription.metadata.end(), ptr, ptr + len); + } + + initializeParameters(); +} + +void EvsVideoEmulatedCamera::initializeParameters() { + mParams.emplace( + CameraParam::BRIGHTNESS, + new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255)); + mParams.emplace( + CameraParam::CONTRAST, + new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255)); + mParams.emplace( + CameraParam::SHARPNESS, + new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255)); +} + +::android::status_t EvsVideoEmulatedCamera::allocateOneFrame(buffer_handle_t* /* handle */) { + LOG(FATAL) << __func__ << ": Not implemented yet."; + return ::android::UNKNOWN_ERROR; +} + +bool EvsVideoEmulatedCamera::startVideoStreamImpl_locked( + const std::shared_ptr& /* receiver */, + ndk::ScopedAStatus& /* status */, std::unique_lock& /* lck */) { + LOG(FATAL) << __func__ << ": Not implemented yet."; + return false; +} + +bool EvsVideoEmulatedCamera::stopVideoStreamImpl_locked(ndk::ScopedAStatus& /* status */, + std::unique_lock& /* lck */) { + LOG(FATAL) << __func__ << ": Not implemented yet."; + return false; +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::forcePrimaryClient( + const std::shared_ptr& /* display */) { + /* Because EVS HW module reference implementation expects a single client at + * a time, this returns a success code always. + */ + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getCameraInfo(evs::CameraDesc* _aidl_return) { + *_aidl_return = mDescription; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getExtendedInfo(int32_t opaqueIdentifier, + std::vector* value) { + const auto it = mExtInfo.find(opaqueIdentifier); + if (it == mExtInfo.end()) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(EvsResult::INVALID_ARG)); + } else { + *value = mExtInfo[opaqueIdentifier]; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getIntParameter(evs::CameraParam id, + std::vector* value) { + const auto it = mParams.find(id); + if (it == mParams.end()) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(EvsResult::NOT_SUPPORTED)); + } + value->push_back(it->second->value); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getIntParameterRange(evs::CameraParam id, + evs::ParameterRange* _aidl_return) { + const auto it = mParams.find(id); + if (it == mParams.end()) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(EvsResult::NOT_SUPPORTED)); + } + _aidl_return->min = it->second->range.min; + _aidl_return->max = it->second->range.max; + _aidl_return->step = it->second->range.step; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getParameterList( + std::vector* _aidl_return) { + if (mCameraInfo) { + _aidl_return->resize(mCameraInfo->controls.size()); + std::size_t idx = 0; + for (const auto& [name, range] : mCameraInfo->controls) { + (*_aidl_return)[idx++] = name; + } + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::getPhysicalCameraInfo(const std::string& /* deviceId */, + evs::CameraDesc* _aidl_return) { + return getCameraInfo(_aidl_return); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::setExtendedInfo( + int32_t opaqueIdentifier, const std::vector& opaqueValue) { + mExtInfo.insert_or_assign(opaqueIdentifier, opaqueValue); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::setIntParameter(evs::CameraParam id, int32_t value, + std::vector* effectiveValue) { + const auto it = mParams.find(id); + if (it == mParams.end()) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(EvsResult::NOT_SUPPORTED)); + } + // Rounding down to the closest value. + int32_t candidate = value / it->second->range.step * it->second->range.step; + if (candidate < it->second->range.min || candidate > it->second->range.max) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(EvsResult::INVALID_ARG)); + } + it->second->value = candidate; + effectiveValue->push_back(candidate); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::setPrimaryClient() { + /* Because EVS HW module reference implementation expects a single client at + * a time, this returns a success code always. + */ + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus EvsVideoEmulatedCamera::unsetPrimaryClient() { + /* Because EVS HW module reference implementation expects a single client at + * a time, there is no chance that this is called by the secondary client and + * therefore returns a success code always. + */ + return ndk::ScopedAStatus::ok(); +} + +std::shared_ptr EvsVideoEmulatedCamera::Create(const char* deviceName) { + std::unique_ptr nullCamInfo = nullptr; + return Create(deviceName, nullCamInfo); +} + +std::shared_ptr EvsVideoEmulatedCamera::Create( + const char* deviceName, std::unique_ptr& camInfo, + const evs::Stream* /* streamCfg */) { + std::shared_ptr c = + ndk::SharedRefBase::make(Sigil{}, deviceName, camInfo); + if (!c) { + LOG(ERROR) << "Failed to instantiate EvsVideoEmulatedCamera."; + return nullptr; + } + c->mDescription.vendorFlags = 0xFFFFFFFF; // Arbitrary test value + return c; +} + +EvsVideoEmulatedCamera::~EvsVideoEmulatedCamera() {} + +} // namespace aidl::android::hardware::automotive::evs::implementation