2022-12-25 07:36:00 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
2025-11-07 19:56:21 -05:00
|
|
|
#import "UsbCameraDelegate.hpp"
|
|
|
|
|
#import "UsbCameraImplObjc.hpp"
|
2022-12-25 07:36:00 -08:00
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <optional>
|
|
|
|
|
|
2026-01-04 16:59:02 -08:00
|
|
|
#include "wpi/util/PixelFormat.hpp"
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "wpi/util/StringMap.hpp"
|
2025-04-30 22:02:59 +08:00
|
|
|
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "SourceImpl.hpp"
|
2022-12-25 07:36:00 -08:00
|
|
|
|
2025-11-07 20:00:05 -05:00
|
|
|
namespace wpi::cs {
|
2022-12-25 07:36:00 -08:00
|
|
|
struct CameraFPSRange {
|
|
|
|
|
int min;
|
|
|
|
|
int max;
|
|
|
|
|
|
|
|
|
|
bool IsWithinRange(int fps) { return fps >= min && fps <= max; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct CameraModeStore {
|
|
|
|
|
VideoMode mode;
|
|
|
|
|
AVCaptureDeviceFormat* format;
|
|
|
|
|
std::vector<CameraFPSRange> fpsRanges;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class UsbCameraImpl : public SourceImpl {
|
|
|
|
|
public:
|
2025-11-07 20:00:05 -05:00
|
|
|
UsbCameraImpl(std::string_view name, wpi::util::Logger& logger, Notifier& notifier,
|
2022-12-25 07:36:00 -08:00
|
|
|
Telemetry& telemetry, std::string_view path);
|
2025-11-07 20:00:05 -05:00
|
|
|
UsbCameraImpl(std::string_view name, wpi::util::Logger& logger, Notifier& notifier,
|
2022-12-25 07:36:00 -08:00
|
|
|
Telemetry& telemetry, int deviceId);
|
|
|
|
|
~UsbCameraImpl() override;
|
|
|
|
|
|
|
|
|
|
void Start() override;
|
|
|
|
|
|
|
|
|
|
// Property functions
|
|
|
|
|
void SetProperty(int property, int value, CS_Status* status) override;
|
|
|
|
|
void SetStringProperty(int property, std::string_view value,
|
|
|
|
|
CS_Status* status) override;
|
|
|
|
|
|
|
|
|
|
// Standard common camera properties
|
|
|
|
|
void SetBrightness(int brightness, CS_Status* status) override;
|
|
|
|
|
int GetBrightness(CS_Status* status) const override;
|
|
|
|
|
void SetWhiteBalanceAuto(CS_Status* status) override;
|
|
|
|
|
void SetWhiteBalanceHoldCurrent(CS_Status* status) override;
|
|
|
|
|
void SetWhiteBalanceManual(int value, CS_Status* status) override;
|
|
|
|
|
void SetExposureAuto(CS_Status* status) override;
|
|
|
|
|
void SetExposureHoldCurrent(CS_Status* status) override;
|
|
|
|
|
void SetExposureManual(int value, CS_Status* status) override;
|
|
|
|
|
|
|
|
|
|
bool SetVideoMode(const VideoMode& mode, CS_Status* status) override;
|
2026-01-04 16:59:02 -08:00
|
|
|
bool SetPixelFormat(wpi::util::PixelFormat pixelFormat,
|
2022-12-25 07:36:00 -08:00
|
|
|
CS_Status* status) override;
|
|
|
|
|
bool SetResolution(int width, int height, CS_Status* status) override;
|
|
|
|
|
bool SetFPS(int fps, CS_Status* status) override;
|
|
|
|
|
|
|
|
|
|
void NumSinksChanged() override;
|
|
|
|
|
void NumSinksEnabledChanged() override;
|
|
|
|
|
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::cs::Notifier& objcGetNotifier() { return m_notifier; }
|
2022-12-25 07:36:00 -08:00
|
|
|
|
|
|
|
|
void objcSwapVideoModes(std::vector<VideoMode>& modes) {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
m_videoModes.swap(modes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void objcSetVideoMode(const VideoMode& mode) {
|
|
|
|
|
std::scoped_lock lock(m_mutex);
|
|
|
|
|
m_mode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void objcPutFrame(std::unique_ptr<Image> image, Frame::Time time) {
|
|
|
|
|
PutFrame(std::move(image), time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VideoMode& objcGetVideoMode() const { return m_mode; }
|
|
|
|
|
|
|
|
|
|
std::vector<CameraModeStore>& objcGetPlatformVideoModes() {
|
|
|
|
|
return m_platformModes;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::util::Logger& objcGetLogger() { return m_logger; }
|
2022-12-25 07:36:00 -08:00
|
|
|
|
|
|
|
|
UsbCameraImplObjc* cppGetObjc() { return m_objc; }
|
|
|
|
|
|
2025-04-30 22:02:59 +08:00
|
|
|
int CreatePropertyPublic(std::string_view name, std::function<std::unique_ptr<PropertyImpl>()> newFunc) {
|
|
|
|
|
return CreateProperty(name, newFunc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyImpl* GetPropertyPublic(int property) {
|
|
|
|
|
return GetProperty(property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NotifyPropertyCreatedPublic(int propIndex, PropertyImpl& prop) {
|
|
|
|
|
NotifyPropertyCreated(propIndex, prop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdatePropertyValuePublic(int property, bool setString, int value, std::string_view valueStr) {
|
|
|
|
|
UpdatePropertyValue(property, setString, value, valueStr);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::util::mutex& GetMutex() { return m_mutex; }
|
2025-04-30 22:02:59 +08:00
|
|
|
|
|
|
|
|
// Property cache accessors
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::util::StringMap<uint32_t>& GetPropertyCache() { return m_propertyCache; }
|
|
|
|
|
wpi::util::StringMap<uint32_t>& GetPropertyAutoCache() { return m_propertyAutoCache; }
|
2025-04-30 22:02:59 +08:00
|
|
|
|
2022-12-25 07:36:00 -08:00
|
|
|
private:
|
|
|
|
|
UsbCameraImplObjc* m_objc;
|
|
|
|
|
std::vector<CameraModeStore> m_platformModes;
|
2025-04-30 22:02:59 +08:00
|
|
|
|
|
|
|
|
// Property caches
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::util::StringMap<uint32_t> m_propertyCache;
|
|
|
|
|
wpi::util::StringMap<uint32_t> m_propertyAutoCache;
|
2022-12-25 07:36:00 -08:00
|
|
|
};
|
2025-11-07 20:00:05 -05:00
|
|
|
} // namespace wpi::cs
|