blob: 96d4e0a2750694ee3614cb227e284ec7f1e17254 [file] [log] [blame]
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "camera-app.h"
#include "tls-certificate-management-instance.h"
#include "tls-client-management-instance.h"
#include <app/clusters/push-av-stream-transport-server/CodegenIntegration.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::Chime;
using namespace chip::app::Clusters::PushAvStreamTransport;
using namespace chip::app::Clusters::WebRTCTransportProvider;
using namespace chip::app::Clusters::CameraAvStreamManagement;
using namespace chip::app::Clusters::CameraAvSettingsUserLevelManagement;
using namespace chip::app::Clusters::ZoneManagement;
template <typename T>
using List = chip::app::DataModel::List<T>;
using Status = Protocols::InteractionModel::Status;
CameraApp::CameraApp(chip::EndpointId aClustersEndpoint, CameraDeviceInterface * aCameraDevice)
{
mEndpoint = aClustersEndpoint;
mCameraDevice = aCameraDevice;
// Instantiate Chime Server
mChimeServerPtr = std::make_unique<ChimeServer>(mEndpoint, mCameraDevice->GetChimeDelegate());
// Instantiate WebRTCTransport Provider
mWebRTCTransportProviderPtr =
std::make_unique<WebRTCTransportProviderServer>(mCameraDevice->GetWebRTCProviderDelegate(), mEndpoint);
Clusters::PushAvStreamTransport::SetDelegate(mEndpoint, &(mCameraDevice->GetPushAVTransportDelegate()));
Clusters::PushAvStreamTransport::SetTLSClientManagementDelegate(mEndpoint,
&Clusters::TlsClientManagementCommandDelegate::GetInstance());
Clusters::PushAvStreamTransport::SetTlsCertificateManagementDelegate(
mEndpoint, &Clusters::TlsCertificateManagementCommandDelegate::getInstance());
// Fetch all initialization parameters for CameraAVStreamMgmt Server
BitFlags<CameraAvStreamManagement::Feature> avsmFeatures;
BitFlags<CameraAvStreamManagement::OptionalAttribute> avsmOptionalAttrs;
avsmFeatures.Set(CameraAvStreamManagement::Feature::kSnapshot);
avsmFeatures.Set(CameraAvStreamManagement::Feature::kVideo);
// Enable the Watermark and OSD features if camera supports
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsWatermark())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kWatermark);
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsOSD())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kOnScreenDisplay);
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsSoftPrivacy())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kPrivacy);
}
// Check microphone support to set Audio feature
if (mCameraDevice->GetCameraHALInterface().HasMicrophone())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kAudio);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kMicrophoneAGCEnabled);
}
if (mCameraDevice->GetCameraHALInterface().HasLocalStorage())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kLocalStorage);
}
// Check if camera has speaker
if (mCameraDevice->GetCameraHALInterface().HasSpeaker())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kSpeaker);
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsHDR())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kHighDynamicRange);
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsNightVision())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kNightVision);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kNightVisionIllum);
}
if (mCameraDevice->GetCameraHALInterface().HasHardPrivacySwitch())
{
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kHardPrivacyModeOn);
}
if (mCameraDevice->GetCameraHALInterface().HasStatusLight())
{
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kStatusLightEnabled);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kStatusLightBrightness);
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsImageControl())
{
avsmFeatures.Set(CameraAvStreamManagement::Feature::kImageControl);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kImageFlipVertical);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kImageFlipHorizontal);
avsmOptionalAttrs.Set(CameraAvStreamManagement::OptionalAttribute::kImageRotation);
}
uint32_t maxConcurrentVideoEncoders = mCameraDevice->GetCameraHALInterface().GetMaxConcurrentEncoders();
uint32_t maxEncodedPixelRate = mCameraDevice->GetCameraHALInterface().GetMaxEncodedPixelRate();
VideoSensorParamsStruct sensorParams = mCameraDevice->GetCameraHALInterface().GetVideoSensorParams();
bool nightVisionUsesInfrared = mCameraDevice->GetCameraHALInterface().GetNightVisionUsesInfrared();
VideoResolutionStruct minViewport = mCameraDevice->GetCameraHALInterface().GetMinViewport();
std::vector<RateDistortionTradeOffStruct> rateDistortionTradeOffPoints =
mCameraDevice->GetCameraHALInterface().GetRateDistortionTradeOffPoints();
uint32_t maxContentBufferSize = mCameraDevice->GetCameraHALInterface().GetMaxContentBufferSize();
AudioCapabilitiesStruct micCapabilities = mCameraDevice->GetCameraHALInterface().GetMicrophoneCapabilities();
AudioCapabilitiesStruct spkrCapabilities = mCameraDevice->GetCameraHALInterface().GetSpeakerCapabilities();
TwoWayTalkSupportTypeEnum twowayTalkSupport = TwoWayTalkSupportTypeEnum::kNotSupported;
std::vector<SnapshotCapabilitiesStruct> snapshotCapabilities = mCameraDevice->GetCameraHALInterface().GetSnapshotCapabilities();
uint32_t maxNetworkBandwidth = mCameraDevice->GetCameraHALInterface().GetMaxNetworkBandwidth();
std::vector<StreamUsageEnum> supportedStreamUsages = mCameraDevice->GetCameraHALInterface().GetSupportedStreamUsages();
std::vector<StreamUsageEnum> streamUsagePriorities = mCameraDevice->GetCameraHALInterface().GetStreamUsagePriorities();
// Instantiate the CameraAVStreamMgmt Server
mAVStreamMgmtServerPtr = std::make_unique<CameraAVStreamMgmtServer>(
mCameraDevice->GetCameraAVStreamMgmtDelegate(), mEndpoint, avsmFeatures, avsmOptionalAttrs, maxConcurrentVideoEncoders,
maxEncodedPixelRate, sensorParams, nightVisionUsesInfrared, minViewport, rateDistortionTradeOffPoints, maxContentBufferSize,
micCapabilities, spkrCapabilities, twowayTalkSupport, snapshotCapabilities, maxNetworkBandwidth, supportedStreamUsages,
streamUsagePriorities);
// Fetch all initialization parameters for CameraAVSettingsUserLevelMgmt Server
BitFlags<CameraAvSettingsUserLevelManagement::Feature, uint32_t> avsumFeatures(
CameraAvSettingsUserLevelManagement::Feature::kDigitalPTZ, CameraAvSettingsUserLevelManagement::Feature::kMechanicalPan,
CameraAvSettingsUserLevelManagement::Feature::kMechanicalTilt,
CameraAvSettingsUserLevelManagement::Feature::kMechanicalZoom,
CameraAvSettingsUserLevelManagement::Feature::kMechanicalPresets);
BitFlags<CameraAvSettingsUserLevelManagement::OptionalAttributes, uint32_t> avsumAttrs(
CameraAvSettingsUserLevelManagement::OptionalAttributes::kMptzPosition,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kMaxPresets,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kMptzPresets,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kDptzStreams,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kZoomMax,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kTiltMin,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kTiltMax,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kPanMin,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kPanMax,
CameraAvSettingsUserLevelManagement::OptionalAttributes::kMovementState);
const uint8_t appMaxPresets = 5;
// Instantiate the CameraAVSettingsUserLevelMgmt Server
mAVSettingsUserLevelMgmtServerPtr = std::make_unique<CameraAvSettingsUserLevelMgmtServer>(
mEndpoint, mCameraDevice->GetCameraAVSettingsUserLevelMgmtDelegate(), avsumFeatures, avsumAttrs, appMaxPresets);
mAVSettingsUserLevelMgmtServerPtr->SetPanMin(mCameraDevice->GetCameraHALInterface().GetPanMin());
mAVSettingsUserLevelMgmtServerPtr->SetPanMax(mCameraDevice->GetCameraHALInterface().GetPanMax());
mAVSettingsUserLevelMgmtServerPtr->SetTiltMin(mCameraDevice->GetCameraHALInterface().GetTiltMin());
mAVSettingsUserLevelMgmtServerPtr->SetTiltMax(mCameraDevice->GetCameraHALInterface().GetTiltMax());
mAVSettingsUserLevelMgmtServerPtr->SetZoomMax(mCameraDevice->GetCameraHALInterface().GetZoomMax());
// Fetch all initialization parameters for the ZoneManagement Server
BitFlags<ZoneManagement::Feature, uint32_t> zoneMgmtFeatures(
ZoneManagement::Feature::kTwoDimensionalCartesianZone, ZoneManagement::Feature::kPerZoneSensitivity,
ZoneManagement::Feature::kUserDefined, ZoneManagement::Feature::kFocusZones);
uint8_t appMaxZones = mCameraDevice->GetCameraHALInterface().GetMaxZones();
uint8_t appMaxUserDefinedZones = mCameraDevice->GetCameraHALInterface().GetMaxUserDefinedZones();
uint8_t sensitivityMax = mCameraDevice->GetCameraHALInterface().GetSensitivityMax();
TwoDCartesianVertexStruct appTwoDCartesianMax = {};
appTwoDCartesianMax.x = sensorParams.sensorWidth - 1;
appTwoDCartesianMax.y = sensorParams.sensorHeight - 1;
// Instantiate the ZoneManagement Server
mZoneMgmtServerPtr = std::make_unique<ZoneMgmtServer>(mCameraDevice->GetZoneManagementDelegate(), mEndpoint, zoneMgmtFeatures,
appMaxUserDefinedZones, appMaxZones, sensitivityMax, appTwoDCartesianMax);
mZoneMgmtServerPtr->SetSensitivity(mCameraDevice->GetCameraHALInterface().GetDetectionSensitivity());
}
void CameraApp::InitializeCameraAVStreamMgmt()
{
// Set the attribute defaults
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsHDR())
{
mAVStreamMgmtServerPtr->SetHDRModeEnabled(mCameraDevice->GetCameraHALInterface().GetHDRMode());
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsSoftPrivacy())
{
mAVStreamMgmtServerPtr->SetSoftRecordingPrivacyModeEnabled(
mCameraDevice->GetCameraHALInterface().GetSoftRecordingPrivacyModeEnabled());
mAVStreamMgmtServerPtr->SetSoftLivestreamPrivacyModeEnabled(
mCameraDevice->GetCameraHALInterface().GetSoftLivestreamPrivacyModeEnabled());
}
if (mCameraDevice->GetCameraHALInterface().HasHardPrivacySwitch())
{
mAVStreamMgmtServerPtr->SetHardPrivacyModeOn(mCameraDevice->GetCameraHALInterface().GetHardPrivacyMode());
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsNightVision())
{
mAVStreamMgmtServerPtr->SetNightVision(mCameraDevice->GetCameraHALInterface().GetNightVision());
}
mAVStreamMgmtServerPtr->SetViewport(mCameraDevice->GetCameraHALInterface().GetViewport());
if (mCameraDevice->GetCameraHALInterface().HasSpeaker())
{
mAVStreamMgmtServerPtr->SetSpeakerMuted(mCameraDevice->GetCameraHALInterface().GetSpeakerMuted());
mAVStreamMgmtServerPtr->SetSpeakerVolumeLevel(mCameraDevice->GetCameraHALInterface().GetSpeakerVolume());
mAVStreamMgmtServerPtr->SetSpeakerMaxLevel(mCameraDevice->GetCameraHALInterface().GetSpeakerMaxLevel());
mAVStreamMgmtServerPtr->SetSpeakerMinLevel(mCameraDevice->GetCameraHALInterface().GetSpeakerMinLevel());
}
if (mCameraDevice->GetCameraHALInterface().HasMicrophone())
{
mAVStreamMgmtServerPtr->SetMicrophoneMuted(mCameraDevice->GetCameraHALInterface().GetMicrophoneMuted());
mAVStreamMgmtServerPtr->SetMicrophoneVolumeLevel(mCameraDevice->GetCameraHALInterface().GetMicrophoneVolume());
mAVStreamMgmtServerPtr->SetMicrophoneMaxLevel(mCameraDevice->GetCameraHALInterface().GetMicrophoneMaxLevel());
mAVStreamMgmtServerPtr->SetMicrophoneMinLevel(mCameraDevice->GetCameraHALInterface().GetMicrophoneMinLevel());
}
// Video and Snapshot features are already enabled.
if (mCameraDevice->GetCameraHALInterface().HasLocalStorage())
{
mAVStreamMgmtServerPtr->SetLocalVideoRecordingEnabled(
mCameraDevice->GetCameraHALInterface().GetLocalVideoRecordingEnabled());
mAVStreamMgmtServerPtr->SetLocalSnapshotRecordingEnabled(
mCameraDevice->GetCameraHALInterface().GetLocalSnapshotRecordingEnabled());
}
if (mCameraDevice->GetCameraHALInterface().HasStatusLight())
{
mAVStreamMgmtServerPtr->SetStatusLightEnabled(mCameraDevice->GetCameraHALInterface().GetStatusLightEnabled());
}
if (mCameraDevice->GetCameraHALInterface().GetCameraSupportsImageControl())
{
mAVStreamMgmtServerPtr->SetImageRotation(mCameraDevice->GetCameraHALInterface().GetImageRotation());
mAVStreamMgmtServerPtr->SetImageFlipVertical(mCameraDevice->GetCameraHALInterface().GetImageFlipVertical());
mAVStreamMgmtServerPtr->SetImageFlipHorizontal(mCameraDevice->GetCameraHALInterface().GetImageFlipHorizontal());
}
mAVStreamMgmtServerPtr->Init();
}
void CameraApp::InitCameraDeviceClusters()
{
// Initialize Cluster Servers
mWebRTCTransportProviderPtr->Init();
mCameraDevice->GetWebRTCProviderController().SetWebRTCTransportProvider(std::move(mWebRTCTransportProviderPtr));
mChimeServerPtr->Init();
mAVSettingsUserLevelMgmtServerPtr->Init();
InitializeCameraAVStreamMgmt();
mZoneMgmtServerPtr->Init();
}
void CameraApp::ShutdownCameraDeviceClusters()
{
ChipLogDetail(Camera, "CameraAppShutdown: Shutting down Camera device clusters");
mAVSettingsUserLevelMgmtServerPtr->Shutdown();
mWebRTCTransportProviderPtr->Shutdown();
}
static constexpr EndpointId kCameraEndpointId = 1;
Platform::UniquePtr<CameraApp> gCameraApp;
void CameraAppInit(CameraDeviceInterface * cameraDevice)
{
gCameraApp = Platform::MakeUnique<CameraApp>(kCameraEndpointId, cameraDevice);
gCameraApp.get()->InitCameraDeviceClusters();
ChipLogDetail(Camera, "CameraAppInit: Initialized Camera clusters");
}
void CameraAppShutdown()
{
ChipLogDetail(Camera, "CameraAppShutdown: Shutting down Camera app");
gCameraApp.get()->ShutdownCameraDeviceClusters();
gCameraApp = nullptr;
}