cscore: Refactor sink and source creation

Also make sources and sinks members of Instance private, with appropriate
accessor functions.
This commit is contained in:
Peter Johnson
2018-11-06 19:42:39 -08:00
parent 81d10bc656
commit 0abae17653
13 changed files with 185 additions and 137 deletions

View File

@@ -124,27 +124,23 @@ namespace cs {
CS_Sink CreateCvSink(const wpi::Twine& name, CS_Status* status) {
auto& inst = Instance::GetInstance();
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry);
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
return handle;
return inst.CreateSink(
CS_SINK_CV, std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry));
}
CS_Sink CreateCvSinkCallback(const wpi::Twine& name,
std::function<void(uint64_t time)> processFrame,
CS_Status* status) {
auto& inst = Instance::GetInstance();
auto sink = std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry, processFrame);
auto handle = inst.sinks.Allocate(CS_SINK_CV, sink);
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
return handle;
return inst.CreateSink(
CS_SINK_CV, std::make_shared<CvSinkImpl>(name, inst.logger, inst.notifier,
inst.telemetry, processFrame));
}
void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -153,7 +149,7 @@ void SetSinkDescription(CS_Sink sink, const wpi::Twine& description,
}
uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -163,7 +159,7 @@ uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -172,7 +168,7 @@ uint64_t GrabSinkFrameTimeout(CS_Sink sink, cv::Mat& image, double timeout,
}
std::string GetSinkError(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -182,7 +178,7 @@ std::string GetSinkError(CS_Sink sink, CS_Status* status) {
wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -191,7 +187,7 @@ wpi::StringRef GetSinkError(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
}
void SetSinkEnabled(CS_Sink sink, bool enabled, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_CV) {
*status = CS_INVALID_HANDLE;
return;

View File

@@ -32,7 +32,11 @@ CvSourceImpl::CvSourceImpl(const wpi::Twine& name, wpi::Logger& logger,
CvSourceImpl::~CvSourceImpl() {}
void CvSourceImpl::Start() {}
void CvSourceImpl::Start() {
m_notifier.NotifySource(*this, CS_SOURCE_CONNECTED);
m_notifier.NotifySource(*this, CS_SOURCE_VIDEOMODES_UPDATED);
m_notifier.NotifySourceVideoMode(*this, m_mode);
}
bool CvSourceImpl::SetVideoMode(const VideoMode& mode, CS_Status* status) {
{
@@ -145,20 +149,13 @@ namespace cs {
CS_Source CreateCvSource(const wpi::Twine& name, const VideoMode& mode,
CS_Status* status) {
auto& inst = Instance::GetInstance();
auto source = std::make_shared<CvSourceImpl>(name, inst.logger, inst.notifier,
inst.telemetry, mode);
auto handle = inst.sources.Allocate(CS_SOURCE_CV, source);
inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED);
// Generate initial events here so they come after the source created event
source->Start(); // causes a property event
inst.notifier.NotifySource(name, handle, CS_SOURCE_CONNECTED);
inst.notifier.NotifySource(name, handle, CS_SOURCE_VIDEOMODES_UPDATED);
inst.notifier.NotifySourceVideoMode(*source, mode);
return handle;
return inst.CreateSource(CS_SOURCE_CV, std::make_shared<CvSourceImpl>(
name, inst.logger, inst.notifier,
inst.telemetry, mode));
}
void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -168,7 +165,7 @@ void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) {
void NotifySourceError(CS_Source source, const wpi::Twine& msg,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -177,7 +174,7 @@ void NotifySourceError(CS_Source source, const wpi::Twine& msg,
}
void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -187,7 +184,7 @@ void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) {
void SetSourceDescription(CS_Source source, const wpi::Twine& description,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -199,7 +196,7 @@ CS_Property CreateSourceProperty(CS_Source source, const wpi::Twine& name,
CS_PropertyKind kind, int minimum, int maximum,
int step, int defaultValue, int value,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return -1;
@@ -214,7 +211,7 @@ CS_Property CreateSourcePropertyCallback(
CS_Source source, const wpi::Twine& name, CS_PropertyKind kind, int minimum,
int maximum, int step, int defaultValue, int value,
std::function<void(CS_Property property)> onChange, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return -1;
@@ -228,7 +225,7 @@ CS_Property CreateSourcePropertyCallback(
void SetSourceEnumPropertyChoices(CS_Source source, CS_Property property,
wpi::ArrayRef<std::string> choices,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_CV) {
*status = CS_INVALID_HANDLE;
return;
@@ -241,7 +238,7 @@ void SetSourceEnumPropertyChoices(CS_Source source, CS_Property property,
*status = CS_INVALID_HANDLE;
return;
}
auto data2 = Instance::GetInstance().sources.Get(Handle{i, Handle::kSource});
auto data2 = Instance::GetInstance().GetSource(Handle{i, Handle::kSource});
if (!data2 || data->source.get() != data2->source.get()) {
*status = CS_INVALID_HANDLE;
return;

View File

@@ -28,7 +28,7 @@ class CvSourceImpl : public SourceImpl {
Telemetry& telemetry, const VideoMode& mode);
~CvSourceImpl() override;
void Start();
void Start() override;
bool SetVideoMode(const VideoMode& mode, CS_Status* status) override;

View File

@@ -482,10 +482,7 @@ CS_Source CreateHttpCamera(const wpi::Twine& name, const wpi::Twine& url,
break;
}
if (!source->SetUrls(url.str(), status)) return 0;
auto handle = inst.sources.Allocate(CS_SOURCE_HTTP, source);
inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED);
source->Start();
return handle;
return inst.CreateSource(CS_SOURCE_HTTP, source);
}
CS_Source CreateHttpCamera(const wpi::Twine& name,
@@ -499,14 +496,11 @@ CS_Source CreateHttpCamera(const wpi::Twine& name,
auto source = std::make_shared<HttpCameraImpl>(name, kind, inst.logger,
inst.notifier, inst.telemetry);
if (!source->SetUrls(urls, status)) return 0;
auto handle = inst.sources.Allocate(CS_SOURCE_HTTP, source);
inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED);
source->Start();
return handle;
return inst.CreateSource(CS_SOURCE_HTTP, source);
}
CS_HttpCameraKind GetHttpCameraKind(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_HTTP) {
*status = CS_INVALID_HANDLE;
return CS_HTTP_UNKNOWN;
@@ -520,7 +514,7 @@ void SetHttpCameraUrls(CS_Source source, wpi::ArrayRef<std::string> urls,
*status = CS_EMPTY_VALUE;
return;
}
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_HTTP) {
*status = CS_INVALID_HANDLE;
return;
@@ -530,7 +524,7 @@ void SetHttpCameraUrls(CS_Source source, wpi::ArrayRef<std::string> urls,
std::vector<std::string> GetHttpCameraUrls(CS_Source source,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_HTTP) {
*status = CS_INVALID_HANDLE;
return std::vector<std::string>{};

View File

@@ -34,7 +34,7 @@ class HttpCameraImpl : public SourceImpl {
wpi::Logger& logger, Notifier& notifier, Telemetry& telemetry);
~HttpCameraImpl() override;
void Start();
void Start() override;
// Property functions
void SetProperty(int property, int value, CS_Status* status) override;

View File

@@ -53,12 +53,36 @@ void Instance::SetDefaultLogger() { logger.SetLogger(def_log_func); }
std::pair<CS_Source, std::shared_ptr<SourceData>> Instance::FindSource(
const SourceImpl& source) {
return sources.FindIf(
return m_sources.FindIf(
[&](const SourceData& data) { return data.source.get() == &source; });
}
std::pair<CS_Sink, std::shared_ptr<SinkData>> Instance::FindSink(
const SinkImpl& sink) {
return sinks.FindIf(
return m_sinks.FindIf(
[&](const SinkData& data) { return data.sink.get() == &sink; });
}
CS_Source Instance::CreateSource(CS_SourceKind kind,
std::shared_ptr<SourceImpl> source) {
auto handle = m_sources.Allocate(kind, source);
notifier.NotifySource(source->GetName(), handle, CS_SOURCE_CREATED);
source->Start();
return handle;
}
CS_Sink Instance::CreateSink(CS_SinkKind kind, std::shared_ptr<SinkImpl> sink) {
auto handle = m_sinks.Allocate(kind, sink);
notifier.NotifySink(sink->GetName(), handle, CS_SINK_CREATED);
return handle;
}
void Instance::DestroySource(CS_Source handle) {
if (auto data = m_sources.Free(handle))
notifier.NotifySource(data->source->GetName(), handle, CS_SOURCE_DESTROYED);
}
void Instance::DestroySink(CS_Sink handle) {
if (auto data = m_sinks.Free(handle))
notifier.NotifySink(data->sink->GetName(), handle, CS_SINK_DESTROYED);
}

View File

@@ -51,13 +51,16 @@ class Instance {
static Instance& GetInstance();
UnlimitedHandleResource<Handle, SourceData, Handle::kSource> sources;
UnlimitedHandleResource<Handle, SinkData, Handle::kSink> sinks;
wpi::Logger logger;
Notifier notifier;
Telemetry telemetry;
NetworkListener network_listener;
private:
UnlimitedHandleResource<Handle, SourceData, Handle::kSource> m_sources;
UnlimitedHandleResource<Handle, SinkData, Handle::kSink> m_sinks;
public:
wpi::EventLoopRunner event_loop;
std::pair<CS_Sink, std::shared_ptr<SinkData>> FindSink(const SinkImpl& sink);
@@ -66,6 +69,41 @@ class Instance {
void SetDefaultLogger();
std::shared_ptr<SourceData> GetSource(CS_Source handle) {
return m_sources.Get(handle);
}
std::shared_ptr<SinkData> GetSink(CS_Sink handle) {
return m_sinks.Get(handle);
}
CS_Source CreateSource(CS_SourceKind kind,
std::shared_ptr<SourceImpl> source);
CS_Sink CreateSink(CS_SinkKind kind, std::shared_ptr<SinkImpl> sink);
void DestroySource(CS_Source handle);
void DestroySink(CS_Sink handle);
wpi::ArrayRef<CS_Source> EnumerateSourceHandles(
wpi::SmallVectorImpl<CS_Source>& vec) {
return m_sources.GetAll(vec);
}
wpi::ArrayRef<CS_Sink> EnumerateSinkHandles(
wpi::SmallVectorImpl<CS_Sink>& vec) {
return m_sinks.GetAll(vec);
}
wpi::ArrayRef<CS_Sink> EnumerateSourceSinks(
CS_Source source, wpi::SmallVectorImpl<CS_Sink>& vec) {
vec.clear();
m_sinks.ForEach([&](CS_Sink sinkHandle, const SinkData& data) {
if (source == data.sourceHandle.load()) vec.push_back(sinkHandle);
});
return vec;
}
private:
Instance();
};

View File

@@ -915,19 +915,18 @@ CS_Sink CreateMjpegServer(const wpi::Twine& name,
CS_Status* status) {
auto& inst = Instance::GetInstance();
wpi::SmallString<128> listenAddressBuf;
auto sink = std::make_shared<MjpegServerImpl>(
name, inst.logger, inst.notifier, inst.telemetry, listenAddress, port,
std::unique_ptr<wpi::NetworkAcceptor>(new wpi::TCPAcceptor(
port,
listenAddress.toNullTerminatedStringRef(listenAddressBuf).data(),
inst.logger)));
auto handle = inst.sinks.Allocate(CS_SINK_MJPEG, sink);
inst.notifier.NotifySink(name, handle, CS_SINK_CREATED);
return handle;
return inst.CreateSink(
CS_SINK_MJPEG,
std::make_shared<MjpegServerImpl>(
name, inst.logger, inst.notifier, inst.telemetry, listenAddress, port,
std::unique_ptr<wpi::NetworkAcceptor>(new wpi::TCPAcceptor(
port,
listenAddress.toNullTerminatedStringRef(listenAddressBuf).data(),
inst.logger))));
}
std::string GetMjpegServerListenAddress(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_MJPEG) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -936,7 +935,7 @@ std::string GetMjpegServerListenAddress(CS_Sink sink, CS_Status* status) {
}
int GetMjpegServerPort(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_MJPEG) {
*status = CS_INVALID_HANDLE;
return 0;

View File

@@ -42,6 +42,8 @@ class SourceImpl : public PropertyContainer {
SourceImpl(const SourceImpl& oth) = delete;
SourceImpl& operator=(const SourceImpl& oth) = delete;
virtual void Start() = 0;
wpi::StringRef GetName() const { return m_name; }
void SetDescription(const wpi::Twine& description);

View File

@@ -50,11 +50,13 @@ class UnlimitedHandleResource {
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
std::shared_ptr<TStruct> Free(THandle handle);
template <typename T>
wpi::ArrayRef<T> GetAll(wpi::SmallVectorImpl<T>& vec);
std::vector<std::shared_ptr<TStruct>> FreeAll();
// @param func functor with (THandle, const TStruct&) parameters
template <typename F>
void ForEach(F func);
@@ -121,14 +123,17 @@ UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::Get(
}
template <typename THandle, typename TStruct, int typeValue, typename TMutex>
inline void UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::Free(
inline std::shared_ptr<TStruct>
UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::Free(
THandle handle) {
auto index =
handle.GetTypedIndex(static_cast<typename THandle::Type>(typeValue));
if (index < 0) return;
if (index < 0) return nullptr;
std::lock_guard<TMutex> sync(m_handleMutex);
if (index >= static_cast<int>(m_structures.size())) return;
if (index >= static_cast<int>(m_structures.size())) return nullptr;
auto rv = std::move(m_structures[index]);
m_structures[index].reset();
return rv;
}
template <typename THandle, typename TStruct, int typeValue, typename TMutex>
@@ -140,6 +145,15 @@ UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::GetAll(
return vec;
}
template <typename THandle, typename TStruct, int typeValue, typename TMutex>
inline std::vector<std::shared_ptr<TStruct>>
UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::FreeAll() {
std::lock_guard<TMutex> sync(m_handleMutex);
auto rv = std::move(m_structures);
m_structures.clear();
return rv;
}
template <typename THandle, typename TStruct, int typeValue, typename TMutex>
template <typename F>
inline void

View File

@@ -28,7 +28,7 @@ static std::shared_ptr<PropertyContainer> GetPropertyContainer(
Handle handle{propertyHandle};
if (handle.IsType(Handle::kProperty)) {
int i = handle.GetParentIndex();
auto data = Instance::GetInstance().sources.Get(Handle{i, Handle::kSource});
auto data = Instance::GetInstance().GetSource(Handle{i, Handle::kSource});
if (!data) {
*status = CS_INVALID_HANDLE;
return nullptr;
@@ -36,7 +36,7 @@ static std::shared_ptr<PropertyContainer> GetPropertyContainer(
container = data->source;
} else if (handle.IsType(Handle::kSinkProperty)) {
int i = handle.GetParentIndex();
auto data = Instance::GetInstance().sinks.Get(Handle{i, Handle::kSink});
auto data = Instance::GetInstance().GetSink(Handle{i, Handle::kSink});
if (!data) {
*status = CS_INVALID_HANDLE;
return nullptr;
@@ -160,7 +160,7 @@ std::vector<std::string> GetEnumPropertyChoices(CS_Property property,
//
CS_SourceKind GetSourceKind(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return CS_SOURCE_UNKNOWN;
@@ -169,7 +169,7 @@ CS_SourceKind GetSourceKind(CS_Source source, CS_Status* status) {
}
std::string GetSourceName(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -179,7 +179,7 @@ std::string GetSourceName(CS_Source source, CS_Status* status) {
wpi::StringRef GetSourceName(CS_Source source, wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -188,7 +188,7 @@ wpi::StringRef GetSourceName(CS_Source source, wpi::SmallVectorImpl<char>& buf,
}
std::string GetSourceDescription(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -200,7 +200,7 @@ std::string GetSourceDescription(CS_Source source, CS_Status* status) {
wpi::StringRef GetSourceDescription(CS_Source source,
wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -209,7 +209,7 @@ wpi::StringRef GetSourceDescription(CS_Source source,
}
uint64_t GetSourceLastFrameTime(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -220,7 +220,7 @@ uint64_t GetSourceLastFrameTime(CS_Source source, CS_Status* status) {
void SetSourceConnectionStrategy(CS_Source source,
CS_ConnectionStrategy strategy,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -229,7 +229,7 @@ void SetSourceConnectionStrategy(CS_Source source,
}
bool IsSourceConnected(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -238,7 +238,7 @@ bool IsSourceConnected(CS_Source source, CS_Status* status) {
}
bool IsSourceEnabled(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -248,7 +248,7 @@ bool IsSourceEnabled(CS_Source source, CS_Status* status) {
CS_Property GetSourceProperty(CS_Source source, const wpi::Twine& name,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -264,7 +264,7 @@ CS_Property GetSourceProperty(CS_Source source, const wpi::Twine& name,
wpi::ArrayRef<CS_Property> EnumerateSourceProperties(
CS_Source source, wpi::SmallVectorImpl<CS_Property>& vec,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -277,7 +277,7 @@ wpi::ArrayRef<CS_Property> EnumerateSourceProperties(
}
VideoMode GetSourceVideoMode(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return VideoMode{};
@@ -287,7 +287,7 @@ VideoMode GetSourceVideoMode(CS_Source source, CS_Status* status) {
bool SetSourceVideoMode(CS_Source source, const VideoMode& mode,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -297,7 +297,7 @@ bool SetSourceVideoMode(CS_Source source, const VideoMode& mode,
bool SetSourcePixelFormat(CS_Source source, VideoMode::PixelFormat pixelFormat,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -307,7 +307,7 @@ bool SetSourcePixelFormat(CS_Source source, VideoMode::PixelFormat pixelFormat,
bool SetSourceResolution(CS_Source source, int width, int height,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -316,7 +316,7 @@ bool SetSourceResolution(CS_Source source, int width, int height,
}
bool SetSourceFPS(CS_Source source, int fps, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return false;
@@ -326,7 +326,7 @@ bool SetSourceFPS(CS_Source source, int fps, CS_Status* status) {
std::vector<VideoMode> EnumerateSourceVideoModes(CS_Source source,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return std::vector<VideoMode>{};
@@ -338,21 +338,17 @@ wpi::ArrayRef<CS_Sink> EnumerateSourceSinks(CS_Source source,
wpi::SmallVectorImpl<CS_Sink>& vec,
CS_Status* status) {
auto& inst = Instance::GetInstance();
auto data = inst.sources.Get(source);
auto data = inst.GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return wpi::ArrayRef<CS_Sink>{};
}
vec.clear();
inst.sinks.ForEach([&](CS_Sink sinkHandle, const SinkData& data) {
if (source == data.sourceHandle.load()) vec.push_back(sinkHandle);
});
return vec;
return inst.EnumerateSourceSinks(source, vec);
}
CS_Source CopySource(CS_Source source, CS_Status* status) {
if (source == 0) return 0;
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -364,16 +360,12 @@ CS_Source CopySource(CS_Source source, CS_Status* status) {
void ReleaseSource(CS_Source source, CS_Status* status) {
if (source == 0) return;
auto& inst = Instance::GetInstance();
auto data = inst.sources.Get(source);
auto data = inst.GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
}
if (data->refCount-- == 0) {
inst.notifier.NotifySource(data->source->GetName(), source,
CS_SOURCE_DESTROYED);
inst.sources.Free(source);
}
if (data->refCount-- == 0) inst.DestroySource(source);
}
//
@@ -381,7 +373,7 @@ void ReleaseSource(CS_Source source, CS_Status* status) {
//
void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -390,7 +382,7 @@ void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status) {
}
int GetCameraBrightness(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -399,7 +391,7 @@ int GetCameraBrightness(CS_Source source, CS_Status* status) {
}
void SetCameraWhiteBalanceAuto(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -408,7 +400,7 @@ void SetCameraWhiteBalanceAuto(CS_Source source, CS_Status* status) {
}
void SetCameraWhiteBalanceHoldCurrent(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -418,7 +410,7 @@ void SetCameraWhiteBalanceHoldCurrent(CS_Source source, CS_Status* status) {
void SetCameraWhiteBalanceManual(CS_Source source, int value,
CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -427,7 +419,7 @@ void SetCameraWhiteBalanceManual(CS_Source source, int value,
}
void SetCameraExposureAuto(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -436,7 +428,7 @@ void SetCameraExposureAuto(CS_Source source, CS_Status* status) {
}
void SetCameraExposureHoldCurrent(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -445,7 +437,7 @@ void SetCameraExposureHoldCurrent(CS_Source source, CS_Status* status) {
}
void SetCameraExposureManual(CS_Source source, int value, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -458,7 +450,7 @@ void SetCameraExposureManual(CS_Source source, int value, CS_Status* status) {
//
CS_SinkKind GetSinkKind(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return CS_SINK_UNKNOWN;
@@ -467,7 +459,7 @@ CS_SinkKind GetSinkKind(CS_Sink sink, CS_Status* status) {
}
std::string GetSinkName(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -477,7 +469,7 @@ std::string GetSinkName(CS_Sink sink, CS_Status* status) {
wpi::StringRef GetSinkName(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -486,7 +478,7 @@ wpi::StringRef GetSinkName(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
}
std::string GetSinkDescription(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return std::string{};
@@ -497,7 +489,7 @@ std::string GetSinkDescription(CS_Sink sink, CS_Status* status) {
wpi::StringRef GetSinkDescription(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return wpi::StringRef{};
@@ -507,7 +499,7 @@ wpi::StringRef GetSinkDescription(CS_Sink sink, wpi::SmallVectorImpl<char>& buf,
CS_Property GetSinkProperty(CS_Sink sink, const wpi::Twine& name,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -522,7 +514,7 @@ CS_Property GetSinkProperty(CS_Sink sink, const wpi::Twine& name,
wpi::ArrayRef<CS_Property> EnumerateSinkProperties(
CS_Sink sink, wpi::SmallVectorImpl<CS_Property>& vec, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -534,7 +526,7 @@ wpi::ArrayRef<CS_Property> EnumerateSinkProperties(
}
void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
@@ -542,7 +534,7 @@ void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) {
if (source == 0) {
data->sink->SetSource(nullptr);
} else {
auto sourceData = Instance::GetInstance().sources.Get(source);
auto sourceData = Instance::GetInstance().GetSource(source);
if (!sourceData) {
*status = CS_INVALID_HANDLE;
return;
@@ -555,7 +547,7 @@ void SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status) {
}
CS_Source GetSinkSource(CS_Sink sink, CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -565,7 +557,7 @@ CS_Source GetSinkSource(CS_Sink sink, CS_Status* status) {
CS_Property GetSinkSourceProperty(CS_Sink sink, const wpi::Twine& name,
CS_Status* status) {
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -575,7 +567,7 @@ CS_Property GetSinkSourceProperty(CS_Sink sink, const wpi::Twine& name,
CS_Sink CopySink(CS_Sink sink, CS_Status* status) {
if (sink == 0) return 0;
auto data = Instance::GetInstance().sinks.Get(sink);
auto data = Instance::GetInstance().GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return 0;
@@ -587,15 +579,12 @@ CS_Sink CopySink(CS_Sink sink, CS_Status* status) {
void ReleaseSink(CS_Sink sink, CS_Status* status) {
if (sink == 0) return;
auto& inst = Instance::GetInstance();
auto data = inst.sinks.Get(sink);
auto data = inst.GetSink(sink);
if (!data) {
*status = CS_INVALID_HANDLE;
return;
}
if (data->refCount-- == 0) {
inst.notifier.NotifySink(data->sink->GetName(), sink, CS_SINK_DESTROYED);
inst.sinks.Free(sink);
}
if (data->refCount-- == 0) inst.DestroySink(sink);
}
//
@@ -682,12 +671,12 @@ void SetDefaultLogger(unsigned int min_level) {
wpi::ArrayRef<CS_Source> EnumerateSourceHandles(
wpi::SmallVectorImpl<CS_Source>& vec, CS_Status* status) {
return Instance::GetInstance().sources.GetAll(vec);
return Instance::GetInstance().EnumerateSourceHandles(vec);
}
wpi::ArrayRef<CS_Sink> EnumerateSinkHandles(wpi::SmallVectorImpl<CS_Sink>& vec,
CS_Status* status) {
return Instance::GetInstance().sinks.GetAll(vec);
return Instance::GetInstance().EnumerateSinkHandles(vec);
}
std::string GetHostname() { return wpi::GetHostname(); }

View File

@@ -1264,18 +1264,13 @@ CS_Source CreateUsbCameraDev(const wpi::Twine& name, int dev,
CS_Source CreateUsbCameraPath(const wpi::Twine& name, const wpi::Twine& path,
CS_Status* status) {
auto& inst = Instance::GetInstance();
auto source = std::make_shared<UsbCameraImpl>(
name, inst.logger, inst.notifier, inst.telemetry, path);
auto handle = inst.sources.Allocate(CS_SOURCE_USB, source);
inst.notifier.NotifySource(name, handle, CS_SOURCE_CREATED);
// Start thread after the source created event to ensure other events
// come after it.
source->Start();
return handle;
return inst.CreateSource(CS_SOURCE_USB, std::make_shared<UsbCameraImpl>(
name, inst.logger, inst.notifier,
inst.telemetry, path));
}
std::string GetUsbCameraPath(CS_Source source, CS_Status* status) {
auto data = Instance::GetInstance().sources.Get(source);
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_USB) {
*status = CS_INVALID_HANDLE;
return std::string{};

View File

@@ -40,7 +40,7 @@ class UsbCameraImpl : public SourceImpl {
Telemetry& telemetry, const wpi::Twine& path);
~UsbCameraImpl() override;
void Start();
void Start() override;
// Property functions
void SetProperty(int property, int value, CS_Status* status) override;