mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
230 lines
11 KiB
C++
230 lines
11 KiB
C++
/*
|
|
*
|
|
* 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 "esp_matter_data_model_provider.h"
|
|
|
|
using namespace chip;
|
|
using namespace chip::app;
|
|
using namespace chip::app::Clusters;
|
|
using namespace chip::app::Clusters::Chime;
|
|
using namespace chip::app::Clusters::WebRTCTransportProvider;
|
|
using namespace chip::app::Clusters::CameraAvStreamManagement;
|
|
|
|
static constexpr uint32_t kBitsPerMegabit = 1000000;
|
|
|
|
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;
|
|
|
|
// 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 =
|
|
mCameraDevice->GetCameraHALInterface().HasMicrophone() && mCameraDevice->GetCameraHALInterface().HasSpeaker()
|
|
? TwoWayTalkSupportTypeEnum::kFullDuplex
|
|
: TwoWayTalkSupportTypeEnum::kNotSupported;
|
|
std::vector<SnapshotCapabilitiesStruct> snapshotCapabilities = mCameraDevice->GetCameraHALInterface().GetSnapshotCapabilities();
|
|
uint32_t maxNetworkBandwidth = mCameraDevice->GetCameraHALInterface().GetMaxNetworkBandwidth() * kBitsPerMegabit;
|
|
std::vector<StreamUsageEnum> supportedStreamUsages = mCameraDevice->GetCameraHALInterface().GetSupportedStreamUsages();
|
|
std::vector<StreamUsageEnum> streamUsagePriorities = mCameraDevice->GetCameraHALInterface().GetStreamUsagePriorities();
|
|
|
|
// Instantiate the CameraAVStreamMgmt Server
|
|
mAVStreamMgmtServerPtr = std::make_unique<CameraAVStreamManagementCluster>(
|
|
mCameraDevice->GetCameraAVStreamMgmtDelegate(), mEndpoint, avsmFeatures, avsmOptionalAttrs, maxConcurrentVideoEncoders,
|
|
maxEncodedPixelRate, sensorParams, nightVisionUsesInfrared, minViewport, rateDistortionTradeOffPoints, maxContentBufferSize,
|
|
micCapabilities, spkrCapabilities, twowayTalkSupport, snapshotCapabilities, maxNetworkBandwidth, supportedStreamUsages,
|
|
streamUsagePriorities);
|
|
}
|
|
|
|
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
|
|
mWebRTCTransportProviderServer.Create(mEndpoint, mCameraDevice->GetWebRTCProviderDelegate());
|
|
CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Register(mWebRTCTransportProviderServer.Registration());
|
|
if (err != CHIP_NO_ERROR) {
|
|
ChipLogError(Camera,
|
|
"Failed to register WebRTCTransportProvider on endpoint %u: "
|
|
"%" CHIP_ERROR_FORMAT,
|
|
mEndpoint, err.Format());
|
|
}
|
|
InitializeCameraAVStreamMgmt();
|
|
}
|
|
|
|
void CameraApp::ShutdownCameraDeviceClusters()
|
|
{
|
|
ChipLogDetail(Camera, "CameraAppShutdown: Shutting down Camera device clusters");
|
|
|
|
CHIP_ERROR err = esp_matter::data_model::provider::get_instance().registry().Unregister(&mWebRTCTransportProviderServer.Cluster());
|
|
if (err != CHIP_NO_ERROR) {
|
|
ChipLogError(Camera, "WebRTCTransportProvider unregister error: %" CHIP_ERROR_FORMAT, err.Format());
|
|
}
|
|
mWebRTCTransportProviderServer.Destroy();
|
|
}
|
|
|
|
static constexpr EndpointId kCameraEndpointId = 1;
|
|
|
|
std::unique_ptr<CameraApp> gCameraApp;
|
|
|
|
void CameraAppInit(CameraDeviceInterface * cameraDevice)
|
|
{
|
|
|
|
gCameraApp = std::make_unique<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;
|
|
}
|