mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +00:00
Add method to get source/sink type.
Also provide convenience method to enumerate all sinks connected to a source.
This commit is contained in:
@@ -85,6 +85,25 @@ enum CS_PropertyType {
|
||||
CS_PROP_ENUM = 8
|
||||
};
|
||||
|
||||
//
|
||||
// Source types
|
||||
//
|
||||
enum CS_SourceType {
|
||||
CS_SOURCE_UNKNOWN = 0,
|
||||
CS_SOURCE_USB = 1,
|
||||
CS_SOURCE_HTTP = 2,
|
||||
CS_SOURCE_CV = 4
|
||||
};
|
||||
|
||||
//
|
||||
// Sink types
|
||||
//
|
||||
enum CS_SinkType {
|
||||
CS_SINK_UNKNOWN = 0,
|
||||
CS_SINK_MJPEG = 2,
|
||||
CS_SINK_CV = 4
|
||||
};
|
||||
|
||||
//
|
||||
// Listener event types
|
||||
//
|
||||
@@ -160,6 +179,7 @@ CS_Source CS_CreateCvSource(const char* name, const CS_VideoMode* mode,
|
||||
//
|
||||
// Source Functions
|
||||
//
|
||||
CS_SourceType CS_GetSourceType(CS_Source source, CS_Status* status);
|
||||
char* CS_GetSourceName(CS_Source source, CS_Status* status);
|
||||
char* CS_GetSourceDescription(CS_Source source, CS_Status* status);
|
||||
uint64_t CS_GetSourceLastFrameTime(CS_Source source, CS_Status* status);
|
||||
@@ -184,6 +204,8 @@ CS_Bool CS_SetSourceResolution(CS_Source source, int width, int height,
|
||||
CS_Bool CS_SetSourceFPS(CS_Source source, int fps, CS_Status* status);
|
||||
CS_VideoMode* CS_EnumerateSourceVideoModes(CS_Source source, int* count,
|
||||
CS_Status* status);
|
||||
CS_Sink* CS_EnumerateSourceSinks(CS_Source source, int* count,
|
||||
CS_Status* status);
|
||||
CS_Source CS_CopySource(CS_Source source, CS_Status* status);
|
||||
void CS_ReleaseSource(CS_Source source, CS_Status* status);
|
||||
|
||||
@@ -218,6 +240,7 @@ CS_Sink CS_CreateCvSinkCallback(const char* name, void* data,
|
||||
//
|
||||
// Sink Functions
|
||||
//
|
||||
CS_SinkType CS_GetSinkType(CS_Sink sink, CS_Status* status);
|
||||
char* CS_GetSinkName(CS_Sink sink, CS_Status* status);
|
||||
char* CS_GetSinkDescription(CS_Sink sink, CS_Status* status);
|
||||
void CS_SetSinkSource(CS_Sink sink, CS_Source source, CS_Status* status);
|
||||
|
||||
@@ -165,6 +165,7 @@ CS_Source CreateCvSource(llvm::StringRef name, const VideoMode& mode,
|
||||
//
|
||||
// Source Functions
|
||||
//
|
||||
CS_SourceType GetSourceType(CS_Source source, CS_Status* status);
|
||||
std::string GetSourceName(CS_Source source, CS_Status* status);
|
||||
llvm::StringRef GetSourceName(CS_Source source,
|
||||
llvm::SmallVectorImpl<char>& buf,
|
||||
@@ -190,6 +191,8 @@ bool SetSourceResolution(CS_Source source, int width, int height,
|
||||
bool SetSourceFPS(CS_Source source, int fps, CS_Status* status);
|
||||
std::vector<VideoMode> EnumerateSourceVideoModes(CS_Source source,
|
||||
CS_Status* status);
|
||||
llvm::ArrayRef<CS_Sink> EnumerateSourceSinks(
|
||||
CS_Source source, llvm::SmallVectorImpl<CS_Sink>& vec, CS_Status* status);
|
||||
CS_Source CopySource(CS_Source source, CS_Status* status);
|
||||
void ReleaseSource(CS_Source source, CS_Status* status);
|
||||
|
||||
@@ -223,6 +226,7 @@ CS_Sink CreateCvSinkCallback(llvm::StringRef name,
|
||||
//
|
||||
// Sink Functions
|
||||
//
|
||||
CS_SinkType GetSinkType(CS_Sink sink, CS_Status* status);
|
||||
std::string GetSinkName(CS_Sink sink, CS_Status* status);
|
||||
llvm::StringRef GetSinkName(CS_Sink sink, llvm::SmallVectorImpl<char>& buf,
|
||||
CS_Status* status);
|
||||
|
||||
@@ -83,6 +83,13 @@ class VideoSource {
|
||||
friend class VideoSink;
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
kUnknown = CS_SOURCE_UNKNOWN,
|
||||
kUSB = CS_SOURCE_USB,
|
||||
kHTTP = CS_SOURCE_HTTP,
|
||||
kCv = CS_SOURCE_CV
|
||||
};
|
||||
|
||||
VideoSource() noexcept : m_handle(0) {}
|
||||
VideoSource(const VideoSource& source);
|
||||
VideoSource(VideoSource&& other) noexcept;
|
||||
@@ -99,6 +106,9 @@ class VideoSource {
|
||||
|
||||
bool operator!=(const VideoSource& other) const { return !(*this == other); }
|
||||
|
||||
/// Get the type of the source.
|
||||
Type GetType() const;
|
||||
|
||||
/// Get the name of the source. The name is an arbitrary identifier
|
||||
/// provided when the source is created, and should be unique.
|
||||
std::string GetName() const;
|
||||
@@ -158,6 +168,10 @@ class VideoSource {
|
||||
|
||||
CS_Status GetLastStatus() const { return m_status; }
|
||||
|
||||
/// Enumerate all sinks connected to this source.
|
||||
/// @return Vector of sinks.
|
||||
std::vector<VideoSink> EnumerateSinks();
|
||||
|
||||
/// Enumerate all existing sources.
|
||||
/// @return Vector of sources.
|
||||
static std::vector<VideoSource> EnumerateSources();
|
||||
@@ -260,8 +274,15 @@ class CvSource : public VideoSource {
|
||||
/// A sink for video that accepts a sequence of frames.
|
||||
class VideoSink {
|
||||
friend class VideoEvent;
|
||||
friend class VideoSource;
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
kUnknown = CS_SINK_UNKNOWN,
|
||||
kMJPEG = CS_SINK_MJPEG,
|
||||
kCv = CS_SINK_CV
|
||||
};
|
||||
|
||||
VideoSink() noexcept : m_handle(0) {}
|
||||
VideoSink(const VideoSink& sink);
|
||||
VideoSink(VideoSink&& sink) noexcept;
|
||||
@@ -278,6 +299,9 @@ class VideoSink {
|
||||
|
||||
bool operator!=(const VideoSink& other) const { return !(*this == other); }
|
||||
|
||||
/// Get the type of the sink.
|
||||
Type GetType() const;
|
||||
|
||||
/// Get the name of the sink. The name is an arbitrary identifier
|
||||
/// provided when the sink is created, and should be unique.
|
||||
std::string GetName() const;
|
||||
|
||||
@@ -93,6 +93,11 @@ inline VideoSource::~VideoSource() {
|
||||
if (m_handle != 0) ReleaseSource(m_handle, &m_status);
|
||||
}
|
||||
|
||||
inline VideoSource::Type VideoSource::GetType() const {
|
||||
m_status = 0;
|
||||
return static_cast<VideoSource::Type>(GetSourceType(m_handle, &m_status));
|
||||
}
|
||||
|
||||
inline std::string VideoSource::GetName() const {
|
||||
m_status = 0;
|
||||
return GetSourceName(m_handle, &m_status);
|
||||
@@ -236,6 +241,11 @@ inline VideoSink::~VideoSink() {
|
||||
if (m_handle != 0) ReleaseSink(m_handle, &m_status);
|
||||
}
|
||||
|
||||
inline VideoSink::Type VideoSink::GetType() const {
|
||||
m_status = 0;
|
||||
return static_cast<VideoSink::Type>(GetSinkType(m_handle, &m_status));
|
||||
}
|
||||
|
||||
inline std::string VideoSink::GetName() const {
|
||||
m_status = 0;
|
||||
return GetSinkName(m_handle, &m_status);
|
||||
|
||||
@@ -398,6 +398,20 @@ JNIEXPORT jint JNICALL Java_edu_wpi_cscore_CameraServerJNI_createCvSource
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: getSourceType
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_edu_wpi_cscore_CameraServerJNI_getSourceType
|
||||
(JNIEnv *env, jclass, jint source)
|
||||
{
|
||||
CS_Status status = 0;
|
||||
auto val = cs::GetSourceType(source, &status);
|
||||
CheckStatus(env, status);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: getSourceName
|
||||
@@ -582,6 +596,21 @@ JNIEXPORT jobjectArray JNICALL Java_edu_wpi_cscore_CameraServerJNI_enumerateSour
|
||||
return jarr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: enumerateSourceSinks
|
||||
* Signature: (I)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_edu_wpi_cscore_CameraServerJNI_enumerateSourceSinks
|
||||
(JNIEnv *env, jclass, jint source)
|
||||
{
|
||||
CS_Status status = 0;
|
||||
llvm::SmallVector<CS_Sink, 16> buf;
|
||||
auto arr = cs::EnumerateSourceSinks(source, buf, &status);
|
||||
if (!CheckStatus(env, status)) return nullptr;
|
||||
return MakeJIntArray(env, arr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: copySource
|
||||
@@ -732,6 +761,20 @@ JNIEXPORT jint JNICALL Java_edu_wpi_cscore_CameraServerJNI_createCvSink
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: getSinkType
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_edu_wpi_cscore_CameraServerJNI_getSinkType
|
||||
(JNIEnv *env, jclass, jint sink)
|
||||
{
|
||||
CS_Status status = 0;
|
||||
auto val = cs::GetSinkType(sink, &status);
|
||||
CheckStatus(env, status);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_cscore_CameraServerJNI
|
||||
* Method: getSinkName
|
||||
|
||||
@@ -110,6 +110,7 @@ public class CameraServerJNI {
|
||||
//
|
||||
// Source Functions
|
||||
//
|
||||
public static native int getSourceType(int source);
|
||||
public static native String getSourceName(int source);
|
||||
public static native String getSourceDescription(int source);
|
||||
public static native long getSourceLastFrameTime(int source);
|
||||
@@ -122,6 +123,7 @@ public class CameraServerJNI {
|
||||
public static native boolean setSourceResolution(int source, int width, int height);
|
||||
public static native boolean setSourceFPS(int source, int fps);
|
||||
public static native VideoMode[] enumerateSourceVideoModes(int source);
|
||||
public static native int[] enumerateSourceSinks(int source);
|
||||
public static native int copySource(int source);
|
||||
public static native void releaseSource(int source);
|
||||
|
||||
@@ -146,6 +148,7 @@ public class CameraServerJNI {
|
||||
//
|
||||
// Sink Functions
|
||||
//
|
||||
public static native int getSinkType(int sink);
|
||||
public static native String getSinkName(int sink);
|
||||
public static native String getSinkDescription(int sink);
|
||||
public static native void setSinkSource(int sink, int source);
|
||||
|
||||
@@ -11,6 +11,20 @@ package edu.wpi.cscore;
|
||||
/// consist of multiple images (e.g. from a stereo or depth camera); these
|
||||
/// are called channels.
|
||||
public class VideoSink {
|
||||
public enum Type {
|
||||
kUnknown(0), kMJPEG(2), kCv(4);
|
||||
private int value;
|
||||
|
||||
private Type(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
static final Type[] m_typeValues = Type.values();
|
||||
|
||||
protected VideoSink(int handle) {
|
||||
m_handle = handle;
|
||||
}
|
||||
@@ -42,6 +56,11 @@ public class VideoSink {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// Get the type of the sink.
|
||||
public Type getType() {
|
||||
return m_typeValues[CameraServerJNI.getSinkType(m_handle)];
|
||||
}
|
||||
|
||||
/// Get the name of the sink. The name is an arbitrary identifier
|
||||
/// provided when the sink is created, and should be unique.
|
||||
public String getName() {
|
||||
|
||||
@@ -11,6 +11,20 @@ package edu.wpi.cscore;
|
||||
/// consist of multiple images (e.g. from a stereo or depth camera); these
|
||||
/// are called channels.
|
||||
public class VideoSource {
|
||||
public enum Type {
|
||||
kUnknown(0), kUSB(1), kHTTP(2), kCv(4);
|
||||
private int value;
|
||||
|
||||
private Type(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
static final Type[] m_typeValues = Type.values();
|
||||
|
||||
protected VideoSource(int handle) {
|
||||
m_handle = handle;
|
||||
}
|
||||
@@ -42,6 +56,11 @@ public class VideoSource {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/// Get the type of the source.
|
||||
public Type getType() {
|
||||
return m_typeValues[CameraServerJNI.getSourceType(m_handle)];
|
||||
}
|
||||
|
||||
/// Get the name of the source. The name is an arbitrary identifier
|
||||
/// provided when the source is created, and should be unique.
|
||||
public String getName() {
|
||||
@@ -129,6 +148,17 @@ public class VideoSource {
|
||||
return CameraServerJNI.enumerateSourceVideoModes(m_handle);
|
||||
}
|
||||
|
||||
/// Enumerate all sinks connected to this source.
|
||||
/// @return Vector of sinks.
|
||||
public VideoSink[] enumerateSinks() {
|
||||
int[] handles = CameraServerJNI.enumerateSourceSinks(m_handle);
|
||||
VideoSink[] rv = new VideoSink[handles.length];
|
||||
for (int i=0; i<handles.length; i++) {
|
||||
rv[i] = new VideoSink(handles[i]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/// Enumerate all existing sources.
|
||||
/// @return Vector of sources.
|
||||
public static VideoSource[] enumerateSources() {
|
||||
|
||||
@@ -97,20 +97,20 @@ namespace cs {
|
||||
|
||||
CS_Sink CreateCvSink(llvm::StringRef name, CS_Status* status) {
|
||||
auto sink = std::make_shared<CvSinkImpl>(name);
|
||||
return Sinks::GetInstance().Allocate(SinkData::kCv, sink);
|
||||
return Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
|
||||
}
|
||||
|
||||
CS_Sink CreateCvSinkCallback(llvm::StringRef name,
|
||||
std::function<void(uint64_t time)> processFrame,
|
||||
CS_Status* status) {
|
||||
auto sink = std::make_shared<CvSinkImpl>(name, processFrame);
|
||||
return Sinks::GetInstance().Allocate(SinkData::kCv, sink);
|
||||
return Sinks::GetInstance().Allocate(CS_SINK_CV, sink);
|
||||
}
|
||||
|
||||
void SetSinkDescription(CS_Sink sink, llvm::StringRef description,
|
||||
CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data || data->type != SinkData::kCv) {
|
||||
if (!data || data->type != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ void SetSinkDescription(CS_Sink sink, llvm::StringRef description,
|
||||
|
||||
uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data || data->type != SinkData::kCv) {
|
||||
if (!data || data->type != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return 0;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ uint64_t GrabSinkFrame(CS_Sink sink, cv::Mat& image, CS_Status* status) {
|
||||
|
||||
std::string GetSinkError(CS_Sink sink, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data || data->type != SinkData::kCv) {
|
||||
if (!data || data->type != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return std::string{};
|
||||
}
|
||||
@@ -138,7 +138,7 @@ std::string GetSinkError(CS_Sink sink, CS_Status* status) {
|
||||
llvm::StringRef GetSinkError(CS_Sink sink, llvm::SmallVectorImpl<char>& buf,
|
||||
CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data || data->type != SinkData::kCv) {
|
||||
if (!data || data->type != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return llvm::StringRef{};
|
||||
}
|
||||
@@ -147,7 +147,7 @@ llvm::StringRef GetSinkError(CS_Sink sink, llvm::SmallVectorImpl<char>& buf,
|
||||
|
||||
void SetSinkEnabled(CS_Sink sink, bool enabled, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data || data->type != SinkData::kCv) {
|
||||
if (!data || data->type != CS_SINK_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,12 +157,12 @@ namespace cs {
|
||||
CS_Source CreateCvSource(llvm::StringRef name, const VideoMode& mode,
|
||||
CS_Status* status) {
|
||||
auto source = std::make_shared<CvSourceImpl>(name, mode);
|
||||
return Sources::GetInstance().Allocate(SourceData::kCv, source);
|
||||
return Sources::GetInstance().Allocate(CS_SOURCE_CV, source);
|
||||
}
|
||||
|
||||
void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ void PutSourceFrame(CS_Source source, cv::Mat& image, CS_Status* status) {
|
||||
void NotifySourceError(CS_Source source, llvm::StringRef msg,
|
||||
CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
@@ -181,7 +181,7 @@ void NotifySourceError(CS_Source source, llvm::StringRef msg,
|
||||
|
||||
void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ void SetSourceConnected(CS_Source source, bool connected, CS_Status* status) {
|
||||
void SetSourceDescription(CS_Source source, llvm::StringRef description,
|
||||
CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
@@ -203,7 +203,7 @@ CS_Property CreateSourceProperty(CS_Source source, llvm::StringRef name,
|
||||
int step, int defaultValue, int value,
|
||||
CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return -1;
|
||||
}
|
||||
@@ -216,7 +216,7 @@ CS_Property CreateSourcePropertyCallback(
|
||||
int maximum, int step, int defaultValue, int value,
|
||||
std::function<void(CS_Property property)> onChange, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return -1;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ void SetSourceEnumPropertyChoices(CS_Source source, CS_Property property,
|
||||
llvm::ArrayRef<std::string> choices,
|
||||
CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data || data->type != SourceData::kCv) {
|
||||
if (!data || data->type != CS_SOURCE_CV) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
19
src/Handle.h
19
src/Handle.h
@@ -71,16 +71,10 @@ class Handle {
|
||||
};
|
||||
|
||||
struct SourceData {
|
||||
enum Type {
|
||||
kUnknown = 0,
|
||||
kUSB,
|
||||
kHTTP,
|
||||
kCv
|
||||
};
|
||||
SourceData(Type type_, std::shared_ptr<SourceImpl> source_)
|
||||
SourceData(CS_SourceType type_, std::shared_ptr<SourceImpl> source_)
|
||||
: type{type_}, refCount{0}, source{source_} {}
|
||||
|
||||
Type type;
|
||||
CS_SourceType type;
|
||||
std::atomic_int refCount;
|
||||
std::shared_ptr<SourceImpl> source;
|
||||
};
|
||||
@@ -89,15 +83,10 @@ typedef StaticUnlimitedHandleResource<Handle, SourceData, Handle::kSource>
|
||||
Sources;
|
||||
|
||||
struct SinkData {
|
||||
enum Type {
|
||||
kUnknown = 0,
|
||||
kHTTP,
|
||||
kCv
|
||||
};
|
||||
explicit SinkData(Type type_, std::shared_ptr<SinkImpl> sink_)
|
||||
explicit SinkData(CS_SinkType type_, std::shared_ptr<SinkImpl> sink_)
|
||||
: type{type_}, refCount{0}, sourceHandle{0}, sink{sink_} {}
|
||||
|
||||
Type type;
|
||||
CS_SinkType type;
|
||||
std::atomic_int refCount;
|
||||
std::atomic<CS_Source> sourceHandle;
|
||||
std::shared_ptr<SinkImpl> sink;
|
||||
|
||||
@@ -696,7 +696,7 @@ CS_Sink CreateMJPEGServer(llvm::StringRef name, llvm::StringRef listenAddress,
|
||||
name, desc.str(),
|
||||
std::unique_ptr<wpi::NetworkAcceptor>(
|
||||
new wpi::TCPAcceptor(port, str.c_str(), Logger::GetInstance())));
|
||||
return Sinks::GetInstance().Allocate(SinkData::kHTTP, sink);
|
||||
return Sinks::GetInstance().Allocate(CS_SINK_MJPEG, sink);
|
||||
}
|
||||
|
||||
} // namespace cs
|
||||
|
||||
@@ -1360,7 +1360,7 @@ CS_Source CreateUSBCameraDev(llvm::StringRef name, int dev, CS_Status* status) {
|
||||
CS_Source CreateUSBCameraPath(llvm::StringRef name, llvm::StringRef path,
|
||||
CS_Status* status) {
|
||||
auto source = std::make_shared<USBCameraImpl>(name, path);
|
||||
return Sources::GetInstance().Allocate(SourceData::kUSB, source);
|
||||
return Sources::GetInstance().Allocate(CS_SOURCE_USB, source);
|
||||
}
|
||||
|
||||
std::vector<USBCameraInfo> EnumerateUSBCameras(CS_Status* status) {
|
||||
|
||||
@@ -55,6 +55,10 @@ class UnlimitedHandleResource {
|
||||
template <typename T>
|
||||
llvm::ArrayRef<T> GetAll(llvm::SmallVectorImpl<T>& vec);
|
||||
|
||||
// @param func functor with (THandle, const TStruct&) parameters
|
||||
template <typename F>
|
||||
void ForEach(F func);
|
||||
|
||||
private:
|
||||
THandle MakeHandle(size_t i) {
|
||||
return THandle{static_cast<int>(i),
|
||||
@@ -128,12 +132,19 @@ template <typename T>
|
||||
llvm::ArrayRef<T>
|
||||
UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::GetAll(
|
||||
llvm::SmallVectorImpl<T>& vec) {
|
||||
ForEach([&](THandle handle, const TStruct& data) { vec.push_back(handle); });
|
||||
return vec;
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, int typeValue, typename TMutex>
|
||||
template <typename F>
|
||||
void UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex>::ForEach(
|
||||
F func) {
|
||||
std::lock_guard<TMutex> sync(m_handleMutex);
|
||||
size_t i;
|
||||
for (i = 0; i < m_structures.size(); i++) {
|
||||
if (m_structures[i] != nullptr) vec.push_back(MakeHandle(i));
|
||||
if (m_structures[i] != nullptr) func(MakeHandle(i), *(m_structures[i]));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, int typeValue,
|
||||
|
||||
@@ -80,6 +80,10 @@ CS_Source CS_CreateHTTPCamera(const char* name, const char* url,
|
||||
return cs::CreateHTTPCamera(name, url, status);
|
||||
}
|
||||
|
||||
CS_SourceType CS_GetSourceType(CS_Source source, CS_Status* status) {
|
||||
return cs::GetSourceType(source, status);
|
||||
}
|
||||
|
||||
char* CS_GetSourceName(CS_Source source, CS_Status* status) {
|
||||
llvm::SmallString<128> buf;
|
||||
auto str = cs::GetSourceName(source, buf, status);
|
||||
@@ -168,6 +172,17 @@ CS_VideoMode* CS_EnumerateSourceVideoModes(CS_Source source, int* count,
|
||||
return out;
|
||||
}
|
||||
|
||||
CS_Sink* CS_EnumerateSourceSinks(CS_Source source, int* count,
|
||||
CS_Status* status) {
|
||||
llvm::SmallVector<CS_Sink, 32> buf;
|
||||
auto handles = cs::EnumerateSourceSinks(source, buf, status);
|
||||
CS_Sink* sinks =
|
||||
static_cast<CS_Sink*>(std::malloc(handles.size() * sizeof(CS_Sink)));
|
||||
*count = handles.size();
|
||||
std::copy(handles.begin(), handles.end(), sinks);
|
||||
return sinks;
|
||||
}
|
||||
|
||||
CS_Source CS_CopySource(CS_Source source, CS_Status* status) {
|
||||
return cs::CopySource(source, status);
|
||||
}
|
||||
@@ -176,6 +191,10 @@ void CS_ReleaseSource(CS_Source source, CS_Status* status) {
|
||||
return cs::ReleaseSource(source, status);
|
||||
}
|
||||
|
||||
CS_SinkType CS_GetSinkType(CS_Sink sink, CS_Status* status) {
|
||||
return cs::GetSinkType(sink, status);
|
||||
}
|
||||
|
||||
char* CS_GetSinkName(CS_Sink sink, CS_Status* status) {
|
||||
llvm::SmallString<128> buf;
|
||||
auto str = cs::GetSinkName(sink, buf, status);
|
||||
|
||||
@@ -152,6 +152,15 @@ CS_Source CreateHTTPCamera(llvm::StringRef name, llvm::StringRef url,
|
||||
// Source Functions
|
||||
//
|
||||
|
||||
CS_SourceType GetSourceType(CS_Source source, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return CS_SOURCE_UNKNOWN;
|
||||
}
|
||||
return data->type;
|
||||
}
|
||||
|
||||
std::string GetSourceName(CS_Source source, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data) {
|
||||
@@ -299,6 +308,20 @@ std::vector<VideoMode> EnumerateSourceVideoModes(CS_Source source,
|
||||
return data->source->EnumerateVideoModes(status);
|
||||
}
|
||||
|
||||
llvm::ArrayRef<CS_Sink> EnumerateSourceSinks(
|
||||
CS_Source source, llvm::SmallVectorImpl<CS_Sink>& vec, CS_Status* status) {
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
if (!data) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return llvm::ArrayRef<CS_Sink>{};
|
||||
}
|
||||
vec.clear();
|
||||
Sinks::GetInstance().ForEach([&](CS_Sink sinkHandle, const SinkData& data) {
|
||||
if (source == data.sourceHandle.load()) vec.push_back(sinkHandle);
|
||||
});
|
||||
return vec;
|
||||
}
|
||||
|
||||
CS_Source CopySource(CS_Source source, CS_Status* status) {
|
||||
if (source == 0) return 0;
|
||||
auto data = Sources::GetInstance().Get(source);
|
||||
@@ -325,6 +348,15 @@ void ReleaseSource(CS_Source source, CS_Status* status) {
|
||||
// Sink Functions
|
||||
//
|
||||
|
||||
CS_SinkType GetSinkType(CS_Sink sink, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data) {
|
||||
*status = CS_INVALID_HANDLE;
|
||||
return CS_SINK_UNKNOWN;
|
||||
}
|
||||
return data->type;
|
||||
}
|
||||
|
||||
std::string GetSinkName(CS_Sink sink, CS_Status* status) {
|
||||
auto data = Sinks::GetInstance().Get(sink);
|
||||
if (!data) {
|
||||
|
||||
@@ -21,6 +21,18 @@ std::vector<VideoProperty> VideoSource::EnumerateProperties() const {
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::vector<VideoSink> VideoSource::EnumerateSinks() {
|
||||
llvm::SmallVector<CS_Sink, 16> handles_buf;
|
||||
CS_Status status = 0;
|
||||
auto handles = EnumerateSourceSinks(m_handle, handles_buf, &status);
|
||||
|
||||
std::vector<VideoSink> sinks;
|
||||
sinks.reserve(handles.size());
|
||||
for (int handle : handles)
|
||||
sinks.emplace_back(VideoSink{handle});
|
||||
return sinks;
|
||||
}
|
||||
|
||||
std::vector<VideoSource> VideoSource::EnumerateSources() {
|
||||
llvm::SmallVector<CS_Source, 16> handles_buf;
|
||||
CS_Status status = 0;
|
||||
|
||||
Reference in New Issue
Block a user