#include "AstraMiniDevice.hpp"
#include "DevicePids.hpp"
#include "InternalTypes.hpp"
#include "utils/Utils.hpp"
#include "environment/EnvConfig.hpp"
#include "usb/uvc/UvcDevicePort.hpp"
#include "stream/StreamProfileFactory.hpp"
#include "FilterFactory.hpp"
#include "OpenNIPropertyAccessors.hpp"
#include "OpenNIAlgParamManager.hpp"
#include "publicfilters/FormatConverterProcess.hpp"
#include "sensor/video/VideoSensor.hpp"
#include "sensor/video/DisparityBasedSensor.hpp"
#include "timestamp/GlobalTimestampFitter.hpp"
#include "property/VendorPropertyAccessor.hpp"
#include "property/UvcPropertyAccessor.hpp"
#include "property/PropertyServer.hpp"
#include "property/CommonPropertyAccessors.hpp"
#include "property/FilterPropertyAccessors.hpp"
#include "property/PrivateFilterPropertyAccessors.hpp"
#include "monitor/DeviceMonitor.hpp"
#include "OpenNIDisparitySensor.hpp"
#include "AstraMiniSensorStreamStrategy.hpp"
#include "DevicePids.hpp"
#include <algorithm>
namespace libobsensor {
constexpr uint8_t INTERFACE_DEPTH = 0;
constexpr uint8_t INTERFACE_COLOR = 4;
AstraMiniDevice::AstraMiniDevice(const std::shared_ptr<const IDeviceEnumInfo> &info) : OpenNIDeviceBase(info) {
LOG_INFO("Create {} device.", info->getName());
init();
}
AstraMiniDevice::~AstraMiniDevice() noexcept {
LOG_INFO("Destroy {} device.", deviceInfo_->name_);
}
void AstraMiniDevice::init() {
OpenNIDeviceBase::init();
}
void AstraMiniDevice::initSensorList() {
OpenNIDeviceBase::initSensorList();
const auto &sourcePortInfoList = enumInfo_->getSourcePortInfoList();
auto depthPortInfoIter = std::find_if(sourcePortInfoList.begin(), sourcePortInfoList.end(), [](const std::shared_ptr<const SourcePortInfo> &portInfo) {
return portInfo->portType == SOURCE_PORT_USB_UVC && std::dynamic_pointer_cast<const USBSourcePortInfo>(portInfo)->infIndex == INTERFACE_DEPTH;
});
if(depthPortInfoIter != sourcePortInfoList.end()) {
auto depthPortInfo = *depthPortInfoIter;
registerComponent(
OB_DEV_COMPONENT_DEPTH_SENSOR,
[this, depthPortInfo]() {
auto port = getSourcePort(depthPortInfo);
auto sensor = std::make_shared<OpenNIDisparitySensor>(this, OB_SENSOR_DEPTH, port);
auto frameTimestampCalculator = videoFrameTimestampCalculatorCreator_();
sensor->setFrameTimestampCalculator(frameTimestampCalculator);
auto frameProcessor = getComponentT<FrameProcessor>(OB_DEV_COMPONENT_DEPTH_FRAME_PROCESSOR, false);
if(frameProcessor) {
sensor->setFrameProcessor(frameProcessor.get());
}
sensor->enableTimestampAnomalyDetection(false);
auto propServer = getPropertyServer();
propServer->setPropertyValueT<bool>(OB_PROP_SDK_DISPARITY_TO_DEPTH_BOOL, true);
propServer->setPropertyValueT(OB_PROP_DEPTH_PRECISION_LEVEL_INT, OB_PRECISION_1MM);
sensor->setDepthUnit(1.0f);
sensor->markOutputDisparityFrame(true);
initSensorStreamProfile(sensor);
return sensor;
},
true);
registerSensorPortInfo(OB_SENSOR_DEPTH, depthPortInfo);
registerComponent(OB_DEV_COMPONENT_DEPTH_FRAME_PROCESSOR, [this]() {
auto factory = getComponentT<FrameProcessorFactory>(OB_DEV_COMPONENT_FRAME_PROCESSOR_FACTORY);
auto frameProcessor = factory->createFrameProcessor(OB_SENSOR_DEPTH);
return frameProcessor;
});
registerComponent(OB_DEV_COMPONENT_MAIN_PROPERTY_ACCESSOR, [this, depthPortInfo]() {
auto port = getSourcePort(depthPortInfo);
auto accessor = std::make_shared<VendorPropertyAccessor>(this, port);
return accessor;
});
registerComponent(OB_DEV_COMPONENT_DEVICE_MONITOR, [this, depthPortInfo]() {
auto port = getSourcePort(depthPortInfo);
auto devMonitor = std::make_shared<DeviceMonitor>(this, port);
return devMonitor;
});
}
auto colorPortInfoIter = std::find_if(sourcePortInfoList.begin(), sourcePortInfoList.end(), [](const std::shared_ptr<const SourcePortInfo> &portInfo) {
return portInfo->portType == SOURCE_PORT_USB_UVC && std::dynamic_pointer_cast<const USBSourcePortInfo>(portInfo)->infIndex == INTERFACE_COLOR;
});
if(colorPortInfoIter != sourcePortInfoList.end()) {
auto colorPortInfo = *colorPortInfoIter;
registerComponent(
OB_DEV_COMPONENT_COLOR_SENSOR,
[this, colorPortInfo]() {
auto port = getSourcePort(colorPortInfo);
auto sensor = std::make_shared<VideoSensor>(this, OB_SENSOR_COLOR, port);
std::vector<FormatFilterConfig> formatFilterConfigs = {
{ FormatFilterPolicy::REMOVE, OB_FORMAT_NV12, OB_FORMAT_ANY, nullptr },
};
auto formatConverter = getSensorFrameFilter("FormatConverter", OB_SENSOR_COLOR, false);
if(formatConverter) {
formatFilterConfigs.push_back({ FormatFilterPolicy::ADD, OB_FORMAT_UYVY, OB_FORMAT_RGB, formatConverter });
}
sensor->updateFormatFilterConfig(formatFilterConfigs);
auto frameTimestampCalculator = videoFrameTimestampCalculatorCreator_();
sensor->setFrameTimestampCalculator(frameTimestampCalculator);
auto frameProcessor = getComponentT<FrameProcessor>(OB_DEV_COMPONENT_COLOR_FRAME_PROCESSOR, false);
if(frameProcessor) {
sensor->setFrameProcessor(frameProcessor.get());
}
sensor->enableTimestampAnomalyDetection(false);
initSensorStreamProfile(sensor);
return sensor;
},
true);
registerSensorPortInfo(OB_SENSOR_COLOR, colorPortInfo);
registerComponent(OB_DEV_COMPONENT_COLOR_FRAME_PROCESSOR, [this]() {
auto factory = getComponentT<FrameProcessorFactory>(OB_DEV_COMPONENT_FRAME_PROCESSOR_FACTORY);
auto frameProcessor = factory->createFrameProcessor(OB_SENSOR_COLOR);
return frameProcessor;
});
}
auto sensorStreamStrategy = std::make_shared<AstraMiniSensorStreamStrategy>(this);
registerComponent(OB_DEV_COMPONENT_SENSOR_STREAM_STRATEGY, sensorStreamStrategy);
}
void AstraMiniDevice::initProperties() {
OpenNIDeviceBase::initProperties();
auto propertyServer = getPropertyServer();
auto sensors = getSensorTypeList();
for(auto &sensor: sensors) {
auto &sourcePortInfo = getSensorPortInfo(sensor);
if(sensor == OB_SENSOR_COLOR) {
auto uvcPropertyAccessor = std::make_shared<LazyPropertyAccessor>([this, &sourcePortInfo]() {
auto port = getSourcePort(sourcePortInfo);
auto accessor = std::make_shared<UvcPropertyAccessor>(port);
return accessor;
});
propertyServer->registerProperty(OB_PROP_COLOR_AUTO_EXPOSURE_BOOL, "rw", "rw", uvcPropertyAccessor);
propertyServer->registerProperty(OB_PROP_COLOR_GAIN_INT, "rw", "rw", uvcPropertyAccessor);
propertyServer->registerProperty(OB_PROP_COLOR_EXPOSURE_INT, "rw", "rw", uvcPropertyAccessor);
propertyServer->registerProperty(OB_PROP_COLOR_AUTO_WHITE_BALANCE_BOOL, "rw", "rw", uvcPropertyAccessor);
propertyServer->registerProperty(OB_PROP_COLOR_WHITE_BALANCE_INT, "rw", "rw", uvcPropertyAccessor);
}
if(sensor == OB_SENSOR_DEPTH) {
propertyServer->registerProperty(OB_PROP_TEMPERATURE_COMPENSATION_BOOL, "rw", "rw", vendorPropertyAccessor_);
auto deviceTempPropertyAccessor = std::make_shared<OpenNITemperatureStructurePropertyAccessor>(this);
propertyServer->registerProperty(OB_STRUCT_DEVICE_TEMPERATURE, "r", "r", deviceTempPropertyAccessor);
}
}
}
}