Web Streaming

<< 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

 

Conversion/Compression

First a converter has to be created with CVB, which holds the configuration of the image conversion.

 

Valid Inputformats:

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.

 

Output formats:

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.

 

Example (with Jpeg compression):

 

 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

 

Transport 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.

 

Example (websocket with the converter from above):

 

 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");

 

Streaming

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.

 

Example (with sync sending):

 

 IMG image = nullptr; // we assume this image has been initialized and filled ...

 // ...

 if (CVWSStreamingSyncSendImage(server, image) == 0)

 {

         // success

 }

 else

 {

         // error

 }

 

Receiving images

The CVB Webstreaming implementation does NOT provide a client for receiving. This is a deliberate choice. There are multiple easily available APIs for Websockets.

 

Example (Javascript, not a complete example):

 

 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) {

                 // ...

         };

 }

 

Example (C++ with boost::beast)

 

 #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();

 }

 

Object lifetime

 

The server and converter must be released after usage, to avoid leaked handles.

 

 if (server)

  ReleaseObject(server);

 if (converter)

   ReleaseObject(converter);

 

API / Library location

 

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/