<< Click to Display Table of Contents >> Navigation: Image Manager > CVB Technology > Web Streaming |
CVB Webstreaming is a modular library for image conversion/compression and image transport.
The 2 modules are:
•A converter
•A transport server
First a converter has to be created with CVB, which holds the configuration of the image conversion.
•Mono 8 bit
•RGB 8 bit
•Mono 16 bit*
•RGB 16 bit*
*These image formats will be automatically converted to the corresponding 8 bit variant.
•Raw (i.e. no conversion/compression)
•RGBA 8 bit (this essentially causes data bloat, but is useful for displaying the images)
•Jpeg
•(more formats are in development, such as h265)
The API for the converter does NOT allow passing images to the converter directly, this is internally done via the transport server.
The API for the converter does NOT grant access to the converted images. Instead the converter is passed to the transport server (i.e. shared ownership), who controls the converter.
CVWSCONVERTER converter = nullptr;
if (CVWSCreateConverter(CVWSCT_Jpeg, converter) != 0)
throw std::runtime_error("no converter created");
NOTE: Each converter should only be passed to one server
The image transport is handled via the server.
Currently the each server will use the websocket technology for transporting data. More transport technologies are in development, such as RTP.
At creation the server will need all needed information regarding the transport of data as well as the previously created converter.
CVWSSERVER server = nullptr;
std::string ip = "127.0.0.1";
int port = 1112;
if (CVWSCreateServer(ip.c_str(), port, converter, server) != 0)
throw std::runtime_error("no server created");
With the created server and the acquired image(s), the user may start synchronous or asynchronous streaming.
With the synchronous streaming the function will return once the images was successfully transmitted.
Using the asynchronous streaming, the user does not know, when the image is sent.
The image handle given to the sending function can be discarded after the call, i.e. the server either has made a copy or has finished compression/conversion.
In other words the compression/conversion is always synchronous.
IMG image = nullptr; // we assume this image has been initialized and filled ...
// ...
if (CVWSStreamingSyncSendImage(server, image) == 0)
{
// success
}
else
{
// error
}
The CVB Webstreaming implementation does NOT provide a client for receiving. This is a deliberate choice. There are multiple easily available APIs for Websockets.
function connect(ipAdress, port) {
let portPrefix = ":";
let wsPrefix = "ws://";
let desiredServerAdress = wsPrefix + ipAdress + portPrefix + port;
websocket = new WebSocket(desiredServerAdress);
websocket.onopen = function(evt) {
// ...
};
websocket.onclose = function(evt) {
// ...
};
websocket.onmessage = function(evt) {
// here you can handle a new image
};
websocket.onerror = function(evt) {
// ...
};
}
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
namespace beast = boost::beast;
namespace http = beast::http;
namespace websocket = beast::websocket;
namespace asio = boost::asio;
class WebSocketExample
{
private:
using SocketPtr = std::unique_ptr<websocket::stream<boost::asio::ip::tcp::socket>>;
asio::io_context ioc;
SocketPtr socket_;
public:
WebSocketExample(std::string host = "localhost", int port = 1112)
{
socket_ = std::make_unique<websocket::stream<boost::asio::ip::tcp::socket>>(ioc);
boost::asio::ip::tcp::resolver resolver{ioc};
auto const results = resolver.resolve(host, std::to_string(port));
asio::connect(socket_->next_layer(), results.begin(), results.end());
socket_->set_option(websocket::stream_base::decorator([](websocket::request_type &req) {
req.set(http::field::user_agent, std::string(BOOST_BEAST_VERSION_STRING) + " websocketclient");
}));
socket_->handshake(host, "/");
}
std::vector<uint8_t> Read()
{
beast::flat_buffer buffer;
// read data
socket_->read(buffer);
auto data = reinterpret_cast<uint8_t *>(buffer.data().data());
// copy data
std::vector<uint8_t> out(data, data + buffer.data().size());
return out;
}
};
int main()
{
WebSocketExample e("localhost", 1112);
auto buffer = e.Read();
}
The server and converter must be released after usage, to avoid leaked handles.
if (server)
ReleaseObject(server);
if (converter)
ReleaseObject(converter);
Header:
•Windows
iCVWebStreaming.h, found in %CVB%include
•Linux
iCVWebStreaming.h, found in $CVB/include
Library:
•Windows
CVWebStreaming.dll, found in %CVB%
CVWebStreaming.lib, found in %CVB%Lib\C
•Linux
libCVWebStreaming.so, found in $CVB/lib/