Add Axis camera creation functions and Http camera NT publishing. (#420)

This commit is contained in:
Peter Johnson
2016-12-24 21:05:08 -06:00
committed by GitHub
parent dc9a9e5d96
commit 4800c201e4
4 changed files with 359 additions and 56 deletions

View File

@@ -84,6 +84,100 @@ class CameraServer : public ErrorBase {
*/
void StartAutomaticCapture(const cs::VideoSource& camera);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const char* host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const std::string& host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String[])} with
* name "Axis Camera".
*
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(llvm::ArrayRef<std::string> hosts);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String[])} with
* name "Axis Camera".
*
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(std::initializer_list<T> hosts);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, llvm::StringRef host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, const char* host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, const std::string& host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name,
llvm::ArrayRef<std::string> hosts);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(llvm::StringRef name,
std::initializer_list<T> hosts);
/**
* Get OpenCV access to the primary camera feed. This allows you to
* get images from the camera for image processing on the roboRIO.
@@ -176,6 +270,7 @@ class CameraServer : public ErrorBase {
CameraServer();
std::shared_ptr<ITable> GetSourceTable(CS_Source source);
std::vector<std::string> GetSinkStreamValues(CS_Sink sink);
void UpdateStreamValues();
static constexpr char const* kPublishName = "/CameraPublisher";
@@ -193,3 +288,5 @@ class CameraServer : public ErrorBase {
};
} // namespace frc
#include "CameraServer.inc"

View File

@@ -0,0 +1,30 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <string>
#include <vector>
namespace frc {
template <typename T>
inline cs::AxisCamera CameraServer::AddAxisCamera(
std::initializer_list<T> hosts) {
return AddAxisCamera("Axis Camera", hosts);
}
template <typename T>
inline cs::AxisCamera CameraServer::AddAxisCamera(
llvm::StringRef name, std::initializer_list<T> hosts) {
std::vector<std::string> vec;
vec.reserve(hosts.size());
for (const auto& host : hosts) vec.emplace_back(host);
return AddAxisCamera(name, vec);
}
} // namespace frc

View File

@@ -34,7 +34,8 @@ static llvm::StringRef MakeSourceValue(CS_Source source,
case cs::VideoSource::kHttp: {
llvm::StringRef prefix{"ip:"};
buf.append(prefix.begin(), prefix.end());
// TODO
auto urls = cs::GetHttpCameraUrls(source, &status);
if (!urls.empty()) buf.append(urls[0].begin(), urls[0].end());
break;
}
case cs::VideoSource::kCv:
@@ -61,41 +62,78 @@ std::shared_ptr<ITable> CameraServer::GetSourceTable(CS_Source source) {
return m_tables.lookup(source);
}
std::vector<std::string> CameraServer::GetSinkStreamValues(CS_Sink sink) {
CS_Status status = 0;
// Ignore all but MjpegServer
if (cs::GetSinkKind(sink, &status) != CS_SINK_MJPEG)
return std::vector<std::string>{};
// Get port
int port = cs::GetMjpegServerPort(sink, &status);
// Generate values
std::vector<std::string> values;
auto listenAddress = cs::GetMjpegServerListenAddress(sink, &status);
if (!listenAddress.empty()) {
// If a listen address is specified, only use that
values.emplace_back(MakeStreamValue(listenAddress, port));
} else {
// Otherwise generate for hostname and all interface addresses
values.emplace_back(MakeStreamValue(cs::GetHostname() + ".local", port));
for (const auto& addr : m_addresses) {
if (addr == "127.0.0.1") continue; // ignore localhost
values.emplace_back(MakeStreamValue(addr, port));
}
}
return values;
}
static std::vector<std::string> GetSourceStreamValues(CS_Source source) {
CS_Status status = 0;
// Ignore all but HttpCamera
if (cs::GetSourceKind(source, &status) != CS_SOURCE_HTTP)
return std::vector<std::string>{};
// Generate values
auto values = cs::GetHttpCameraUrls(source, &status);
for (auto& value : values) value = "mjpg:" + value;
// Set table value
return values;
}
void CameraServer::UpdateStreamValues() {
std::lock_guard<std::mutex> lock(m_mutex);
// Over all the sinks...
for (const auto& i : m_sinks) {
CS_Status status = 0;
// Ignore all but MjpegServer
if (i.second.GetKind() != cs::VideoSink::kMjpeg) continue;
CS_Sink sink = i.second.GetHandle();
// Get the source's subtable (if none exists, we're done)
CS_Source source = cs::GetSinkSource(sink, &status);
auto table = m_tables.lookup(source);
if (!table) continue;
// Get port
int port = cs::GetMjpegServerPort(sink, &status);
// Generate values
std::vector<std::string> values;
auto listenAddress = cs::GetMjpegServerListenAddress(sink, &status);
if (!listenAddress.empty()) {
// If a listen address is specified, only use that
values.emplace_back(MakeStreamValue(listenAddress, port));
} else {
// Otherwise generate for hostname and all interface addresses
values.emplace_back(MakeStreamValue(cs::GetHostname() + ".local", port));
for (const auto& addr : m_addresses) {
if (addr == "127.0.0.1") continue; // ignore localhost
values.emplace_back(MakeStreamValue(addr, port));
}
if (table) {
// Set table value
auto values = GetSinkStreamValues(sink);
if (!values.empty()) table->PutStringArray("streams", values);
}
}
// Set table value
table->PutStringArray("streams", values);
// Over all the sources...
for (const auto& i : m_sources) {
CS_Source source = i.second.GetHandle();
// Get the source's subtable (if none exists, we're done)
auto table = m_tables.lookup(source);
if (table) {
// Set table value
auto values = GetSourceStreamValues(source);
if (!values.empty()) table->PutStringArray("streams", values);
}
}
}
@@ -129,7 +167,8 @@ CameraServer::CameraServer()
cs::GetSourceDescription(event.sourceHandle, descBuf, &status));
table->PutBoolean("connected", cs::IsSourceConnected(
event.sourceHandle, &status));
table->PutStringArray("streams", std::vector<std::string>{});
table->PutStringArray("streams",
GetSourceStreamValues(event.sourceHandle));
break;
}
case cs::VideoEvent::kSourceDestroyed: {
@@ -227,6 +266,50 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(llvm::StringRef name,
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(const char* host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(const std::string& host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::ArrayRef<std::string> hosts) {
return AddAxisCamera("Axis Camera", hosts);
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
llvm::StringRef host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
const char* host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
const std::string& host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
llvm::ArrayRef<std::string> hosts) {
cs::AxisCamera camera{name, hosts};
AddCamera(camera);
return camera;
}
void CameraServer::StartAutomaticCapture(const cs::VideoSource& camera) {
llvm::SmallString<64> name{"serve_"};
name += camera.GetName();