diff --git a/cscore/src/main/native/cpp/CvSinkImpl.cpp b/cscore/src/main/native/cpp/CvSinkImpl.cpp index 7b422f7332..17dbd18a74 100644 --- a/cscore/src/main/native/cpp/CvSinkImpl.cpp +++ b/cscore/src/main/native/cpp/CvSinkImpl.cpp @@ -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(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(name, inst.logger, inst.notifier, + inst.telemetry)); } CS_Sink CreateCvSinkCallback(const wpi::Twine& name, std::function processFrame, CS_Status* status) { auto& inst = Instance::GetInstance(); - auto sink = std::make_shared(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(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& 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& 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; diff --git a/cscore/src/main/native/cpp/CvSourceImpl.cpp b/cscore/src/main/native/cpp/CvSourceImpl.cpp index 97b56dc565..449a9ee17d 100644 --- a/cscore/src/main/native/cpp/CvSourceImpl.cpp +++ b/cscore/src/main/native/cpp/CvSourceImpl.cpp @@ -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(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( + 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 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 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; diff --git a/cscore/src/main/native/cpp/CvSourceImpl.h b/cscore/src/main/native/cpp/CvSourceImpl.h index c5f06d42ac..e1a9cd2cf0 100644 --- a/cscore/src/main/native/cpp/CvSourceImpl.h +++ b/cscore/src/main/native/cpp/CvSourceImpl.h @@ -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; diff --git a/cscore/src/main/native/cpp/HttpCameraImpl.cpp b/cscore/src/main/native/cpp/HttpCameraImpl.cpp index 143f2c5f5d..367ebd06d7 100644 --- a/cscore/src/main/native/cpp/HttpCameraImpl.cpp +++ b/cscore/src/main/native/cpp/HttpCameraImpl.cpp @@ -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(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 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 urls, std::vector 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{}; diff --git a/cscore/src/main/native/cpp/HttpCameraImpl.h b/cscore/src/main/native/cpp/HttpCameraImpl.h index f39d153cbf..497d45dccf 100644 --- a/cscore/src/main/native/cpp/HttpCameraImpl.h +++ b/cscore/src/main/native/cpp/HttpCameraImpl.h @@ -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; diff --git a/cscore/src/main/native/cpp/Instance.cpp b/cscore/src/main/native/cpp/Instance.cpp index 6ee362a5bc..e6cb69a0a9 100644 --- a/cscore/src/main/native/cpp/Instance.cpp +++ b/cscore/src/main/native/cpp/Instance.cpp @@ -53,12 +53,36 @@ void Instance::SetDefaultLogger() { logger.SetLogger(def_log_func); } std::pair> Instance::FindSource( const SourceImpl& source) { - return sources.FindIf( + return m_sources.FindIf( [&](const SourceData& data) { return data.source.get() == &source; }); } std::pair> 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 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 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); +} diff --git a/cscore/src/main/native/cpp/Instance.h b/cscore/src/main/native/cpp/Instance.h index 9cb52f65dc..8e84a370a2 100644 --- a/cscore/src/main/native/cpp/Instance.h +++ b/cscore/src/main/native/cpp/Instance.h @@ -51,13 +51,16 @@ class Instance { static Instance& GetInstance(); - UnlimitedHandleResource sources; - UnlimitedHandleResource sinks; - wpi::Logger logger; Notifier notifier; Telemetry telemetry; NetworkListener network_listener; + + private: + UnlimitedHandleResource m_sources; + UnlimitedHandleResource m_sinks; + + public: wpi::EventLoopRunner event_loop; std::pair> FindSink(const SinkImpl& sink); @@ -66,6 +69,41 @@ class Instance { void SetDefaultLogger(); + std::shared_ptr GetSource(CS_Source handle) { + return m_sources.Get(handle); + } + + std::shared_ptr GetSink(CS_Sink handle) { + return m_sinks.Get(handle); + } + + CS_Source CreateSource(CS_SourceKind kind, + std::shared_ptr source); + + CS_Sink CreateSink(CS_SinkKind kind, std::shared_ptr sink); + + void DestroySource(CS_Source handle); + void DestroySink(CS_Sink handle); + + wpi::ArrayRef EnumerateSourceHandles( + wpi::SmallVectorImpl& vec) { + return m_sources.GetAll(vec); + } + + wpi::ArrayRef EnumerateSinkHandles( + wpi::SmallVectorImpl& vec) { + return m_sinks.GetAll(vec); + } + + wpi::ArrayRef EnumerateSourceSinks( + CS_Source source, wpi::SmallVectorImpl& 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(); }; diff --git a/cscore/src/main/native/cpp/MjpegServerImpl.cpp b/cscore/src/main/native/cpp/MjpegServerImpl.cpp index d2dd792123..40c4a36b04 100644 --- a/cscore/src/main/native/cpp/MjpegServerImpl.cpp +++ b/cscore/src/main/native/cpp/MjpegServerImpl.cpp @@ -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( - name, inst.logger, inst.notifier, inst.telemetry, listenAddress, port, - std::unique_ptr(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( + name, inst.logger, inst.notifier, inst.telemetry, listenAddress, port, + std::unique_ptr(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; diff --git a/cscore/src/main/native/cpp/SourceImpl.h b/cscore/src/main/native/cpp/SourceImpl.h index 09c84a783e..4a93018e07 100644 --- a/cscore/src/main/native/cpp/SourceImpl.h +++ b/cscore/src/main/native/cpp/SourceImpl.h @@ -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); diff --git a/cscore/src/main/native/cpp/UnlimitedHandleResource.h b/cscore/src/main/native/cpp/UnlimitedHandleResource.h index 971cd625ba..c297cfab31 100644 --- a/cscore/src/main/native/cpp/UnlimitedHandleResource.h +++ b/cscore/src/main/native/cpp/UnlimitedHandleResource.h @@ -50,11 +50,13 @@ class UnlimitedHandleResource { std::shared_ptr Get(THandle handle); - void Free(THandle handle); + std::shared_ptr Free(THandle handle); template wpi::ArrayRef GetAll(wpi::SmallVectorImpl& vec); + std::vector> FreeAll(); + // @param func functor with (THandle, const TStruct&) parameters template void ForEach(F func); @@ -121,14 +123,17 @@ UnlimitedHandleResource::Get( } template -inline void UnlimitedHandleResource::Free( +inline std::shared_ptr +UnlimitedHandleResource::Free( THandle handle) { auto index = handle.GetTypedIndex(static_cast(typeValue)); - if (index < 0) return; + if (index < 0) return nullptr; std::lock_guard sync(m_handleMutex); - if (index >= static_cast(m_structures.size())) return; + if (index >= static_cast(m_structures.size())) return nullptr; + auto rv = std::move(m_structures[index]); m_structures[index].reset(); + return rv; } template @@ -140,6 +145,15 @@ UnlimitedHandleResource::GetAll( return vec; } +template +inline std::vector> +UnlimitedHandleResource::FreeAll() { + std::lock_guard sync(m_handleMutex); + auto rv = std::move(m_structures); + m_structures.clear(); + return rv; +} + template template inline void diff --git a/cscore/src/main/native/cpp/cscore_cpp.cpp b/cscore/src/main/native/cpp/cscore_cpp.cpp index b1a4ef1f6f..d838a35531 100644 --- a/cscore/src/main/native/cpp/cscore_cpp.cpp +++ b/cscore/src/main/native/cpp/cscore_cpp.cpp @@ -28,7 +28,7 @@ static std::shared_ptr 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 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 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& 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& 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& 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 EnumerateSourceProperties( CS_Source source, wpi::SmallVectorImpl& 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 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 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{}; @@ -338,21 +338,17 @@ wpi::ArrayRef EnumerateSourceSinks(CS_Source source, wpi::SmallVectorImpl& 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{}; } - 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& 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& 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& 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& 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 EnumerateSinkProperties( CS_Sink sink, wpi::SmallVectorImpl& 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 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 EnumerateSourceHandles( wpi::SmallVectorImpl& vec, CS_Status* status) { - return Instance::GetInstance().sources.GetAll(vec); + return Instance::GetInstance().EnumerateSourceHandles(vec); } wpi::ArrayRef EnumerateSinkHandles(wpi::SmallVectorImpl& vec, CS_Status* status) { - return Instance::GetInstance().sinks.GetAll(vec); + return Instance::GetInstance().EnumerateSinkHandles(vec); } std::string GetHostname() { return wpi::GetHostname(); } diff --git a/cscore/src/main/native/linux/UsbCameraImpl.cpp b/cscore/src/main/native/linux/UsbCameraImpl.cpp index 4dabe2109e..a945f9bf77 100644 --- a/cscore/src/main/native/linux/UsbCameraImpl.cpp +++ b/cscore/src/main/native/linux/UsbCameraImpl.cpp @@ -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( - 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( + 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{}; diff --git a/cscore/src/main/native/linux/UsbCameraImpl.h b/cscore/src/main/native/linux/UsbCameraImpl.h index 2b6afdab7a..eb4a3113d8 100644 --- a/cscore/src/main/native/linux/UsbCameraImpl.h +++ b/cscore/src/main/native/linux/UsbCameraImpl.h @@ -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;