Files
allwpilib/cscore/src/main/native/cpp/HttpCameraImpl.hpp

164 lines
5.3 KiB
C++
Raw Normal View History

// 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.
2025-11-07 19:57:55 -05:00
#ifndef CSCORE_HTTPCAMERAIMPL_HPP_
#define CSCORE_HTTPCAMERAIMPL_HPP_
#include <atomic>
#include <functional>
#include <initializer_list>
2017-08-25 17:48:06 -07:00
#include <memory>
#include <span>
2017-08-25 17:48:06 -07:00
#include <string>
#include <string_view>
#include <thread>
#include <vector>
2025-11-07 19:56:21 -05:00
#include "SourceImpl.hpp"
#include "wpi/cs/cscore_cpp.hpp"
#include "wpi/net/HttpUtil.hpp"
2025-11-07 19:57:55 -05:00
#include "wpi/util/StringMap.hpp"
#include "wpi/util/condition_variable.hpp"
#include "wpi/util/raw_istream.hpp"
2025-11-07 20:00:05 -05:00
namespace wpi::cs {
class HttpCameraImpl : public SourceImpl {
public:
HttpCameraImpl(std::string_view name, CS_HttpCameraKind kind,
2025-11-07 20:01:58 -05:00
wpi::util::Logger& logger, Notifier& notifier,
Telemetry& telemetry);
~HttpCameraImpl() 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;
void NumSinksChanged() override;
void NumSinksEnabledChanged() override;
CS_HttpCameraKind GetKind() const;
bool SetUrls(std::span<const std::string> urls, CS_Status* status);
std::vector<std::string> GetUrls() const;
// Property data
class PropertyData : public PropertyImpl {
public:
PropertyData() = default;
explicit PropertyData(std::string_view name_) : PropertyImpl{name_} {}
PropertyData(std::string_view name_, std::string_view httpParam_,
bool viaSettings_, CS_PropertyKind kind_, int minimum_,
int maximum_, int step_, int defaultValue_, int value_)
: PropertyImpl(name_, kind_, step_, defaultValue_, value_),
viaSettings(viaSettings_),
httpParam(httpParam_) {
hasMinimum = true;
minimum = minimum_;
hasMaximum = true;
maximum = maximum_;
}
~PropertyData() override = default;
bool viaSettings{false};
std::string httpParam;
};
protected:
std::unique_ptr<PropertyImpl> CreateEmptyProperty(
std::string_view name) const override;
bool CacheProperties(CS_Status* status) const override;
void CreateProperty(std::string_view name, std::string_view httpParam,
bool viaSettings, CS_PropertyKind kind, int minimum,
int maximum, int step, int defaultValue, int value) const;
template <typename T>
void CreateEnumProperty(std::string_view name, std::string_view httpParam,
bool viaSettings, int defaultValue, int value,
std::initializer_list<T> choices) const;
private:
// The camera streaming thread
void StreamThreadMain();
// Functions used by StreamThreadMain()
2025-11-07 20:00:05 -05:00
wpi::net::HttpConnection* DeviceStreamConnect(
wpi::util::SmallVectorImpl<char>& boundary);
void DeviceStream(wpi::util::raw_istream& is, std::string_view boundary);
bool DeviceStreamFrame(wpi::util::raw_istream& is, std::string& imageBuf);
// The camera settings thread
void SettingsThreadMain();
2025-11-07 20:00:05 -05:00
void DeviceSendSettings(wpi::net::HttpRequest& req);
// The monitor thread
void MonitorThreadMain();
std::atomic_bool m_connected{false};
std::atomic_bool m_active{true}; // set to false to terminate thread
std::thread m_streamThread;
std::thread m_settingsThread;
std::thread m_monitorThread;
//
// Variables protected by m_mutex
//
// The camera connections
2025-11-07 20:00:05 -05:00
std::unique_ptr<wpi::net::HttpConnection> m_streamConn;
std::unique_ptr<wpi::net::HttpConnection> m_settingsConn;
CS_HttpCameraKind m_kind;
2025-11-07 20:00:05 -05:00
std::vector<wpi::net::HttpLocation> m_locations;
2017-08-25 17:48:06 -07:00
size_t m_nextLocation{0};
int m_prefLocation{-1}; // preferred location
std::atomic_int m_frameCount{0};
2025-11-07 20:00:05 -05:00
wpi::util::condition_variable m_sinkEnabledCond;
2025-11-07 20:00:05 -05:00
wpi::util::StringMap<std::string> m_settings;
wpi::util::condition_variable m_settingsCond;
2025-11-07 20:00:05 -05:00
wpi::util::StringMap<std::string> m_streamSettings;
std::atomic_bool m_streamSettingsUpdated{false};
2025-11-07 20:00:05 -05:00
wpi::util::condition_variable m_monitorCond;
};
class AxisCameraImpl : public HttpCameraImpl {
public:
2025-11-07 20:01:58 -05:00
AxisCameraImpl(std::string_view name, wpi::util::Logger& logger,
Notifier& notifier, Telemetry& telemetry)
: HttpCameraImpl{name, CS_HTTP_AXIS, logger, notifier, telemetry} {}
#if 0
void SetProperty(int property, int value, CS_Status* status) override;
void SetStringProperty(int property, std::string_view value,
CS_Status* status) override;
#endif
protected:
bool CacheProperties(CS_Status* status) const override;
};
2025-11-07 20:00:05 -05:00
} // namespace wpi::cs
2025-11-07 19:57:55 -05:00
#endif // CSCORE_HTTPCAMERAIMPL_HPP_