This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Agile Content

1 - Agile Live

Agile Live Product Documentation

1.1 - Overview

High-level overview of the system and its components

Agile Live is a software-based platform for production of media using standard, off-the-shelf hardware and datacenter building blocks.

The Agile Live system consists of multiple software components, distributed geographically between recording studios, remote production control rooms and datacenters.

All Agile Live components have the same understanding of the time ‘now’. The time reference used by all software components is TAI (Temps Atomique International), which provides a monotonically, steady time reference no matter the geographic location.

This makes it possible to compensate for differences in relative delay between the media streams. The synchronized timing makes the system unique compared to other solutions usually bound to buffer levels and various queueing mechanisms.

The synchronization of the streams transported over networks with various delays makes it possible to build a distributed production environment, where the mixing of the video and audio sources can take place at a different location compared to the studio where they were captured.

System overview

Agile Live components

Media sources, such as video cameras and microphones, are connected to a computer called Ingest. In practice, this will usually be some kind of off-the-shelf desktop computer, potentially equipped with a frame grabber card to allow physical input interfaces such as SDI cables, but it could also be a smartphone with a dedicated app using the built-in camera.

The Ingest is responsible for receiving the media data from the source, encode it and transport it using a network to the production environment inside the cloud/datacenter.

From the datacenter the remote production team can get multi-view streams of the available media sources to base their production decisions on, as well as a low-delay feedback display showing the result of the production.

The production in the datacenter will also output a high quality program output, which is broadcast to the viewers. Both the multi-views and the feedback display will usually have a lower quality compared to the high quality program output that is broadcast to the viewers. This is to allow an as short as possible end-to-end delay between what happens in front of the cameras in the studio and the output stream on the feedback display.

This in turn allows for feedback loops back to the studio, for instance for video cameras that are remotely controlled by the production team based on what they see on the multi-views, or having additional feedback displays in the studio.

1.2 - Introduction to Agile Live technology

An introduction to the technology that makes up the Agile Live platform and solution, and how it all fits together

Agile Live is a software-based platform and solution for live media production that enables remote and distributed workflows in software running on standard, off-the-shelf hardware. It can be deployed on-premises or in private or public cloud.

The system is built with an ‘API first’ philosophy throughout. It is built in several stacked conceptual layers, and a customer may choose how many layers to include in their solution, depending on which customisations they wish to do themselves. It is implemented in a distributed manner with a number of different software binaries the customer is responsible for running on their own hardware and operating system. If using all layers, the full solution provides media capture, synchronised contribution, video & audio mixing including Digital Video Effects and HTML-based graphics overlay, various production control panel integrations and a fully customisable multiview, primary distribution and a management & orchestration API layer with a configuration & monitoring GUI on top of it.

The layers of the platform are the “Base Layer”, the “Rendering Engine & Generic Control Panels” layer and the “GUIs & Orchestration, Specific Control Panels” layer.

Agile Live Layers

The base layer

The base layer of the platform can in a very simplified way be described as being responsible for transporting media of diverse types from many different locations into a central location in perfect sync, present it there to higher layer software that processes it in some way, and to distribute the end result. This piece of software, which is not a part of the base layer, is referred to as a “rendering engine”. The base layer also carries control commands from remote control panels into the rendering engine, without having any knowledge of the actual control command syntax.

The following image shows a schematic of the roles played by the base layer. The parts in blue are higher layer functionality.

Base Layer

The base layer is separated into three components based on their different roles in a distributed computing system:

  • the Ingest component handles acquisition of the media sources and timestamping of media frames, followed by encoding, muxing and origination of reliable transport over unreliable networks using SRT or RIST
  • the Production Pipeline component handles terminating all incoming media streams from ingests, demuxing and decoding, aligning all the sources according to timestamps and feeding them synchronously into the rendering engine. It also receives the resulting media frames from the rendering engine and encodes, muxes and streams out the media streams using MPEG-TS over UDP or SRT. It constructs a multiview from the aligned sources by fully customizable scaling and compositing. Finally, it receives control commands from the control panel component, aligns them in time with the media sources and feeds them into the rendering engine. NOTE that the rendering engine is NOT a part of the base layer, and must be supplied by a higher layer or by the implementer themselves.
  • The control panel component is responsible for acquiring control command data (the internal syntax of which it has no knowledge of), timestamp it, and send it to the production pipeline component.

The base layer is delivered as libraries and header files, to be used to build binaries that make up the platform. The ingest component is for convenience also delivered as a precompiled binary named acl-ingest as there is very little customization to be done around it at the current moment.

The functionalities in the base layer are managed via a REST API. A separate software program called the System Controller acts as a REST service and communicates with the rest of the Base Layer software to control and monitor it. The REST API is Open API 2.0 compliant, and is documented here. Apart from the three components (ingest, production pipeline, controlpanel), the concepts of a Stream (transporting one source from one ingest to one production pipeline using one specific set of properties) and a controlconnection (transporting control commands from one control panel to one production pipeline or from one production pipeline to another) are central to the REST API.

The rendering engine and generic control panels layer

Though it is fully possible to use only the base layer and to build everything else yourself, a very capable version of a rendering engine is supplied. Our rendering engine implementation consists of a modular video mixer, an audio router and mixer, an interface towards 3rd party audio mixers, and an HTML renderer to overlay HTML-based graphics. It defines a control protocol for configuration and control which can be used by specific control panel implementations.

The rendering engine is delivered bundled with the production pipeline component as a binary named acl-renderingengine. This is because the production pipeline component from the base layer is only delivered as a library that the rendering engine implementation makes use of.

Communication with the rendering engine for configuration and control takes place over the control connections from control panels, as provided by the base layer. The control panels are contructed by using the control panel library, but to assist in getting up and running fast, a few generic control panels are provided, that will act as proxies for control commands. There is one that sets up a TCP server and accepts control commands over connections to it, and another one that acts as a websocket server for the same purpose. Finally there is one that takes commands over stdin from a terminal session forwards control commands.

The GUI and orchestration layer

On top of the REST API it is possible to build GUIs for configuring and monitoring the system. One default GUI is provided.

Prometheus-exporters can be configured to report on the details of the machines in the system, and there is also an exporter for the REST API statistics. The data in Prometheus can then be presented in Grafana.

Using the control command protocol defined by our rendering engine and either the generic control panels or custom control panel integrations, GUIs can be constructed to configure and control the components inside the rendering engine. For example, Bitfocus Companion can be configured to send control commands to the tcpcontrolpanel which will send them further into the system. The custom integration audio_control_gui can be used to interface with audio panels that support the Mackie Control protocol and to send control commands to the tcpcontrolpanel.

Direct editing mode vs proxy editing mode

The components of the Agile Live platform can be combined in many different ways. The two most common ways is the Direct Editing Mode and the Proxy Editing Mode. The direct editing mode is what has commonly been done for remote productions, where the mixer operator edits directly in the flow that goes out to the viewer.

Direct editing mode

In the proxy editing mode, the operator works with a low delay but lower quality flow, makes mixing decisions, and then those decisions are replicated in a frame accurate manner on a high quality flow that is delayed in time.

Proxy editing mode

There are good reasons for using a proxy editing mode. The mixer operator may be communicating via intercom with personnel at the venue, such as camera operators, or PTZ cameras may be operated remotely. In these cases it is important that the delay from the cameras to the production pipeline and out to the mixer operator is as short as possible. But having a low latency for this flow goes in direct opposition to having a high quality video compression and a very reliable transport. Therefore, in the proxy editing mode, we have both a low delay workflow and a high quality but slower workflow. This way both requirements can be satisfied. This technique is made possible by the synchronization functionalities of the base layer platform.

1.3 - Installation and configuration

How to install and configure the system and its dependencies

A working knowledge of the technical basis of the Agile Live solution is beneficial before starting with this installation guide.

This guide will often point to subpages for the detailed description of steps. The major steps of this guide are:

  1. Hardware and operating system requirements
  2. Install, configure and start the System Controller
  3. The base platform components
    1. Install prerequisites
    2. Preparing the base system for installation
    3. Install Agile Live platform
    4. Configure and start the Agile Live components
  4. Install the configuration-and-monitoring GUI (optional)
  5. Install Prometheus and Grafana, and configure them (optional)
  6. Install and start control panel GUI examples

1. Hardware and operating system requirements

The bulk of the platform runs on computer systems based on x86 CPUs and running the Ubuntu 22.04 operating system. This includes the following software components: the ingest, the production pipeline, the control panel integrations, and the system controller. The remaining components, i.e. the configuration and monitoring GUI, the control panel GUI examples, and the Prometheus database and Grafana frontend can be run in the platform of choice, as they are cross platform.

The platform does not have explicit hardware performance requirements, as it will utilize the performance of the system it is given, but suggestions for hardware specifications can be found here.

Agile Live is supported and tested on Ubuntu 22.04 LTS. Other versions may work but are not officially supported.

2. Install, configure and start the System Controller

The System Controller is the central backend that ties together and controls the different components of the base platform, and that provides the REST API that is used by the user to configure and monitor the system. When each Agile Live component, such as an Ingest or a Production Pipeline, starts up it connects to and registers with the System Controller, so it is a good idea to install and configure the System Controller first.

Instructuctions on how to install and configure it can be found here.

3. The base platform components

The base platform consists of the software components Ingests, Production Pipelines, and Control Panel interfaces. Each machine that is intended to act as an aquisition device for media shall run exactly one instance of the Ingest application, as it is responsible for interfacing with third party software such as SDKs for SDI cards and NDI.

The production pipeline application instance (interchangably called a rendering engine application instance in parts of this documentation) uses the resources of its host machine in a non-exclusive way (including the GPU), so there may therefore reside more than one instance on a single host machine.

The control panel integrations preferably reside on a machine close to the actual control panel.

However, in a very minimal system not all of these machines need to be separate; in fact, all the above could run on a single computer if so is desired.

A guide to installing and configuring the Agile Live base platform can be found here.

4. Install the configuration-and-monitoring GUI (optional)

There is a basic configuration-and-monitoring GUI that is intended to be used as an easy way to get going with using the system. It uses the REST API to configure and monitor the system.

Instructions for how to install it can be found here and a tutorial for how to use it can be found here

5. Install Prometheus and Grafana, and configure them (optional)

To collect useful system metrics for stability and performance monitoring, we advise to use Prometheus. For visualizing the metrics collected by Prometheus you could use Grafana.

The System controller receives a lot of internal metrics from the Agile Live components. These can be pulled by a Prometheus instance from the endpoint https://system-controller-host:port/metrics.

It is also possible to install external exporters for various hardware and OS metrics.

To install and run prometheus exporters on the servers that run ingest and production pipeline software, as well as installing, configuring and running the Prometheus database and the associated Grafana instance on the server dedicated to management and orchestration, follow this guide.

6. Install and start control panel GUI examples

To install the example control panel GUIs that are delivered as source code, follow this guide.

1.3.1 - Hardware examples

Agile Live hardware examples

The following hardware specifications serve as examples of how much can be expected from certain hardware setups. The maximum number of inputs and outputs are highly dependent on the quality and resolution settings chosen when setting up a production, so these numbers shall be seen as approximations of what can be expected from a certain hardware under some form of normal use.

Hardware example #1

System Specifications
CPUIntel Core i7 12700K
RAMKingston FURY Beast 32GB (2x16GB) 3200MHz CL16 DDR4
Graphics CardNVIDIA RTX A2000 12GB
PSU750W PSU
MotherboardASUS Prime H670-Plus D4 DDR4 S-1700 ATX
SSDSamsung 980 NVMe M.2 1TB SSD
Capture Card (Ingest only)Blackmagic Design Decklink Duo 2

One such server is capable of fulfilling either of the two use-cases below:

  • Ingest server
    • With Proxy editing: ingesting 4 sources (encoded as 4 Low Delay streams, AVC 720p50 1 Mbps and 4 High Quality streams, HEVC 1080p50 25 Mbps).
    • With Direct editing: ingesting 6 sources, (HEVC 1080p50 25 Mbps).
  • Production server, running both a High Quality and a Low Delay pipeline with at least 10 connected sources (i.e. at least 20 incoming streams), with at least one 1080p50 multi-view output, one 1080p High Quality program output and one 720p Low Delay output.

Hardware example #2

System Specifications
CPUIntel Core i7 12700K
RAMKingston FURY Beast 32GB (2x16GB) 6000MHz CL36 DDR5
Graphics CardNVIDIA RTX 4000 SFF Ada Generation 20GB
PSU750W PSU
MotherboardASUS ROG Maximus Z690 Hero DDR5 ATX
SSDWD Blue SN570 M.2 1TB SSD
Capture Card (Ingest only)Blackmagic Design Decklink Quad 2

One such server is capable of fulfilling either of the two use-cases below:

  • Ingest server
    • With Proxy editing: ingesting 6-8 sources (encoded as 6-8 Low Delay streams, AVC 720p50 1 Mbps and 6-8 High Quality streams, HEVC 1080p50 25 Mbps).
    • With Direct editing: ingesting 8-10 sources (HEVC 1080p50 25 Mbps).
  • Production server, running both the High Quality and the Low Delay pipeline with at least 20 connected sources (i.e. at least 40 incoming streams), with at least three 4K multi-view outputs, four 1080p High Quality outputs and four 720p Low Delay outputs.

1.3.2 - The System Controller

Installing and configuring the System Controller

The System Controller is the central backend that ties together and controls the different components of the base platform, and that provides the REST API that is used by the user to configure and monitor the system.

When each Agile Live component (such as an Ingest or a Production Pipeline) starts up, it connects to and registers with the System Controller. This means the System Controller must run in a network location that is reachable from all other components.

From release 6.0.0 and on, the System Controller is distributed as a debian package, acl-system-controller. To install the System Controller application, do the following:

sudo apt -y install acl-system-controller_<version>_amd64.deb

The System Controller binary will be installed in the directory /opt/agile_live/bin/ and its configuration file will be placed in /etc/opt/agile_live/.

The System Controller is configured either using a settings file or using environment variables, or a combination thereof. The settings file, named acl_sc_settings.json, is searched for in /etc/opt/agile_live and current directory, or the search path can be pointed to using a flag on the command line when starting the application:

./acl-system-controller for default search paths or ./acl-system-controller -settings-path /path/to/directory/where/settings_file/exists

To use environment variables overriding settings from the configuration file, construct the variables from the json objects in the settings file by prepending with ACL_SC and then the json object flattened out with _ as the delimiter, e.g.:

export ACL_SC_LOGGER_LEVEL=debug
export ACL_SC_PROTO=https

Starting with the basic configuration file in the release, edit a few settings inside it (see this guide for help with the security related parameters):

  • change the psk parameter to something random of your own
  • change the salt to some long string of your own
  • set the username and password to protect the REST API
  • specify TLS certificate and key files
  • set the host and port parameters to where the System Controller shall be reached

Also consider setting the file_name_prefix to set the log file location, otherwise it defaults to /tmp/.

From the installation directory, the System Controller is started with:

./acl-system-controller

If started successfully, it will display a log message showing the server endpoint.

The System Controller comes with built-in Swagger documentation that makes it easy to explore the API in a regular web browser. To access the Swagger REST API documentation hosted by the System Controller, open https://<IP>:<port>/swagger/ in your browser. The Swagger UI can be used to poll or edit the state of the actual system by using the “Try it out” buttons.

Running the System Controller as a service

It may be useful to run the System Controller as a service in Ubuntu, so that it starts automatically on boot and restarts if it terminates abnormally. In Ubuntu 22.04 systemd manages the services. Here follows an example of how a service can be configured, started and monitored.

First create a “service unit file”, named for example /etc/systemd/system/acl-system-controller.service and put the following in it:

[Unit]
Description=Agile Live System Controller service

[Service]
User=<YOUR_USER>
Environment=<ANY_ENV_VARS_HERE>
ExecStart=/opt/agile_live/bin/acl-system-controller
Restart=always

[Install]
WantedBy=multi-user.target

Replace <YOUR_USER> with the user that will be executing the System Controller binary on the host machine. The Environment attribute is used if you want to set any parameters as environment variables.

After saving the service unit file, run:

sudo systemctl daemon-reload
sudo systemctl enable acl-system-controller.service
sudo systemctl start acl-system-controller

The service should now be started. The status of the service can be queried using:

sudo systemctl status acl-system-controller.service

1.3.3 - The base platform

Installation instructions for the base platform

This page describes the steps needed to install and configure the base platform.

Install Third-party packages

Agile Live has a few dependencies on third party software that have to be installed separately first. Which ones are needed depends on the component of Agile Live that you will be running on the specific system.

A machine running the Ingest needs the following:

  • CUDA Toolkit
  • oneVPL
  • Blackmagic Desktop Video (Optional, is needed when using Blackmagic DeckLink SDI cards)
  • NDI SDK for Linux
  • Base packages via ‘apt’

A machine running the Rendering Engine only needs a subset:

  • CUDA Toolkit
  • Base packages via ‘apt’

A machine running control panels needs yet fewer:

  • Base packages via ‘apt’

CUDA Toolkit

For video encoding and decoding on NVidia GPUs you need Nvidia CUDA Toolkit installed. It must be installed on Ingest machines even if they don’t have Nvidia cards.

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb

sudo apt update
sudo apt -y install cuda

You need to reboot the system after installation. Then check the installation by running nvidia-smi. If installing more dependencies, it is ok to proceed with that and reboot once after installing all parts.

oneVPL

All machines running the Ingest application need the Intel oneAPI Video Processing Library (oneVPL) installed. It is used for encoding and thumbnail processing on Intel GPUs and is required even for Ingests which will not use the Intel GPU for encoding. Install oneVPL by running:

sudo apt install -y gpg-agent wget

# Download and run oneVPL offline installer:
# https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#onevpl
VPL_INSTALLER=l_oneVPL_p_2023.1.0.43488_offline.sh
wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/e2f5aca0-c787-4e1d-a233-92a6b3c0c3f2/$VPL_INSTALLER
chmod +x $VPL_INSTALLER
sudo ./$VPL_INSTALLER -a -s --eula accept

# Install the latest general purpose GPU (GPGPU) run-time and development software packages
# https://dgpu-docs.intel.com/driver/client/overview.html

wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | \
  sudo gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu jammy arc' | \
  sudo tee  /etc/apt/sources.list.d/intel.gpu.jammy.list
sudo apt update
sudo apt install -y ffmpeg intel-media-va-driver-non-free libdrm2 libmfx-gen1.2 libva2

# Add VA environment variables
if [[ -z "${LIBVA_DRIVERS_PATH}" ]]; then
  sudo sh -c "echo 'LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri' >> /etc/environment"
fi
if [[ -z "${LIBVA_DRIVER_NAME}" ]]; then
  sudo sh -c "echo 'LIBVA_DRIVER_NAME=iHD' >> /etc/environment"
fi

# Give users access to the GPU device for compute and render node workloads
# https://www.intel.com/content/www/us/en/develop/documentation/installation-guide-for-intel-oneapi-toolkits-linux/top/prerequisites/install-intel-gpu-drivers.html
sudo usermod -aG video,render ${USER}

# Set environment variables for development
echo "# oneAPI environment variables for development" >> ~/.bashrc
echo "source /opt/intel/oneapi/setvars.sh > /dev/null" >> ~/.bashrc

You need to reboot the system after installation. If installing more dependencies, it is ok to proceed with that and reboot once after installing all parts.

Support for Blackmagic Design SDI grabber cards

If the Ingest shall be able to use Blackmagic DeckLink SDI cards, the drivers need to be installed.

Download https://www.blackmagicdesign.com/se/support/family/capture-and-playback (Desktop Video).

Unpack and install (Replace all commands with the version you downloaded):

sudo apt install dctrl-tools dkms
tar -xvf Blackmagic_Desktop_Video_Linux_12.7.tar.gz
cd Blackmagic_Desktop_Video_Linux_12.7/deb/x86_64
sudo dpkg -i desktopvideo_12.7a4_amd64.deb

Support for NDI sources

For machines running Ingests, you need to install the NDI library and additional dependencies:

## Install library
sudo apt -y install avahi-daemon avahi-discover avahi-utils libnss-mdns mdns-scan
wget https://downloads.ndi.tv/SDK/NDI_SDK_Linux/Install_NDI_SDK_v5_Linux.tar.gz
tar -xvzf Install_NDI_SDK_v5_Linux.tar.gz
PAGER=skip-pager ./Install_NDI_SDK_v5_Linux.sh <<< y
cd NDI\ SDK\ for\ Linux/lib/x86_64-linux-gnu/
NDI_LIBRARY_FILE=$(ls libndi.so.5.*.*)
cd ../../..
sudo cp NDI\ SDK\ for\ Linux/lib/x86_64-linux-gnu/${NDI_LIBRARY_FILE} /usr/lib/x86_64-linux-gnu
sudo ln -fs /usr/lib/x86_64-linux-gnu/${NDI_LIBRARY_FILE} /usr/lib/x86_64-linux-gnu/libndi.so
sudo ln -fs /usr/lib/x86_64-linux-gnu/${NDI_LIBRARY_FILE} /usr/lib/x86_64-linux-gnu/libndi.so.5
sudo ldconfig
sudo cp NDI\ SDK\ for\ Linux/include/* /usr/include/.

Base packages installed via ‘apt’

When installing version 5.0.0 or earlier, please refer to this guide for this step.

All systems that run an Ingest, Rendering Engine or Control Panel need chrony as NTP client. The systemd-coredump package is also really handy to have installed to be able to debug core dumps later on, but is technically optional.

These packages can be installed with the apt package manager:

sudo apt -y update && sudo apt -y upgrade && sudo apt -y install chrony systemd-coredump

Preparing the base system for installation

To prepare the system for Agile Live, the NTP client must be configured correctly by following this guide, and some general Linux settings shall be configured by following this guide. Also, CUDA should be prevented from automatically installing upgrades by following this guide.

Installing the Agile Live components

When installing version 5.0.0 or earlier, please refer to this guide for this step.

The following Agile Live .deb packages are distributed:

  • acl-system-controller - Contains the System Controller application (explained in separate section)
  • acl-libingest - Contains the library used by the Ingest application
  • acl-ingest - Contains the Ingest application
  • acl-libproductionpipeline - Contains the libraries used by the Rendering Engine application
  • acl-renderingengine - Contains Agile Live’s default Rendering Engine application
  • acl-libcontroldatasender - Contains the libraries used by Control Panel applications
  • acl-controlpanels - Contains the generic Control Panel applications
  • acl-dev - Contains the header files required for development of custom Control Panels and Rendering Engines

All binaries will be installed in the directory /opt/agile_live/bin. Libraries are installed in /opt/agile_live/lib. Header files are installed in /opt/agile_live/include.

Ingest

To install the Ingest application, install the following .deb-packages:

sudo apt -y install ./acl-ingest_<version>_amd64.deb ./acl-libingest_<version>_amd64.deb

Rendering engine

To install the Rendering Engine application, install the following .deb-packages:

sudo apt -y install ./acl-renderingengine_<version>_amd64.deb ./acl-libproductionpipeline_<version>_amd64.deb

Control panels

To install the generic Control Panel applications acl-manualcontrolpanel, acl-tcpcontrolpanel and acl-websocketcontrolpanel, install the following .deb-packages:

sudo apt -y install ./acl-controlpanels_<version>_amd64.deb ./acl-libcontroldatasender_<version>_amd64.deb

Dev

To install the acl-dev package containing the header files needed for building your own applications, install the following .deb-package:

sudo apt -y install ./acl-dev_<version>_amd64.deb

Configuring and starting the Ingest(s)

The Ingest component is a binary which ingests raw video input sources such as SDI or NDI, timestamps, processes, encodes and originates transport to the rest of the platform.

Settings for the ingest binary are added as environment variables. There is one setting that must be set:

  • ACL_SYSTEM_CONTROLLER_PSK shall be set to the same as in the settings file of the System Controller

Also, there are some parameters that have default settings that you will most probably want to override:

  • ACL_SYSTEM_CONTROLLER_IP and ACL_SYSTEM_CONTROLLER_PORT shall be set to the location where the System Controller is hosted
  • ACL_INGEST_NAME is optional but is well used as an aid to identify the Ingest in the REST interface if multiple instances are connected to the same System Controller

You may also want to set the log location by setting ACL_LOG_PATH. The log location defaults to /tmp/.

As an example, from the installation directory, the Ingest is started with:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q" ACL_INGEST_NAME="My Ingest" ./acl-ingest

If started successfully, it will display a log message showing that the Ingest is up and running.

Running the Ingest SW as a service

It may be useful to run the Ingest SW as a service in Ubuntu, so that it starts automatically on boot and restarts if it terminates abnormally. In Ubuntu 22.04 systemd manages the services. Here follows an example of how a service can be configured, started and monitored.

First create a “service unit file”, named for example /etc/systemd/system/acl-ingest.service and put the following in it:

[Unit]
Description=Agile Live Ingest service

[Service]
User=<YOUR_USER>
Environment=ACL_SYSTEM_CONTROLLER_PSK=<YOUR_PSK>
ExecStart=/bin/bash -c '\
source /opt/intel/oneapi/setvars.sh; \
exec /opt/agile_live/bin/acl-ingest'
Restart=always

[Install]
WantedBy=multi-user.target

Replace <YOUR_USER> with the user that will be executing the Ingest binary on the host machine. The Environment attribute should be set in the same way as described above for manually starting the binary.

After saving the service unit file, run:

sudo systemctl daemon-reload
sudo systemctl enable acl-ingest.service
sudo systemctl start acl-ingest

The service should now be started. The status of the service can be queried using:

sudo systemctl status acl-ingest.service

Configuring and starting the Production pipeline(s) including rendering engine

The production pipeline component and the rendering engine component are combined into one binary named acl-renderingengine and terminates transport of media streams from ingests, demuxes, decodes, aligns according to timestamps and clock sync, separately mixes audio and video (including HTML-based graphics insertion) and finally encodes, muxes and originates transport of finished mixed outputs as well as multiviews.

It is possible to run just one production pipeline if doing direct editing (the “traditional way”, in the stream) or to use two pipelines in order to set up a proxy editing workflow. In the latter case, there is one designated for the Low Delay flow which will be used for quick feedbacks on the editing commands and one designated for High Quality flows which will produce the final quality stream to broadcast to the viewers. The Production Pipeline is simply called a “pipeline” in the REST API. The rendering engine is not managed through the REST API but rather through the control command API from the control panels.

Settings for the production pipeline binary are added as environment variables. There is one setting that must be set:

  • ACL_SYSTEM_CONTROLLER_PSK shall be set to the same as in the settings file of the System Controller

Also, there are some parameters that have default settings that you will most probably want to override:

  • ACL_SYSTEM_CONTROLLER_IP and ACL_SYSTEM_CONTROLLER_PORT shall be set to the location where the System Controller is hosted
  • ACL_RENDERING_ENGINE_NAME is needed to identify the different production pipelines in the REST API and shall thus be set uniquely and descriptively
  • ACL_MY_PUBLIC_IP shall be set to the IP address or hostname where the ingest shall find the production pipeline. If the production pipeline is behind a NAT or needs DNS resolving, setting this variable is necessary
  • DISPLAY is needed but may already be set by the operating system. If not (because the server is headless) it needs to be set.

You may also want to set the log location by setting ACL_LOG_PATH. The log location defaults to /tmp/.

Here is an example of how to start two instances (one for Low Delay flow and one for High Quality Flow) of the acl-renderingengine application and name them accordingly so that you and the GUI can tell them apart. First start the Low Delay instance by running:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q" ACL_RENDERING_ENGINE_NAME="My LD Pipeline" ./acl-renderingengine

Then start the High Quality Rendering Engine in the same way:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q" ACL_RENDERING_ENGINE_NAME="My HQ Pipeline" ./acl-renderingengine

Configuring and starting the generic Control Panels

TCP control panel

acl-tcpcontrolpanel is a control panel application that starts a TCP server on a configurable set of endpoints and relays control commands over a control connection if one has been set up. It is preferably run geographically very close to the control panel whose control commands it will relay, but can alternatively run close to the production pipeline that it is connected to. To start with, it is easiest to run it on the same machine as the associated production pipeline.

Settings for the tcp control panel binary are added as environment variables. There is one setting that must be set:

  • ACL_SYSTEM_CONTROLLER_PSK shall be set to the same as in the settings file of the System Controller

Also, there are some parameters that have default settings that you will most probably want to override:

  • ACL_SYSTEM_CONTROLLER_IP and ACL_SYSTEM_CONTROLLER_PORT shall be set to the location where the System Controller is hosted
  • ACL_CONTROL_PANEL_NAME can be set to make it easier to identify the control panel through the REST API
  • ACL_TCP_ENDPOINT from release 6.0.0 on, contains the IP address and port of the TCP endpoint to be opened, written as <ip>:>port>. Several clients can connect to the same listening port. In release 5.0.0 and earlier, instead use ACL_TCP_ENDPOINTS, a comma-separated list of endpoints to be opened, where each endpoint is written as <ip>:>port>

You may also want to set the log location by setting ACL_LOG_PATH. The log location defaults to /tmp/.

As an example, from the installation directory, the tcp control panel is started with:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q" ACL_TCP_ENDPOINT=0.0.0.0:7000 ACL_CONTROL_PANEL_NAME="My TCP Control Panel" ./acl-tcpcontrolpanel

Websocket control panel

acl-websocketcontrolpanel is a control panel application that acts as a websocket server, and relays control commands that come in over websockets that are opened typically by web-based GUIs.

The basic settings are the same as for the tcp control panel. But to specify where the websocket server shall open an endpoint, use this environment variable:

  • ACL_WEBSOCKET_ENDPOINT is the endpoint to listen for incoming messages on. On the form <ip>:<port>

You may also want to set the log location by setting ACL_LOG_PATH. The log location defaults to /tmp/.

An example of how to start it is the following:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q ACL_WEBSOCKET_ENDPOINT=0.0.0.0:6999 ACL_CONTROL_PANEL_NAME="My Websocket Control Panel" ./acl-websocketcontrolpanel

Manual control panel

acl-manualcontrolpanel is a basic Control Panel application operated from the command line.

The basic settings are the same as for the other generic control panels but it does not open any network endpoints for input, instead the control commands are written in the terminal. It can be started with:

ACL_SYSTEM_CONTROLLER_IP="10.10.10.10" ACL_SYSTEM_CONTROLLER_PORT=8080 ACL_SYSTEM_CONTROLLER_PSK="FBCZeWB3kMj5me58jmcpmEd3bcPZbp4q ACL_CONTROL_PANEL_NAME="My Manual Control Panel" ./acl-manualcontrolpanel

1.3.3.1 - NTP

Agile Live NTP instructions

To ensure that all ingest servers and production pipelines are in sync, a clock synchronization protocol called NTP is required. Historically that has been handled by a systemd service service called timesyncd.

Chrony

Starting from version 4.0.0 of Agile Live the required NTP client has switched from systemd-timesyncd to chrony. Chrony is installed by defualt in many Linux distributions since it has a lot of advantages over using systemd-timesyncd. Some of the advantages are listed below.

  • Full NTP support (systemd-timesyncd only supports Simple NTP)
  • Syncing against multiple servers
  • More complex but more accurate
  • Gradually adjusts the system time instead of hard steps

Installation

Install chrony with:

$ sudo apt install chrony

This will replace systemd-timesyncd if installed.

NTP servers

The default configuration for chrony uses a pool of 8 NTP servers to synchronize against. It is recommended to use these default servers hosted by Ubuntu. Verify that the configuration is valid by checking the configuration file after installing.

$ cat /etc/chrony/chrony.conf
...
pool ntp.ubuntu.com        iburst maxsources 4
pool 0.ubuntu.pool.ntp.org iburst maxsources 1
pool 1.ubuntu.pool.ntp.org iburst maxsources 1
pool 2.ubuntu.pool.ntp.org iburst maxsources 2
...

The file should also contain the line below for the correct handling of leap seconds. It is used to set the leap second timezone to get the correct TAI time.

leapsectz right/UTC

Useful Commands

For a simple check to see that the system time is synchronized, run:

$ timedatectl
               Local time: Wed 2023-03-08 08:23:37 CET
           Universal time: Wed 2023-03-08 07:23:37 UTC
                 RTC time: Wed 2023-03-08 07:23:37
                Time zone: Europe/Stockholm (CET, +0100)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

To get more details on how the system time is running compared to NTP, use the chrony client chronyc. The subcommand tracking shows information about the current system time and the selected time server used.

$ chronyc tracking
Reference ID    : C23ACA14 (sth1.ntp.netnod.se)
Stratum         : 2
Ref time (UTC)  : Wed Mar 08 07:23:37 2023
System time     : 0.000662344 seconds slow of NTP time
Last offset     : -0.000669114 seconds
RMS offset      : 0.001053432 seconds
Frequency       : 10.476 ppm slow
Residual freq   : +0.001 ppm
Skew            : 0.295 ppm
Root delay      : 0.007340557 seconds
Root dispersion : 0.001045418 seconds
Update interval : 1028.7 seconds
Leap status     : Normal

The sources subcommand to get a list of the other time servers that chrony uses.

$ chronyc sources -v

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current best, '+' = combined, '-' = not combined,
| /             'x' = may be in error, '~' = too variable, '?' = unusable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||      Reachability register (octal) -.           |  xxxx = adjusted offset,
||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
||                                \     |          |  zzzz = estimated error.
||                                 |    |           \
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^- prod-ntp-5.ntp4.ps5.cano>     2   6    17     8    +59us[  -11us] +/-   23ms
^- pugot.canonical.com           2   6    17     7  -1881us[-1951us] +/-   48ms
^+ prod-ntp-4.ntp1.ps5.cano>     2   6    17     7  -1872us[-1942us] +/-   24ms
^+ prod-ntp-3.ntp1.ps5.cano>     2   6    17     6   +878us[ +808us] +/-   23ms
^- ntp4.flashdance.cx            2   6    17     7   -107us[ -176us] +/-   34ms
^+ time.cloudflare.com           3   6    17     8   -379us[ -449us] +/- 5230us
^* time.cloudflare.com           3   6    17     8   +247us[ +177us] +/- 5470us
^- ntp5.flashdance.cx            2   6    17     7  -1334us[-1404us] +/-   34ms

Leap seconds

Due to small variations in the Earth’s rotation speed a one second time adjustment is occasionally introduced in UTC (Coordinated Universal Time). This is usually handled by stepping back the clock in the NTP server one second. These hard steps could cause problems in such a time critical product as video production. To avoid this the system uses a clock known as TAI (International Atomic Time), which does not introduce any leap seconds, and is therefore slightly offset from UTC (37 seconds in 2023).

Leap smearing

Another technique for handling the introduction of a new leap second is called leap smearing. Instead of stepping back the clock in on big step, the leap second is introduced in many minor microsecond intervals during a longer period, usually over 12 to 24 hours. This technique is used by most of the larger cloud providers. Most NTP servers that use leap smearing don’t announce the current TAI offset and will thereby cause issues if used in combination with systems that are using TAI time. It is therefore highly recommended to use Ubuntu’s default NTP servers as described above, as none of these use leap smearing. Mixing leap smearing and non-leap smearing time servers will result in that components in the system will have clocks that are off from each other by 37 seconds (as of 2023), as the ones using leap smearing time servers without TAI offset will set the TAI clock to UTC.

1.3.3.2 - Linux settings

Recommended changes to various Linux settings

UDP buffers

To improve the performance while receiving and sending multiple streams, and not overflow UDP buffers (leading to receive buffer errors as identified using e.g. ‘netstat -suna’), it is recommended to adjust some UDP buffer settings on the host system.

Recommended value of the buffers is 16MB, but different setups may need larger buffers or would suffice with lower values. To change the buffer values issue:

sudo sysctl -w net.core.rmem_default=16000000
sudo sysctl -w net.core.rmem_max=16000000
sudo sysctl -w net.core.wmem_default=16000000
sudo sysctl -w net.core.wmem_max=16000000

To make the changes persistant edit/add the values to /etc/sysctl.conf:

net.core.rmem_default=16000000
net.core.rmem_max=16000000

net.core.wmem_default=16000000
net.core.wmem_max=16000000

Core dump

On the rare occasion that a segmentation fault or a similar error should occur, a core dump is generated by the operating system to record the state of the application to aid in troubleshooting. By default these core dumps are handled by the ‘apport’ service in Ubuntu and not written to file. To store them to file instead we recommend installing the systemd core dump service.

sudo apt install systemd-coredump

Core dumps will now be compressed and stored in /var/lib/systemd/coredump.

The systemd core dump package also includes a helpful CLI tool for accessing core dumps.

List all core dumps:

$ coredumpctl list

TIME                            PID   UID   GID SIG COREFILE  EXE
Thu 2022-10-20 17:24:16 CEST 985485  1007  1008  11 present   /usr/bin/example

You can print some basic information from the core dump to send to the Agile Live developer to aid debugging the crash

$ coredumpctl info 985485

In some cases, the developers might want to see the entire core dump to understand the crash, then save the core dump using

$ coredumpctl dump 985485 --output=myfilename.coredump

Core dumps will not persist between reboots.

1.3.3.3 - Disabling unattended upgrades of CUDA toolkit

Recommended changes to the unattended upgrades

CUDA Driver/library mismatch

Per default Ubuntu runs automatic upgrades on APT installed packages every night, a process called unattended upgrades. This will sometimes cause issues when the unattended upgrade process tries to update the CUDA toolkit, as it will be able to update the libraries, but cannot update the driver, as it is in use by some application. The result is that the CUDA driver cannot be used because of the driver-library mismatch and the Agile Live applications will fail to start. In case an Agile Live application fails to start with some CUDA error, the easiest way to see if this is because of a driver-library mismatch, is to run nvidia-smi in a terminal and check the output:

$ nvidia-smi
Failed to initialize NVML: Driver/library version mismatch

In case this happens, just reboot the machine and the new CUDA driver should be loaded instead of the old one at startup. (It is sometimes possible to manually reload the CUDA driver without rebooting, but this can be troublesome as you have to find all applications using the driver)

How to disable unattended upgrades of CUDA toolkit

One way to get rid of these unpleasant surprises when the applications suddenly no longer can start, without disabling unattended upgrades for other packages, is to blacklist the CUDA toolkit from the unattended upgrades process. This will make Ubuntu still update other packages, but CUDA toolkit will require a manual upgrade, which can be done at a suitable time point.

To blacklist the CUDA driver, open the file /etc/apt/apt.conf.d/50unattended-upgrades in a text editor and look for the Unattended-Upgrade::Package-Blacklist block. Add "cuda" and "(lib)?nvidia" to the list, like so:

// Python regular expressions, matching packages to exclude from upgrading
Unattended-Upgrade::Package-Blacklist {
    "cuda";
    "(lib)?nvidia";
};

This will disable unattended upgrades for packages with names starting with cuda, libnvidia or just nvidia.

How to manually update CUDA toolkit

Once you want to manually update the CUDA toolkit and the driver, run the following commands:

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install cuda

This will likely trigger the driver-library mismatch in case you run nvidia-smi. Then reboot the machine to reload the new driver.

Sometimes a reboot is required before the cuda package can be installed, so in case the upgrade did not work the first time, try a reboot, then apt install cuda and then reboot again.

1.3.3.4 - Installing older releases

Installation instructions parts of the base platform for older releases

This page describes a couple of steps in installing the base platform that are specific for releases 5.0.0 and older, and replaces these sections in the main documentation.

Base packages installed via ‘apt’

To make it possible to run the Ingest and Rendering Engine, some packages must be installed. The following base packages can be installed with the apt package manager:

sudo apt -y update && sudo apt -y upgrade && sudo apt -y install libssl3 libfdk-aac2 libopus0 libcpprest2.10 libspdlog1 libfmt8 libsystemd0 chrony libcairo2 systemd-coredump

The systemd-coredump package in the list above is really handy to have installed to be able to debug core dumps later on.

Installing the Agile Live components

Extract the following release artifacts from the release files listed under Releases:

  • Ingest application consisting of binary acl-ingest and shared library libacl-ingest.so
  • Production pipeline library libacl-productionpipeline.so and associated header files
  • Rendering engine application acl-renderingengine
  • Production control panel interface library libacl-controldatasender.so and associated header files
  • Generic control panel applications acl-manualcontrolpanel, acl-tcpcontrolpanel and acl-websocketcontrolpanel

1.3.4 - Configuration and monitoring GUI

Installing the Configuration and monitoring GUI

The following guide will show how to run the configuration and monitoring GUI using Docker compose. The OS specific parts of the guide, how to install Docker and aws-cli, is written for Ubuntu 22.04.

Install Docker Engine

First install Docker on the machine you want to run the GUI and the GUI database:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Login to Docker container registry

To access the Agile Docker container registry to pull the GUI image, you need to log in install and log into AWS CLI

Install AWS CLI:

sudo apt-get install unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

Configure AWS access, use the access key id and secret access key that you should have received from Agile Content. Set region to eu-north-1 and leave output format as None (just hit enter):

aws configure --profile agile-live-gui
AWS Access Key ID [None]: AKIA****************
AWS Secret Access Key [None]: ****************************************
Default region name [None]: eu-north-1
Default output format [None]:

Login to Agile’s AWS Elastic Container Repository to be able to pull the container image: 263637530387.dkr.ecr.eu-north-1.amazonaws.com/agile-live-gui. If your user is in the docker group, sudo part can be skipped.

aws --profile agile-live-gui ecr get-login-password | sudo docker login --username AWS --password-stdin 263637530387.dkr.ecr.eu-north-1.amazonaws.com

MongoDB configuration

The GUI uses MongoDB to store information. When starting up the MongoDB Docker container it will create a database user that the GUI backend will use to communicate with the Mongo database.

Create the file mongo-init.js for the API user (replace <API_USER> and <API_PASSWORD> with a username and password of your choice):

productionsDb = db.getSiblingDB('agile-live-gui');

productionsDb.createUser({
  user: '<API_USER>',
  pwd: '<API_PASSWORD>',
  roles: [{ role: 'readWrite', db: 'agile-live-gui' }]
});

Create a docker-compose.yml file

Create a file docker-compose.yml to start the GUI backend and the MongoDB instance. Give the file the following content:

version: '3.7'

services:
  agileui:
    image: 263637530387.dkr.ecr.eu-north-1.amazonaws.com/agile-live-gui:latest
    container_name: agileui
    environment:
      MONGODB_URI: mongodb://<API_USER>:<API_PASSWORD>@mongodb:27017/agile-live-gui
      AGILE_URL: https://<SYSTEM_CONTROLLER_IP>:<SYSTEM_CONTROLLER_PORT>
      AGILE_CREDENTIALS: <SYSTEM_CONTROLLER_USER>:<SYSTEM_CONTROLLER_PASSWORD>
      NODE_TLS_REJECT_UNAUTHORIZED: 1
      NEXTAUTH_SECRET: <INSERT_GENERATED_SECRET>
      NEXTAUTH_URL: http://<SERVER_IP>:<SERVER_PORT>
      BCRYPT_SALT_ROUNDS: 10
      UI_LANG: en
    ports:
      - <HOST_PORT>:3000

  mongodb:
    image: mongo:latest
    container_name: mongodb
    environment:
      MONGO_INITDB_ROOT_USERNAME: <MONGODB_USERNAME>
      MONGO_INITDB_ROOT_PASSWORD: <MONGODB_PASSWORD>
    ports:
      - 27017:27017
    volumes:
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
      - ./mongodb:/data/db

Details about some of the parameters:

  • image - Use latest tag for always starting the latest version, set to :X.Y.Z to lock on a specific version.
  • ports - Internally port 3000 is used, open a mapping from your HOST_PORT of choice to access the GUI at.
  • extra_hosts - Adding “host.docker.internal:host-gateway” makes it possible for docker container to access host machine from host.docker.internal
  • MONGODB_URI - The mongodb connection string including credentials, API_USER and API_PASSWORD should match what you wrote in mongo-init.js
  • AGILE_URL - The URL to the Agile-live system controller REST API
  • AGILE_CREDENTIALS - Credentials for the Agile-live system controller REST API, used by backend to talk to the Agile-live REST API.
  • NODE_TLS_REJECT_UNAUTHORIZED - Set to 0 to disable SSL verification. This is useful if testing using self-signed certs
  • NEXTAUTH_SECRET - The secret used to encrypt the JWT Token, can be generated by openssl rand -base64 32
  • NEXTAUTH_URL - The base url for the service, used for redirecting after login, eg. http://my-host-machine-ip:3000
  • BCRYPT_SALT_ROUNDS - The number of salt rounds the bcrypt hashing function will perform, you probably don’t want this higher than 13 ( 13 = ~1 hash/second )
  • UI_LANG - Set language for the user interface (en|sv). Default is en
  • MONGODB_USERNAME - Select a username for a root user in MongoDB
  • MONGODB_PASSWORD - Select a password for your root user in MongoDB

Start, stop and signing in to the Agile-live GUI

Start the UI container by running Docker compose in the same directory as the docker-compose.yml file`:

sudo docker compose up -d

Once the containers are started you should now be able to reach the GUI at the host-port that you selected in the docker-compose.yml-file.

To login to the GUI, use username admin and type a password longer than 8 characters. This password will now be stored in the database and required for any new logins. For more information on how to reset passwords and add new users, read more here

After signing in to the GUI, the statuses in the bottom left should all be green, else there is probably a problem in your System Controller or database configuration in the docker-compose.yml-file.

To stop the GUI and database container run:

sudo docker compose down

Installing support for VLC on client machine, to open Multiview directly from GUI:

On Windows operating system, the GUI supports redirecting the user via links to VLC. To make this work, the following open-source program needs to be installed: https://github.com/stefansundin/vlc-protocol/tree/main

This is not supported on Linux or Mac.

1.3.4.1 - Custom MongoDB installation

Instructions for installing MongoDB instead of running it in docker

This page contains instruction on making a manual installation of MongoDB, instead of running MongoDB in Docker as is described here. In most cases we recommend running MongoDB in Docker, as it is easier to set up and manage.

Custom installation of MongoDB

Install the database software, MongoDB.

sudo apt-get install gnupg
curl -fsSL https://pgp.mongodb.com/server-6.0.asc | \
   sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg \
   --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org

Create a /etc/mongod.conf that contains the following:

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
#  engine:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

security:
  authorization: enabled

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:

Then start the database

sudo systemctl enable mongod
sudo systemctl start mongod

Create the file ~/mongosh-admin.js containing (replace <ADMIN_PASSWORD>):

use admin
db.createUser(
  {
    user: "admin",
    pwd: "<ADMIN_PASSWORD>",
    roles: [
      { role: "userAdminAnyDatabase", db: "admin" },
      { role: "readWriteAnyDatabase", db: "admin" }
    ]
  }
)

Create the admin user

mongosh localhost < ~/mongosh-admin.js

Create the file ~/mongosh-api.js for the API user (replace <API_PASSWORD>):

productionsDb = db.getSiblingDB('agile-live-gui');

productionsDb.createUser({
  user: 'api',
  pwd: '<API_PASSWORD>',
  roles: [{ role: 'readWrite', db: 'agile-live-gui' }]
});

Create the API user

mongosh -u admin -p <ADMIN_PASSWORD> < ~/mongosh-api.js

1.3.5 - Prometheus and Grafana for monitoring

Installing and running Prometheus exporters, Prometheus database and Grafana

To collect useful system metrics for stability and performance monitoring, we advise to use Prometheus. For visualizing the metrics collected by Prometheus you could use Grafana.

The System controller receives a lot of internal metrics from the Agile Live components. These can be pulled by a Prometheus instance from the endpoint https://system-controller-host:8080/metrics.

It is also possible to install external exporters for various hardware and OS metrics.

Prometheus

Installation

Use this guide to install Prometheus: https://prometheus.io/docs/prometheus/latest/installation/.

Configuration

Prometheus should be configured to poll or scrape the system controller with something like this in the prometheus.yml file:

scrape_configs:
  - job_name: 'system_controller_exporter'
    scrape_interval: 5s
    scheme: https
    tls_config:
      insecure_skip_verify: true
    static_configs:
    - targets: ['system-controller-host:8080']

External exporters

Node Exporter

Node Exporter is an exporter used for general hardware and OS metrics, such as CPU load and memory usage.

Instructions for installation and configuration can be found here: https://github.com/prometheus/node_exporter

Add a new scrape_config in prometheus.yml like so:

  - job_name: 'node_exporter'
    scrape_interval: 15s
    static_configs:
    - targets: ['node-exporter-host:9100']

DCGM Exporter

This exporter uses Nvidia DCGM to gather metrics from Nvidia GPUs. Includes encoder and decoder utilization.

More info and installation instructions to be found here: https://github.com/NVIDIA/dcgm-exporter

Add a new scrape_config in prometheus.yml like so:

  - job_name: 'dcgm_exporter'
    scrape_interval: 15s
    static_configs:
    - targets: ['dcgm-exporter-host:9400']

Grafana

Installation of Grafana is described here: https://grafana.com/docs/grafana/latest/setup-grafana/installation/

As a start, the following Dashboards can be used to visualize the Node Exporter and DCGM Exporter data:

Example of running Node Exporter and DCGM Exporter with Docker Compose

To simplify setup of the Node Exporter and DCGM Exporter on multiple machines to monitor, the following example Docker Compose file can be used. First, after a normal installation of Docker and the Docker Compose plugin, the Nvidia Container Toolkit must be installed and configured to allow access to the Nvidia GPU from inside a Docker container:

sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Then the following example docker-compose.yml file can be used to start both the Node Exporter and the DCGM Exporter:

version: '3.8'

services:
  node_exporter:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter
    command:
      - '--path.rootfs=/host'
    network_mode: host
    pid: host
    restart: unless-stopped
    volumes:
      - '/:/host:ro,rslave'

  dcgm_exporter:
    image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.3-3.3.1-ubuntu22.04
    container_name: dcgm_exporter
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [ gpu ]
    restart: unless-stopped
    environment:
      - DCGM_EXPORTER_NO_HOSTNAME=1
    cap_add:
      - SYS_ADMIN
    ports:
      - "9400:9400"

Start the Docker containers as usual with docker compose up -d. To verify the exporters work, you can use Curl to access the metrics data like: curl localhost:9100/metrics for the Node Exporter and curl localhost:9400/metrics for the DCGM exporter. Note that the DCGM exporter might take several seconds before the first metrics are collected, resulting in that the first requests might yield an empty response body.

1.3.6 - Control panel GUI examples

Installing and configuring some Control panel GUI examples

The rendering engine, which contains the video mixer, HTML renderer, audio mixer, etc., is configured and controlled via a control command API over the control connections. Some source code examples of control panel integrations are provided, together with 3rd party software recommendations. All these use the generic control panels as proxies when communicating with the rendering engine. However, it is recommended for integrators to, when possible, write their own control panel integrations using the libraries and header files provided by the base layer of the platform instead of relaying the commands via the generic control panels.

Streamdeck and Companion

A good first starting point for a control panel to control the video (and audio) mixer is to use an Elgato Streamdeck in combination with the open source software Bitfocus Companion.

The source code examples

Unzip the file agile-live-unofficial-tools-5.0.0.zip to find several different source code examples of control panel integrations in various languages. Some communicate with the generic tcp control panel, some with the generic websocket control panel, some directly with the REST API. The source code is free to reuse and adapt.

The audio control interface and GUI

An example audio control panel interface and GUI is provided as source code in Python 3. It attempts to find a control panel HW, either the Korg nanoKONTROL2 or Behringer X-Touch Extender, via MIDI and to communicate with it using the Mackie Control protocol. (Note that the Korg nanoKONTROL2 does not use the Maicke protocol by default. Refer to the nanoKONTROL2 user manual on how to set it up)

The audio control panel uses the tkinter GUI library in the Python standard libraries, and also depends upon the python packages python_rtmidi and mido which can be installed using pip3 install.

The chroma key control panels

There is a Python3+tkinter-based GUI for configuring the chroma key (“green screen”) functionality, which communicates with the generic tcp control panel.

There is also a HTML-based version that communicates with the generic websocket control panel.

The thumbnail viewer

The thumbnail viewer is an example web GUI to poll the REST API and visualize all ingests and sources that are connected to a given System Controller. Thumbnails of all sources are shown, and updated every 5 seconds.

1.4 - Tutorials and How-To's

Instructions for setting up the system and increasing security

1.4.1 - Getting Started

Getting up and running with Agile Live including all components and tools needed for a full solution

This is a tutorial that describes the steps needed to set up a full Agile Live system, everything from the Base Platform to the configuration-and-monitoring GUI and the control panel integrations. It relies on links to a number of separate sub-guides.

Prerequisites

A working knowledge of the technical basis of the Agile Live solution is beneficial when starting with this tutorial but not required. It is assumed that sufficient hardware has been provided, i.e.:

  • at least one server to be used for ingesting media via an SDI capture card or as NDI via a network interface
  • at least one server to be used for running the production pipeline(s) including the rendering engine that performs the video and audio mixing, as well as the generic control panels
  • one server that will run all management and orchestration software, including the System Controller, the configuration-and-monitoring GUI, the Prometheus database and the associated Grafana instance
  • at least one computer that will have control panel hardware connected to it, run the control panel integration software, and receive and display the multiview video stream and the monitor feed media stream

The servers may be in the field, in a datacenter or in a private or public cloud. For cloud VMs, the requirement is that they have Nvidia GPUs with NvEnc+NvDec support. All major cloud providers have VMs with Nvidia T4’s.

In a very minimal system not all of these machines need to be separate; in fact, all the above could run on a single computer if so is desired. Recommended hardware requirements for the servers running the ingest and production pipelines can be found here.

Installing all components

A guide to installing all the components of the system can be found here, start by following it.

Using the configuration-and-monitoring GUI to set up and monitor a production workflow

A guide on how to use the basic configuration-and-monitoring GUI to set up a working system can be found here.

Using the Grafana dashboard example

Viewing the multiview and outputs

The multiview and outputs (low delay monitor feed and high quality program out) are sent from the platform as MPEG TS streams in SRT or UDP. For viewing the streams, please refer to this guide.

Creating a video mixer control panel in Companion

A good starting point for a video mixer control panel is to use Bitfocus Companion with an Elgato Streamdeck device. Some guidelines for how to use those to build a video mixer control panel for Agile Live can be found here

Using the audio control GUI

There is an example audio control panel integration that also includes a GUI. A guide on how to use it can be found here

1.4.2 - Using the configuration-and-monitoring GUI

Using the configuration-and-monitoring GUI to set up and monitor a production workflow

Using the configuration-and-monitoring GUI to set up and monitor a production workflow

When loading the configuration and monitoring GUI in a web browser the first screen you will encounter is the login screen. Log in using the credentials that you set when installing. After logging in you will see the home screen. Make sure that the bottom strip says that the System Controller is online and that the database is online.

Configure sources

On the home screen, click the Inventory Management button. This will take you to the inventory management page. On the left side there is a list of all sources in the system at the moment. It is possible to filter the list based on source type, location, and active state. For each source, it is possible (and recommended) to click the Edit button to open the source configuration editing page. It is recommended to set a descriptive name (e.g. “Front wide camera”), a type, and a location for the source. This view is also used to configure which embedded audio channels to transport up to the production pipelines. Click Save to save your changes and exit this page and return to the inventory management page. Repeat the process for each source. Whenever a new source is added to the system, it is recommended to perform this step on it. Press the Home button to return to the home screen.

Create and start a production configuration

A production configuration is a description of how the system is configured for a specific production workflow, e.g. a TV program. On the home screen, click the Create New button to create a new production configuration. Give it a decriptive name, e.g. “Stockholm local news”, and click the Create button. This will bring you to the configuration page for the new production configuraton. Click Add Source to add a source to this production configuration. This will bring out a list of available sources on the left side of the screen. Again, it is possible to filter the sources the same way as on the inventory management page. Click Add for the sources that you want to have in your production configuration. The order of the sources is the same as the order they will be presented in the multiviewer. To change the order, drag and drop them. For each source, it is possible to set the UMD text by clicking the name above the thumbnail and editing it.

A preset is a collection of all the detailed variables of each part of the production configuration that will be set up. This includes detailed quality settings, network latency settings, etc. To choose a preset for your current production configuration, click Select Preset and select one of the pre-defined presets. Once that has been done, some settings can be edited by clicking the button with the cogwheel icon.

To run a production configuration click the Start button. Once the production is started, click the Home button to return to the home screen.

Use the runtime monitoring

On the top of the screen there will now be a pane for each pipeline that is running, and information on where to find the multiview and output streams. For the production configuration that is currently running, there is a Runtime Monitoring button, that is either green if all is well, or red if there are any error counters that have increased in the last minute. Clicking the button takes you to the runtime monitoring screen.

The runtime monitoring screen is built as an expanding tree, where each level and instance has a status icon that is either green or red. This way it is very easy to trace an error through the tree down to the erroring counter. On the lowest level, the actual counters can have three colors. White means it is an informational counter that cannot indicate an error. Green color means that the counter is able to indicate an error but at the moment it is fine. Red color means that the counter is currently indicating an error. Such a counter is red if it has increased in the last 60 seconds. A red counter will revert to green after 60 seconds without increasing.

Editing the database

To add or edit production presets and new users, the Mongo database can be manually edited.

The GUI tool MongoDB Compass can be used to edit the database, but MongoDB Shell and other MongoDB tools will also work. Since you connect to the MongoDB via the network, Compass can be used on any computer with network access to the GUI server on port 27017.

After installing MongoDB Compass, connect to the database by pressing the “New Connection” button. In the URI field, exchange localhost for the hostname of the GUI server (unless you run Compass on the same server as the GUI, of course). Add agile_live_gui last in the URL-field, to access the GUI database only. Then under Advanced Connection Options, select Authentication and use method Username/Password. Type the <API_USER> and <API_PASSWORD> you put in the mongo-init.js file when setting up the GUI server. The URI field should then look something like:

mongodb://<API_USER>:<API_PASSWORD>@<HOSTNAME>:27017/agile-live-gui?authMechanism=DEFAULT

Add or edit production presets

Once connected you will see the databases to the left. The database agile-live-gui contains the collections used by the GUI. To add a new, or modify an old production preset, open the presets collection under the agile-live-gui database. To create a new preset, the easiest way is to clone an old preset and make your changes to it. Hover your mouse over one of the presets you want to clone, and press the Clone document button on the top right of the preset. In the popup window you can make your edits to the new preset. Most important is to set a new name for it in the "name" field. This is the name that will be displayed in the GUI when selecting which preset to use. Under pipelines the quality settings for the streams from the Ingests to the Pipelines can be set.

Add new users to the system

New users to the GUI can be added to the Mongo database as well. Open the users collection under the agile-live-gui database. Then add a new user by pressing the Clone document button on one of the existing users. In the popup window, set the username of the new user and remove the hashed password, leaving the password field empty (i.e. "password": ""). Press insert to add the new user to the database. Then open the GUI in a web browser. On the sign-in page, write the username of the new user and then type a password to set it as the new password in the database. A new password must have at least 8 characters to be approved.

1.4.3 - Viewing the multiview and outputs

Examples on how tho view the multiview and output streams

Viewing the multiview and outputs

The multiview and outputs (low delay monitor feed and high quality program out) are sent from the platform as MPEG TS streams in SRT or UDP. For viewing the streams, VLC can be used. For the multiview and low delay monitoring feeds it is important that the viewer does not add a lot of buffering delay. Therefore there is a need to configure it not to do so. The setting network-caching can be used to set the buffering. It can be done in the VLC GUI in settings, or on the command line by specifying --network-caching=140 when starting VLC, for example when using Windows:

C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" --network-caching=140 srt://mydomain:9900

1.4.4 - Creating a video mixer control panel in Companion

How to create a video mixer control panel in Companion

Create buttons in Companion by using the action tcp-udp: Send Command to send control commands that are listed here

An example companion config can be found here

1.4.5 - Using the audio control GUI

How to start and use the audio control GUI example

The audio control GUI is written in Python and should run in all systems that have Python3. However, since it uses tkinter and the native support of tkinter on some platforms is not perfect, there may occur problems. The application is verified to work on Ubuntu 22.04.

It is started with: ./acl_audio_control.py

First connect to an open TCP port on an acl-tcpcontrolpanel by setting the correct IP/hostname and port under “Mixer network address”. Once connected, use the “Add strip” and “Remove strip” buttons to add and remove volume strips. Then map the audio of each strip. Select the “Slot” of the connected (video) source you want to take the audio from. Then select which channel in the source to find the audio (or to find the L channel in case of stereo, the R channel will be assumed to be the next channel) and if the strip should be a mono or stereo strip. The name of the strip can be changed by clicking on it and editing it.

Once everything is set up, the configuration can be saved with the “Save” and “Save as…” buttons. The configuration is stored as a json file.

1.4.6 - Setting up multi-view outputs using the REST API

How to set up and manage Agile Live production multi-view outputs using the REST API

This is a tutorial that describes how to create and update multi-view outputs from a Pipeline using the REST API of the System controller.

Prerequisites

Knowledge on how to set up a system and create a production using the REST API.

The multi-view generator

The Agile Live system includes a built-in multi-view generator that can be used with any Rendering Engine and produce multiple composited mosaic video steams of selected inputs with a given layout. The multi-view generator can technically be used both in the High Quality and Low Delay pipelines, but in the general case it is only used in the Low Delay pipeline.

Start a new multi-view output stream

To start a new multi-view output stream, use the [POST] /pipelines/{uuid}/multiviews/ endpoint in the REST API, where {uuid} is the UUID of the Pipeline component from which you want to create the multi-view output (generally the Low Delay pipeline). Then provide a JSON payload to describe how the multi-view output should look. For instance:

{
  "layout": {
    "output_height": 1080,
    "output_width": 1920,
    "views": [
      {
        "width": 960,
        "height": 540,
        "x": 0,
        "y": 0
        "input_slot": 1,
        "label": "Camera 1",
      },
      ... // More views here
    ]
  },
  "output": {
    "format": "MPEG-TS-SRT",
    "frame_rate_d": 1,
    "frame_rate_n": 50,
    "ip": "0.0.0.0",
    "port": 4567,
    "video_format": "AVC",
    "video_kilobit_rate": 5000
  }
}

The description contains two parts, the layout part describing how the multi-view output will look and the output part to describe the format the stream should be encoded to. Starting with the output part, this will generate a stream of MPEG-TS over SRT format, with the SRT in server mode (IP address is 0.0.0.0) on port 4567. The frame rate is set to 50 FPS and the encoding format is set to AVC (H264) and 5000 kilobits/second. To playback the stream, use ffplay or VLC.

ffplay srt://<ip-address>:4567

or in VLC, press Media and then Open network stream and write srt://<ip-address>:4567 in the dialog that pops up. Note that the default latency in VLC is quite high (several seconds) compared to ffplay.

Multi-view layout

The layout part of the JSON payload contains a description of the multi-view. The parameters output_height and output_width defines the resolution of the main frame in pixels, i.e. the resolution of the resulting video stream. Within this frame, multiple views can be placed. Each view can display any of the input sources connected to the pipeline, or any of the auxiliary feedback outputs from the Rendering Engine, more on that below. The views are defined as a width and height of the view in pixels and the x and y position of the view inside the outer frame (the position of the top left corner of the view in pixels from the top left corner of the frame, see the illustration below). Then the content of the view is defined using the input_slot parameter and an optional label to display under the view is provided using the label parameter. In case two views overlap, the one first appearing in the view array will be drawn on top of the other one. In case the aspect ratio of the view does not match the aspect ratio of the source, the video image will be resized with its aspect ratio kept, to fit entirely inside the defined view. Areas that are not covered by the video will be filled with black.

Multi-view measurements

The input_slot parameter can be any of the sources connected to an input slot in the Pipeline. Just use the same input slot as used when the source was connected using the [POST] /streams endpoint. The input_slot parameter of the multi-view layout can also be any of the auxiliary feedback outputs of the Rendering Engine, i.e. video streams that are created by the Rendering Engine. These feedback streams also have their own input_slot number. To show which such feedback streams the Rendering Engine is providing, use the [GET] /pipelines/{uuid} endpoint with the UUID of the Pipeline. The result might look something like this:

{
  "uuid": "ab552c6c-4226-a9ec-66b8-65f98753beaa",
  "name": "My LD Pipeline",
  "type": "pipeline",
  "streams": [
    ...
  ],
  "feedback_streams": [
    {
      "input_slot": 1001,
      "name": "Program"
    },
    {
      "input_slot": 1002,
      "name": "Preview"
    }
  ],
  "multiviews": [
    ...
  ]
}

In this case the Rendering Engine provides two feedback streams to the multi-view generator, one called “Program” on input_slot 1001 which is the mixed output stream and one “Preview” on input_slot 1002 which shows what the Rendering Engine is previewing right now. The “Program” output is the same as the video stream you get from the Output component connected to the same pipeline.

Tally borders

Tally borders, i.e. colored borders around the views shown in the multi-view output that tell which views are currently being used in the program output (red frame) and the preview output (green frame) are automatically added to the multi-view outputs. Setting, removing and choosing the colors of the borders are controlled by the Rendering Engine. The Agile Live Rendering engine (acl-renderingengine) will also use borders on views containing the Program and Preview feedback outputs.

Update the layout

Once a multi-view output is created it will turn up when listing multi-view outputs using the [GET] /pipelines/{uuid}/multiviews endpoint, as well as in some of the other Pipeline related endpoints. When a multi-view output is created, the layout of that multi-view stream can be updated, without interrupting the stream. This can be done using the [PUT] /pipelines/{uuid}/multiviews/{viewid} endpoint. The viewid parameter is the id of the multi-view output stream within that Pipeline component. This id is provided in the JSON-blob returned with the HTTP response when creating the multi-view, and can also be retrieved using the [GET] /pipelines/{uuid} endpoint.

In the update request, an array of views, just like the one used when creating the multi-view output, is provided as a JSON payload. It is not possible to change the resolution of the main frame/stream or change any of the values set in the output section when the stream was created, as it would interrupt the stream. In case you want to alter any of these settings, you will need to stop the multi-view output and create a new one with the desired format.

Multiple multi-view outputs

The Pipeline supports outputting multiple multi-view output stream. Each output stream can have its own, unique layout and have different labels on the views compared to other multi-view outputs. The maximum number of multi-view output streams are limited by the hardware the Pipeline is running on.

Remove a multi-view output

A multi-view output stream can be closed by calling the [DELETE] /pipelines/{uuid}/multiviews/{viewid} with the id of the multi-view output to close.

1.4.7 - Security in Agile Live

How to set up secure connections in Agile Live

This is a tutorial that describes how to setup and use encryption throughout the Agile Live system.

Connections in the system

There are several types of network connections in the Agile Live system that need encryption to protect them, which is especially important when running productions in a public cloud environment or at least transporting parts of a production’s data over public internet. These connections are:

  • The HTTP requests to the REST API of the System Controller
  • The WebSocket connections between the components in the system and the System Controller
  • The SRT/RIST streams transporting the video and audio from the Ingests to the Production Pipelines.
  • The TCP control connections used to transport control commands from the Control Panel to the Production Pipeline, and to propagate the commands from the Low Delay pipeline to the High Quality pipeline.

The last two connection types above will always be encrypted. Each stream/connection will be setup with its own uniquely generated encryption key. The REST API and the WebSocket connections between the components and the System Controller, however, require some manual setup by the user.

Enable HTTPS in the System Controller

Turning the HTTP requests of the REST API and the WebSocket connection between the components and the System Controller secure, requires the following steps to be taken:

  1. Get a TLS certificate from a certificate authority
  2. Point out the cert.pem and key.pem provided by your certificate authority in the System Controller config file under https, attributes certificate_file and private_key_file. Also make sure enabled under https is set to true.
  3. Start the System controller and make sure it prints that the API is served using https
  4. Try accessing the REST API using HTTPS to make sure it works as expected

WebSocket connections will automatically be encrypted when HTTPS is turned on.

In case a component trying to connect to the System Controller using HTTPS and fails with the following error message: Failed to connect to System Controller, message: set_fail_handler: 8: TLS handshake failed this is likely because the ACL_SYSTEM_CONTROLLER_IP is not set to the same hostname as the “Common Name” field is set to in the certificate. Set ACL_SYSTEM_CONTROLLER_IP to the same hostname as in the System Controller’s certificate to make it work.

Pre-shared key (PSK)

Components connecting to the System Controller must authorize themselves to be accepted and connected. When components connect to the System Controller they present a pre-shared key (PSK) to the System Controller, which must match the PSK set in the System Controller for the component to be allowed to connect. The PSK is set in the System Controller’s config file using the psk attribute before it is started. The PSK must be 32 characters long. All components must then connect using the same PSK, by setting the environment variable ACL_SYSTEM_CONTROLLER_PSK before starting the application. In case the user fails to set the PSK before starting the application, it will immediately quit and print an error message.

Authentication in the REST API

The System Controller REST API is protected with Basic Authentication that will require a username and password to access the API endpoints. To configure this, edit the client_auth part of the System Controller’s config file. Choose which username and password should grant access to the REST API and make sure enabled is set to true to actually activate the authentication check. The configured password is tested for strength on start. The System Controller will not start if the password is judged to be too easy to crack with brute-force.

1.4.8 - Statistics in Agile Live

Introduction to the statistics counters in Agile Live

This is a tutorial that explains in more detail how the statistics in Agile Live should be interpreted and how the system measures them.

Statistics

Timestamps and measurements

Let’s start by taking a closer look on how the system measures these statistics:

/ingests/{uuid}/streams/{stream_uuid} {
    processing_time_audio,
    processing_time_video,
    audio_encode_duration,
    video_encode_duration
    }
/pipelines/{uuid}/streams/{stream_uuid} {
    time_to_arrival_audio,
    time_to_arrival_video,
    time_to_ready_audio,
    time_to_ready_video,
    audio_decode_duration,
    video_decode_duration
    }

All media that is ingested will be assigned a timestamp as soon as the audio and video is captured, this is the capture timestamp. With this timestamp as a reference the system calculates three more timestamps which all measure the time passed since the capture timestamp was taken.

processing_time_audio & processing_time_video

After the capture step, the audio and video is converted into the format that the user selected, this may involve resizing, deinterlacing and any color format conversion that is needed. Next step will be to encode the audio and video. Once the encoding is done, a new timestamp is taken which then measures the difference between the capture time and the current time after the encoding is done. Note that these values may be negative (and in rare cases the following timestamps), in cases where the system has shifted the capture timestamp into the future to handle drifting.

time_to_arrival_audio & time_to_arrival_video

When the Rendering Engine receives the EFP stream, and has received a full audio or video frame, a new timestamp is taken, which measures the difference between the capture time and the current time after a full frame was received. This duration also includes the network transport time, i.e. the maximum time that the network protocol will use for re-transmissions. This value can be configured with the max_network_latency_ms value when setting up the stream.

time_to_ready_audio & time_to_ready_video

Next step will be to decode the compressed audio and video into raw data. When the media is decoded a new timestamp is taken, which measures the difference between the capture time and the current time after the decoding of a frame is done. This will be when a frame is ready to be delivered to the Rendering Engine. The alignment of the stream between Ingest and Pipeline must be larger than time_to_ready_audio/video statistics, otherwise the frames will be too late and dropped. This is a good value to check if you experience dropped frames, and potentially increase the alignment value if so. You can also experiment with lowering the bitrate or decreasing the max_network_latency_ms setting. If a frame is ready earlier than the aligment time, it will be queued until the system reaches the alignment time. For the video frames there is also a queue of compressed frames before the actual decoding, this queue makes sure that only a maximum of 10 decoded frames are kept in memory after the decoder. Due to this the difference between these timestamps and the alignment value normally is never larger than the duration of 10 video frames.

The sytem also tracks for how long a frame is processed by the encoders and decoders with the following values:

audio_encode_duration & video_encode_duration

These metrics show how long time audio and video frames take to pass through their respective encoder. This duration includes any delay in the encoder as well, measuring the time from when each frame is passed to the encoder until the encoder returns the compressed frame. For video this also includes the time to do any format conversions, resizing and de-interlacing. Note that B-frames will cause the metric to increase to more than one frame-time, as more frames are needed in some cases before the previous ones can be outputted to the stream.

audio_decode_duration & video_decode_duration

These metrics show how long time audio and video frames take to pass through their respective decoder. This duration includes any delay in the decoder as well, measuring the time from when each frame is passed to the decoder until the decoder returns the raw frame. Also here, B-frames will cause this time to be longer than one frame time, because the decoder has to wait for more frames before the decoding can start.

Timestamp timeline

1.4.9 - Using Media Player metadata in HTML pages

How to use metadata from Media Players in HTML pages

This is a tutorial that describes how the playback state of currently active Media Players can be propagated and used in HTML pages within the production. The functionality is available from Agile Live version 6.0.0.

Subscribing to metadata

HTML pages loaded into the Rendering Engine can subscribe to metadata from Media Players located on other input slots of the Rendering Engine. The metadata can for instance be used to create graphics to aid the production crew.

In order for Media Player metadata to propagate to an HTML page, the page must first subscribe to metadata updates. This is done in the JavaScript code of the HTML page by calling the function window.aclInputSlotMetadataSubscribe() when the page has been loaded. After doing this the global variable aclInputSlotMetadata will become available and updated periodically. In the simplest case:

<body onLoad="window.aclInputSlotMetadataSubscribe()">

Metadata structure

aclInputSlotMetadata is a JSON object with the Media Player information located in the “media_players” section and further organized by which input slot the Media Player is located at. An example with a media file being played at input slot number 2:

var aclInputSlotMetadata = {
   "media_players": {
     "2": {
         "file_name": "/mnt/media/ads/Clip32.mov",
         "is_paused": false,
         "is_looping": true,
         "current_time_ms": 400000,
         "start_time_ms": 300000,
         "input_duration_ms": 1800000,
         "duration_ms": 120000,
         "time_left_ms": 20000
     }
   }
}

HTML example

The file “media-playback.html” located in the Agile Live examples ZIP file provides a full example of how to subscribe to, and use, the metadata from a Media Player. It can be loaded into the Rendering Engine to create a view that displays the metadata of the currently playing file. The HTML page accepts the Media Player’s input slot number as a query parameter. For example, if a Media Player is located at input slot number 4 and media-playback.html is served at localhost:8899 (on the same machine as the Rendering Engine is running) the following commands can be used to load the page into a new input slot:

html create 5 1920 1080
html load http://localhost:8899/media-playback.html?slot=4

1.5 - Releases

List of releases with change logs and upgrade instructions

1.5.1 - Release 6.0.0

Agile Live 6.0.0 release information

Build date

2024-01-29

Release status

Type: Sixth production ready release

Release content

Product version

6.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest binary and shared libraryagile-live-ingest-6.0.0-5d0d6e4.tarcd21f5cf57a7ac5a4022d290c4badab87d768bafd8057c8142dc9397beb77086
Rendering Engine binary and acl-libproductionpipeline shared libraryagile-live-renderingengine-6.0.0-5d0d6e4.tar7aa15accad3a254a0f8a842cc41046f51d5e7a2b586489596831eb6310bf53f2
Generic control panels and acl-libcontroldatasender shared libraryagile-live-controlpanels-6.0.0-5d0d6e4.tar095ead70169afc0f4f5e2be00fc4507e787955cd4bfd93677a7e61779c0881e1
Include filesagile-live-dev-6.0.0-5d0d6e4.tar2686768b00e38bb02fd211da981c55e1399604edbaef317601ea11ae82d31cf1
System Controlleragile-live-systemcontroller-6.0.0-38a4fc7.tar86e58778cb5641ac1d7f2761ffabb3a69c51e24cbe2d41ed6b8df6093862f4b8

Changelog

  • From this release Agile Live will be released as .deb packages instead of an archive of binaries and shared libs.
  • To simplify compatibility verifications, all components inside Agile Live now have the same version number as the version of the release they belong to, in this release 6.0.0. This means some components have received an older version number compared to earlier and some components have skipped several major versions.
  • The component -> System Controller communication has been changed from a request-response type of communication to a one-way communication, where the System Controller won’t send a response back and the component won’t expect a response back.
  • More informative error messages from the System Controller in case requests fail

Ingest

  • Support for ingesting SRT sources. Both caller and listener mode is supported, with or without passphrase. Currently AVC and HEVC video codecs are supported and AAC audio. New SRT sources can be set up using the REST API.
  • Counters for dropped_frames, lost_frames and duplicated_frames are now split into separate counters for audio and video called dropped_audio_frames, dropped_video_frames, lost_audio_frames and so on
  • The NDI interface now supports interlaced NDI sources with individual fields
  • The Ingest application now logs the enabled input interfaces more clearly and also outputs the API version of all interfaces supported on the machine.

Rendering Engine

  • The Rendering Engine now supports playback of media files directly in the mixer itself. The player supports seeking as well as looping of the entire clip, or a section of the clip.
  • The Rendering Engine can send information on the states of all media players to HTML pages. This way graphics can be shown for countdown until a clip ends, or to overlay such information to aid hosts in the studio.
  • The generic control panel acl-tcpcontrolpanel now accepts multiple connections on a single port. As a result of this, the environment variable has changed name to ACL_TCP_ENDPOINT without an S and only accepts a single endpoint.
  • Fix a crash when some invalid control commands was sent to the Rendering Engine.

Production Pipeline

  • The visibility of the audio bars in the multi-views is now configurable per multi-view output.

Control Data Sender and Control Data Receiver

No changes

System Controller

  • Fields are not correctly marked as “required” or “optional” in the OpenAPI specification served from the System Controller
  • Fixed a bug where the metrics for retransmitted_packets and sent_bytes on the GET requests to multi-view did not increment
  • The PSK is now checked for complexity. A too simple PSK (for instance just the same letter repeated 32 times) will not be accepted anymore
  • Fix for CVE-2023-44487: DOS with HTTP/2
  • The list of locations where the System Controller searches for the acl_sc_settings.json file has changed to just two locations: /etc/opt/agile_live followed by the current working directory.
  • The log file of the System Controller is now created with file permissions that let any user read it
  • The public IP of Pipelines are now included in the REST API

Known limitations

Media Player

Videos will be stretched in case the video played does not have the same aspect ratio as the Rendering Engine is using.

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

MPEG-TS over UDP

For Outputs and multi-view outputs it is currently not possible to bind to a specific IP and port with MPEG-TS over UDP, even if local_ip and local_port are exposed in the REST API.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

Security

No known issues

1.5.2 - Release 5.0.0

Agile Live 5.0.0 release information

Build date

2023-10-09

Release status

Type: Fifth production ready release

Release content

Product version

5.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest and Rendering Engine binaries, headers, and shared librariesagile-live-5.0.0-9d0ae4b.zip08681e43e592b7d347752457be7fadfbb1f09d9ba6145714c004003fcc45f666
System Controlleragile-live-system-controller-5.0.0-1820bd9.zip826c99d8bc679ebe37762a4cfd408655807b19ac36419f826c9fbee02af1fe91

Library details

libacl-ingest.so

Version: 11.0.0

Library containing the core Ingest functionality used by the acl-ingest executable.

libacl-productionpipeline.so

Version: 12.0.0

Library containing the MediaReceiver, MediaStreamer and ControlDataReceiver classes, used to implement a Rendering Engine. Also used by the acl-renderingengine application

libacl-controldatasender.so

Version: 11.0.0

Library containing the ControlDataSender class, used to send control messages to a ControlDataReceiver component.

Changelog

  • It is now possible to use hostnames instead of just IP addresses for ACL_SYSTEM_CONTROLLER_IP environment variable.
  • HTTPS and client authentication are now enabled by default in the system
  • The new environment variable ACL_CUSTOM_CA_CERT_FILE makes it possible to set a custom CA certificate to use for verifying the system controller’s certificate. This can be used in cases when the CA certificate cannot be added to the list of OS trusted CA certificates.
  • SRT logs are now printed to the components’ log files and not just to the terminal

Ingest 11.0.0

  • SRT connections to Production Pipelines will now automatically try to reconnect in case the network link goes down.

Rendering Engine 3.0.0

  • The Rendering Engine now features a built in HTML renderer using the Chromium web engine through Chromium Embedded Framework. The HTML renderer is capable of opening multiple “browsers”, connected to input slots of the operator’s choice, rendering HTML graphics hosted by HTTP servers or even loading regular webpages.
  • A new chroma key node was added to make green screen effects possible.
  • The internal audio mixer now features a high pass and a low pass filter

Production Pipeline 12.0.0

  • The cadence and speed/quality balance can now be set for the MediaStreamer and Multi view outputs
  • MediaStreamer now supports multiple output streams (e.g. both SRT and UDP, or multiple SRTs and UDP outputs with different settings), as long as they use the same encoding settings.
  • Performance of the Production Pipeline has been improved. The load on the NvDec chip is reduced by up to ~50% and the load on the CUDA cores reduced by up to ~60% in certain conditions.
  • The Multi View outputs now show peak meter audio bars for all views, which makes solving audio problems much easier, as one can see both the audio of the incoming and outgoing video streams.
  • The Random Access Indicator (RAI) is now correctly set in the MPEG-TS output streams
  • Outputs with SRT in caller mode will now start even if the connection was not successfully made. The SRT connection will try to connect until it succeeds, or is manually closed down. In case the network link is broken, the SRT caller will try to keep connecting until it succeeds or is manually closed down.

Control Data Sender 11.0.0 and Control Data Receiver 12.0.0

  • The release now features a new acl-websocketcontrolpanel, which works like the already existing acl-tcpcontrolpanel, but allows for multiple clients to connect via WebSocket to the control panel instead.
  • It is now possible to use hostnames instead of just IP addresses when connecting a Control Data Sender or Receiver to another Control Data Receiver.
  • Fix bug where it was not possible to disconnect a Control Data Sender/Control Panel from a Receiver and connect it to another Receiver on another port.

System Controller 5.0.0

  • The REST API now correctly flags parameters with a default value in the Swagger documentation. These values does not need to be passed in the JSON blob with the REST API call. Parameters without a default value are correctly flagged as required in the documentation.
  • The Outputs part of the REST API has been updated to support multiple output streams from the same output component. The name of the REST API endpoints has been moved from pipelines/{uuid}/outputs/{output_uuid}/stream to pipelines/{uuid}/outputs/{output_uuid}/streams to reflect this. The POST request will return an id integer to identify the stream within the Output component. A new endpoint [DELETE] pipelines/{uuid}/outputs/{output_uuid}/streams/{stream_id} has been added to close a specific stream. All streams of an output can be closed with the old [DELETE] pipelines/{uuid}/outputs/{output_uuid}/streams endpoint.
  • System controller now logs to file. Default log location is /tmp with the log file prefixed with acl-system-controller.
  • Requests to the REST API are now rate limited to prevent overloading the components and to mitigate DOS attacks.
  • The IPBB cadence and speed/quality balance can now be specified for the encoder in both Output streams and Multiview output streams.
  • Prometheus endpoint now stops reporting metrics for closed streams.
  • Improve execution time of [DELETE] streams/{stream_uuid}
  • Authentication has been added to the Prometheus endpoint.
  • The parameters ip and port in the [GET] pipelines/{uuid}/outputs/{output_uuid}/streams has been corrected to remote_ip and remote_port. Their values are now reported correctly.
  • Security of the System Controller has been improved in several ways.
  • Prometheus endpoint has been updated with some missing statistics
  • The missing audio_mapping parameter has been added to the [GET] ingests/{uuid}/streams/{stream_uuid} and [GET] pipelines/{uuid}/streams/{stream_uuid} endpoints.
  • The sent_bytes parameter of the output statistics is now incremented as expected for both Multi View outputs and Output streams.
  • Fixed a bug where the System Controller application would crash when started with a filename as -settings-path parameter.

Known limitations

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

MPEG-TS over UDP

For Outputs and multi-view outputs it is currently not possible to bind to a specific IP and port with MPEG-TS over UDP, even if local_ip and local_port are exposed in the REST API.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

Security

No known issues

1.5.3 - Release 4.0.0

Agile Live 4.0.0 release information

Build date

2023-06-16

Release status

Type: Fourth production ready release

Release content

Product version

4.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest and Rendering Engine binaries, headers, and shared librariesagile-live-4.0.0-d02f52d.zip9f95bfe78ab7d295268ad2de913ed18cda8b9407d977feb9afc7f5a738034a73
System Controlleragile-live-system-controller-4.0.0-745ecee.zipf19331fffa499db7d57d10c99af09b78e94fec5459188d6df832a009b0b92947

Library details

libacl-ingest.so

Version: 10.0.0

Library containing the core Ingest functionality used by the acl-ingest executable.

libacl-productionpipeline.so

Version: 11.0.0

Library containing the MediaReceiver, MediaStreamer and ControlDataReceiver classes, used to implement a Rendering Engine. Also used by the acl-renderingengine application

libacl-controldatasender.so

Version: 9.0.0

Library containing the ControlDataSender class, used to send control messages to a ControlDataReceiver component.

Changelog

  • The system now requires Chrony as the NTP client for time synchronization. See NTP instructions for more details. The applications will not start if Chrony reports an drift greater than 5 ms.
  • New environment variables ACL_LOG_MAX_FILE_SIZE and ACL_LOG_MAX_LOG_ROTATIONS to control the number and size of the rotated log files for the applications
  • Fix parsing of boolean environment variables

Ingest 10.0.0

  • Support for transporting up to 16 channels of audio to the production, where a subset of the channels can be selected.
  • Added support for using Opus as audio codec in transport to the Production Pipeline. This codec has a lower delay compared to the existing AAC codec. The user can now select codec per connected stream.
  • Improved handling of NDI sources.
  • Handle cases when SDI sources deliver one extra or one too few audio sample.
  • The built-in MediaSourceGenerator now has a lower audio level of -20 LUFS.

Rendering Engine 2.0.0

  • New audio mixer implementation with per-input-strip three-band parametric equalizer, compressor and panning.
  • New automatic transition types: left and right wipe
  • Add support for picture-in-picture effects. Currently the rendering engine support two separate picture-in-picture effects with an additional graphic effect on top.
  • All control commands executed by a rendering engine is now written to a log file in /tmp
  • Fix bug where disconnecting a source would leave the last frame frozen in the input slot with corrupted audio.

Production Pipeline 11.0.0

  • It is now possible to include input slots where no stream has been connected yet to a multi-view output. The view will be empty until a source has been connected to that input slot, with the label visible.
  • Views in the multi-view will remain after the corresponding input slot has been disconnected, showing a black frame with the label. The video will automatically turn up again when another stream is connected to the same input slot.
  • Fix bug where the multi-view output would stop sending video when none of the sources in the multi-view were connected.
  • Add support for SRT in caller mode for multi-view outputs and MediaStreamer outputs.
  • Add support for setting the SRT latency and an optional passphrase for the multi-view outputs and MediaStreamer outputs.
  • MediaReceiver API has a new method removeCustomMultiViewSourceInput to remove a custom feedback input earlier registered using getCustomMultiViewSourceInput.
  • Improved latency of video decoder with ~1 frame.

Control Data Sender 9.0.0 and Control Data Receiver 10.0.0

  • Fix application crash with acl-tcpcontrolpanel on connection failure.
  • Updated control command protocol for video commands, where the first word addresses the node in the graph to make the change to. This allows for the same node to be used multiple times. See Rendering Engine commands for more details on the new protocol.
  • Updated API where multiple, separate control commands can be sent in the same message, guaranteed to be delivered to the Rendering Engine at the same time point. The new method sendMultiRequestToReceivers is used to send such messages. The old API for sending just a single control command per message is unchanged.
  • Raise the maximum control message length to 65535 bytes.

System Controller 4.0.0

  • Expose a number of new metrics from the components for system monitoring in the REST API and Prometheus endpoint, including average/min/max encode and decode durations per stream, frame counters for video and audio in multiple locations, statistics for outgoing output streams and round trip time and measured bandwidth on the contribution links.
  • The POST /streams endpoint now require an audio_mapping to know which audio channels to transport to the production. Use "[[0,1]]" for the same behavior as in previous versions (i.e. transport only channels 0 and 1, encoded as stereo).
  • New counter lost_frames for Pipeline streams. It counts fully lost frames, not only broken frames, as the received_broken_frames counter.
  • The counter lost_packets in the GET /ingests/{uuid}/streams endpoints has been removed in favor for the lost_packets and dropped_packets in the Pipeline.
  • Counter queuing_video_frames has changed name to video_frames_in_queue.
  • REST API now correctly returns the selected port when automatic port selection is requested (by setting the local_port to 0), instead of returning the port number as 0.
  • REST API now show if sources are active or inactive, instead of hiding inactive sources (a source is active if it is ready to be used, as opposed to an inactive source, which has been seen earlier, but not any longer)
  • Fix bug where the wrong port numbers of Control Connections would be shown in REST-API for port numbers automatically assigned by the OS.

Known limitations

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

MPEG-TS over UDP

For Outputs and multi-view outputs it is currently not possible to bind to a specific IP and port with MPEG-TS over UDP, even if local_ip and local_port are exposed in the REST API.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

Security issues

There is no rate limiting implemented in any of the components. Should the application be running in a network where ports are accessible to unauthorized users, there is a risk of a denial of service (DOS). The network should be configured with firewall rules closing out unauthorized users.

Encryption (HTTPS) is not enabled by default in acl-system-controller. This means that pre-shared keys (PSK) used for encrypted communication between components and the System Controller will be exchanged in the clear and could be revealed.

Client authentication is not enabled by default in acl-system-controller so anyone with access to HTTP on the machine hosting acl-system-controller will have access to the REST API.

Even when client authentication is enabled, there is no enforcement of the length or format of the password. Also note that HTTPS should be enabled when using client authentication since the credentials would otherwise be sent in clear text.

It is strongly recommended to enable both HTTPS and client authentication.

1.5.4 - Release 3.0.0

Agile Live 3.0.0 release information

Build date

2023-01-23

Release status

Type: Third production ready release

Release content

Product version

3.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest and Rendering Engine binaries, headers, and shared librariesacl-3.0.0-d4de107.zip4743f2c8c6fe74b09d04a0210747276fac7ef9fa0145a7ee51ec54de4def84dc
System Controlleracl-system-controller-3.0.0-10046c8.zip919f469ed773bb3ad65735d41dd0942e08b91bd23a317f7227ccdccbc2807437

Library details

libacl-ingest.so

Version: 9.0.0

Library containing the core Ingest functionality used by the acl-ingest executable.

libacl-productionpipeline.so

Version: 10.0.0

Library containing the MediaReceiver, MediaStreamer and ControlDataReceiver classes, used to implement a Rendering Engine. Also used by the acl-renderingengine application

libacl-controldatasender.so

Version: 9.0.0

Library containing the ControlDataSender class, used to send control messages to a ControlDataReceiver component.

Changelog

Ingest 9.0.0

  • Ingesting interlaced sources is now supported both with the Intel and Nvidia encoders. De-interlacing is automatically applied to interlaced input, so no extra work is needed by the user of the REST API when setting up the stream compared to a progressive source. The implementation supports de-interlacing 50i sources into 50p.
  • The Ingest now supports encoding JPEG thumbnails using Nvidia GPUs. For now, only the first Nvidia GPU will be used on multi-GPU systems.
  • Earlier when encoding HEVC with the Intel encoder, the setup would fail in case any of the fast, faster, good or better speed/quality settings were used, as these were not supported by the encoder. Now these settings are automatically changed to the closest supported setting, i.e. fast and good is changed to balanced, faster to fastest and better to best.
  • The Intel JPEG encoder now supports encoding JPEGs with a width that is not evenly divisible by 16. Also requests for thumbnails with odd number of pixels in width/height will automatically be encoded with one extra pixel in width/height compared to the request, instead of failing the request.
  • The Intel JPEG encoder now supports encoding thumbnails of interlaced sources.

Rendering Engine 1.0.0

No new features since last release.

Production Pipeline 10.0.0

  • The network endpoints of the incoming streams from the Ingests are now closed after the Ingest has connected.

Control Data Sender 9.0.0 and Control Data Receiver 10.0.0

  • Support for connecting multiple ControlDataSenders (or Receivers) to a single ControlDataReceiver is now working again.
  • Improved verification of the established connection between ControlData components.
  • Message delay can now be set per incoming connection to a ControlDataReceiver.

System Controller 3.0.0

  • New version of the REST API, v2, which is served from /api/v2. The API has been reorganized and cleaned up to make it easier to use.
  • Streams and Control Connections now get their own unique UUIDs when created using the REST API. This UUID is then used to reference the connection when making changes to and closing the connection. The UUID is returned when the connection is created and is also shown when querying information from the components on both sides of the connection. The old connection_id concept has been completely removed.
  • The endpoints related to Control Connections are now on the top level and the same endpoints are used whether the connection is originating from a ControlDataSender or a ControlDataReceiver. Both Control Connections and Streams are now closed using their UUID and the corresponding DELETE endpoints. Also the PATCH endpoints use the UUID of the connection to identify the connection to make changes to.
  • The Output and Control Receiver endpoint has been moved in under the Pipeline endpoint to better show their tight connection. When querying the Pipeline endpoint it will return its Outputs and Control Receivers.
  • The parameter id used for an Ingest’s sources has been changed to source_id.
  • The parameters resolution_x and resolution_y have been changed to width and height.
  • The endpoint for /components has been removed in favor for the /ingests, /pipelines and /controlpanels endpoints.
  • The thumbnail endpoint now has a new parameter encoder where the user can explicitly request that a certain encoder should be used for encoding the thumbnail. Current options are intel_gpu, nvidia_gpu or auto, where the last option will make the Ingest select the best encoder that is supported on the hardware the Ingest is running on.

Known limitations

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

Audio channels

Only stereo audio is supported with two channels embedded per connected input.

Security issues

There is no rate limiting implemented in any of the components. Should the application be running in a network where ports are accessible to unauthorized users, there is a risk of a denial of service (DOS). The network should be configured with firewall rules closing out unauthorized users.

Encryption (HTTPS) is not enabled by default in acl-system-controller. This means that pre-shared keys (PSK) used for encrypted communication between components and the System Controller will be exchanged in the clear and could be revealed.

Client authentication is not enabled by default in acl-system-controller so anyone with access to HTTP on the machine hosting acl-system-controller will have access to the REST API.

Even when client authentication is enabled, there is no enforcement of the length or format of the password. Also note that HTTPS should be enabled when using client authentication since the credentials would otherwise be sent in clear text.

It is strongly recommended to enable both HTTPS and client authentication.

1.5.5 - Release 2.0.0

Agile Live 2.0.0 release information

Build date

2022-11-17

Release status

Type: Second production ready release

Release content

Product version

2.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest and Rendering Engine binaries, headers, and shared librariesacl_2.0.0-4ae95d4.zipdacc86efa0c2c08b28658e4218abd4ba58f24381a37eba93f0dbac10d9702e2a
System Controlleracl_system_controller_2.0.0-85ac2cd.zip085465799bae8ceaa201ad462efedcdc19a2ea2f80e99c1332efc88ac0ce82dd

Library details

libacl-ingest.so

Version: 8.0.0

Library containing the core Ingest functionality used by the acl-ingest executable.

libacl-productionpipeline.so

Version: 9.0.0

Library containing the MediaReceiver, MediaStreamer and ControlDataReceiver classes, used to implement a Rendering Engine. Also used by the acl-renderingengine application

libacl-controldatasender.so

Version: 8.0.0

Library containing the ControlDataSender class, used to send control messages to a ControlDataReceiver component.

Changelog

The supported OS has changed from Ubuntu 20.04 LTS to Ubuntu 22.04 LTS. Official support for Ubuntu 20.04 LTS is dropped from this release.

Ingest 8.0.0

  • Changed to epoch aligned timestamps
  • Improve duplicating and dropping of frames to cover up drifting cameras
  • Expose counters for dropped, duplicated and lost frames per source in the REST API
  • Fix a memory leak when generating thumbnails
  • Interlaced sources are now shown in the REST API and correctly marked as interlaced
  • Improved support for detecting connection and disconnection of SDI cables at runtime, as well as changes in the format of the sent SDI stream.
  • Applications are now stopped by pressing Ctrl-C instead of pressing enter to prevent accidental stopping
  • Thumbnails and source info are now cached for each source to improve response time in the REST API. This means that sources that are not connected to any production will only update its thumbnails and source info every ~5 seconds or so. Sources that are connected will update the info continuously.
  • The field active for sources in the REST API was not working before and has now been removed in favor for a new field in_use which indicates if a source is currently being streamed somewhere or not.
  • Log files will now get a unique name by appending the date of creation to the filename
  • Log files will now have the same log level as the terminal output
  • Appending the --help flag to the ingest executable will print information about the binary and list the environment variables
  • A stack trace is now printed in case the application should crash

Rendering Engine 1.0.0

  • First version of the Rendering Engine application
  • Support for program, preview and cutting between them
  • Support for fading between sources over a given time
  • Support for graphics with key (alpha) by ingesting the fill and key (color and alpha) as two separate sources
  • Support for fade to black
  • Support for setting the audio volume per source

Production Pipeline 9.0.0

  • Support for tally borders in the Multi-view generator with new API for setting and clearing the borders from the Rendering Engine in the MediaReceiver class.
  • Updated API for passing video memory to and from the Rendering Engine, now uses RAII classes for automatic memory handling. See upgrade guide for more details.
  • The MediaReceivernow passes the mRenderingTimestamp to the Rendering Engine, i.e. the timestamp when the frame was delivered.
  • Alignment is internally rounded to the nearest even frame time. This together with the changes in the Ingest results in that the frames delivered to the RenderingEngine will have rendering timestamps that are evenly devisable by the frame time.
  • PTS in MediaStreamers are now calculated based on the mRenderingTimestamp, instead of a newly taken timestamp when the frame was sent to the MediaStreamer. This will make the PTSes of the output streams equidistant, even if the Rendering Engine jitters slightly.
  • New class PipelineSystemControllerInterfaceFactory to help Rendering Engine implementors in creation of SystemControllerConnections by reducing code duplication

Control Data Sender 8.0.0 and Control Data Receiver 9.0.0

  • The control channel between ControlDataSenders and ControlDataReceivers are now encrypted by default. Read more about it in the security tutorial
  • The support for connecting multiple ControlDataSenders or ControlDataReceivers to another ControlDataReceiver is temporarily disabled.

System Controller 2.0.0

  • Added support for HTTPS communication with the REST API and encrypted connections between the components and the System Controller. Read about how to activate it in the security tutorial
  • Components now automatically reconnects to the System Controller in case they loose connection to it. This means that the System Controller can be restarted during a broadcast and all components will automatically reconnect to it once it turns up again on the network. It also means that components can be started before the System Controller and get connected as soon as the System Controller is started
  • REST API now features basic authentication. Read more about it in the security tutorial
  • Streams (of audio and video) between Ingests and Production Pipelines are now automatically encrypted when set up by the System controller
  • Control connections between Control Panels and Production Pipelines are now automatically encrypted when set up by the System controller
  • Fix a bug where the System Controller would not search for the config file in all the directories listed in the documentation. Also make the application search in the application’s directory and not only the current working directory.
  • New endpoint [PATCH] /pipelines/{uuid}/streamconnections/{connection_id} to change the alignment of an already created stream during runtime. Note that changing the alignment will cause the audio and video of that stream to make a sudden jump and/or freeze for a moment, so it is not recommended to do this on stream connections that are on air
  • The endpoint [POST] /stream now has improved error messages in case the System Controller failed to start the stream. The endpoint also closes the Pipeline’s stream connection instead of leaving it open in case the Ingest failed to start the stream
  • The [DELETE] endpoints for the specific components has been removed in favor for the general [DELETE] /components/{uuid} endpoint
  • Fix a bug where the System Controller would crash in some rare cases when a component is shut down at the same time as a REST request is using that component.
  • Fix some false positive log outputs

Known limitations

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

Number of Control Senders per Control Receiver

For now the system is limited to only connect one Control Sender (or Receiver) to another Control Receiver. This means that, for now, it is only possible to connect a single Control Panel to a production.

Audio channels

Only stereo audio is supported with two channels embedded per connected input.

Security issues

There is no rate limiting implemented in any of the components. Should the application be running in a network where ports are accessible to unauthorized users, there is a risk of a denial of service (DOS). The network should be configured with firewall rules closing out unauthorized users.

Encryption (HTTPS) is not enabled by default in acl-system-controller. This means that pre-shared keys (PSK) used for encrypted communication between components and the System Controller will be exchanged in the clear and could be revealed.

Client authentication is not enabled by default in acl-system-controller so anyone with access to HTTP on the machine hosting acl-system-controller will have access to the REST API.

Even when client authentication is enabled, there is no enforcement of the length or format of the password. Also note that HTTPS should be enabled when using client authentication since the credentials would otherwise be sent in clear text.

It is strongly recommended to enable both HTTPS and client authentication.

1.5.6 - Release 1.0.0

Agile Live 1.0.0 release information

Build date

2022-06-23

Release status

Type: First production ready release

Release content

Product version

1.0.0

Release artifacts

DetailsFilenameSHA-256
Ingest binary, headers, and shared librariesacl_v1.0.0-336067b-release.zipf2beb75a0109403860d455bde14618e4e7a9bbf690b5a7ed79f743fb19224cef
Ingest binary, Headers, and shared libraries, debug buildacl_v1.0.0-336067b-debug.zipe555ea542b84f73008efa0ab3769835e456c31f499ef88d6a315bb0506592d04
System Controlleracl_system_controller_v1.0.0-0f2417f.zip82094afe07da10c81d96fab03babca1737ca48f57c2cde9584babebbe44db947

Library details

libacl-ingest.so

Version: 7.0.0

Library containing the IngestApplication class used to implement an Ingest component.

libacl-productionpipeline.so

Version: 8.0.0

Library containing the MediaReceiver, MediaStreamer and ControlDataReceiver classes, used to implement a Rendering Engine.

libacl-controldatasender.so

Version: 7.0.0

Library containing the ControlDataSender class, used to send control messages to a ControlDataReceiver component.

Changelog

Ingest 7.0.0

  • New metrics are available for the Ingest streamconnections in the REST API that can be used to monitor the streams.
  • Fixed bug where the Ingest would crash with a std::runtime_error if grabbing a thumbnail on hardware without an Intel CPU with integrated GPU.
  • Improved error messages for encoders and sources.
  • Missing fields in the REST API for the Ingests have been added, such as max_network_latency_ms for streamconnections.
  • Logs are now automatically flushed every 5 seconds.
  • The class StaticIngestSystemController has been removed, please use the SystemControllerConnection class and the system controller instead.

Production Pipeline 8.0.0

  • New metrics are available for the Pipeline streamconnections and Output in the REST API that can be used to monitor the streams.
  • Fixed the AUD format in MEPG-TS output of the Pipelines when using HEVC, which earlier caused clicks in the audio channel and a lot of Invalid NAL unit 4, skipping. errors when playing back the streams using ffmpeg.
  • Support for labels (so-called “Under Monitor Display”, UMD) in the multi-view outputs. The labels are set through the REST API when setting up multi-view outputs and can be changed at runtime.
  • Missing fields in the REST API for the Pipelines have been added, such as max_network_latency_ms, alignment_ms and convert_color_range for streamconnections.
  • Fixed DTS calculation for output streams in both the Multi-view generator and Output components.
  • The network connections between a ControlDataReceiver and other ControlDataReceivers are now using TCP as protocol instead of SRT, which means that the messages are delivered as soon as they arrive and that no control messages will be dropped due to to timeouts in the transport.
  • Fixed a minor CUDA memory leak in the multi-view generator that caused a slow, constantly growing GPU memory usage.
  • Fixed CUDA memory corruption sometimes occurring when stopping and quickly restarting a multi-view output.
  • Nvidia Ampere GPUs are now working with older CUDA drivers than version 510.
  • Logs are now automatically flushed every 5 seconds.
  • The classes StaticMediaReceiverSystemController and StaticMediaStreamerSystemController have been removed, please use the SystemControllerConnection class and the system controller instead.

Control Data Sender 7.0.0 and Control Data Receiver 8.0.0

  • The network connections between a ControlDataSender and ControlDataReceivers are now using TCP as protocol instead of SRT, which means that the messages are delivered as soon as they arrive and that no control messages will be dropped due to timeouts in the transport.
  • The classes StaticControlDataSenderSystemController and StaticControlDataReceiverSystemController have been removed, please use the SystemControllerConnection class and the System Controller instead.

System Controller 1.0.0

  • Support for setting CORS and custom HTTP response headers in the configuration file.
  • Improved validation of HTTP request payloads and improved error messages.
  • New endpoint for deleting any type of component, [DELETE] /component.
  • New, built-in Prometheus exporter, accessible through endpoint at [GET] /metrics.
  • The version of the running system controller is now returned in each HTTP response in the X-Binary-Version header.

Known limitations

GPU performance

The GPU utilization in the Ingest status message is currently not working. Use intel_gpu_top and/or nvidia-smi instead.

Drivers

You need to install the CUDA Toolkit on Ingest machines, even if they don’t have Nvidia cards.

MPEG-TS output

The timestamps in the MPEG-TS output are not equidistant, which might confuse some playback tools. Playback the stream using a tool that works for now, such as ffmpeg.

Pre-shared key

The pre-shared key used to authorize components in the System controller is currently hard-coded into the Ingest application. This means that the psk in the System controller’s example config file must be used, otherwise is it not possible to connect an Ingest to the system.

1.5.7 - Upgrade instructions

Agile Live upgrade instructions

Upgrade to 6.0.0 from 5.0.0

System Controller

  • In endpoints /ingests/{uuid}?expand=true, /ingests/{uuid}/sources and /ingest/{uuid}/sources/{source_id} these three metrics has been split into audio and video variants: acl_ingest_source_dropped_frames has been split into acl_ingest_source_dropped_audio_frames and acl_ingest_source_dropped_video_frames, metric acl_ingest_source_duplicated_frames is split into acl_ingest_source_duplicated_audio_frames and acl_ingest_source_duplicated_video_frames; and acl_ingest_source_lost_frames is split into acl_ingest_source_lost_audio_frames and acl_ingest_source_lost_video_frames.
  • In case the entropy of the PSK set in the System Controller was too low, the System Controller won’t start. Generate a new PSK and use that one.
  • The System Controller does not longer search for the configuration file acl_sc_settings.json in the directories /etc/acl_system_controller, /app,/service,/acl_system_controller or /opt/acl_system_controller. Either put the file in the current working directory of the system controller application, in the directory /etc/opt/agile_live, or explicitly point at the directory of the config file using the flag --settings-path <PATH> when starting the System Controller.

Rendering Engine

  • For the acl-tcpcontrolpanel the environment variable ACL_TCP_ENDPOINTS has changed name to ACL_TCP_ENDPOINT and only accept a single endpoint. This endpoint will now accept multiple connections.

C++ SDK

  • AlignedFrame::PixelFormat has been replaced with ACL::PixelFormat, found in PixelFormat.h.
  • ISystemControllerInterface::sendRequest has been replaced with ISystemControllerInterface::sendMessage, the System Controller will no longer send a response on messages. Since connection is over TCP, if the message could be sent, it has arrived properly to the System Controller, so there is no need for a response message that verifies that.

Upgrade to 5.0.0 from 4.0.0

System Controller

  • Endpoints /pipelines/{uuid}/outputs/{output_uuid}/stream have been moved to /pipelines/{uuid}/outputs/{output_uuid}/streams to indicate multiple streams for the same Output can be created. The POST request takes the same parameters as before, but returns an ID of the newly created stream, which is globally unique together with the UUID of the Output. As of now, it is only possible to start multiple streams if the encoder settings match for all streams. Use the new endpoint [DELETE] /pipelines/{uuid}/outputs/{output_uuid}/streams/{stream_id} to stop a stream with a given ID.
  • The response of [GET] /pipelines/{uuid}/outputs/{output_uuid}/streams differs from the old variant. In the new one not just a single active stream is presented, but a list of active_streams.
  • The [POST] /pipelines/{uuid}/outputs/{output_uuid}/stream and [POST] /pipelines/{uuid}/multiviews endpoints now support setting the pic_mode and speed_quality_balance to control the quality of the encoding. While they don’t have to be explicitly specified in the REST API request as they have default values (pic_mode_ip and balanced), it might be desirable to manually specify them.

ProductionPipeline

  • MediaReceiver::start has changed signature. It now takes a CUcontext as the second parameter, which should be a CUDA context reference to the device to run the CUDA operations on.
  • The MediaReceiver::Settings struct has a new parameter mAlignedFrameFreeStream which should be a CUDA stream within the CUDA context passed to the MediaReceiver::start method, to use as the stream to make the asynchronous free on, after all the DeviceMemory pointers have been released.
  • MediaStreamer::configure now has a second parameter to a CUcontext, which is the CUDA context defining which device to run the MediaStreamer on.
  • PipelineSystemControllerInterfaceFactory constructor now takes an extra customCaCertFile parameter, pointing out an optional CA certificate file to use for validating certificates from the System Controller.

Upgrade to 4.0.0 from 3.0.0

System Controller

  • The endpoint POST /streams now require two additional parameters audio_format and audio_mapping. The first one selects if AAC-LC or the new Opus codec should be used for audio encoding. AAC-LC has slightly higher quality, but is slower to encode. Opus has a lower latency and gives better quality at lower bitrates. The second parameter, audio_mapping tells the Ingest which audio channels to pick from the source and if they should be encoded as mono or stereo streams. (Stereo streams save bandwidth, but does not need to be used as stereo in the Rendering Engine). For example the mapping [4, [1, 2], 0] will result in 4 channels out in the Rendering Engine, where the channel with index 4 is output at index 0 and encoded as a mono channel, index 1 and 2 in the Ingest are encoded as stereo and output at channels 1 and 2 in the output and channel 0 in the input is encoded as mono and output to channel 3 in the output. Channel 4 in the input (and 5 and above) are ignored. To get the same behavior as in the previous release, pass AAC-LC and [[0,1]] respectively for audio_format and audio_mapping.
  • Metric queueing_video_frames has changed name to video_frames_in_queue.
  • In POST /pipelines/{uuid}/outputs/{output_uuid}/stream and POST /pipelines/{uuid}/multiviews the parameters ip and port are removed and replaced by four parameters called local_ip, local_port, remote_ip and remote_port. In MPEG-TS over SRT mode, their useage depends on the SRT mode. When in listener mode (srt_mode == listener) only the local_ip and local_port are used to set the address to listen to. Set local_port to 0, to make the OS automatically pick an available port. In SRT caller mode both local_ip, local_port and remote_ip, remote_port are used. The remote_* ones define the remote address to connect to and the local* ones the local address to bind to. To get the old behavior, where the local bind address is automatically chosen, set local_ip to 0.0.0.0 and local_port to 0 to automatically pick an unused port. For MPEG-TS over UDP mode, set the address to send the stream to using the remote_* parameters (The local_* variants should be present but must be set to 0.0.0.0 and 0, currently).
  • The output of the GET /pipelines/{uuid}/outputs/{output_uuid}/stream and GET /pipelines/{uuid}/multiviews endpoints have changed the layout. See the REST API documentation for more details.
  • The video_kilobit_rate parameter in GET /pipelines/{uuid}/streams/{stream_uuid} has been removed. Use the same parameter in the GET /ingests/{uuid}/streams/{stream_uuid} endpoint instead.
  • The counter lost_packets in the GET /ingests/{uuid}/streams/{stream_uuid} endpoint has been removed in favor for the lost_packets and dropped_packets in the Pipeline.

ProductionPipeline

  • The API of ControlDataReceiver::IncomingRequest has changed to get an std::vector of messages (std::vector<uint8_t>), to allow multiple messages to be delivered at the same time point. Just loop through the messages and handle them as before.
  • The settings for mDebugVideo and mDebugAudio has been removed from MediaReceiver::Settings.

Upgrade to 3.0.0 from 2.0.0

System Controller

  • The System Controller uses the new API prefix /api/v2, so all calls must update to this API version. The old API /api/v1 has been removed.
  • All calls to the Control Receiver and Output endpoints must be updated, as these have been moved in under the /pipelines endpoint. See the REST API reference for details.
  • When setting up Control Connections, the old [POST] /controlpanels/{uuid}/controlconnections and [POST] /controlpanels/{uuid}/controlconnections endpoints have been replaced with a single endpoint [POST] /controlconnections. The sending side component (whether a Control Panel or a Control Receiver) is passed as a parameter in the JSON HTTP body. Delete endpoints for controlconnections formerly under Control Panel and Control Receiver, have been replaced with a single endpoint [DELETE] /controlreceivers/{uuid}, which will close both sides of the connection.
  • When closing streams, the [DELETE] /ingests/{uuid}/streamconnections/{connection_id} and [DELETE] /pipeline/{uuid}/streamconnections/{connection_id} have been replaced by a single endpoint [DELETE] /streams/{uuid}, which will close down both sides of the Stream.
  • The endpoints for getting information from either the Ingest or Pipeline end of a Stream has been moved from [GET] /ingests/{uuid}/streamconnections/{connection_id} and [GET] /pipeline/{uuid}/streamconnections/{connection_id}to [GET] /ingests/{uuid}/streams/{stream_uuid} and [GET] /pipeline/{uuid}/streams/{stream_uuid}, where stream_uuid is the system-wide, unique identifier of the stream and is the same UUID on both the Ingest and Pipeline side of the connection in contrast to the old connection_id which was different in the Ingest and the Pipeline.
  • The endpoint for changing the alignment of a stream has been moved from [PATCH] /pipelines/{uuid}/streamconnections/{connection_id} to [PATCH] /streams/{uuid}.
  • The parameter id referring to a source has changed name to source_id in [POST] /streams and in responses from the Ingest when querying for information on the Sources or Streams.
  • The parameters resolution_x and resoulution_y have changed name to width and height in several endpoints, among others the [POST] /streams and [POST] /ingests/{uuid}/sources/{source_id}/thumbnail.
  • The thumbnails endpoint has been moved from [POST] /ingests/{uuid}/thumbnail to [POST] /ingests/{uuid}/sources/{source_id}/thumbnail, passing the source_id parameter in the path instead of the JSON HTTP body.
  • The new encoder parameter must be specified when requesting thumbnails using the [POST] /ingests/{uuid}/sources/{source_id}/thumbnail endpoint. Set it to auto unless a specific implementation is required.

Upgrade to 2.0.0 from 1.0.0

System Controller

  • Make sure to generate a new PSK (pre-shared key) for the acl_sc_settings.json file. This will be used to authorize components connecting to the System controller. All components connecting to the System controller must use the same PSK set using the environment variable ACL_SYSTEM_CONTROLLER_PSK. In case a component is started without the environment variable it will log an error and stop. Read more about this in the Security tutorial.

ProductionPipeline

  • The API of the former struct AlignedData::DataFrame has changed.
    • The namespace AlignedData has been removed and the struct itself has been renamed to AlignedFrame. The enums CompressedVideoFormat and PixelFormat and typedef AudioSampleRow have been moved inside the struct.
    • The field mPTS has been removed and replaced by two new fields mCaptureTimestamp and mRenderingTimestamp, where the first is the TAI timestamp in mircoseconds since the UNIX epoch when the frame was captured by the Ingest and the second one is the timestamp when the frame was delivered to the Rendering Engine from the MediaReceiver. Both these timestamps are rounded to the nearest even frame step since the UNIX epoch, which should make it easier to group frames with the same rendering time. The mRenderingTimestamp is also used by the OutputStreamer to calculate the timestamps for the outgoing streams, so in case the Rendering Engine creates new AlignedFrame instances, make sure this value is incremented correctly for each frame that is put to the OutputStreamer.
    • The CUDA pointer mVideoDataCudaPtr has been removed in favor for an std::shared_ptr to an RAII class called DeviceMemory that keeps track of the CUDA memory pointer adn releases the memory automatically once not longer used by anyone. This makes it possible for the Rendering Engine to make copies of the shared pointer and then discard the AlignedFrame it was delivered with, in order to, for instance, cache the video frame or to handle video and audio data separately. Please do remember that the DeviceMemory from the AlignedFrames delivered by the MediaReceiver is read-only and should never be changed by any CUDA kernel, as this memory is also used by the multi-view generator to generate the multi-view outputs. The Rendering Engine might copy the shared pointer and keep it at long as it wants to, but never change the content of the DeviceMemory or write to the CUDA memory pointed to by it. AlignedFrames (and DeviceMemory instances made outside of an AlignedFrame) created by the Rendering Engine can of course be changed and used freely.

1.6 - Reference

Reference documentation for the API:s

1.6.1 - Agile Live 6.0.0 developer reference

Agile Live 6.0.0 developer reference

1.6.1.1 - REST API v2

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v2.

1.6.1.2 - Agile Live Rendering Engine command documentation

Reference for the Agile Live Rendering Engine commands

This page describes all the commands available in the Agile Live Rendering Engine.

Command protocol

All commands to the Agile Live Rendering Engine is sent as human readable strings and are listed below. The Rendering Engine expect no line termination, meaning that you do not need to append any type of new line (\n) characters, or string termination (\0) characters.

Video commands

Background

The data path of the video mixer in the Rendering Engine looks as follows:

The video mixer data path

There are eight different node types used in this mixer.

  • The Transition node is used to pick which input slots to use for the program and preview output. The node also supports making transitions between the program and preview.
  • The Select node simply forwards one of the available sources to its output.
  • The Transform node takes one input stream and transforms it (scaling and translating) to one output stream.
  • The Alpha combine node is used to pick two input slots (or the same input slot) to copy the color from one input and combine it with some information from the other input to form the alpha. The color will just be copied from the color input frame, but there are several modes that can be used to produce the alpha channel in the output frame in different ways. This is known as “key & fill” in broadcasting.
  • The Alpha over node is used to perform an “Alpha Over” operation, that is to put the overlay video stream on top of the background video stream, and let the background be seen through the overlay depending on the alpha of the overlay. The node also features fading the graphics in and out by multiplying the alpha channel by a constant factor.
  • The Chroma Key node takes one input stream, and by setting appropriate parameters for the keying, it will remove areas with the key color from the incoming video stream both affecting the alpha and color channels
  • The Fade to black node takes one input stream, which it can fade to or from black gradually, and then outputs that stream.
  • The Output node has one input stream and will output that stream out from the video mixer, back to the Rendering Engine

There are six different flows into this mixer. There is the one starting with the Transition node, which represents the main program that is being produced. Overlaying on top of that is one key+fill graphics overlay (starting with an Alpha Combine node which can combine two video inputs with key form one and fill from another, or both from the same source), then there is a chroma key overlay, which can be used to add green screen effects (Starting with a Select node), then there are two instances of picture-in-picture flows (also starting with select nodes) and on top of that another graphics overlay, called HTML graphics in the illustration, but which can be used with any source where the key and fill comes from the same source. The overlay flows are inserted into the main program using Alpha over nodes.

Each video command in the Rendering Engine command protocol targets one of these nodes.

Transitions

The main flow of the video mixer can be controlled with the following commands:

  • transition cut <input_slot> - Cut (hot punch) the program output to the given input slot. This won’t affect the preview output.
  • transition preview <input_slot> - Preview the given input slot. This won’t affect the program output.
  • transition cut - Cut between the current program and preview outputs, effectively swapping their place.
  • transition panic <input_slot> - Cut (hot punch) both the preview and program output to the given input slot.

Some transition commands last over a duration of time, for example wipes. These can be performed either automatically or manually. The automatic mode works by the operator first selecting the type of transition, for instance a fade, setting the preview to the input slot to fade to and then trigger the transition at the right time with a set duration for the transition. In manual mode the exact “position” of the transition is set by the control panel. This is used for implementing T-bars, where the T-bar repeatedly sends the current position of the bar. In the manual mode, the transition type is set before the transition begins, just as in the automatic mode. Note that an automatic transition will be overridden in case the transition “position” is manually set, by interrupting the automatic transition and jumping to the manually set position.

  • transition type <type> - Set the transition type to use for transitions hereafter. Valid modes are:
    • fade - Fade (mix) from one source to the next
    • wipe_left - Wipe from one source to the next, wipe going from right side of the screen to the left
    • wipe_right - Wipe from one source to the next, wipe going from left side of the screen to the right
  • transition auto <duration_ms> - Perform an automatic transition from the current program output to the current preview output, lasting for <duration_ms> milliseconds. The currently set transition type is used.
  • transition factor <factor> - Manually set the position/factor of the transition. <factor> should be between 0.0 and 1.0, where 0.0 is the value before the transition starts and 1.0 is the end of the transition. Note that setting this value to 1.0 will effectively swap place of program and preview output, resetting the transition factor to 0.0 internally. Control panels using this command must take this into consideration to not cause a sudden jump in the transition once the physical control is moved again. Sending this command will interrupt any ongoing automatic transition.

Key and fill

The key and fill graphics flow will be inserted before the picture-in-picture flows, and will therefore be rendered under them. The graphics flow can be controlled with these commands:

  • alpha_combine color <input_slot> - Set which input slot to copy the color data from in the Alpha combine node
  • alpha_combine alpha <input_slot> - Set which input slot to use to create the alpha channel of the output frame in the Alpha combine node
  • alpha_combine mode <mode> - Set which way the alpha channel of the output frame will be produced. Valid modes are:
    • copy-r - Copy the R-channel of the input “alpha frame” and use it as alpha for the output
    • copy-g - Copy the G-channel of the input “alpha frame” and use it as alpha for the output
    • copy-b - Copy the B-channel of the input “alpha frame” and use it as alpha for the output
    • copy-a - Copy the A-channel of the input “alpha frame” and use it as alpha for the output
    • average-rgb - Take the average of the R, G and B channels of the input “alpha frame” and use it as alpha channel for the output
  • alpha_over factor <factor> - Manually set the transparency multiplier for the Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the overlay is completely invisible and 1.0 means that the overlay is fully visible (where it should be visible according to the overlay image’s alpha channel). Default is 0.0.
  • alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible overlay over the duration of <duration_ms> milliseconds.
  • alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible overlay over the duration of <duration_ms> milliseconds.

Picture-in-Picture

The two picture-in-picture boxes can be controlled with these commands:

  • pip1_select cut <input_slot> - Choose which input slot to forward. Changing looks like a cut.
  • pip1_transform scale <factor> - Set the scale of the picture-in-picture box, relative the original size. Parameter factor must be > 0. Default is 1.0.
  • pip1_transform x <position> - Set the X offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame width, where 0.0 is the left side of the frame and 1.0 is the right side of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_transform y <position> - Set the Y offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame height, where 0.0 is the top of the frame and 1.0 is the bottom of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_alpha_over factor <factor> - Manually set the transparency multiplier for the picture-in-picture 1 Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the picture-in-picture box is completely invisible and 1.0 means that the box is fully visible. Default is 0.0.
  • pip1_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible picture-in-picture box over the duration of <duration_ms> milliseconds.
  • pip1_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible picture-in-picture box over the duration of <duration_ms> milliseconds.

For the second picture-in-picture flow, replace pip1 with pip2.

Chroma Key

The nodes of the chroma key branch of the graph can be controlled with these commands:

  • chroma_key_select cut <input_slot> - Choose which input slot to forward. Changing looks like a cut.
  • chroma_key r <value> - Set the red component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key g <value> - Set the green component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key b <value> - Set the blue component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key distance <value> - Set the distance parameter, ranging from 0.0 to 1.0, telling how far from the key color is also considered a part of the key. Larger values will result in more colors being included, 0.0 means only the exact key color is considered.
  • chroma_key falloff <value> - Set the falloff parameter, ranging from 0.0 to 1.0, which makes edges smoother. A lower value means harder edges between the key color and the parts to keep, a higher value means a more smooth falloff between removed and kept parts.
  • chroma_key spill <value> - Set the color spill reduction parameter, ranging from 0.0 to 1.0, which will desaturate the key color in the parts of the image that are left. Useful for hiding green rims around objects in from of a green screen etc. 0.0 means off and a higher value means more colors further away from the chroma key color will be desaturated.
  • chroma_key color_picker <x_factor> <y_factor> <square_size> - Set the chroma key by sampling the pixels covered by the square area of size square_size x square_size. The position x,y is set by <x_factor> * width of video and <y_factor> * height of video. <x_factor> & <y_factor> should be a float between 0.0 and 1.0. The <square_size> should be an integer > 0.0.
  • chroma_key alpha_as_video <value> - Instead of writing an alpha mask, set the alpha value as the RGB value, creating a grayscale image of the mask. Value should be 0.0 or 1.0.
  • chroma_key show_key_color <value> - Draw a 100x100 box in upper left corner with the current chroma key (RGB) value. Value should be 0.0 or 1.
  • chroma_key show_color_picker <value> - Draw a pink border around the area where the color picker will sample a new chroma key. Value should be 0.0 or 1.
  • chroma_key_transform scale <factor> - Set the scale of the chroma key output, relative the original size. Parameter factor must be > 0.0. Default is 1.0.
  • chroma_key_transform x <position> - Set the X offset of the top left corner of the chroma key output, relative the top left corner of the frame. Position is measured in percent of frame width, where 0.0 is the left side of the frame and 1.0 is the right side of the frame. Values outside of the range 0.0, 1.0 are valid. Default is 0.0.
  • chroma_key_transform y <position> - Set the Y offset of the top left corner of the chroma key output, relative the top left corner of the frame. Position is measured in percent of frame height, where 0.0 is the top of the frame and 1.0 is the bottom of the frame. Values outside of the range 0.0, 1.0 are valid. Default is 0.0.
  • chroma_key_alpha_over factor <factor> - Manually set the transparency multiplier for the chroma key Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the chroma key output is completely invisible and 1.0 means that the chroma key output is fully visible. Default is 0.0.
  • chroma_key_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible chroma key output over the duration of <duration_ms> milliseconds.
  • chroma_key_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible chroma key output over the duration of <duration_ms> milliseconds.

Graphics overlay (HTML)

The overlay graphics flow, marked with HTML in the illustration. This will be inserted on top of both the key and fill and picture-in-picture. It can be controlled with these commands:

  • html_select cut <input_slot> - Choose which input slot to use for the graphics. It must contain both fill and key (such as the HTML graphics), otherwise, no parts of the layer will be transparent. Changing looks like a cut.
  • html_alpha_over factor <factor> - Manually set the transparency multiplier for the graphics overlay Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the graphics is completely invisible and 1.0 means that it is fully visible. Default is 0.0.
  • html_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible graphics over the duration of <duration_ms> milliseconds.
  • html_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible graphics over the duration of <duration_ms> milliseconds.

Fade to black

The fade to black node can be controlled via the following commands:

  • fade_to_black factor <factor> - Manually set the blackness factor on a scale from 0.0 to 1.0, where 0.0 means not black and 1.0 means fully black output.
  • fade_to_black fade to <duration_ms> - Start an automatic fade to a fully black output over the duration of <duration_ms> milliseconds.
  • fade_to_black fade from <duration_ms> - Start an automatic fade to a fully visible (non-black) output over the duration of <duration_ms> milliseconds.

Audio Router commands

The same audio router is used to route specific audio channels from an input slot of the Rendering Engine to an input channel strip on the audio mixer. By default, it has no audio routes set up. The router can be controlled with the following commands:

  • audio map <input_slot> <channel> mono <input_strip> - Map the <channel> from input slot <input_slot> as a mono channel into input strip <input_strip> of the audio mixer
  • audio map <input_slot> <left_channel> stereo <input_strip> - Map the <left_channel> and <left_channel> + 1 from input slot <input_slot> as a stereo pair into input strip <input_strip> of the audio mixer ’ audio map reset <input_strip> - Remove the current mapping from <input_strip> of the audio mixer.

Audio commands

The audio mixer and audio router have the following data path:

Audio mixer block diagram

In the example picture above, three sources are connected to the input slots and four mono or stereo audio streams are picked as input to the audio mixer. The audio mixer is completely separate from the video mixer, so switching image in the video mixer will not change the audio mixer in any way. The internal audio mixer can be controlled using the following commands:

To control the pre-gain of each input strip use:

  • audio gain <input_strip> <level_dB> - Set the pre-gain level of a specific input in dB. Parameter <level> should be a floating point number. Default is 0.0.

To control the low-pass filter of each input strip use:

  • audio lpf <input_strip> freq <value> - Set the cutoff frequency for the low-pass filter in an input strip. <value> is the frequency in Hz as a floating point number. The frequency range is 20 Hz to 20 kHz. Setting a value of 20 kHz or higher will bypass the filter.
  • audio lpf <input_strip> q <value> - Set the q-value for the low-pass filter in an input strip. The q-value controls the steepness of cutoff curve with a higher value being a steeper slope. The value is a floating point number ranging from 0.4 to 6.0. The default value is 0.7.

To control the high-pass filter of each input strip use:

  • audio hpf <input_strip> freq <value> - Set the cutoff frequency for the high-pass filter in an input strip. <value> is the frequency in Hz as a floating point number. The frequency range is 20 Hz to 20 kHz. Setting a value of 20 Hz or lower will bypass the filter.
  • audio hpf <input_strip> q <value> - Set the q-value for the high-pass filter in an input strip. The q-value controls the steepness of cutoff curve with a higher value being a steeper slope. The value is a floating point number ranging from 0.4 to 6.0. The default value is 0.7.

To control the parametric equalizer of each input strip use (the equalizer has three bands):

  • audio eq <input_strip> <band> freq <value> - Set the frequency of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the frequency in Hz
  • audio eq <input_strip> <band> gain <value> - Set the gain of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the gain in dB.
  • audio eq <input_strip> <band> q <value> - Set the q-value of a specific band in the parametric equalizer to shape the falloff of the band. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the q-value where a higher value means a more pointy curve. Default value is 0.7.
  • audio eq <input_strip> <band> type <type> - Set the type of falloff to use for a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <type> is either of low, band or high, where low and high is a low and high shelf filter and band is a band pass filter. By default, the first band is low shelf, the last band is high shelf and any bands inbetween are band pass.

To control the panning of each input strip use:

  • audio pan <input_strip> <factor> - Pan the mono or stereo input of an input strip to the left or right. The range of <factor> is between -1.0 and +1.0, where 0.0 means center (no panning), negative values means more to the left and positive value more to the right. Values outside this range will be clamped. A value of +/- 1.0 means that there will only be audio in the left/right channel.

To control the dynamic range compressor of each input strip use:

  • audio comp <input_strip> threshold <value> - Set the threshold for activation of the compressor. The threshold is a negative dB value ranging from -30 dB to 0 dB. The volume of audio which is above the threshold value will be reduced (compressed). The default value is 0 dB, i.e. only compression if the audio signal is overloaded.
  • audio comp <input_strip> ratio <value> - Set the compression ratio for audio exceeding the loudness threshold. The value is the numerator in the compression ratio <value>:1. For instance, if the value is set to 4, the compression ratio is 4:1 and volume overshoot above the threshold will be scaled down to 25 %. The ratio numerator is a floating point number in the range from 1.0 to 24.0, with 4.0 as the default value.
  • audio comp <input_strip> knee <value> - Set the width of the soft knee in decibels. Instead of simply turning the compression completely on or off at the threshold, the knee defines a volume range in which the compression ratio follows a curve, the “knee”. The knee is a floating point number between 0 dB and 30 dB, with a default value of 2.5 dB.
  • audio comp <input_strip> attack <value> - Set the attack time of the compressor in milliseconds. The attack time determines how long it takes to reach the full compression after the threshold has been exceeded. The value is a floating point number in the range from 0.1 ms to 120 ms. The default value is 50 ms.
  • audio comp <input_strip> release <value> - Set the release time of the compressor in milliseconds. The release time determines how long it takes to return to zero compression when the volume is below the compression threshold. The value is a floating point number in the range from 10 ms to 1000 ms. The default value is 200 ms.
  • audio comp <input_strip> gain <value> - Set the make-up gain i decibels. Since the compression filter lowers the volume of louder audio sections it can be desirable to increase the gain after the filtering. The gain value increases the audio volume with the specified number of decibels. The value is a floating point number in the range from 0 dB to 24 dB. The default value is 0 dB.

To control the volume faders and master volume faders use:

  • audio volume <input_strip> <output> <level> - Set the volume level of a specific input in proportion to its original strength for a given output. Parameter <level> should be a floating point number, where 0.0 means that the input slot is not mixed into the output at all and 1.0 means that the volume of the input slot is kept as is for the output. The signal can also be amplified by using values > 1.0. Default is 0.0.
  • audio mastervolume <output> <level> - Set the master volume level of an output, before the audio is clamped and converted from floating point samples to 16-bit integer samples. This can be used to avoid clipping of the audio when mixing multiple input sources. Parameter <level> is a floating point number where 0.0 means that all audio output is off, 1.0 means that the volume is not changed and any value above 1.0 means that the master volume is amplified. Default is 1.0.

HTML rendering

The Rendering Engine also features a built-in HTML renderer which uses the Chromium web browser engine to render HTML pages. The following commands can be used to create and control the HTML browser instances:

  • html create <input_slot> <width> <height> - Create a new HTML browser instance with the canvas size of width x height pixels and output the rendered frames to the given input slot
  • html close <input_slot> - Close the HTML browser instance on the given input slot
  • html load <input_slot> <url> - Load a new URL in the HTML browser on the given input slot
  • html execute <input_slot> <java script> - Execute JavaScript in the HTML browser on the given input slot. The JavaScript snippet might span over multiple lines and may contain spaces.

Media player

The Rendering Engine can create media player instances to play video and audio files from the hard drive of the machine running the Rendering Engine. It is up to the user of the API to ensure the files are uploaded to the machines running the Rendering Engine(s) before trying to run them. The media players use the FFmpeg library to demux and decode the media files, so most files supported by FFmpeg should work. The media players each have three state parameters: start, duration and looping, to mark a section of the video to loop, or a last frame to stop at in case looping is set to false. The following commands can be used to create and control the media player instances:

  • media create <input_slot> <filename> - Create a new media player instance with the given media file and output the rendered frames to the given input slot.
  • media load <input_slot> <filename> - Load another file into an existing media player on the given input slot. This will reset the start, duration and looping parameters of that media player.
  • media close <input_slot> - Close the media player instance on the given input slot
  • media play <input_slot> - Start/resume playing the currently loaded media file in the media player on the given input slot
  • media pause <input_slot> - Pause the media player on the given input slot
  • media seek <input_slot> <time_ms> - Seek the media player on the given input slot to a time point time_ms milliseconds from the start of the media file and pause the playback at the first frame. Use media play <input_slot> to resume the playback
  • media set_start <input_slot> <start_time_ms> - Set the start time of the looping section of the media player on the given input slot to a time point start_time_ms milliseconds from the start of the media file. It will still be possible to seek before this time point and play the video from there.
  • media set_duration <input_slot> <duration_ms> - Set the duration of the playing/looping section of the media player on the given input slot to duration_ms milliseconds from the start_time_ms of the media file. The duration will be clamped in case it spans past the end of the media file. A running media player will either stop at this point, or loop the video depending on the state of the looping parameter
  • media set_looping <input_slot> <true/false> - Set if the media should loop from the start time when the media player on the given input slot hits either the end of the looping section defined by the start time and duration, or the end of the media file. If set to false, the media player will stop at the end of the section or at the end of the file instead of looping it from the start point.

1.6.1.3 - C++ SDK

Agile Content Live C++ SDK reference

Agile Content Live C++ SDK reference.

1.6.1.3.1 - Classes

Classes

  • namespace ACL
  • namespace AclLog
    A namespace for logging utilities.
  • struct AlignedAudioFrame
    AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
  • struct AlignedFrame
    A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class DeviceMemory
    RAII class for a CUDA memory buffer.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class PipelineSystemControllerInterfaceFactory
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.
  • namespace spdlog

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.1 - AclLog::CommandLogFormatter

AclLog::CommandLogFormatter

This class is used to format log entries for Rendering Engine commands.

#include <AclLog.h>

Inherits from spdlog::formatter

Public Functions

Name
CommandLogFormatter()
voidformat(const spdlog::details::log_msg & msg, spdlog::memory_buf_t & dest) override
std::unique_ptr< spdlog::formatter >clone() const override

Public Functions Documentation

function CommandLogFormatter

CommandLogFormatter()

function format

void format(
    const spdlog::details::log_msg & msg,
    spdlog::memory_buf_t & dest
) override

function clone

std::unique_ptr< spdlog::formatter > clone() const override

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.2 - AclLog::FileLocationFormatterFlag

AclLog::FileLocationFormatterFlag

A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

#include <AclLog.h>

Inherits from spdlog::custom_flag_formatter

Public Functions

Name
voidformat(const spdlog::details::log_msg & msg, const std::tm & , spdlog::memory_buf_t & dest) override
std::unique_ptr< custom_flag_formatter >clone() const override

Public Functions Documentation

function format

inline void format(
    const spdlog::details::log_msg & msg,
    const std::tm & ,
    spdlog::memory_buf_t & dest
) override

function clone

inline std::unique_ptr< custom_flag_formatter > clone() const override

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.3 - AclLog::ThreadNameFormatterFlag

AclLog::ThreadNameFormatterFlag

Inherits from spdlog::custom_flag_formatter

Public Functions

Name
voidformat(const spdlog::details::log_msg & , const std::tm & , spdlog::memory_buf_t & dest) override
std::unique_ptr< custom_flag_formatter >clone() const override

Public Functions Documentation

function format

inline void format(
    const spdlog::details::log_msg & ,
    const std::tm & ,
    spdlog::memory_buf_t & dest
) override

function clone

inline std::unique_ptr< custom_flag_formatter > clone() const override

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.4 - AlignedAudioFrame

AlignedAudioFrame

AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.

#include <AlignedFrame.h>

Public Attributes

Name
std::vector< float >mSamples
uint8_tmNumberOfChannels
uint32_tmNumberOfSamplesPerChannel

Public Attributes Documentation

variable mSamples

std::vector< float > mSamples;

variable mNumberOfChannels

uint8_t mNumberOfChannels = 0;

variable mNumberOfSamplesPerChannel

uint32_t mNumberOfSamplesPerChannel = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.5 - AlignedFrame

AlignedFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedFrame.h>

Public Functions

Name
AlignedFrame() =default
~AlignedFrame() =default
AlignedFrame(AlignedFrame const & ) =delete
AlignedFrame &operator=(AlignedFrame const & ) =delete
std::shared_ptr< AlignedFrame >makeShallowCopy() const
Make a shallow copy of this AlignedFrame (video and audio pointers will point to the same video and audio memory buffers as in the frame copied from)

Public Attributes

Name
int64_tmCaptureTimestamp
int64_tmRenderingTimestamp
std::shared_ptr< DeviceMemory >mVideoFrame
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
AlignedAudioFramePtrmAudioFrame
uint32_tmAudioSamplingFrequency

Public Functions Documentation

function AlignedFrame

AlignedFrame() =default

function ~AlignedFrame

~AlignedFrame() =default

function AlignedFrame

AlignedFrame(
    AlignedFrame const & 
) =delete

function operator=

AlignedFrame & operator=(
    AlignedFrame const & 
) =delete

function makeShallowCopy

std::shared_ptr< AlignedFrame > makeShallowCopy() const

Make a shallow copy of this AlignedFrame (video and audio pointers will point to the same video and audio memory buffers as in the frame copied from)

Return: A pointer to a new frame, which is a shallow copy of the old one, pointing to the same video and audio memory buffers

Public Attributes Documentation

variable mCaptureTimestamp

int64_t mCaptureTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame was captured by the ingest

variable mRenderingTimestamp

int64_t mRenderingTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame should be delivered to the rendering engine

variable mVideoFrame

std::shared_ptr< DeviceMemory > mVideoFrame = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioFrame

AlignedAudioFramePtr mAudioFrame = nullptr;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.6 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType = ConnectionType::DISCONNECTED;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.7 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.8 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.9 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.10 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< std::vector< uint8_t > >mMessages
std::stringmSenderUUID
The actual messages.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessages

std::vector< std::vector< uint8_t > > mMessages;

variable mSenderUUID

std::string mSenderUUID;

The actual messages.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.11 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.12 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.13 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v2.1.0-231-gcd012ab”, followed by “-dirty” in case there are changes made to the Git repo.

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.14 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.15 - DeviceMemory

DeviceMemory

RAII class for a CUDA memory buffer.

#include <DeviceMemory.h>

Public Functions

Name
DeviceMemory() =default
Default constructor, creates an empty object, without allocating any memory on the device.
DeviceMemory(size_t numberOfBytes)
Constructor allocating the required number of bytes.
DeviceMemory(size_t numberOfBytes, cudaStream_t cudaStream)
Constructor allocating the required number of bytes by making an async allocation. The allocation will be put in the given CUDA stream.
DeviceMemory(void * deviceMemory)
Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.
boolallocateMemory(size_t numberOfBytes)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolallocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolreallocateMemory(size_t numberOfBytes)
Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.
boolreallocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream)
Asynchronously reallocate device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.
boolallocateAndResetMemory(size_t numberOfBytes)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolallocateAndResetMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolfreeMemory()
Free the device memory held by this class. Calling this when no memory is allocated is a no-op.
boolfreeMemoryAsync(cudaStream_t cudaStream)
Deallocate memory asynchronously, in a given CUDA stream. Calling this when no memory is allocated is a no-op.
voidsetFreeingCudaStream(cudaStream_t cudaStream)
Set which CUDA stream to use for freeing this DeviceMemory. In case the DeviceMemory already holds a CUDA stream to use for freeing the memory, this will be overwritten.
~DeviceMemory()
Destructor, frees the internal CUDA memory.
template
T *
getDevicePointer() const
size_tgetSize() const
DeviceMemory(DeviceMemory && other)
DeviceMemory &operator=(DeviceMemory && other)
voidswap(DeviceMemory & other)
DeviceMemory(DeviceMemory const & ) =delete
DeviceMemory is not copyable.
DeviceMemoryoperator=(DeviceMemory const & ) =delete

Public Functions Documentation

function DeviceMemory

DeviceMemory() =default

Default constructor, creates an empty object, without allocating any memory on the device.

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes
)

Constructor allocating the required number of bytes.

Parameters:

  • numberOfBytes Number of bytes to allocate

Exceptions:

  • std::runtime_error In case the allocation failed

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Constructor allocating the required number of bytes by making an async allocation. The allocation will be put in the given CUDA stream.

Parameters:

  • size Number of bytes to allocate
  • cudaStream The CUDA stream to put the async allocation in. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Exceptions:

  • std::runtime_error In case the async allocation failed to be put in queue.

See: freeMemoryAsync method is not explicitly called, the memory will be freed synchronously when this DeviceMemory instance goes out of scope, meaning that the entire GPU is synchronized, which will impact performance negatively.

Note:

  • The method will return as soon as the allocation is put in queue in the CUDA stream, i.e. before the actual allocation is made. Using this DeviceMemory is only valid as long as it is used in the same CUDA stream, or in case another stream is used, only if that stream is synchronized first with respect to cudaStream.
  • In case the

function DeviceMemory

explicit DeviceMemory(
    void * deviceMemory
)

Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.

Parameters:

  • deviceMemory CUDA memory pointer to take ownership over.

function allocateMemory

bool allocateMemory(
    size_t numberOfBytes
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function allocateMemoryAsync

bool allocateMemoryAsync(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate
  • cudaStream The CUDA stream to use for the allocation. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function reallocateMemory

bool reallocateMemory(
    size_t numberOfBytes
)

Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.

Parameters:

  • numberOfBytes Number of bytes to allocate in the new allocation

Return: True on success, false if CUDA free or CUDA malloc failed.

function reallocateMemoryAsync

bool reallocateMemoryAsync(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Asynchronously reallocate device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.

Parameters:

  • numberOfBytes Number of bytes to allocate in the new allocation
  • cudaStream The CUDA stream to use for the allocation and freeing of memory. A reference to this stream will also be saved internally to be used to asynchronously free them memory when this instance goes out of scope.

Return: True on success, false if CUDA free or CUDA malloc failed.

function allocateAndResetMemory

bool allocateAndResetMemory(
    size_t numberOfBytes
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function allocateAndResetMemoryAsync

bool allocateAndResetMemoryAsync(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate
  • cudaStream The CUDA stream to use for the allocation and resetting. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function freeMemory

bool freeMemory()

Free the device memory held by this class. Calling this when no memory is allocated is a no-op.

See: freeMemoryAsync instead.

Return: True in case the memory was successfully freed (or not allocated to begin with), false otherwise.

Note: This method will free the memory in an synchronous fashion, synchronizing the entire CUDA context and ignoring the internally saved CUDA stream reference in case one exist. For async freeing of the memory, use

function freeMemoryAsync

bool freeMemoryAsync(
    cudaStream_t cudaStream
)

Deallocate memory asynchronously, in a given CUDA stream. Calling this when no memory is allocated is a no-op.

Parameters:

  • cudaStream The CUDA stream to free the memory asynchronously in

Return: True in case the memory deallocation request was successfully put in queue in the CUDA stream.

Note:

  • The method will return as soon as the deallocation is put in queue in the CUDA stream, i.e. before the actual deallocation is made.
  • It is the programmer’s responsibility to ensure this DeviceMemory is not used in another CUDA stream before this method is called. In case it is used in another CUDA stream, sufficient synchronization must be made before calling this method (and a very good reason given for not freeing the memory in that CUDA stream instead)

function setFreeingCudaStream

void setFreeingCudaStream(
    cudaStream_t cudaStream
)

Set which CUDA stream to use for freeing this DeviceMemory. In case the DeviceMemory already holds a CUDA stream to use for freeing the memory, this will be overwritten.

Parameters:

  • cudaStream The new CUDA stream to use for freeing the memory when the destructor is called.

Note: It is the programmer’s responsibility to ensure this DeviceMemory is not used in another CUDA stream before this instance is destructed. In case it is used in another CUDA stream, sufficient synchronization must be made before setting this as the new CUDA stream to use when freeing the memory.

function ~DeviceMemory

~DeviceMemory()

Destructor, frees the internal CUDA memory.

function getDevicePointer

template <typename T  =uint8_t>
inline T * getDevicePointer() const

Template Parameters:

  • T The pointer type to return

Return: the CUDA memory pointer handled by this class. Nullptr in case no memory is allocated.

function getSize

size_t getSize() const

Return: The size of the CUDA memory allocation held by this class.

function DeviceMemory

DeviceMemory(
    DeviceMemory && other
)

function operator=

DeviceMemory & operator=(
    DeviceMemory && other
)

function swap

void swap(
    DeviceMemory & other
)

function DeviceMemory

DeviceMemory(
    DeviceMemory const & 
) =delete

DeviceMemory is not copyable.

function operator=

DeviceMemory operator=(
    DeviceMemory const & 
) =delete

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.16 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v1.0.0”, or “v2.1.0-231-gcd012ab”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.17 - IngestApplication::Settings

IngestApplication::Settings


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.18 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual std::optional< std::string >sendMessage(const std::string & messageTitle, const nlohmann::json & parameters) =0
Send a message containing a JSON object to the controller.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendMessage

virtual std::optional< std::string > sendMessage(
    const std::string & messageTitle,
    const nlohmann::json & parameters
) =0

Send a message containing a JSON object to the controller.

Parameters:

  • messageTitle The title of the status type or request
  • parameters The parameters part of the JSON message

Return: Optional containing an error message on error, else nullopt in case the message was successfully sent

Reimplemented by: SystemControllerConnection::sendMessage

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.19 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.20 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.21 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Types

Name
enum class uint32_tTallyBorderColor { kNone, kRed, kGreen, kYellow}
Available colors for tally border in multi view.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, CUcontext cudaContext, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const AlignedFramePtr &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
boolremoveCustomMultiViewSourceInput(uint32_t inputSlot)
Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.
voidsetTallyBorder(uint32_t inputSlot, TallyBorderColor color)
Set tally border color in the multi-views for a specific input slot.
voidclearTallyBorder(uint32_t inputSlot)
Remove tally border in the multi-views for a specific input slot.
voidclearAllTallyBorders()
Remove all tally borders.
MediaReceiver::TallyBorderColorgetTallyBorder(uint32_t inputSlot) const
get tally border color for an input slot
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Public Types Documentation

enum TallyBorderColor

EnumeratorValueDescription
kNone
kRed
kGreen
kYellow

Available colors for tally border in multi view.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    CUcontext cudaContext,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • cudaContext The CUDA context to use for this MediaReceiver. The frames will delivered as CUDA pointers, valid in this context, and the multi-view generator will use this context for rendering and encoding.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const AlignedFramePtr &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Note: Make sure no CUDA stream will write to the DeviceMemory in the AlignedFrame passed to the function. Failing to do so will lead to undefined behavior. In case another CUDA stream has written to the DeviceMemory, make sure to synchronize with the stream before passing the AlignedFrame.

Precondition: The AlignedFrame sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function removeCustomMultiViewSourceInput

bool removeCustomMultiViewSourceInput(
    uint32_t inputSlot
)

Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.

Parameters:

  • inputSlot The input slot the custom multi-view source input is connected to, that should be removed

Return: True if the custom multi-view source input was successfully removed, false in case there was no custom input registered for the given input slot, or in case of an internal error.

function setTallyBorder

void setTallyBorder(
    uint32_t inputSlot,
    TallyBorderColor color
)

Set tally border color in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source
  • color the color to set

function clearTallyBorder

void clearTallyBorder(
    uint32_t inputSlot
)

Remove tally border in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source

function clearAllTallyBorders

void clearAllTallyBorders()

Remove all tally borders.

function getTallyBorder

MediaReceiver::TallyBorderColor getTallyBorder(
    uint32_t inputSlot
) const

get tally border color for an input slot

Parameters:

  • inputSlot the input slot to get color for

Return: the tally border color for the given input slot

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.22 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.23 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDeliverOld
Set to true if this MediaReceiver should have a multi-view generator.
CUstreammAlignedFrameFreeStream

Public Attributes Documentation

variable mDecodedFormat

PixelFormat mDecodedFormat = PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

Note: The internal CUDA stream is synchronized before delivering the AlignedFrames, meaning the DeviceMemory in the AlignedFrame will always contain the written data; no further synchronization is needed before the rendering engine can read the data.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDeliverOld

bool mDeliverOld = false;

Set to true if this MediaReceiver should have a multi-view generator.

variable mAlignedFrameFreeStream

CUstream mAlignedFrameFreeStream = nullptr;

Set to true if the media frames should be delivered, even if the delivery time has already passed, otherwise they are discarded The CUDA stream to use for asynchronously freeing the AlignedFrames’ DeviceMemory. Set this to the rendering engine’s CUDA stream, to ensure memory is not freed before the rendering engine is done using it asynchronously in its CUDA stream. Note that the MediaReceiver instance and all AlignedFrames delivered from it must be destroyed before the CUDA stream can be destroyed.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.24 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, CUcontext cudaContext)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
boolhasFormatAndIsRunning() const
boolhasOpenOutputStream() const
booloutputData(const AlignedFramePtr & frame)
Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    CUcontext cudaContext
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer
  • cudaContext The CUDA context to use for this MediaStreamer. The frames passed to this instance should be valid in this CUDA context. The streamer will use this context for preprocessing and encoding.

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the format reset, or if the format was not set before this method was called, false on error.

function hasFormatAndIsRunning

bool hasFormatAndIsRunning() const

Return: True if the input format is set and the OutputStreamer is running, false otherwise

function hasOpenOutputStream

bool hasOpenOutputStream() const

See:

  • outputData will be discarded without being encoded, as there is no stream to output them to. This method can be used to check if the frame even needs to be produced by the rendering engine. Note however, that the
  • outputData method will still log the frames sent to it as received, even if they are not encoded when the output stream is closed.

Return: True if the output stream of the MediaStreamer is currently open and outputting the data, false otherwise. In case this returns false all frames passed to

function outputData

bool outputData(
    const AlignedFramePtr & frame
)

Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

Note: The DeviceMemory in the AlignedFrame passed to this method must not be in use by any CUDA stream. In case the memory has been used in kernels in another CUDA stream, make sure to first synchronize with the stream, before passing it over to the MediaStreamer.

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.25 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

PixelFormat mIncomingPixelFormat = PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.26 - PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory

Public Functions

Name
PipelineSystemControllerInterfaceFactory(const std::string & systemControllerIP, uint16_t systemControllerPort, const std::string & systemControllerPostfix, const std::string & psk, const std::string & myIP, bool useHTTPS, bool allowInsecureHTTPS, const std::string & customCaCertFile)
Constructor.
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const && ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const && ) =delete
std::shared_ptr< SystemControllerConnection >getMediaReceiverInterface(const std::string & name)
Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.
std::shared_ptr< SystemControllerConnection >createMediaStreamerInterface(const std::string & name)
Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.
std::shared_ptr< SystemControllerConnection >createControlReceiverInterface(const std::string & name)
Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Public Functions Documentation

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    const std::string & systemControllerIP,
    uint16_t systemControllerPort,
    const std::string & systemControllerPostfix,
    const std::string & psk,
    const std::string & myIP,
    bool useHTTPS,
    bool allowInsecureHTTPS,
    const std::string & customCaCertFile
)

Constructor.

Parameters:

  • systemControllerIP The IP address of the System controller to connect to.
  • systemControllerPort The network port of the System controller to connect to.
  • systemControllerPostfix The postfix of the System controller’s address, to chose which API endpoints to use.
  • psk The Pre-shared key used for authorization at the System controller.
  • myIP The public IP address of the pipeline, i.e. the external IP used to connect to the pipeline.
  • useHTTPS If HTTPS should be used instead of HTTP
  • allowInsecureHTTPS Set to true to allow self-signed HTTPS certificates. Should normally be false.
  • customCaCertFile Full path to CA certificate file for verifying server cert, optional.

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function getMediaReceiverInterface

std::shared_ptr< SystemControllerConnection > getMediaReceiverInterface(
    const std::string & name
)

Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.

Parameters:

  • name The human readable name of the MediaReceiver to provide to the System controller

Return: A configured connection on success, otherwise nullptr

function createMediaStreamerInterface

std::shared_ptr< SystemControllerConnection > createMediaStreamerInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the MediaStreamer to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called

Return: A configured connection on success, otherwise nullptr

function createControlReceiverInterface

std::shared_ptr< SystemControllerConnection > createControlReceiverInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the ControlReceiver to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called to generate the parent interface.

Return: A configured connection on success, otherwise nullptr


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.27 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual std::optional< std::string >sendMessage(const std::string & messageTitle, const nlohmann::json & parameters) override
Send a message containing a JSON object to the system controller server.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendMessage

virtual std::optional< std::string > sendMessage(
    const std::string & messageTitle,
    const nlohmann::json & parameters
) override

Send a message containing a JSON object to the system controller server.

Parameters:

  • messageTitle The title of the status type or request
  • parameters The parameters part of the JSON message

Return: Optional containing an error message on error, else nullopt in case the message was successfully sent

Reimplements: ISystemControllerInterface::sendMessage

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.28 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout
boolmEnableHTTPS
boolmInsecureHTTPS
std::stringmCustomCaCertFile

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

variable mEnableHTTPS

bool mEnableHTTPS;

variable mInsecureHTTPS

bool mInsecureHTTPS;

variable mCustomCaCertFile

std::string mCustomCaCertFile;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.29 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock
doublemTimeDiffS

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

variable mTimeDiffS

double mTimeDiffS = 0.0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.1.30 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.
classAclLog::ThreadNameFormatterFlag
classAclLog::FileLocationFormatterFlag
A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <filesystem>
#include <string>

#include <spdlog/details/log_msg.h>
#include <spdlog/fmt/fmt.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>
#include <sys/prctl.h>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void initCommandLog(const std::string& name);

void setLevel(Level level);

void logCommand(const std::string& origin, const std::string& command);

AclLog::Level getLogLevel();

size_t getMaxFileSize();

size_t getMaxLogRotations();

std::filesystem::path getLogFileFullPath(const std::string& name);

class CommandLogFormatter : public spdlog::formatter {
public:
    CommandLogFormatter();
    void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override;
    [[nodiscard]] std::unique_ptr<spdlog::formatter> clone() const override;

private:
    std::unique_ptr<spdlog::pattern_formatter> mCommandLogPattern;
};

inline std::string getThreadName() {
    static const size_t RECOMMENDED_BUFFER_SIZE = 20;
    static thread_local std::string name;

    if (name.empty()) {
        char buffer[RECOMMENDED_BUFFER_SIZE];
        int retval = prctl(PR_GET_NAME, buffer);
        if (retval == -1) {
            throw spdlog::spdlog_ex("Failed to get thread name: ", errno);
        }
        name = std::string(buffer);
    }
    return name;
}

class ThreadNameFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg&, const std::tm&, spdlog::memory_buf_t& dest) override {
        std::string threadName = getThreadName();
        dest.append(threadName.data(), threadName.data() + threadName.size());
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<ThreadNameFormatterFlag>();
    }
};

class FileLocationFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg& msg, const std::tm&, spdlog::memory_buf_t& dest) override {
        if (!msg.source.empty()) {
            using namespace spdlog::details;

            dest.push_back('[');
            const char* filename = short_filename_formatter<null_scoped_padder>::basename(msg.source.filename);
            fmt_helper::append_string_view(filename, dest);
            dest.push_back(':');
            fmt_helper::append_int(msg.source.line, dest);
            dest.push_back(']');
        }
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<FileLocationFormatterFlag>();
    }
};

} // namespace AclLog

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.2 - include/AlignedFrame.h

include/AlignedFrame.h

Classes

Name
structAlignedAudioFrame
AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
structAlignedFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
using std::shared_ptr< AlignedAudioFrame >AlignedAudioFramePtr
using std::shared_ptr< const AlignedAudioFrame >AlignedAudioFrameConstPtr
using std::shared_ptr< AlignedFrame >AlignedFramePtr

Functions

Name
AlignedAudioFramePtrcreateAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel)
Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.
AlignedAudioFramePtrextractChannel(AlignedAudioFrameConstPtr sourceFrame, uint8_t channelIndex)
Extract one channel from an AlignedAudioFrame as a new AlignedAudioFrame. The new AlignedAudioFrame will share no data with the original frame, meaning the new frame can be edited without corrupting the old one.

Types Documentation

using AlignedAudioFramePtr

using AlignedAudioFramePtr =  std::shared_ptr<AlignedAudioFrame>;

using AlignedAudioFrameConstPtr

using AlignedAudioFrameConstPtr =  std::shared_ptr<const AlignedAudioFrame>;

using AlignedFramePtr

using AlignedFramePtr =  std::shared_ptr<AlignedFrame>;

Functions Documentation

function createAlignedAudioFrame

AlignedAudioFramePtr createAlignedAudioFrame(
    uint8_t numberOfChannels,
    uint32_t numberOfSamplesPerChannel
)

Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.

Parameters:

  • numberOfChannels Number of channels to allocate space for
  • numberOfSamplesPerChannel Number of samples per channel to allocate space for

Return: Shared pointer to the new AudioFrame

function extractChannel

AlignedAudioFramePtr extractChannel(
    AlignedAudioFrameConstPtr sourceFrame,
    uint8_t channelIndex
)

Extract one channel from an AlignedAudioFrame as a new AlignedAudioFrame. The new AlignedAudioFrame will share no data with the original frame, meaning the new frame can be edited without corrupting the old one.

Parameters:

  • sourceFrame The frame to extract a channel from
  • channelIndex The zero-based channel index to extract

Return: Shared pointer to a new mono AlignedAudioFrame, or nullptr if channel is out of bounds

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <memory>
#include <vector>

#include <cuda_runtime_api.h>

#include "DeviceMemory.h"
#include "PixelFormat.h"

struct AlignedAudioFrame {
    // The samples interleaved
    std::vector<float> mSamples;
    uint8_t mNumberOfChannels = 0;
    uint32_t mNumberOfSamplesPerChannel = 0;
};

using AlignedAudioFramePtr = std::shared_ptr<AlignedAudioFrame>;
using AlignedAudioFrameConstPtr = std::shared_ptr<const AlignedAudioFrame>;

AlignedAudioFramePtr createAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel);

AlignedAudioFramePtr extractChannel(AlignedAudioFrameConstPtr sourceFrame, uint8_t channelIndex);

struct AlignedFrame {

    AlignedFrame() = default;

    ~AlignedFrame() = default;

    AlignedFrame(AlignedFrame const&) = delete;            // Copy construct
    AlignedFrame& operator=(AlignedFrame const&) = delete; // Copy assign

    [[nodiscard]] std::shared_ptr<AlignedFrame> makeShallowCopy() const;

    int64_t mCaptureTimestamp = 0;

    int64_t mRenderingTimestamp = 0;

    // Video
    std::shared_ptr<DeviceMemory> mVideoFrame = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    AlignedAudioFramePtr mAudioFrame = nullptr;
    uint32_t mAudioSamplingFrequency = 0;
};

using AlignedFramePtr = std::shared_ptr<AlignedFrame>;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstdint>
#include <string>
#include <vector>

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType = ConnectionType::DISCONNECTED;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<std::vector<uint8_t>> mMessages; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.7 - include/DeviceMemory.h

include/DeviceMemory.h

Classes

Name
classDeviceMemory
RAII class for a CUDA memory buffer.

Types

Name
using std::shared_ptr< DeviceMemory >DeviceMemoryPtr

Types Documentation

using DeviceMemoryPtr

using DeviceMemoryPtr =  std::shared_ptr<DeviceMemory>;

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstddef>
#include <cstdint>
#include <memory>

#include <cuda_runtime.h>

class DeviceMemory {
public:
    DeviceMemory() = default;

    explicit DeviceMemory(size_t numberOfBytes);

    explicit DeviceMemory(size_t numberOfBytes, cudaStream_t cudaStream);

    explicit DeviceMemory(void* deviceMemory) noexcept;

    bool allocateMemory(size_t numberOfBytes);

    bool allocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream);

    bool reallocateMemory(size_t numberOfBytes);

    bool reallocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream);

    bool allocateAndResetMemory(size_t numberOfBytes);

    bool allocateAndResetMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream);

    bool freeMemory();

    bool freeMemoryAsync(cudaStream_t cudaStream);

    void setFreeingCudaStream(cudaStream_t cudaStream);

    ~DeviceMemory();

    template <typename T = uint8_t> [[nodiscard]] T* getDevicePointer() const {
        return reinterpret_cast<T*>(dMemory);
    }

    [[nodiscard]] size_t getSize() const;

    DeviceMemory(DeviceMemory&& other) noexcept;
    DeviceMemory& operator=(DeviceMemory&& other) noexcept;

    void swap(DeviceMemory& other) noexcept;

    DeviceMemory(DeviceMemory const&) = delete;
    DeviceMemory operator=(DeviceMemory const&) = delete;

private:
    uint8_t* dMemory = nullptr;
    size_t mAllocatedBytes = 0;
    cudaStream_t mCudaStream = nullptr; // Stream to use for Async free
};

using DeviceMemoryPtr = std::shared_ptr<DeviceMemory>;

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.8 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {};

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.9 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.10 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <optional>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual std::optional<std::string> sendMessage(const std::string& messageTitle,
                                                   const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.11 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include <cuda.h>

#include "AlignedFrame.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        PixelFormat mDecodedFormat = PixelFormat::kRgba64Le;

        std::function<std::function<void(const AlignedFramePtr&)>(uint32_t inputSlot,
                                                                  const std::string& streamID,
                                                                  const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDeliverOld = false;     

        CUstream mAlignedFrameFreeStream = nullptr;
    };

    enum class TallyBorderColor : uint32_t { kNone, kRed, kGreen, kYellow };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface,
               CUcontext cudaContext,
               const Settings& settings);

    void stop();

    std::function<void(const AlignedFramePtr&)> getCustomMultiViewSourceInput(uint32_t inputSlot,
                                                                              const std::string& name = "");

    bool removeCustomMultiViewSourceInput(uint32_t inputSlot);

    void setTallyBorder(uint32_t inputSlot, TallyBorderColor color);

    void clearTallyBorder(uint32_t inputSlot);

    void clearAllTallyBorders();

    [[nodiscard]] MediaReceiver::TallyBorderColor getTallyBorder(uint32_t inputSlot) const;

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.12 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>
#include <cuda.h>

#include "AlignedFrame.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        PixelFormat mIncomingPixelFormat = PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, CUcontext cudaContext);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    [[nodiscard]] bool hasFormatAndIsRunning() const;

    [[nodiscard]] bool hasOpenOutputStream() const;

    bool outputData(const AlignedFramePtr& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.13 - include/PipelineSystemControllerInterfaceFactory.h

include/PipelineSystemControllerInterfaceFactory.h

Classes

Name
classPipelineSystemControllerInterfaceFactory

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <string>

#include "SystemControllerConnection.h"

class PipelineSystemControllerInterfaceFactory final {
public:
    PipelineSystemControllerInterfaceFactory(const std::string& systemControllerIP,
                                             uint16_t systemControllerPort,
                                             const std::string& systemControllerPostfix,
                                             const std::string& psk,
                                             const std::string& myIP,
                                             bool useHTTPS,
                                             bool allowInsecureHTTPS,
                                             const std::string& customCaCertFile);

    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&&) = delete;

    std::shared_ptr<SystemControllerConnection> getMediaReceiverInterface(const std::string& name);

    //    /// to generate the parent interface.
    std::shared_ptr<SystemControllerConnection> createMediaStreamerInterface(const std::string& name);

    std::shared_ptr<SystemControllerConnection> createControlReceiverInterface(const std::string& name);

private:
    std::string mSystemControllerIP;
    uint16_t mSystemControllerPort = 0;
    std::string mSystemControllerPostfix;
    std::string mPsk;
    std::string mMyIP;
    bool mUseHTTPS = true;
    bool mAllowInsecureHTTPS = false;
    std::string mCustomCaCertFile;

    std::shared_ptr<SystemControllerConnection> mReceiverController;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.14 - include/PixelFormat.h

include/PixelFormat.h

Namespaces

Name
ACL

Types

Name
enum uint32_tPixelFormat { kUnknown = 0, kNv12 = ACL::makeFourCC(‘N’, ‘V’, ‘1’, ‘2’), kUyvy = ACL::makeFourCC(‘U’, ‘Y’, ‘V’, ‘Y’), kP010 = ACL::makeFourCC(‘P’, ‘0’, ‘1’, ‘0’), kP016 = ACL::makeFourCC(‘P’, ‘0’, ‘1’, ‘6’), kP210 = ACL::makeFourCC(‘P’, ‘2’, ‘1’, ‘0’), kP216 = ACL::makeFourCC(‘P’, ‘2’, ‘1’, ‘6’), kRgba =
ACL::makeFourCC(‘R’, ‘G’, ‘B’, ‘A’), kV210 = ACL::makeFourCC(‘V’, ‘2’, ‘1’, ‘0’), kRgba64Le =
ACL::makeFourCC(‘R’, ‘G’, ‘B’, 64)}
Enumeration of FourCC formats.

Functions

Name
std::ostream &operator«(std::ostream & stream, PixelFormat pixelFormat)
Add the string representation of a PixelFormat to the output stream.

Types Documentation

enum PixelFormat

EnumeratorValueDescription
kUnknown0
kNv12ACL::makeFourCC(‘N’, ‘V’, ‘1’, ‘2’)
kUyvyACL::makeFourCC(‘U’, ‘Y’, ‘V’, ‘Y’)
kP010ACL::makeFourCC(‘P’, ‘0’, ‘1’, ‘0’)
kP016ACL::makeFourCC(‘P’, ‘0’, ‘1’, ‘6’)
kP210ACL::makeFourCC(‘P’, ‘2’, ‘1’, ‘0’)
kP216ACL::makeFourCC(‘P’, ‘2’, ‘1’, ‘6’)
kRgba=
ACL::makeFourCC(‘R’, ‘G’, ‘B’, ‘A’)
kV210ACL::makeFourCC(‘V’, ‘2’, ‘1’, ‘0’)
kRgba64Le=
ACL::makeFourCC(‘R’, ‘G’, ‘B’, 64)

Enumeration of FourCC formats.

Functions Documentation

function operator«

std::ostream & operator<<(
    std::ostream & stream,
    PixelFormat pixelFormat
)

Add the string representation of a PixelFormat to the output stream.

Parameters:

  • pixelFormat The PixelFormat to get as a string

Return: The ostream with the string representation of the PixelFormat appended

Source code

// Copyright (c) 2023, Edgeware AB. All rights reserved.

#pragma once

#include <cstdint>
#include <ostream>

namespace ACL {

constexpr uint32_t makeFourCC(char a, char b, char c, char d) {
    return static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8) + (static_cast<uint32_t>(c) << 16) +
           (static_cast<uint32_t>(d) << 24);
}

} // namespace ACL

enum PixelFormat : uint32_t {
    kUnknown = 0,                                // Unknown format
    kNv12 = ACL::makeFourCC('N', 'V', '1', '2'), // 4:2:0 format with Y plane followed by UVUVUV.. plane
    kUyvy = ACL::makeFourCC('U', 'Y', 'V', 'Y'), // 4:2:2 format with packed UYVY macropixels
    kP010 = ACL::makeFourCC('P', '0', '1', '0'), // 4:2:0 P016 with data in the 10 MSB
    kP016 = ACL::makeFourCC('P', '0', '1', '6'), // 4:2:0 format with 16 bit words, Y plane followed by UVUVUV.. plane
    kP210 = ACL::makeFourCC('P', '2', '1', '0'), // 4:2:2 P216 with data in the 10 MSB
    kP216 = ACL::makeFourCC('P', '2', '1', '6'), // 4:2:2 format with 16 bit words, Y plane followed by UVUVUV.. plane
    kRgba =
        ACL::makeFourCC('R', 'G', 'B', 'A'), // 4:4:4:4 RGB format, 8 bit per channel, ordered RGBARGBARG.. in memory
    kV210 = ACL::makeFourCC('V', '2', '1', '0'), // 4:2:2 packed format with 10 bit per component
    kRgba64Le =
        ACL::makeFourCC('R', 'G', 'B', 64) // 16 bit per component, ordered as RGBA in memory with little endian words.
};

std::ostream& operator<<(std::ostream& stream, PixelFormat pixelFormat);

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.15 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000};           // Max time to wait on an announcement response from the server during connection
        bool mEnableHTTPS;   // Enable the communication between the system controller and a component encrypted
        bool mInsecureHTTPS; // Disable the verification of the TLS certificate if requested.
        std::string mCustomCaCertFile; // Custom CA certificate
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    std::optional<std::string> sendMessage(const std::string& messageTitle, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.16 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

#include "expected.hpp"

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
    double mTimeDiffS = 0.0; // Time diff vs NTP in seconds, +/- value means slow/faster than NTP time
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

tl::expected<TimeCommon::TAIStatus, std::string> getStatus();

int64_t getTAIMicro();

std::string taiMicroToString(int64_t taiTimestamp);
} // namespace TimeCommon

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.2.17 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3 - Namespaces

Namespaces


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.1 - ACL

ACL

Functions

Name
constexpr uint32_tmakeFourCC(char a, char b, char c, char d)
Helper function to create a FourCC code out of four characters.

Functions Documentation

function makeFourCC

constexpr uint32_t makeFourCC(
    char a,
    char b,
    char c,
    char d
)

Helper function to create a FourCC code out of four characters.

Return: The characters a-d encoded as a 32 bit FourCC code.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.2 - AclLog

AclLog

A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.
classAclLog::ThreadNameFormatterFlag
classAclLog::FileLocationFormatterFlag
A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidinitCommandLog(const std::string & name)
Init the Rendering Engine command log.
voidsetLevel(Level level)
Set global logging level.
voidlogCommand(const std::string & origin, const std::string & command)
Log a command to the command log.
AclLog::LevelgetLogLevel()
Internal helper function for getting the setting for the log level.
size_tgetMaxFileSize()
Internal helper function for getting the setting for the maximum size for a log file.
size_tgetMaxLogRotations()
Internal helper function for getting the setting for the maximum number of rotated log files.
std::filesystem::pathgetLogFileFullPath(const std::string & name)
Internal helper function for constructing the full path name for the log file.
std::stringgetThreadName()

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name-.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function initCommandLog

void initCommandLog(
    const std::string & name
)

Init the Rendering Engine command log.

Parameters:

  • name The name of the Rendering Engine (used for filename)

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

function logCommand

void logCommand(
    const std::string & origin,
    const std::string & command
)

Log a command to the command log.

Parameters:

  • origin The origin of the command to log, usually the UUID of the control panel sending the command
  • command The command to log

function getLogLevel

AclLog::Level getLogLevel()

Internal helper function for getting the setting for the log level.

Return: The wanted log level fetched from an environment variable if set, or else a default value

function getMaxFileSize

size_t getMaxFileSize()

Internal helper function for getting the setting for the maximum size for a log file.

Return: The wanted maximum size of the log file fetched from an environment variable if set, or else a default value

function getMaxLogRotations

size_t getMaxLogRotations()

Internal helper function for getting the setting for the maximum number of rotated log files.

Return: The wanted number of log files to rotate fetched from an environment variable if set, or else a default value

function getLogFileFullPath

std::filesystem::path getLogFileFullPath(
    const std::string & name
)

Internal helper function for constructing the full path name for the log file.

Parameters:

  • name The name of the component

Return: The full path to the log file

function getThreadName

inline std::string getThreadName()

Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.3 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.4 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.5 - spdlog

spdlog


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.6 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
tl::expected< TimeCommon::TAIStatus, std::string >getStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.
std::stringtaiMicroToString(int64_t taiTimestamp)
Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

tl::expected< TimeCommon::TAIStatus, std::string > getStatus()

Get TAI status.

Return: Expected with the TAI status if successful or an error string in case something went wrong

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds

function taiMicroToString

std::string taiMicroToString(
    int64_t taiTimestamp
)

Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Parameters:

  • taiTimestamp A TAI timestamp with microseconds resolution

Return: Return a human readable timestamp


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.3.3.7 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2024-01-25 at 12:02:05 +0100

1.6.1.4 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
pskpskThe Pre-shared key used to authorize components to connect to the System Controller. Must be 32 characters long""
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnParameter for token and encryption generation. N is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrParameter for token and encryption generation. R is block size factor. R constrain must satisfy R*P < 2^30. 18
security.ppParameter for token and encryption generation. P is the parallelization parameter. P constrain must satisfy R*P < 2^30, if this is exceeded, an error will be returned 11
security.keylenkeylenThe length of the generated tokens32
client_auth.enabledenabledSwitch to enable basic authentication for clients in the REST APItrue
client_auth.usernameusernameThe username that will grant access to the REST API“admin”
client_auth.passwordpasswordPassword that will grant access to the REST API“changeme”
https.enabledenabledSwitch to enable encryption of the REST API as well as the connections between the System Controller and the connected componentstrue
https.certificate_filecertificate_filePath to the certificate file. In pem format""
https.private_key_fileprivate_key_filePath to the private key file. In pem format""
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
logger.file_name_prefixfile_name_prefixThe prefix of the log filename. A unique timecode and “.log” will automatically be appended to this prefix. The prefix can contain both the path and the prefix of the log file.""
site.portportPort on which the service is accessible8080
site.hosthostHostname on which the service is accessiblelocalhost
response_timeoutresponse_timeoutThe maximum time of a request between the System Controller and a component before the request is timed out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that are allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllow the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be made300
custom_headers.[N].keykeyCustom headers, the key of the header, e.g.: Cache-ControlNone
custom_headers.[N].valuevalueCustom headers, the value to the key of the header, e.g.: no-cacheNone

1.6.2 - Agile Live 5.0.0 developer reference

Agile Live 5.0.0 developer reference

1.6.2.1 - REST API v2

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v2.

1.6.2.2 - Agile Live Rendering Engine command documentation

Reference for the Agile Live Rendering Engine commands

This page describes all the commands available in the Agile Live Rendering Engine.

Command protocol

All commands to the Agile Live Rendering Engine is sent as human readable strings and are listed below. The Rendering Engine expect no line termination, meaning that you do not need to append any type of new line (\n) characters, or string termination (\0) characters.

Video commands

Background

The data path of the video mixer in the Rendering Engine looks as follows:

The video mixer data path

There are eight different node types used in this mixer.

  • The Transition node is used to pick which input slots to use for the program and preview output. The node also supports making transitions between the program and preview.
  • The Select node simply forwards one of the available sources to its output.
  • The Transform node takes one input stream and transforms it (scaling and translating) to one output stream.
  • The Alpha combine node is used to pick two input slots (or the same input slot) to copy the color from one input and combine it with some information from the other input to form the alpha. The color will just be copied from the color input frame, but there are several modes that can be used to produce the alpha channel in the output frame in different ways. This is known as “key & fill” in broadcasting.
  • The Alpha over node is used to perform an “Alpha Over” operation, that is to put the overlay video stream on top of the background video stream, and let the background be seen through the overlay depending on the alpha of the overlay. The node also features fading the graphics in and out by multiplying the alpha channel by a constant factor.
  • The Chroma Key node takes one input stream, and by setting appropriate parameters for the keying, it will remove areas with the key color from the incoming video stream both affecting the alpha and color channels
  • The Fade to black node takes one input stream, which it can fade to or from black gradually, and then outputs that stream.
  • The Output node has one input stream and will output that stream out from the video mixer, back to the Rendering Engine

There are six different flows into this mixer. There is the one starting with the Transition node, which represents the main program that is being produced. Overlaying on top of that is one key+fill graphics overlay (starting with an Alpha Combine node which can combine two video inputs with key form one and fill from another, or both from the same source), then there is a chroma key overlay, which can be used to add green screen effects (Starting with a Select node), then there are two instances of picture-in-picture flows (also starting with select nodes) and on top of that another graphics overlay, called HTML graphics in the illustration, but which can be used with any source where the key and fill comes from the same source. The overlay flows are inserted into the main program using Alpha over nodes.

Each video command in the Rendering Engine command protocol targets one of these nodes.

Transitions

The main flow of the video mixer can be controlled with the following commands:

  • transition cut <input_slot> - Cut (hot punch) the program output to the given input slot. This won’t affect the preview output.
  • transition preview <input_slot> - Preview the given input slot. This won’t affect the program output.
  • transition cut - Cut between the current program and preview outputs, effectively swapping their place.
  • transition panic <input_slot> - Cut (hot punch) both the preview and program output to the given input slot.

Some transition commands last over a duration of time, for example wipes. These can be performed either automatically or manually. The automatic mode works by the operator first selecting the type of transition, for instance a fade, setting the preview to the input slot to fade to and then trigger the transition at the right time with a set duration for the transition. In manual mode the exact “position” of the transition is set by the control panel. This is used for implementing T-bars, where the T-bar repeatedly sends the current position of the bar. In the manual mode, the transition type is set before the transition begins, just as in the automatic mode. Note that an automatic transition will be overridden in case the transition “position” is manually set, by interrupting the automatic transition and jumping to the manually set position.

  • transition type <type> - Set the transition type to use for transitions hereafter. Valid modes are:
    • fade - Fade (mix) from one source to the next
    • wipe_left - Wipe from one source to the next, wipe going from right side of the screen to the left
    • wipe_right - Wipe from one source to the next, wipe going from left side of the screen to the right
  • transition auto <duration_ms> - Perform an automatic transition from the current program output to the current preview output, lasting for <duration_ms> milliseconds. The currently set transition type is used.
  • transition factor <factor> - Manually set the position/factor of the transition. <factor> should be between 0.0 and 1.0, where 0.0 is the value before the transition starts and 1.0 is the end of the transition. Note that setting this value to 1.0 will effectively swap place of program and preview output, resetting the transition factor to 0.0 internally. Control panels using this command must take this into consideration to not cause a sudden jump in the transition once the physical control is moved again. Sending this command will interrupt any ongoing automatic transition.

Key and fill

The key and fill graphics flow will be inserted before the picture-in-picture flows, and will therefore be rendered under them. The graphics flow can be controlled with these commands:

  • alpha_combine color <input_slot> - Set which input slot to copy the color data from in the Alpha combine node
  • alpha_combine alpha <input_slot> - Set which input slot to use to create the alpha channel of the output frame in the Alpha combine node
  • alpha_combine mode <mode> - Set which way the alpha channel of the output frame will be produced. Valid modes are:
    • copy-r - Copy the R-channel of the input “alpha frame” and use it as alpha for the output
    • copy-g - Copy the G-channel of the input “alpha frame” and use it as alpha for the output
    • copy-b - Copy the B-channel of the input “alpha frame” and use it as alpha for the output
    • copy-a - Copy the A-channel of the input “alpha frame” and use it as alpha for the output
    • average-rgb - Take the average of the R, G and B channels of the input “alpha frame” and use it as alpha channel for the output
  • alpha_over factor <factor> - Manually set the transparency multiplier for the Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the overlay is completely invisible and 1.0 means that the overlay is fully visible (where it should be visible according to the overlay image’s alpha channel). Default is 0.0.
  • alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible overlay over the duration of <duration_ms> milliseconds.
  • alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible overlay over the duration of <duration_ms> milliseconds.

Picture-in-Picture

The two picture-in-picture boxes can be controlled with these commands:

  • pip1_select cut <input_slot> - Choose which input slot to forward. Changing looks like a cut.
  • pip1_transform scale <factor> - Set the scale of the picture-in-picture box, relative the original size. Parameter factor must be > 0. Default is 1.0.
  • pip1_transform x <position> - Set the X offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame width, where 0.0 is the left side of the frame and 1.0 is the right side of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_transform y <position> - Set the Y offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame height, where 0.0 is the top of the frame and 1.0 is the bottom of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_alpha_over factor <factor> - Manually set the transparency multiplier for the picture-in-picture 1 Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the picture-in-picture box is completely invisible and 1.0 means that the box is fully visible. Default is 0.0.
  • pip1_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible picture-in-picture box over the duration of <duration_ms> milliseconds.
  • pip1_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible picture-in-picture box over the duration of <duration_ms> milliseconds.

For the second picture-in-picture flow, replace pip1 with pip2.

Chroma Key

The nodes of the chroma key branch of the graph can be controlled with these commands:

  • chroma_key_select cut <input_slot> - Choose which input slot to forward. Changing looks like a cut.
  • chroma_key r <value> - Set the red component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key g <value> - Set the green component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key b <value> - Set the blue component of the chroma key color. Should be a float between 0.0 and 1.0.
  • chroma_key distance <value> - Set the distance parameter, ranging from 0.0 to 1.0, telling how far from the key color is also considered a part of the key. Larger values will result in more colors being included, 0.0 means only the exact key color is considered.
  • chroma_key falloff <value> - Set the falloff parameter, ranging from 0.0 to 1.0, which makes edges smoother. A lower value means harder edges between the key color and the parts to keep, a higher value means a more smooth falloff between removed and kept parts.
  • chroma_key spill <value> - Set the color spill reduction parameter, ranging from 0.0 to 1.0, which will desaturate the key color in the parts of the image that are left. Useful for hiding green rims around objects in from of a green screen etc. 0.0 means off and a higher value means more colors further away from the chroma key color will be desaturated.
  • chroma_key color_picker <x_factor> <y_factor> <square_size> - Set the chroma key by sampling the pixels covered by the square area of size square_size x square_size. The position x,y is set by <x_factor> * width of video and <y_factor> * height of video. <x_factor> & <y_factor> should be a float between 0.0 and 1.0. The <square_size> should be an integer > 0.0.
  • chroma_key alpha_as_video <value> - Instead of writing an alpha mask, set the alpha value as the RGB value, creating a grayscale image of the mask. Value should be 0.0 or 1.0.
  • chroma_key show_key_color <value> - Draw a 100x100 box in upper left corner with the current chroma key (RGB) value. Value should be 0.0 or 1.
  • chroma_key show_color_picker <value> - Draw a pink border around the area where the color picker will sample a new chroma key. Value should be 0.0 or 1.
  • chroma_key_transform scale <factor> - Set the scale of the chroma key output, relative the original size. Parameter factor must be > 0.0. Default is 1.0.
  • chroma_key_transform x <position> - Set the X offset of the top left corner of the chroma key output, relative the top left corner of the frame. Position is measured in percent of frame width, where 0.0 is the left side of the frame and 1.0 is the right side of the frame. Values outside of the range 0.0, 1.0 are valid. Default is 0.0.
  • chroma_key_transform y <position> - Set the Y offset of the top left corner of the chroma key output, relative the top left corner of the frame. Position is measured in percent of frame height, where 0.0 is the top of the frame and 1.0 is the bottom of the frame. Values outside of the range 0.0, 1.0 are valid. Default is 0.0.
  • chroma_key_alpha_over factor <factor> - Manually set the transparency multiplier for the chroma key Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the chroma key output is completely invisible and 1.0 means that the chroma key output is fully visible. Default is 0.0.
  • chroma_key_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible chroma key output over the duration of <duration_ms> milliseconds.
  • chroma_key_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible chroma key output over the duration of <duration_ms> milliseconds.

Graphics overlay (HTML)

The overlay graphics flow, marked with HTML in the illustration. This will be inserted on top of both the key and fill and picture-in-picture. It can be controlled with these commands:

  • html_select cut <input_slot> - Choose which input slot to use for the graphics. It must contain both fill and key (such as the HTML graphics), otherwise, no parts of the layer will be transparent. Changing looks like a cut.
  • html_alpha_over factor <factor> - Manually set the transparency multiplier for the graphics overlay Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the graphics is completely invisible and 1.0 means that it is fully visible. Default is 0.0.
  • html_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible graphics over the duration of <duration_ms> milliseconds.
  • html_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible graphics over the duration of <duration_ms> milliseconds.

Fade to black

The fade to black node can be controlled via the following commands:

  • fade_to_black factor <factor> - Manually set the blackness factor on a scale from 0.0 to 1.0, where 0.0 means not black and 1.0 means fully black output.
  • fade_to_black fade to <duration_ms> - Start an automatic fade to a fully black output over the duration of <duration_ms> milliseconds.
  • fade_to_black fade from <duration_ms> - Start an automatic fade to a fully visible (non-black) output over the duration of <duration_ms> milliseconds.

Audio Router commands

The same audio router is used to route specific audio channels from an input slot of the Rendering Engine to an input channel strip on the audio mixer. By default, it has no audio routes set up. The router can be controlled with the following commands:

  • audio map <input_slot> <channel> mono <input_strip> - Map the <channel> from input slot <input_slot> as a mono channel into input strip <input_strip> of the audio mixer
  • audio map <input_slot> <left_channel> stereo <input_strip> - Map the <left_channel> and <left_channel> + 1 from input slot <input_slot> as a stereo pair into input strip <input_strip> of the audio mixer ’ audio map reset <input_strip> - Remove the current mapping from <input_strip> of the audio mixer.

Audio commands

The audio mixer and audio router have the following data path:

Audio mixer block diagram

In the example picture above, three sources are connected to the input slots and four mono or stereo audio streams are picked as input to the audio mixer. The audio mixer is completely separate from the video mixer, so switching image in the video mixer will not change the audio mixer in any way. The internal audio mixer can be controlled using the following commands:

To control the pre-gain of each input strip use:

  • audio gain <input_strip> <level_dB> - Set the pre-gain level of a specific input in dB. Parameter <level> should be a floating point number. Default is 0.0.

To control the low-pass filter of each input strip use:

  • audio lpf <input_strip> freq <value> - Set the cutoff frequency for the low-pass filter in an input strip. <value> is the frequency in Hz as a floating point number. The frequency range is 20 Hz to 20 kHz. Setting a value of 20 kHz or higher will bypass the filter.
  • audio lpf <input_strip> q <value> - Set the q-value for the low-pass filter in an input strip. The q-value controls the steepness of cutoff curve with a higher value being a steeper slope. The value is a floating point number ranging from 0.4 to 6.0. The default value is 0.7.

To control the high-pass filter of each input strip use:

  • audio hpf <input_strip> freq <value> - Set the cutoff frequency for the high-pass filter in an input strip. <value> is the frequency in Hz as a floating point number. The frequency range is 20 Hz to 20 kHz. Setting a value of 20 Hz or lower will bypass the filter.
  • audio hpf <input_strip> q <value> - Set the q-value for the high-pass filter in an input strip. The q-value controls the steepness of cutoff curve with a higher value being a steeper slope. The value is a floating point number ranging from 0.4 to 6.0. The default value is 0.7.

To control the parametric equalizer of each input strip use (the equalizer has three bands):

  • audio eq <input_strip> <band> freq <value> - Set the frequency of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the frequency in Hz
  • audio eq <input_strip> <band> gain <value> - Set the gain of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the gain in dB.
  • audio eq <input_strip> <band> q <value> - Set the q-value of a specific band in the parametric equalizer to shape the falloff of the band. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the q-value where a higher value means a more pointy curve. Default value is 0.7.
  • audio eq <input_strip> <band> type <type> - Set the type of falloff to use for a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <type> is either of low, band or high, where low and high is a low and high shelf filter and band is a band pass filter. By default, the first band is low shelf, the last band is high shelf and any bands inbetween are band pass.

To control the panning of each input strip use:

  • audio pan <input_strip> <factor> - Pan the mono or stereo input of an input strip to the left or right. The range of <factor> is between -1.0 and +1.0, where 0.0 means center (no panning), negative values means more to the left and positive value more to the right. Values outside this range will be clamped. A value of +/- 1.0 means that there will only be audio in the left/right channel.

To control the dynamic range compressor of each input strip use:

  • audio comp <input_strip> threshold <value> - Set the threshold for activation of the compressor. The threshold is a negative dB value ranging from -30 dB to 0 dB. The volume of audio which is above the threshold value will be reduced (compressed). The default value is 0 dB, i.e. only compression if the audio signal is overloaded.
  • audio comp <input_strip> ratio <value> - Set the compression ratio for audio exceeding the loudness threshold. The value is the numerator in the compression ratio <value>:1. For instance, if the value is set to 4, the compression ratio is 4:1 and volume overshoot above the threshold will be scaled down to 25 %. The ratio numerator is a floating point number in the range from 1.0 to 24.0, with 4.0 as the default value.
  • audio comp <input_strip> knee <value> - Set the width of the soft knee in decibels. Instead of simply turning the compression completely on or off at the threshold, the knee defines a volume range in which the compression ratio follows a curve, the “knee”. The knee is a floating point number between 0 dB and 30 dB, with a default value of 2.5 dB.
  • audio comp <input_strip> attack <value> - Set the attack time of the compressor in milliseconds. The attack time determines how long it takes to reach the full compression after the threshold has been exceeded. The value is a floating point number in the range from 0.1 ms to 120 ms. The default value is 50 ms.
  • audio comp <input_strip> release <value> - Set the release time of the compressor in milliseconds. The release time determines how long it takes to return to zero compression when the volume is below the compression threshold. The value is a floating point number in the range from 10 ms to 1000 ms. The default value is 200 ms.
  • audio comp <input_strip> gain <value> - Set the make-up gain i decibels. Since the compression filter lowers the volume of louder audio sections it can be desirable to increase the gain after the filtering. The gain value increases the audio volume with the specified number of decibels. The value is a floating point number in the range from 0 dB to 24 dB. The default value is 0 dB.

To control the volume faders and master volume faders use:

  • audio volume <input_strip> <output> <level> - Set the volume level of a specific input in proportion to its original strength for a given output. Parameter <level> should be a floating point number, where 0.0 means that the input slot is not mixed into the output at all and 1.0 means that the volume of the input slot is kept as is for the output. The signal can also be amplified by using values > 1.0. Default is 0.0.
  • audio mastervolume <output> <level> - Set the master volume level of an output, before the audio is clamped and converted from floating point samples to 16-bit integer samples. This can be used to avoid clipping of the audio when mixing multiple input sources. Parameter <level> is a floating point number where 0.0 means that all audio output is off, 1.0 means that the volume is not changed and any value above 1.0 means that the master volume is amplified. Default is 1.0.

HTML rendering

The Rendering Engine also features a built-in HTML renderer which uses the Chromium web browser engine to render HTML pages. The following commands can be used to create and control the HTML browser instances:

  • html create <input_slot> <width> <height> - Create a new HTML browser instance with the canvas size of width x height pixels and output the rendered frames to the given input slot
  • html close <input_slot> - Close the HTML browser instance on the given input slot
  • html load <input_slot> <url> - Load a new URL in the HTML browser on the given input slot
  • html execute <input_slot> <java script> - Execute JavaScript in the HTML browser on the given input slot. The JavaScript snippet might span over multiple lines and may contain spaces.

1.6.2.3 - C++ SDK

Agile Content Live C++ SDK reference

Agile Content Live C++ SDK reference.

1.6.2.3.1 - Classes

Classes

  • namespace AclLog
    A namespace for logging utilities.
  • struct AlignedAudioFrame
    AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
  • struct AlignedFrame
    A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class DeviceMemory
    RAII class for a CUDA memory buffer.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class PipelineSystemControllerInterfaceFactory
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.
  • namespace spdlog

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.1 - AclLog::CommandLogFormatter

AclLog::CommandLogFormatter

This class is used to format log entries for Rendering Engine commands.

#include <AclLog.h>

Inherits from spdlog::formatter

Public Functions

Name
CommandLogFormatter()
voidformat(const spdlog::details::log_msg & msg, spdlog::memory_buf_t & dest) override
std::unique_ptr< spdlog::formatter >clone() const override

Public Functions Documentation

function CommandLogFormatter

CommandLogFormatter()

function format

void format(
    const spdlog::details::log_msg & msg,
    spdlog::memory_buf_t & dest
) override

function clone

std::unique_ptr< spdlog::formatter > clone() const override

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.2 - AclLog::FileLocationFormatterFlag

AclLog::FileLocationFormatterFlag

A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

#include <AclLog.h>

Inherits from spdlog::custom_flag_formatter

Public Functions

Name
voidformat(const spdlog::details::log_msg & msg, const std::tm & , spdlog::memory_buf_t & dest) override
std::unique_ptr< custom_flag_formatter >clone() const override

Public Functions Documentation

function format

inline void format(
    const spdlog::details::log_msg & msg,
    const std::tm & ,
    spdlog::memory_buf_t & dest
) override

function clone

inline std::unique_ptr< custom_flag_formatter > clone() const override

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.3 - AclLog::ThreadNameFormatterFlag

AclLog::ThreadNameFormatterFlag

Inherits from spdlog::custom_flag_formatter

Public Functions

Name
voidformat(const spdlog::details::log_msg & , const std::tm & , spdlog::memory_buf_t & dest) override
std::unique_ptr< custom_flag_formatter >clone() const override

Public Functions Documentation

function format

inline void format(
    const spdlog::details::log_msg & ,
    const std::tm & ,
    spdlog::memory_buf_t & dest
) override

function clone

inline std::unique_ptr< custom_flag_formatter > clone() const override

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.4 - AlignedAudioFrame

AlignedAudioFrame

AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.

#include <AlignedFrame.h>

Public Attributes

Name
std::vector< float >mSamples
uint8_tmNumberOfChannels
uint32_tmNumberOfSamplesPerChannel

Public Attributes Documentation

variable mSamples

std::vector< float > mSamples;

variable mNumberOfChannels

uint8_t mNumberOfChannels = 0;

variable mNumberOfSamplesPerChannel

uint32_t mNumberOfSamplesPerChannel = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.5 - AlignedFrame

AlignedFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedFrame.h>

Public Types

Name
enum classPixelFormat { kUnknown, kNv12, kP016, kUyvy, kRgba, kRgba64Le}

Public Functions

Name
AlignedFrame() =default
~AlignedFrame() =default
AlignedFrame(AlignedFrame const & ) =delete
AlignedFrame &operator=(AlignedFrame const & ) =delete

Public Attributes

Name
int64_tmCaptureTimestamp
int64_tmRenderingTimestamp
std::shared_ptr< DeviceMemory >mVideoFrame
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
AlignedAudioFramePtrmAudioFrame
uint32_tmAudioSamplingFrequency

Public Types Documentation

enum PixelFormat

EnumeratorValueDescription
kUnknown
kNv12
kP016
kUyvy
kRgba
kRgba64Le

Public Functions Documentation

function AlignedFrame

AlignedFrame() =default

function ~AlignedFrame

~AlignedFrame() =default

function AlignedFrame

AlignedFrame(
    AlignedFrame const & 
) =delete

function operator=

AlignedFrame & operator=(
    AlignedFrame const & 
) =delete

Public Attributes Documentation

variable mCaptureTimestamp

int64_t mCaptureTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame was captured by the ingest

variable mRenderingTimestamp

int64_t mRenderingTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame should be delivered to the rendering engine

variable mVideoFrame

std::shared_ptr< DeviceMemory > mVideoFrame = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioFrame

AlignedAudioFramePtr mAudioFrame = nullptr;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.6 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType = ConnectionType::DISCONNECTED;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.7 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.8 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.9 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.10 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< std::vector< uint8_t > >mMessages
std::stringmSenderUUID
The actual messages.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessages

std::vector< std::vector< uint8_t > > mMessages;

variable mSenderUUID

std::string mSenderUUID;

The actual messages.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.11 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.12 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.13 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v2.1.0-231-gcd012ab”, followed by “-dirty” in case there are changes made to the Git repo.

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.14 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.15 - DeviceMemory

DeviceMemory

RAII class for a CUDA memory buffer.

#include <DeviceMemory.h>

Public Functions

Name
DeviceMemory() =default
Default constructor, creates an empty object, without allocating any memory on the device.
DeviceMemory(size_t numberOfBytes)
Constructor allocating the required number of bytes.
DeviceMemory(size_t numberOfBytes, cudaStream_t cudaStream)
Constructor allocating the required number of bytes by making an async allocation. The allocation will be put in the given CUDA stream.
DeviceMemory(void * deviceMemory)
Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.
boolallocateMemory(size_t numberOfBytes)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolallocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolreallocateMemory(size_t numberOfBytes)
Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.
boolallocateAndResetMemory(size_t numberOfBytes)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolallocateAndResetMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolfreeMemory()
Free the device memory held by this class. Calling this when no memory is allocated is a no-op.
boolfreeMemoryAsync(cudaStream_t cudaStream)
Deallocate memory asynchronously, in a given CUDA stream. Calling this when no memory is allocated is a no-op.
voidsetFreeingCudaStream(cudaStream_t cudaStream)
Set which CUDA stream to use for freeing this DeviceMemory. In case the DeviceMemory already holds a CUDA stream to use for freeing the memory, this will be overwritten.
~DeviceMemory()
Destructor, frees the internal CUDA memory.
template
T *
getDevicePointer() const
size_tgetSize() const
DeviceMemory(DeviceMemory && other)
DeviceMemory &operator=(DeviceMemory && other)
voidswap(DeviceMemory & other)
DeviceMemory(DeviceMemory const & ) =delete
DeviceMemory is not copyable.
DeviceMemoryoperator=(DeviceMemory const & ) =delete

Public Functions Documentation

function DeviceMemory

DeviceMemory() =default

Default constructor, creates an empty object, without allocating any memory on the device.

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes
)

Constructor allocating the required number of bytes.

Parameters:

  • numberOfBytes Number of bytes to allocate

Exceptions:

  • std::runtime_error In case the allocation failed

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Constructor allocating the required number of bytes by making an async allocation. The allocation will be put in the given CUDA stream.

Parameters:

  • size Number of bytes to allocate
  • cudaStream The CUDA stream to put the async allocation in. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Exceptions:

  • std::runtime_error In case the async allocation failed to be put in queue.

See: freeMemoryAsync method is not explicitly called, the memory will be freed synchronously when this DeviceMemory instance goes out of scope, meaning that the entire GPU is synchronized, which will impact performance negatively.

Note:

  • The method will return as soon as the allocation is put in queue in the CUDA stream, i.e. before the actual allocation is made. Using this DeviceMemory is only valid as long as it is used in the same CUDA stream, or in case another stream is used, only if that stream is synchronized first with respect to cudaStream.
  • In case the

function DeviceMemory

explicit DeviceMemory(
    void * deviceMemory
)

Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.

Parameters:

  • deviceMemory CUDA memory pointer to take ownership over.

function allocateMemory

bool allocateMemory(
    size_t numberOfBytes
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function allocateMemoryAsync

bool allocateMemoryAsync(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate
  • cudaStream The CUDA stream to use for the allocation. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function reallocateMemory

bool reallocateMemory(
    size_t numberOfBytes
)

Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.

Parameters:

  • numberOfBytes Number of bytes to allocate in the new allocation

Return: True on success, false if CUDA free or CUDA malloc failed.

function allocateAndResetMemory

bool allocateAndResetMemory(
    size_t numberOfBytes
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function allocateAndResetMemoryAsync

bool allocateAndResetMemoryAsync(
    size_t numberOfBytes,
    cudaStream_t cudaStream
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate
  • cudaStream The CUDA stream to use for the allocation and resetting. A reference to this stream will also be saved internally to be used to asynchronously free them memory when the instance goes out of scope.

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function freeMemory

bool freeMemory()

Free the device memory held by this class. Calling this when no memory is allocated is a no-op.

See: freeMemoryAsync instead.

Return: True in case the memory was successfully freed (or not allocated to begin with), false otherwise.

Note: This method will free the memory in an synchronous fashion, synchronizing the entire CUDA context and ignoring the internally saved CUDA stream reference in case one exist. For async freeing of the memory, use

function freeMemoryAsync

bool freeMemoryAsync(
    cudaStream_t cudaStream
)

Deallocate memory asynchronously, in a given CUDA stream. Calling this when no memory is allocated is a no-op.

Parameters:

  • cudaStream The CUDA stream to free the memory asynchronously in

Return: True in case the memory deallocation request was successfully put in queue in the CUDA stream.

Note:

  • The method will return as soon as the deallocation is put in queue in the CUDA stream, i.e. before the actual deallocation is made.
  • It is the programmer’s responsibility to ensure this DeviceMemory is not used in another CUDA stream before this method is called. In case it is used in another CUDA stream, sufficient synchronization must be made before calling this method (and a very good reason given for not freeing the memory in that CUDA stream instead)

function setFreeingCudaStream

void setFreeingCudaStream(
    cudaStream_t cudaStream
)

Set which CUDA stream to use for freeing this DeviceMemory. In case the DeviceMemory already holds a CUDA stream to use for freeing the memory, this will be overwritten.

Parameters:

  • cudaStream The new CUDA stream to use for freeing the memory when the destructor is called.

Note: It is the programmer’s responsibility to ensure this DeviceMemory is not used in another CUDA stream before this instance is destructed. In case it is used in another CUDA stream, sufficient synchronization must be made before setting this as the new CUDA stream to use when freeing the memory.

function ~DeviceMemory

~DeviceMemory()

Destructor, frees the internal CUDA memory.

function getDevicePointer

template <typename T  =uint8_t>
inline T * getDevicePointer() const

Template Parameters:

  • T The pointer type to return

Return: the CUDA memory pointer handled by this class. Nullptr in case no memory is allocated.

function getSize

size_t getSize() const

Return: The size of the CUDA memory allocation held by this class.

function DeviceMemory

DeviceMemory(
    DeviceMemory && other
)

function operator=

DeviceMemory & operator=(
    DeviceMemory && other
)

function swap

void swap(
    DeviceMemory & other
)

function DeviceMemory

DeviceMemory(
    DeviceMemory const & 
) =delete

DeviceMemory is not copyable.

function operator=

DeviceMemory operator=(
    DeviceMemory const & 
) =delete

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.16 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v1.0.0”, or “v2.1.0-231-gcd012ab”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.17 - IngestApplication::Settings

IngestApplication::Settings


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.18 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) =0
Send a request with some JSON parameters to the controller and await the response.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) =0

Send a request with some JSON parameters to the controller and await the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller.

Reimplemented by: SystemControllerConnection::sendRequest

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.19 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.20 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.21 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Types

Name
enum class uint32_tTallyBorderColor { kNone, kRed, kGreen, kYellow}
Available colors for tally border in multi view.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, CUcontext cudaContext, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const AlignedFramePtr &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
boolremoveCustomMultiViewSourceInput(uint32_t inputSlot)
Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.
voidsetTallyBorder(uint32_t inputSlot, TallyBorderColor color)
Set tally border color in the multi-views for a specific input slot.
voidclearTallyBorder(uint32_t inputSlot)
Remove tally border in the multi-views for a specific input slot.
voidclearAllTallyBorders()
Remove all tally borders.
MediaReceiver::TallyBorderColorgetTallyBorder(uint32_t inputSlot) const
get tally border color for an input slot
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Public Types Documentation

enum TallyBorderColor

EnumeratorValueDescription
kNone
kRed
kGreen
kYellow

Available colors for tally border in multi view.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    CUcontext cudaContext,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • cudaContext The CUDA context to use for this MediaReceiver. The frames will delivered as CUDA pointers, valid in this context, and the multi-view generator will use this context for rendering and encoding.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const AlignedFramePtr &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Note: Make sure no CUDA stream will write to the DeviceMemory in the AlignedFrame passed to the function. Failing to do so will lead to undefined behavior. In case another CUDA stream has written to the DeviceMemory, make sure to synchronize with the stream before passing the AlignedFrame.

Precondition: The AlignedFrame sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function removeCustomMultiViewSourceInput

bool removeCustomMultiViewSourceInput(
    uint32_t inputSlot
)

Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.

Parameters:

  • inputSlot The input slot the custom multi-view source input is connected to, that should be removed

Return: True if the custom multi-view source input was successfully removed, false in case there was no custom input registered for the given input slot, or in case of an internal error.

function setTallyBorder

void setTallyBorder(
    uint32_t inputSlot,
    TallyBorderColor color
)

Set tally border color in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source
  • color the color to set

function clearTallyBorder

void clearTallyBorder(
    uint32_t inputSlot
)

Remove tally border in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source

function clearAllTallyBorders

void clearAllTallyBorders()

Remove all tally borders.

function getTallyBorder

MediaReceiver::TallyBorderColor getTallyBorder(
    uint32_t inputSlot
) const

get tally border color for an input slot

Parameters:

  • inputSlot the input slot to get color for

Return: the tally border color for the given input slot

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.22 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.23 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
AlignedFrame::PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDeliverOld
Set to true if this MediaReceiver should have a multi-view generator.
CUstreammAlignedFrameFreeStream

Public Attributes Documentation

variable mDecodedFormat

AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

Note: The internal CUDA stream is synchronized before delivering the AlignedFrames, meaning the DeviceMemory in the AlignedFrame will always contain the written data; no further synchronization is needed before the rendering engine can read the data.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDeliverOld

bool mDeliverOld = false;

Set to true if this MediaReceiver should have a multi-view generator.

variable mAlignedFrameFreeStream

CUstream mAlignedFrameFreeStream = nullptr;

Set to true if the media frames should be delivered, even if the delivery time has already passed, otherwise they are discarded The CUDA stream to use for asynchronously freeing the AlignedFrames’ DeviceMemory. Set this to the rendering engine’s CUDA stream, to ensure memory is not freed before the rendering engine is done using it asynchronously in its CUDA stream. Note that the MediaReceiver instance and all AlignedFrames delivered from it must be destroyed before the CUDA stream can be destroyed.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.24 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, CUcontext cudaContext)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
boolhasFormatAndIsRunning() const
boolhasOpenOutputStream() const
booloutputData(const AlignedFramePtr & frame)
Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    CUcontext cudaContext
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer
  • cudaContext The CUDA context to use for this MediaStreamer. The frames passed to this instance should be valid in this CUDA context. The streamer will use this context for preprocessing and encoding.

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the format reset, or if the format was not set before this method was called, false on error.

function hasFormatAndIsRunning

bool hasFormatAndIsRunning() const

Return: True if the input format is set and the OutputStreamer is running, false otherwise

function hasOpenOutputStream

bool hasOpenOutputStream() const

See:

  • outputData will be discarded without being encoded, as there is no stream to output them to. This method can be used to check if the frame even needs to be produced by the rendering engine. Note however, that the
  • outputData method will still log the frames sent to it as received, even if they are not encoded when the output stream is closed.

Return: True if the output stream of the MediaStreamer is currently open and outputting the data, false otherwise. In case this returns false all frames passed to

function outputData

bool outputData(
    const AlignedFramePtr & frame
)

Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

Note: The DeviceMemory in the AlignedFrame passed to this method must not be in use by any CUDA stream. In case the memory has been used in kernels in another CUDA stream, make sure to first synchronize with the stream, before passing it over to the MediaStreamer.

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.25 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
AlignedFrame::PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.26 - PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory

Public Functions

Name
PipelineSystemControllerInterfaceFactory(const std::string & systemControllerIP, uint16_t systemControllerPort, const std::string & systemControllerPostfix, const std::string & psk, const std::string & myIP, bool useHTTPS, bool allowInsecureHTTPS, const std::string & customCaCertFile)
Constructor.
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const && ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const && ) =delete
std::shared_ptr< SystemControllerConnection >getMediaReceiverInterface(const std::string & name)
Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.
std::shared_ptr< SystemControllerConnection >createMediaStreamerInterface(const std::string & name)
Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.
std::shared_ptr< SystemControllerConnection >createControlReceiverInterface(const std::string & name)
Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Public Functions Documentation

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    const std::string & systemControllerIP,
    uint16_t systemControllerPort,
    const std::string & systemControllerPostfix,
    const std::string & psk,
    const std::string & myIP,
    bool useHTTPS,
    bool allowInsecureHTTPS,
    const std::string & customCaCertFile
)

Constructor.

Parameters:

  • systemControllerIP The IP address of the System controller to connect to.
  • systemControllerPort The network port of the System controller to connect to.
  • systemControllerPostfix The postfix of the System controller’s address, to chose which API endpoints to use.
  • psk The Pre-shared key used for authorization at the System controller.
  • myIP The public IP address of the pipeline, i.e. the external IP used to connect to the pipeline.
  • useHTTPS If HTTPS should be used instead of HTTP
  • allowInsecureHTTPS Set to true to allow self-signed HTTPS certificates. Should normally be false.
  • customCaCertFile Full path to CA certificate file for verifying server cert, optional.

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function getMediaReceiverInterface

std::shared_ptr< SystemControllerConnection > getMediaReceiverInterface(
    const std::string & name
)

Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.

Parameters:

  • name The human readable name of the MediaReceiver to provide to the System controller

Return: A configured connection on success, otherwise nullptr

function createMediaStreamerInterface

std::shared_ptr< SystemControllerConnection > createMediaStreamerInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the MediaStreamer to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called

Return: A configured connection on success, otherwise nullptr

function createControlReceiverInterface

std::shared_ptr< SystemControllerConnection > createControlReceiverInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the ControlReceiver to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called to generate the parent interface.

Return: A configured connection on success, otherwise nullptr


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.27 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) override
Send a JSON object to the system controller server and awaits the response.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) override

Send a JSON object to the system controller server and awaits the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller

Note: The status code might be TIMEOUT in case no response was received within the timeframe

Reimplements: ISystemControllerInterface::sendRequest

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.28 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout
boolmEnableHTTPS
boolmInsecureHTTPS
std::stringmCustomCaCertFile

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

variable mEnableHTTPS

bool mEnableHTTPS;

variable mInsecureHTTPS

bool mInsecureHTTPS;

variable mCustomCaCertFile

std::string mCustomCaCertFile;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.29 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock
doublemTimeDiffS

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

variable mTimeDiffS

double mTimeDiffS = 0.0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.1.30 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.
classAclLog::ThreadNameFormatterFlag
classAclLog::FileLocationFormatterFlag
A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <filesystem>
#include <string>

#include <spdlog/details/log_msg.h>
#include <spdlog/fmt/fmt.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>
#include <sys/prctl.h>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void initCommandLog(const std::string& name);

void setLevel(Level level);

void logCommand(const std::string& command);

AclLog::Level getLogLevel();

size_t getMaxFileSize();

size_t getMaxLogRotations();

std::filesystem::path getLogFileFullPath(const std::string& name);

class CommandLogFormatter : public spdlog::formatter {
public:
    CommandLogFormatter();
    void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override;
    [[nodiscard]] std::unique_ptr<spdlog::formatter> clone() const override;

private:
    std::unique_ptr<spdlog::pattern_formatter> mCommandLogPattern;
};

inline std::string getThreadName() {
    static const size_t RECOMMENDED_BUFFER_SIZE = 20;
    static thread_local std::string name;

    if (name.empty()) {
        char buffer[RECOMMENDED_BUFFER_SIZE];
        int retval = prctl(PR_GET_NAME, buffer);
        if (retval == -1) {
            throw spdlog::spdlog_ex("Failed to get thread name: ", errno);
        }
        name = std::string(buffer);
    }
    return name;
}

class ThreadNameFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg&, const std::tm&, spdlog::memory_buf_t& dest) override {
        std::string threadName = getThreadName();
        dest.append(threadName.data(), threadName.data() + threadName.size());
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<ThreadNameFormatterFlag>();
    }
};

class FileLocationFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg& msg, const std::tm&, spdlog::memory_buf_t& dest) override {
        if (!msg.source.empty()) {
            using namespace spdlog::details;

            dest.push_back('[');
            const char* filename = short_filename_formatter<null_scoped_padder>::basename(msg.source.filename);
            fmt_helper::append_string_view(filename, dest);
            dest.push_back(':');
            fmt_helper::append_int(msg.source.line, dest);
            dest.push_back(']');
        }
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<FileLocationFormatterFlag>();
    }
};

} // namespace AclLog

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.2 - include/AlignedFrame.h

include/AlignedFrame.h

Classes

Name
structAlignedAudioFrame
AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
structAlignedFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
using std::shared_ptr< AlignedAudioFrame >AlignedAudioFramePtr
using std::shared_ptr< const AlignedAudioFrame >AlignedAudioFrameConstPtr
using std::shared_ptr< AlignedFrame >AlignedFramePtr

Functions

Name
AlignedAudioFramePtrcreateAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel)
Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.
AlignedAudioFramePtrextractChannel(AlignedAudioFrameConstPtr sourceFrame, uint8_t channelIndex)
Extract one channel from an AlignedAudioFrame as a new AlignedAudioFrame. The new AlignedAudioFrame will share no data with the original frame, meaning the new frame can be edited without corrupting the old one.

Types Documentation

using AlignedAudioFramePtr

using AlignedAudioFramePtr =  std::shared_ptr<AlignedAudioFrame>;

using AlignedAudioFrameConstPtr

using AlignedAudioFrameConstPtr =  std::shared_ptr<const AlignedAudioFrame>;

using AlignedFramePtr

using AlignedFramePtr =  std::shared_ptr<AlignedFrame>;

Functions Documentation

function createAlignedAudioFrame

AlignedAudioFramePtr createAlignedAudioFrame(
    uint8_t numberOfChannels,
    uint32_t numberOfSamplesPerChannel
)

Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.

Parameters:

  • numberOfChannels Number of channels to allocate space for
  • numberOfSamplesPerChannel Number of samples per channel to allocate space for

Return: Shared pointer to the new AudioFrame

function extractChannel

AlignedAudioFramePtr extractChannel(
    AlignedAudioFrameConstPtr sourceFrame,
    uint8_t channelIndex
)

Extract one channel from an AlignedAudioFrame as a new AlignedAudioFrame. The new AlignedAudioFrame will share no data with the original frame, meaning the new frame can be edited without corrupting the old one.

Parameters:

  • sourceFrame The frame to extract a channel from
  • channelIndex The zero-based channel index to extract

Return: Shared pointer to a new mono AlignedAudioFrame, or nullptr if channel is out of bounds

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <memory>
#include <vector>

#include <cuda_runtime_api.h>

#include "DeviceMemory.h"

struct AlignedAudioFrame {
    // The samples interleaved
    std::vector<float> mSamples;
    uint8_t mNumberOfChannels = 0;
    uint32_t mNumberOfSamplesPerChannel = 0;
};

using AlignedAudioFramePtr = std::shared_ptr<AlignedAudioFrame>;
using AlignedAudioFrameConstPtr = std::shared_ptr<const AlignedAudioFrame>;

AlignedAudioFramePtr createAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel);

AlignedAudioFramePtr extractChannel(AlignedAudioFrameConstPtr sourceFrame, uint8_t channelIndex);

struct AlignedFrame {

    enum class PixelFormat {
        kUnknown,
        kNv12,    // 8 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kP016,    // 16 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kUyvy,    // 8 bit per component 4:2:2 YUV format. U-Y-V-Y bytes interleaved.
        kRgba,    // 8 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory.
        kRgba64Le // 16 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory with little endian words.
    };

    AlignedFrame() = default;

    ~AlignedFrame() = default;

    AlignedFrame(AlignedFrame const&) = delete;            // Copy construct
    AlignedFrame& operator=(AlignedFrame const&) = delete; // Copy assign

    int64_t mCaptureTimestamp = 0;

    int64_t mRenderingTimestamp = 0;

    // Video
    std::shared_ptr<DeviceMemory> mVideoFrame = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    AlignedAudioFramePtr mAudioFrame = nullptr;
    uint32_t mAudioSamplingFrequency = 0;
};

using AlignedFramePtr = std::shared_ptr<AlignedFrame>;

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstdint>
#include <string>
#include <vector>

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType = ConnectionType::DISCONNECTED;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<std::vector<uint8_t>> mMessages; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.7 - include/DeviceMemory.h

include/DeviceMemory.h

Classes

Name
classDeviceMemory
RAII class for a CUDA memory buffer.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstddef>
#include <cstdint>

#include <cuda_runtime.h>

class DeviceMemory {
public:
    DeviceMemory() = default;

    explicit DeviceMemory(size_t numberOfBytes);

    explicit DeviceMemory(size_t numberOfBytes, cudaStream_t cudaStream);

    explicit DeviceMemory(void* deviceMemory) noexcept;

    bool allocateMemory(size_t numberOfBytes);

    bool allocateMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream);

    bool reallocateMemory(size_t numberOfBytes);

    bool allocateAndResetMemory(size_t numberOfBytes);

    bool allocateAndResetMemoryAsync(size_t numberOfBytes, cudaStream_t cudaStream);

    bool freeMemory();

    bool freeMemoryAsync(cudaStream_t cudaStream);

    void setFreeingCudaStream(cudaStream_t cudaStream);

    ~DeviceMemory();

    template <typename T = uint8_t> [[nodiscard]] T* getDevicePointer() const {
        return reinterpret_cast<T*>(dMemory);
    }

    [[nodiscard]] size_t getSize() const;

    DeviceMemory(DeviceMemory&& other) noexcept;
    DeviceMemory& operator=(DeviceMemory&& other) noexcept;

    void swap(DeviceMemory& other) noexcept;

    DeviceMemory(DeviceMemory const&) = delete;
    DeviceMemory operator=(DeviceMemory const&) = delete;

private:
    uint8_t* dMemory = nullptr;
    size_t mAllocatedBytes = 0;
    cudaStream_t mCudaStream = nullptr; // Stream to use for Async free
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.8 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {};

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.9 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.10 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual Response sendRequest(const std::string& request, const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.11 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include <cuda.h>

#include "AlignedFrame.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

        std::function<std::function<void(const AlignedFramePtr&)>(uint32_t inputSlot,
                                                                  const std::string& streamID,
                                                                  const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDeliverOld = false;     

        CUstream mAlignedFrameFreeStream = nullptr;
    };

    enum class TallyBorderColor : uint32_t { kNone, kRed, kGreen, kYellow };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface,
               CUcontext cudaContext,
               const Settings& settings);

    void stop();

    std::function<void(const AlignedFramePtr&)> getCustomMultiViewSourceInput(uint32_t inputSlot,
                                                                              const std::string& name = "");

    bool removeCustomMultiViewSourceInput(uint32_t inputSlot);

    void setTallyBorder(uint32_t inputSlot, TallyBorderColor color);

    void clearTallyBorder(uint32_t inputSlot);

    void clearAllTallyBorders();

    [[nodiscard]] MediaReceiver::TallyBorderColor getTallyBorder(uint32_t inputSlot) const;

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.12 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>
#include <cuda.h>

#include "AlignedFrame.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, CUcontext cudaContext);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    [[nodiscard]] bool hasFormatAndIsRunning() const;

    [[nodiscard]] bool hasOpenOutputStream() const;

    bool outputData(const AlignedFramePtr& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.13 - include/PipelineSystemControllerInterfaceFactory.h

include/PipelineSystemControllerInterfaceFactory.h

Classes

Name
classPipelineSystemControllerInterfaceFactory

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <string>

#include "SystemControllerConnection.h"

class PipelineSystemControllerInterfaceFactory final {
public:
    PipelineSystemControllerInterfaceFactory(const std::string& systemControllerIP,
                                             uint16_t systemControllerPort,
                                             const std::string& systemControllerPostfix,
                                             const std::string& psk,
                                             const std::string& myIP,
                                             bool useHTTPS,
                                             bool allowInsecureHTTPS,
                                             const std::string& customCaCertFile);

    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&&) = delete;

    std::shared_ptr<SystemControllerConnection> getMediaReceiverInterface(const std::string& name);

    //    /// to generate the parent interface.
    std::shared_ptr<SystemControllerConnection> createMediaStreamerInterface(const std::string& name);

    std::shared_ptr<SystemControllerConnection> createControlReceiverInterface(const std::string& name);

private:
    std::string mSystemControllerIP;
    uint16_t mSystemControllerPort = 0;
    std::string mSystemControllerPostfix;
    std::string mPsk;
    std::string mMyIP;
    bool mUseHTTPS = true;
    bool mAllowInsecureHTTPS = false;
    std::string mCustomCaCertFile;

    std::shared_ptr<SystemControllerConnection> mReceiverController;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.14 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000};           // Max time to wait on an announcement response from the server during connection
        bool mEnableHTTPS;   // Enable the communication between the system controller and a component encrypted
        bool mInsecureHTTPS; // Disable the verification of the TLS certificate if requested.
        std::string mCustomCaCertFile; // Custom CA certificate
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    Response sendRequest(const std::string& request, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.15 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

#include "expected.hpp"

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
    double mTimeDiffS = 0.0; // Time diff vs NTP in seconds, +/- value means slow/faster than NTP time
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

tl::expected<TimeCommon::TAIStatus, std::string> getStatus();

int64_t getTAIMicro();

std::string taiMicroToString(int64_t taiTimestamp);
} // namespace TimeCommon

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.2.16 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3 - Namespaces

Namespaces


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.1 - AclLog

AclLog

A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.
classAclLog::ThreadNameFormatterFlag
classAclLog::FileLocationFormatterFlag
A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidinitCommandLog(const std::string & name)
Init the Rendering Engine command log.
voidsetLevel(Level level)
Set global logging level.
voidlogCommand(const std::string & command)
Log a command to the command log.
AclLog::LevelgetLogLevel()
Internal helper function for getting the setting for the log level.
size_tgetMaxFileSize()
Internal helper function for getting the setting for the maximum size for a log file.
size_tgetMaxLogRotations()
Internal helper function for getting the setting for the maximum number of rotated log files.
std::filesystem::pathgetLogFileFullPath(const std::string & name)
Internal helper function for constructing the full path name for the log file.
std::stringgetThreadName()

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name-.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function initCommandLog

void initCommandLog(
    const std::string & name
)

Init the Rendering Engine command log.

Parameters:

  • name The name of the Rendering Engine (used for filename)

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

function logCommand

void logCommand(
    const std::string & command
)

Log a command to the command log.

Parameters:

  • command The command to log

function getLogLevel

AclLog::Level getLogLevel()

Internal helper function for getting the setting for the log level.

Return: The wanted log level fetched from an environment variable if set, or else a default value

function getMaxFileSize

size_t getMaxFileSize()

Internal helper function for getting the setting for the maximum size for a log file.

Return: The wanted maximum size of the log file fetched from an environment variable if set, or else a default value

function getMaxLogRotations

size_t getMaxLogRotations()

Internal helper function for getting the setting for the maximum number of rotated log files.

Return: The wanted number of log files to rotate fetched from an environment variable if set, or else a default value

function getLogFileFullPath

std::filesystem::path getLogFileFullPath(
    const std::string & name
)

Internal helper function for constructing the full path name for the log file.

Parameters:

  • name The name of the component

Return: The full path to the log file

function getThreadName

inline std::string getThreadName()

Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.2 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.3 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.4 - spdlog

spdlog


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.5 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
tl::expected< TimeCommon::TAIStatus, std::string >getStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.
std::stringtaiMicroToString(int64_t taiTimestamp)
Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

tl::expected< TimeCommon::TAIStatus, std::string > getStatus()

Get TAI status.

Return: Expected with the TAI status if successful or an error string in case something went wrong

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds

function taiMicroToString

std::string taiMicroToString(
    int64_t taiTimestamp
)

Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Parameters:

  • taiTimestamp A TAI timestamp with microseconds resolution

Return: Return a human readable timestamp


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.3.3.6 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2023-10-03 at 14:32:11 +0200

1.6.2.4 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
pskpskThe Pre-shared key used to authorize components to connect to the System Controller. Must be 32 characters long""
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnParameter for token and encryption generation. N is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrParameter for token and encryption generation. R is block size factor. R constrain must satisfy R*P < 2^30. 18
security.ppParameter for token and encryption generation. P is the parallelization parameter. P constrain must satisfy R*P < 2^30, if this is exceeded, an error will be returned 11
security.keylenkeylenThe length of the generated tokens32
client_auth.enabledenabledSwitch to enable basic authentication for clients in the REST APItrue
client_auth.usernameusernameThe username that will grant access to the REST API“admin”
client_auth.passwordpasswordPassword that will grant access to the REST API“changeme”
https.enabledenabledSwitch to enable encryption of the REST API as well as the connections between the System Controller and the connected componentstrue
https.certificate_filecertificate_filePath to the certificate file. In pem format""
https.private_key_fileprivate_key_filePath to the private key file. In pem format""
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
logger.file_name_prefixfile_name_prefixThe prefix of the log filename. A unique timecode and “.log” will automatically be appended to this prefix. The prefix can contain both the path and the prefix of the log file.""
site.portportPort on which the service is accessible8080
site.hosthostHostname on which the service is accessiblelocalhost
response_timeoutresponse_timeoutThe maximum time of a request between the System Controller and a component before the request is timed out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that are allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllow the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be made300
custom_headers.[N].keykeyCustom headers, the key of the header, e.g.: Cache-ControlNone
custom_headers.[N].valuevalueCustom headers, the value to the key of the header, e.g.: no-cacheNone

1.6.3 - Agile Live 4.0.0 developer reference

Agile Live 4.0.0 developer reference

1.6.3.1 - REST API v2

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v2.

1.6.3.2 - Agile Live Rendering Engine command documentation

Reference for the Agile Live Rendering Engine commands

This page describes all the commands available in the Agile Live Rendering Engine.

Command protocol

All commands to the Agile Live Rendering Engine is sent as human readable strings and are listed below. The Rendering Engine expect no line termination, meaning that you do not need to append any type of new line (\n) characters, or string termination (\0) characters.

Video commands

Background

The data path of the video mixer in the Rendering Engine looks as follows:

The video mixer data path

There are seven different node types used in this mixer.

  • The Transition node is used to pick which input slots to use for the program and preview output. The node also supports making transitions between the program and preview.
  • The Select node simply forwards one of the available sources to its output.
  • The Transform node takes one input stream and transforms it (scaling and translating) to one output stream.
  • The Alpha combine node is used to pick two input slots (or the same input slot) to copy the color from one input and combine it with some information from the other input to form the alpha. The color will just be copied from the color input frame, but there are several modes that can be used to produce the alpha channel in the output frame in different ways. This is known as “key & fill” in broadcasting.
  • The Alpha over node is used to perform an “Alpha Over” operation, that is to put the overlay video stream on top of the background video stream, and let the background be seen through the overlay depending on the alpha of the overlay. The node also features fading the graphics in and out by multiplying the alpha channel by a constant factor.
  • The Fade to black node takes one input stream, which it can fade to or from black gradually, and then outputs that stream.
  • The Output node has one input stream and will output that stream out from the video mixer, back to the Rendering Engine

There are five different flows into this mixer. There is the one starting with the Transition node, which represents the main program that is being produced. Overlaying on top of that is one key+fill graphics overlay (starting with an alpha_combine node which can combine two video inputs with key form one and fill from another, or both from the same source), then there are two instances of picture-in-picture flows (starting with Select nodes) and on top of that another graphics overlay, called HTML graphics in the illustration, but which can be used with any source where the key and fill comes from the same source. The overlay flows are inserted into the main program using Alpha over nodes.

Each video command in the Rendering Engine command protocol targets one of these nodes.

Transitions

The main flow of the video mixer can be controlled with the following commands:

  • transition cut <input_slot> - Cut (hot punch) the program output to the given input slot. This won’t affect the preview output.
  • transition preview <input_slot> - Preview the given input slot. This won’t affect the program output.
  • transition cut - Cut between the current program and preview outputs, effectively swapping their place.
  • transition panic <input_slot> - Cut (hot punch) both the preview and program output to the given input slot.

Some transition commands last over a duration of time, for example wipes. These can be performed either automatically or manually. The automatic mode works by the operator first selecting the type of transition, for instance a fade, setting the preview to the input slot to fade to and then trigger the transition at the right time with a set duration for the transition. In manual mode the exact “position” of the transition is set by the control panel. This is used for implementing T-bars, where the T-bar repeatedly sends the current position of the bar. In the manual mode, the transition type is set before the transition begins, just as in the automatic mode. Note that an automatic transition will be overridden in case the transition “position” is manually set, by interrupting the automatic transition and jumping to the manually set position.

  • transition type <type> - Set the transition type to use for transitions hereafter. Valid modes are:
    • fade - Fade (mix) from one source to the next
    • wipe_left - Wipe from one source to the next, wipe going from right side of the screen to the left
    • wipe_right - Wipe from one source to the next, wipe going from left side of the screen to the right
  • transition auto <duration_ms> - Perform an automatic transition from the current program output to the current preview output, lasting for <duration_ms> milliseconds. The currently set transition type is used.
  • transition factor <factor> - Manually set the position/factor of the transition. <factor> should be between 0.0 and 1.0, where 0.0 is the value before the transition starts and 1.0 is the end of the transition. Note that setting this value to 1.0 will effectively swap place of program and preview output, resetting the transition factor to 0.0 internally. Control panels using this command must take this into consideration to not cause a sudden jump in the transition once the physical control is moved again. Sending this command will interrupt any ongoing automatic transition.

Key and fill

The key and fill graphics flow will be inserted before the picture-in-picture flows, and will therefore be rendered under them. The graphics flow can be controlled with these commands:

  • alpha_combine color <input_slot> - Set which input slot to copy the color data from in the Alpha combine node
  • alpha_combine alpha <input_slot> - Set which input slot to use to create the alpha channel of the output frame in the Alpha combine node
  • alpha_combine mode <mode> - Set which way the alpha channel of the output frame will be produced. Valid modes are:
    • copy-r - Copy the R-channel of the input “alpha frame” and use it as alpha for the output
    • copy-g - Copy the G-channel of the input “alpha frame” and use it as alpha for the output
    • copy-b - Copy the B-channel of the input “alpha frame” and use it as alpha for the output
    • copy-a - Copy the A-channel of the input “alpha frame” and use it as alpha for the output
    • average-rgb - Take the average of the R, G and B channels of the input “alpha frame” and use it as alpha channel for the output
  • alpha_over factor <factor> - Manually set the transparency multiplier for the Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the overlay is completely invisible and 1.0 means that the overlay is fully visible (where it should be visible according to the overlay image’s alpha channel). Default is 0.0.
  • alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible overlay over the duration of <duration_ms> milliseconds.
  • alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible overlay over the duration of <duration_ms> milliseconds.

Picture-in-Picture

The two picture-in-picture boxes can be controlled with these commands:

  • pip1_select cut <input_slot> - Choose which input slot to forward. Changing looks like a cut.
  • pip1_transform scale <factor> - Set the scale of the picture-in-picture box, relative the original size. Parameter factor must be > 0. Default is 1.0.
  • pip1_transform x <position> - Set the X offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame width, where 0.0 is the left side of the frame and 1.0 is the right side of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_transform y <position> - Set the Y offset of the top left corner of the picture-in-picture box, relative the top left corner of the frame. Position is measured in percent of frame height, where 0.0 is the top of the frame and 1.0 is the bottom of the frame. Values outside of the range 0, 1 are valid. Default is 0.0.
  • pip1_alpha_over factor <factor> - Manually set the transparency multiplier for the picture-in-picture 1 Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the picture-in-picture box is completely invisible and 1.0 means that the box is fully visible. Default is 0.0.
  • pip1_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible picture-in-picture box over the duration of <duration_ms> milliseconds.
  • pip1_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible picture-in-picture box over the duration of <duration_ms> milliseconds.

For the second picture-in-picture flow, replace pip1 with pip2.

Graphics overlay (HTML)

The overlay graphics flow, marked with HTML in the illustration. This will be inserted on top of both the key and fill and picture-in-picture. It can be controlled with these commands:

  • html_select cut <input_slot> - Choose which input slot to use for the graphics. It must contain both fill and key (such as the HTML graphics), otherwise, no parts of the layer will be transparent. Changing looks like a cut.
  • html_alpha_over factor <factor> - Manually set the transparency multiplier for the graphics overlay Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the graphics is completely invisible and 1.0 means that it is fully visible. Default is 0.0.
  • html_alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible graphics over the duration of <duration_ms> milliseconds.
  • html_alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible graphics over the duration of <duration_ms> milliseconds.

Fade to black

The fade to black node can be controlled via the following commands:

  • fade_to_black factor <factor> - Manually set the blackness factor on a scale from 0.0 to 1.0, where 0.0 means not black and 1.0 means fully black output.
  • fade_to_black fade to <duration_ms> - Start an automatic fade to a fully black output over the duration of <duration_ms> milliseconds.
  • fade_to_black fade from <duration_ms> - Start an automatic fade to a fully visible (non-black) output over the duration of <duration_ms> milliseconds.

Audio Router commands

The same audio router is used to route specific audio channels from an input slot of the Rendering Engine to an input channel strip on the audio mixer. By default, it has no audio routes set up. The router can be controlled with the following commands:

  • audio map <input_slot> <channel> mono <input_strip> - Map the <channel> from input slot <input_slot> as a mono channel into input strip <input_strip> of the audio mixer
  • audio map <input_slot> <left_channel> stereo <input_strip> - Map the <left_channel> and <left_channel> + 1 from input slot <input_slot> as a stereo pair into input strip <input_strip> of the audio mixer ’ audio map reset <input_strip> - Remove the current mapping from <input_strip> of the audio mixer.

Audio commands

The audio mixer and audio router have the following data path:

Audio mixer block diagram

In the example picture above, three sources are connected to the input slots and four mono or stereo audio streams are picked as input to the audio mixer. The audio mixer is completely separate from the video mixer, so switching image in the video mixer will not change the audio mixer in any way. The internal audio mixer can be controlled using the following commands:

To control the pre-gain of each input strip use:

  • audio gain <input_strip> <level_dB> - Set the pre-gain level of a specific input in dB. Parameter <level> should be a floating point number. Default is 0.0.

To control the parametric equalizer of each input strip use (the equalizer has three bands):

  • audio eq <input_strip> <band> freq <value> - Set the frequency of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the frequency in Hz
  • audio eq <input_strip> <band> gain <value> - Set the gain of a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the gain in dB.
  • audio eq <input_strip> <band> q <value> - Set the q-value of a specific band in the parametric equalizer to shape the falloff of the band. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <value> is a floating point number with the q-value where a higher value means a more pointy curve. Default value is 0.7.
  • audio eq <input_strip> <band> type <type> - Set the type of falloff to use for a specific band in the parametric equalizer. Here <band> is a zero based index of the band, where 0 is the first band with the lowest frequency. <type> is either of low, band or high, where low and high is a low and high shelf filter and band is a band pass filter. By default, the first band is low shelf, the last band is high shelf and any bands inbetween are band pass.

To control the panning of each input strip use:

  • audio pan <input_strip> <factor> - Pan the mono or stereo input of an input strip to the left or right. The range of <factor> is between -1.0 and +1.0, where 0.0 means center (no panning), negative values means more to the left and positive value more to the right. Values outside this range will be clamped. A value of +/- 1.0 means that there will only be audio in the left/right channel.

To control the volume faders and master volume faders use:

  • audio volume <input_strip> <output> <level> - Set the volume level of a specific input in proportion to its original strength for a given output. Parameter <level> should be a floating point number, where 0.0 means that the input slot is not mixed into the output at all and 1.0 means that the volume of the input slot is kept as is for the output. The signal can also be amplified by using values > 1.0. Default is 0.0.
  • audio mastervolume <output> <level> - Set the master volume level of an output, before the audio is clamped and converted from floating point samples to 16-bit integer samples. This can be used to avoid clipping of the audio when mixing multiple input sources. Parameter <level> is a floating point number where 0.0 means that all audio output is off, 1.0 means that the volume is not changed and any value above 1.0 means that the master volume is amplified. Default is 1.0.

1.6.3.3 - C++ SDK

Agile Content Live C++ SDK reference

1.6.3.3.1 - Classes

Classes

  • namespace AclLog
    A namespace for logging utilities.
    • class CommandLogFormatter
      This class is used to format log entries for Rendering Engine commands.
  • struct AlignedAudioFrame
    AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
  • struct AlignedFrame
    A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class DeviceMemory
    RAII class for a CUDA memory buffer.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class PipelineSystemControllerInterfaceFactory
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.
  • namespace spdlog

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.1 - AclLog::CommandLogFormatter

AclLog::CommandLogFormatter

This class is used to format log entries for Rendering Engine commands.

#include <AclLog.h>

Inherits from spdlog::formatter

Public Functions

Name
CommandLogFormatter()
voidformat(const spdlog::details::log_msg & msg, spdlog::memory_buf_t & dest) override
std::unique_ptr< spdlog::formatter >clone() const override

Public Functions Documentation

function CommandLogFormatter

CommandLogFormatter()

function format

void format(
    const spdlog::details::log_msg & msg,
    spdlog::memory_buf_t & dest
) override

function clone

std::unique_ptr< spdlog::formatter > clone() const override

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.2 - AlignedAudioFrame

AlignedAudioFrame

AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.

#include <AlignedFrame.h>

Public Attributes

Name
std::vector< float >mSamples
uint8_tmNumberOfChannels
uint32_tmNumberOfSamplesPerChannel

Public Attributes Documentation

variable mSamples

std::vector< float > mSamples;

variable mNumberOfChannels

uint8_t mNumberOfChannels = 0;

variable mNumberOfSamplesPerChannel

uint32_t mNumberOfSamplesPerChannel = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.3 - AlignedFrame

AlignedFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedFrame.h>

Public Types

Name
enum classCompressedVideoFormat { kAvc, kHevc}
enum classPixelFormat { kUnknown, kNv12, kP016, kUyvy, kRgba, kRgba64Le}

Public Functions

Name
AlignedFrame() =default
~AlignedFrame() =default
AlignedFrame(AlignedFrame const & ) =delete
AlignedFrame &operator=(AlignedFrame const & ) =delete

Public Attributes

Name
int64_tmCaptureTimestamp
int64_tmRenderingTimestamp
std::shared_ptr< DeviceMemory >mVideoFrame
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
AlignedAudioFramePtrmAudioFrame
uint32_tmAudioSamplingFrequency

Public Types Documentation

enum CompressedVideoFormat

EnumeratorValueDescription
kAvc
kHevc

enum PixelFormat

EnumeratorValueDescription
kUnknown
kNv12
kP016
kUyvy
kRgba
kRgba64Le

Public Functions Documentation

function AlignedFrame

AlignedFrame() =default

function ~AlignedFrame

~AlignedFrame() =default

function AlignedFrame

AlignedFrame(
    AlignedFrame const & 
) =delete

function operator=

AlignedFrame & operator=(
    AlignedFrame const & 
) =delete

Public Attributes Documentation

variable mCaptureTimestamp

int64_t mCaptureTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame was captured by the ingest

variable mRenderingTimestamp

int64_t mRenderingTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame should be delivered to the rendering engine

variable mVideoFrame

std::shared_ptr< DeviceMemory > mVideoFrame = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioFrame

AlignedAudioFramePtr mAudioFrame = nullptr;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.4 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType = ConnectionType::DISCONNECTED;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.5 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.6 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.7 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the sending side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.8 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< std::vector< uint8_t > >mMessages
std::stringmSenderUUID
The actual messages.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessages

std::vector< std::vector< uint8_t > > mMessages;

variable mSenderUUID

std::string mSenderUUID;

The actual messages.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.9 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.10 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.11 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
boolsendMultiRequestToReceivers(const std::vector< std::vector< uint8_t » & request, uint64_t & requestId)
Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function sendMultiRequestToReceivers

bool sendMultiRequestToReceivers(
    const std::vector< std::vector< uint8_t >> & request,
    uint64_t & requestId
)

Send a multi-message request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v2.1.0-231-gcd012ab”, followed by “-dirty” in case there are changes made to the Git repo.

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.12 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.13 - DeviceMemory

DeviceMemory

RAII class for a CUDA memory buffer.

#include <DeviceMemory.h>

Public Functions

Name
DeviceMemory() =default
Default constructor, creates an empty object, without allocating any memory on the device.
DeviceMemory(size_t numberOfBytes)
Constructor allocating the required number of bytes.
DeviceMemory(void * deviceMemory)
Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.
boolallocateMemory(size_t numberOfBytes)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolreallocateMemory(size_t numberOfBytes)
Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.
boolallocateAndResetMemory(size_t numberOfBytes)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolfreeMemory()
Free the device memory held by this class. Calling this when no memory is allocated is a no-op.
~DeviceMemory()
Destructor, frees the internal CUDA memory.
template
T *
getDevicePointer() const
size_tgetSize() const
DeviceMemory(DeviceMemory && other)
DeviceMemory &operator=(DeviceMemory && other)
voidswap(DeviceMemory & other)
DeviceMemory(DeviceMemory const & ) =delete
DeviceMemory is not copyable.
DeviceMemoryoperator=(DeviceMemory const & ) =delete

Public Functions Documentation

function DeviceMemory

DeviceMemory() =default

Default constructor, creates an empty object, without allocating any memory on the device.

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes
)

Constructor allocating the required number of bytes.

Parameters:

  • numberOfBytes Number of bytes to allocate

function DeviceMemory

explicit DeviceMemory(
    void * deviceMemory
)

Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.

Parameters:

  • deviceMemory CUDA memory pointer to take ownership over.

function allocateMemory

bool allocateMemory(
    size_t numberOfBytes
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function reallocateMemory

bool reallocateMemory(
    size_t numberOfBytes
)

Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.

Parameters:

  • numberOfBytes Number of bytes to allocate in the new allocation

Return: True on success, false if CUDA free or CUDA malloc failed.

function allocateAndResetMemory

bool allocateAndResetMemory(
    size_t numberOfBytes
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function freeMemory

bool freeMemory()

Free the device memory held by this class. Calling this when no memory is allocated is a no-op.

Return: True in case the memory was successfully freed (or not allocated to begin with), false otherwise.

function ~DeviceMemory

~DeviceMemory()

Destructor, frees the internal CUDA memory.

function getDevicePointer

template <typename T  =uint8_t>
inline T * getDevicePointer() const

Template Parameters:

  • T The pointer type to return

Return: the CUDA memory pointer handled by this class. Nullptr in case no memory is allocated.

function getSize

size_t getSize() const

Return: The size of the CUDA memory allocation held by this class.

function DeviceMemory

DeviceMemory(
    DeviceMemory && other
)

function operator=

DeviceMemory & operator=(
    DeviceMemory && other
)

function swap

void swap(
    DeviceMemory & other
)

function DeviceMemory

DeviceMemory(
    DeviceMemory const & 
) =delete

DeviceMemory is not copyable.

function operator=

DeviceMemory operator=(
    DeviceMemory const & 
) =delete

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.14 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v1.0.0”, or “v2.1.0-231-gcd012ab”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.15 - IngestApplication::Settings

IngestApplication::Settings


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.16 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) =0
Send a request with some JSON parameters to the controller and await the response.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) =0

Send a request with some JSON parameters to the controller and await the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller.

Reimplemented by: SystemControllerConnection::sendRequest

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.17 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.18 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.19 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Types

Name
enum class uint32_tTallyBorderColor { kNone, kRed, kGreen, kYellow}
Available colors for tally border in multi view.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const AlignedFramePtr &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
boolremoveCustomMultiViewSourceInput(uint32_t inputSlot)
Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.
voidsetTallyBorder(uint32_t inputSlot, TallyBorderColor color)
Set tally border color in the multi-views for a specific input slot.
voidclearTallyBorder(uint32_t inputSlot)
Remove tally border in the multi-views for a specific input slot.
voidclearAllTallyBorders()
Remove all tally borders.
MediaReceiver::TallyBorderColorgetTallyBorder(uint32_t inputSlot) const
get tally border color for an input slot
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Public Types Documentation

enum TallyBorderColor

EnumeratorValueDescription
kNone
kRed
kGreen
kYellow

Available colors for tally border in multi view.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const AlignedFramePtr &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Precondition: The DataFrames sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function removeCustomMultiViewSourceInput

bool removeCustomMultiViewSourceInput(
    uint32_t inputSlot
)

Remove a custom multi-view generator source input earlier registered using the getCustomMultiViewSourceInput method.

Parameters:

  • inputSlot The input slot the custom multi-view source input is connected to, that should be removed

Return: True if the custom multi-view source input was successfully removed, false in case there was no custom input registered for the given input slot, or in case of an internal error.

function setTallyBorder

void setTallyBorder(
    uint32_t inputSlot,
    TallyBorderColor color
)

Set tally border color in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source
  • color the color to set

function clearTallyBorder

void clearTallyBorder(
    uint32_t inputSlot
)

Remove tally border in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source

function clearAllTallyBorders

void clearAllTallyBorders()

Remove all tally borders.

function getTallyBorder

MediaReceiver::TallyBorderColor getTallyBorder(
    uint32_t inputSlot
) const

get tally border color for an input slot

Parameters:

  • inputSlot the input slot to get color for

Return: the tally border color for the given input slot

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.20 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.21 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
AlignedFrame::PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDeliverOld
Set to true if this MediaReceiver should have a multi-view generator.

Public Attributes Documentation

variable mDecodedFormat

AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDeliverOld

bool mDeliverOld = false;

Set to true if this MediaReceiver should have a multi-view generator.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.22 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
boolhasFormatAndIsRunning() const
boolhasOpenOutputStream() const
booloutputData(const AlignedFramePtr & frame)
Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the the format reset, or if the format was not set before this method was called, false on error.

function hasFormatAndIsRunning

bool hasFormatAndIsRunning() const

Return: True if the input format is set and the OutputStreamer is running, false otherwise

function hasOpenOutputStream

bool hasOpenOutputStream() const

See:

  • outputData will be discarded without being encoded, as there is no stream to output them to. This method can be used to check if the frame even needs to be produced by the rendering engine. Note however, that the
  • outputData method will still log the frames sent to it as received, even if they are not encoded when the output stream is closed.

Return: True if the output stream of the MediaStreamer is currently open and outputting the data, false otherwise. In case this returns false all frames passed to

function outputData

bool outputData(
    const AlignedFramePtr & frame
)

Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.23 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
AlignedFrame::PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.24 - PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory

Public Functions

Name
PipelineSystemControllerInterfaceFactory(const std::string & systemControllerIP, uint16_t systemControllerPort, const std::string & systemControllerPostfix, const std::string & psk, const std::string & myIP, bool useHTTPS, bool allowInsecureHTTPS)
Constructor.
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const && ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const && ) =delete
std::shared_ptr< SystemControllerConnection >getMediaReceiverInterface(const std::string & name)
Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.
std::shared_ptr< SystemControllerConnection >createMediaStreamerInterface(const std::string & name)
Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.
std::shared_ptr< SystemControllerConnection >createControlReceiverInterface(const std::string & name)
Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Public Functions Documentation

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    const std::string & systemControllerIP,
    uint16_t systemControllerPort,
    const std::string & systemControllerPostfix,
    const std::string & psk,
    const std::string & myIP,
    bool useHTTPS,
    bool allowInsecureHTTPS
)

Constructor.

Parameters:

  • systemControllerIP The IP address of the System controller to connect to.
  • systemControllerPort The network port of the System controller to connect to.
  • systemControllerPostfix The postfix of the System controller’s address, to chose which API endpoints to use.
  • psk The Pre-shared key used for authorization at the System controller.
  • myIP The public IP address of the pipeline, i.e. the external IP used to connect to the pipeline.
  • useHTTPS If HTTPS should be used instead of HTTP
  • allowInsecureHTTPS Set to true to allow self-signed HTTPS certificates. Should normally be false.

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function getMediaReceiverInterface

std::shared_ptr< SystemControllerConnection > getMediaReceiverInterface(
    const std::string & name
)

Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.

Parameters:

  • name The human readable name of the MediaReceiver to provide to the System controller

Return: A configured connection on success, otherwise nullptr

function createMediaStreamerInterface

std::shared_ptr< SystemControllerConnection > createMediaStreamerInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the MediaStreamer to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called

Return: A configured connection on success, otherwise nullptr

function createControlReceiverInterface

std::shared_ptr< SystemControllerConnection > createControlReceiverInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the ControlReceiver to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called to generate the parent interface.

Return: A configured connection on success, otherwise nullptr


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.25 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) override
Send a JSON object to the system controller server and awaits the response.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) override

Send a JSON object to the system controller server and awaits the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller

Note: The status code might be TIMEOUT in case no response was received within the timeframe

Reimplements: ISystemControllerInterface::sendRequest

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.26 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout
boolmEnableHTTPS
boolmInsecureHTTPS

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

variable mEnableHTTPS

bool mEnableHTTPS;

variable mInsecureHTTPS

bool mInsecureHTTPS;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.27 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock
doublemTimeDiffS

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

variable mTimeDiffS

double mTimeDiffS = 0.0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.1.28 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <filesystem>
#include <string>

#include <spdlog/details/log_msg.h>
#include <spdlog/fmt/fmt.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void initCommandLog(const std::string& name);

void setLevel(Level level);

void logCommand(const std::string& command);

AclLog::Level getLogLevel();

size_t getMaxFileSize();

size_t getMaxLogRotations();

std::filesystem::path getLogFileFullPath(const std::string& name);

class CommandLogFormatter : public spdlog::formatter {
public:
    CommandLogFormatter();
    void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override;
    [[nodiscard]] std::unique_ptr<spdlog::formatter> clone() const override;

private:
    std::unique_ptr<spdlog::pattern_formatter> mCommandLogPattern;
};

} // namespace AclLog

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.2 - include/AlignedFrame.h

include/AlignedFrame.h

Classes

Name
structAlignedAudioFrame
AlignedAudioFrame is a frame of interleaved floating point audio samples with a given number of channels.
structAlignedFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
using std::shared_ptr< AlignedAudioFrame >AlignedAudioFramePtr
using std::shared_ptr< const AlignedAudioFrame >AlignedAudioFrameConstPtr
using std::shared_ptr< AlignedFrame >AlignedFramePtr

Functions

Name
AlignedAudioFramePtrcreateAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel)
Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.

Types Documentation

using AlignedAudioFramePtr

using AlignedAudioFramePtr =  std::shared_ptr<AlignedAudioFrame>;

using AlignedAudioFrameConstPtr

using AlignedAudioFrameConstPtr =  std::shared_ptr<const AlignedAudioFrame>;

using AlignedFramePtr

using AlignedFramePtr =  std::shared_ptr<AlignedFrame>;

Functions Documentation

function createAlignedAudioFrame

AlignedAudioFramePtr createAlignedAudioFrame(
    uint8_t numberOfChannels,
    uint32_t numberOfSamplesPerChannel
)

Create a new AudioFrame with a given amount of samples allocated and all samples initialized to 0.0f.

Parameters:

  • numberOfChannels Number of channels to allocate space for
  • numberOfSamplesPerChannel Number of samples per channel to allocate space for

Return: Shared pointer to the new AudioFrame

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <memory>
#include <vector>

#include <cuda_runtime_api.h>

#include "DeviceMemory.h"

struct AlignedAudioFrame {
    // The samples interleaved
    std::vector<float> mSamples;
    uint8_t mNumberOfChannels = 0;
    uint32_t mNumberOfSamplesPerChannel = 0;
};

using AlignedAudioFramePtr = std::shared_ptr<AlignedAudioFrame>;
using AlignedAudioFrameConstPtr = std::shared_ptr<const AlignedAudioFrame>;

AlignedAudioFramePtr createAlignedAudioFrame(uint8_t numberOfChannels, uint32_t numberOfSamplesPerChannel);

struct AlignedFrame {

    enum class CompressedVideoFormat {
        kAvc, // H264
        kHevc // H265
    };

    enum class PixelFormat {
        kUnknown,
        kNv12,    // 8 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kP016,    // 16 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kUyvy,    // 8 bit per component 4:2:2 YUV format. U-Y-V-Y bytes interleaved.
        kRgba,    // 8 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory.
        kRgba64Le // 16 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory with little endian words.
    };

    AlignedFrame() = default;

    ~AlignedFrame() = default;

    AlignedFrame(AlignedFrame const&) = delete;            // Copy construct
    AlignedFrame& operator=(AlignedFrame const&) = delete; // Copy assign

    int64_t mCaptureTimestamp = 0;

    int64_t mRenderingTimestamp = 0;

    // Video
    std::shared_ptr<DeviceMemory> mVideoFrame = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    AlignedAudioFramePtr mAudioFrame = nullptr;
    uint32_t mAudioSamplingFrequency = 0;
};

using AlignedFramePtr = std::shared_ptr<AlignedFrame>;

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstdint>
#include <string>
#include <vector>

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType = ConnectionType::DISCONNECTED;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<std::vector<uint8_t>> mMessages; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    bool sendMultiRequestToReceivers(const std::vector<std::vector<uint8_t>>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.7 - include/DeviceMemory.h

include/DeviceMemory.h

Classes

Name
classDeviceMemory
RAII class for a CUDA memory buffer.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstddef>
#include <cstdint>

class DeviceMemory {
public:
    DeviceMemory() = default;

    explicit DeviceMemory(size_t numberOfBytes);

    explicit DeviceMemory(void* deviceMemory) noexcept;

    bool allocateMemory(size_t numberOfBytes);

    bool reallocateMemory(size_t numberOfBytes);

    bool allocateAndResetMemory(size_t numberOfBytes);

    bool freeMemory();

    ~DeviceMemory();

    template <typename T = uint8_t> [[nodiscard]] T* getDevicePointer() const {
        return reinterpret_cast<T*>(dMemory);
    }

    size_t getSize() const;

    DeviceMemory(DeviceMemory&& other) noexcept;

    DeviceMemory& operator=(DeviceMemory&& other) noexcept;

    void swap(DeviceMemory& other) noexcept;

    DeviceMemory(DeviceMemory const&) = delete;
    DeviceMemory operator=(DeviceMemory const&) = delete;

private:
    uint8_t* dMemory = nullptr;
    size_t mAllocatedBytes = 0;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.8 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {};

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.9 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.10 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual Response sendRequest(const std::string& request, const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.11 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include "AlignedFrame.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

        std::function<std::function<void(const AlignedFramePtr&)>(uint32_t inputSlot,
                                                                  const std::string& streamID,
                                                                  const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDeliverOld = false;     
    };

    enum class TallyBorderColor : uint32_t { kNone, kRed, kGreen, kYellow };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    void stop();

    std::function<void(const AlignedFramePtr&)> getCustomMultiViewSourceInput(uint32_t inputSlot,
                                                                              const std::string& name = "");

    bool removeCustomMultiViewSourceInput(uint32_t inputSlot);

    void setTallyBorder(uint32_t inputSlot, TallyBorderColor color);

    void clearTallyBorder(uint32_t inputSlot);

    void clearAllTallyBorders();

    [[nodiscard]] MediaReceiver::TallyBorderColor getTallyBorder(uint32_t inputSlot) const;

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.12 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "AlignedFrame.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    [[nodiscard]] bool hasFormatAndIsRunning() const;

    [[nodiscard]] bool hasOpenOutputStream() const;

    bool outputData(const AlignedFramePtr& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.13 - include/PipelineSystemControllerInterfaceFactory.h

include/PipelineSystemControllerInterfaceFactory.h

Classes

Name
classPipelineSystemControllerInterfaceFactory

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <string>

#include "SystemControllerConnection.h"

class PipelineSystemControllerInterfaceFactory final {
public:
    PipelineSystemControllerInterfaceFactory(const std::string& systemControllerIP,
                                             uint16_t systemControllerPort,
                                             const std::string& systemControllerPostfix,
                                             const std::string& psk,
                                             const std::string& myIP,
                                             bool useHTTPS,
                                             bool allowInsecureHTTPS);

    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&&) = delete;

    std::shared_ptr<SystemControllerConnection> getMediaReceiverInterface(const std::string& name);

    //    /// to generate the parent interface.
    std::shared_ptr<SystemControllerConnection> createMediaStreamerInterface(const std::string& name);

    std::shared_ptr<SystemControllerConnection> createControlReceiverInterface(const std::string& name);

private:
    std::string mSystemControllerIP;
    uint16_t mSystemControllerPort = 0;
    std::string mSystemControllerPostfix;
    std::string mPsk;
    std::string mMyIP;
    bool mUseHTTPS = true;
    bool mAllowInsecureHTTPS = false;

    std::shared_ptr<SystemControllerConnection> mReceiverController;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.14 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000};           // Max time to wait on an announcement response from the server during connection
        bool mEnableHTTPS;   // Enable the communication between the system controller and a component encrypted
        bool mInsecureHTTPS; // Disable the verification of the TLS certificate if requested.
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    Response sendRequest(const std::string& request, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.15 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

#include "expected.hpp"

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
    double mTimeDiffS = 0.0; // Time diff vs NTP in seconds, +/- value means slow/faster than NTP time
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

tl::expected<TimeCommon::TAIStatus, std::string> getStatus();

int64_t getTAIMicro();

std::string taiMicroToString(int64_t taiTimestamp);
} // namespace TimeCommon

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.2.16 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3 - Namespaces

Namespaces


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.1 - AclLog

AclLog

A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidinitCommandLog(const std::string & name)
Init the Rendering Engine command log.
voidsetLevel(Level level)
Set global logging level.
voidlogCommand(const std::string & command)
Log a command to the command log.
AclLog::LevelgetLogLevel()
Internal helper function for getting the setting for the log level.
size_tgetMaxFileSize()
Internal helper function for getting the setting for the maximum size for a log file.
size_tgetMaxLogRotations()
Internal helper function for getting the setting for the maximum number of rotated log files.
std::filesystem::pathgetLogFileFullPath(const std::string & name)
Internal helper function for constructing the full path name for the log file.

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name-.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function initCommandLog

void initCommandLog(
    const std::string & name
)

Init the Rendering Engine command log.

Parameters:

  • name The name of the Rendering Engine (used for filename)

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

function logCommand

void logCommand(
    const std::string & command
)

Log a command to the command log.

Parameters:

  • command The command to log

function getLogLevel

AclLog::Level getLogLevel()

Internal helper function for getting the setting for the log level.

Return: The wanted log level fetched from an environment variable if set, or else a default value

function getMaxFileSize

size_t getMaxFileSize()

Internal helper function for getting the setting for the maximum size for a log file.

Return: The wanted maximum size of the log file fetched from an environment variable if set, or else a default value

function getMaxLogRotations

size_t getMaxLogRotations()

Internal helper function for getting the setting for the maximum number of rotated log files.

Return: The wanted number of log files to rotate fetched from an environment variable if set, or else a default value

function getLogFileFullPath

std::filesystem::path getLogFileFullPath(
    const std::string & name
)

Internal helper function for constructing the full path name for the log file.

Parameters:

  • name The name of the component

Return: The full path to the log file


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.2 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.3 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.4 - spdlog

spdlog


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.5 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
tl::expected< TimeCommon::TAIStatus, std::string >getStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.
std::stringtaiMicroToString(int64_t taiTimestamp)
Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

tl::expected< TimeCommon::TAIStatus, std::string > getStatus()

Get TAI status.

Return: Expected with the TAI status if successful or an error string in case something went wrong

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds

function taiMicroToString

std::string taiMicroToString(
    int64_t taiTimestamp
)

Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Parameters:

  • taiTimestamp A TAI timestamp with microseconds resolution

Return: Return a human readable timestamp


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.3.3.6 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2023-06-13 at 17:00:17 +0200

1.6.3.4 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
pskpskThe Pre-shared key used to authorize components to connect to the System Controller. Must be 32 characters long""
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnParameter for token and encryption generation. N is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrParameter for token and encryption generation. R is block size factor. R constrain must satisfy R*P < 2^30. 18
security.ppParameter for token and encryption generation. P is the parallelization parameter. P constrain must satisfy R*P < 2^30, if this is exceeded, an error will be returned 11
security.keylenkeylenThe length of the generated tokens32
client_auth.enabledenabledSwitch to enable basic authentication for clients in the REST APIfalse
client_auth.usernameusernameThe username that will grant access to the REST API“admin”
client_auth.passwordpasswordPassword that will grant access to the REST API“changeme”
https.enabledenabledSwitch to enable encryption of the REST API as well as the connections between the System Controller and the connected componentsfalse
https.insecureinsecureEnable the use of self-signed and/or unsecure certificatesfalse
https.certificate_filecertificate_filePath to the certificate file. In pem format""
https.private_key_fileprivate_key_filePath to the private key file. In pem format""
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
site.portportPort on which the service is accessible8080
site.hosthostHostname on which the service is accessiblelocalhost
response_timeoutresponse_timeoutThe maximum time of a request between the System Controller and a component before the request is timed out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that are allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllow the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be made300
custom_headers.[N].keykeyCustom headers, the key of the header, e.g.: Cache-ControlNone
custom_headers.[N].valuevalueCustom headers, the value to the key of the header, e.g.: no-cacheNone

1.6.4 - Agile Live 3.0.0 developer reference

Agile Live 3.0.0 developer reference

1.6.4.1 - REST API v2

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v2.

1.6.4.2 - Agile Live Rendering Engine command documentation

Reference for the Agile Live Rendering Engine commands

This page describes all the commands available in the Agile Live Rendering Engine.

Command protocol

All commands to the Agile Live Rendering Engine is sent as human readable strings and are listed below. The Rendering Engine expect no line termination, meaning that you do not need to append any type of new line (\n) characters, or string termination (\0) characters.

Video commands

The data path graph of the video mixer in the Rendering Engine looks as follows:

The video mixer data path

There are four nodes that can be controlled using the protocol. The Transition node is used to pick which input slots to use for the program and preview output. The node also supports making transitions between the program and preview. The video mixer can overlay graphics on top of the background image using the two nodes Alpha combine and Alpha over. The Alpha combine node is used to pick two input slots (or the same input slot) to copy the color from one input and combine it with some information from the other input to form the alpha. The color will just be copied from the color input frame, but there are several modes that can be used to produce the alpha channel in the output frame in different ways. Then the Alpha over node is used to perform an “Alpha Over” operation, that is to put the overlay video stream on top of the background video stream, and let the background be seen through the overlay depending on the alpha of the overlay. The node also features fading the graphics in and out by multiplying the alpha channel by a constant factor.

The video mixer can be controlled with the following commands:

  • cut <input_slot> - Cut (hot punch) the program output to the given input slot. This won’t affect the preview output.
  • preview <input_slot> - Preview the given input slot. This won’t affect the program output.
  • cut - Cut between the current program and preview outputs, effectively swapping their place.
  • fade <duration_ms> - Perform an automatic fade from the current program output to the current preview output, lasting for <duration> milliseconds.

In addition to this the graphics pipeline can be controlled with these commands:

  • alpha_combine color <input_slot> - Set which input slot to copy the color data from in the Alpha combine node
  • alpha_combine alpha <input_slot> - Set which input slot to use to create the alpha channel of the output frame in the Alpha combine node
  • alpha_combine mode <mode> - Set which way the alpha channel of the output frame will be produced. Valid modes are:
    • copy-r - Copy the R-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-g - Copy the G-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-b - Copy the B-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-a - Copy the A-channel of the input “alpha frame” and use it as alpha for the output.
    • average-rgb - Take the average of the R, G and B channels of the input “alpha frame” and use it as alpha channel for the output.
  • alpha_over factor <factor> - Manually set the transparency multiplier for the Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the overlay is completely invisible and 1.0 means that the overlay is fully visible (where it should be visible according to the overlay image’s alpha channel). Default is 0.0.
  • alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible overlay over the duration of <duration_ms> milliseconds.
  • alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible overlay over the duration of <duration_ms> milliseconds.

And before the final output, the video stream can be faded to/from black using these commands:

  • fade_to_black factor <factor> - Manually set the blackness factor on a scale from 0.0 to 1.0, where 0.0 means not black and 1.0 means fully black output.
  • fade_to_black fade to <duration_ms> - Start an automatic fade to a fully black output over the duration of <duration_ms> milliseconds.
  • fade_to_black fade from <duration_ms> - Start an automatic fade to a fully visible (non-black) output over the duration of <duration_ms> milliseconds.

Audio commands

The audio mixer has the following data path:

The audio mixer data path

In the example three sources are connected to input slots 3, 4 and 9. The audio mixer is completely separate from the video mixer, so switching image in the video mixer will not change the audio mixer in any way.

  • volume <input_slot> <level> - Set the volume level of a specific input in proportion to its original strength. Parameter <level> should be a floating point number, where 0.0 means that the input slot is not mixed into the output and 1.0 means that the volume of the input slot is kept as is for the output. The signal can also be amplified by using values > 1.0. Default is 0.0.
  • mastervolume <level> - Set the volume level of the master output, before the audio is clamped and converted from floating point samples to 16-bit integer samples. This can be used to avoid clipping of the audio when mixing multiple input sources. Parameter <level> is a floating point number where 0.0 means that all audio output is off, 1.0 means that the volume is not changed and any value above 1.0 means that the master volume is amplified.

1.6.4.3 - C++ SDK

Agile Live C++ SDK reference

1.6.4.3.1 - Classes

Classes

  • namespace AclLog
    A namespace for logging utilities.
  • struct AlignedFrame
    A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class DeviceMemory
    RAII class for a CUDA memory buffer.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class PipelineSystemControllerInterfaceFactory
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.1 - AlignedFrame

AlignedFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedFrame.h>

Public Types

Name
enum classCompressedVideoFormat { kAvc, kHevc}
enum classPixelFormat { kUnknown, kNv12, kP016, kUyvy, kRgba, kRgba64Le}
typedef std::array< float, 16 >AudioSampleRow
One audio sample in 16 channels.

Public Functions

Name
AlignedFrame() =default
~AlignedFrame() =default
AlignedFrame(AlignedFrame const & ) =delete
AlignedFrame &operator=(AlignedFrame const & ) =delete

Public Attributes

Name
int64_tmCaptureTimestamp
int64_tmRenderingTimestamp
std::shared_ptr< DeviceMemory >mVideoFrame
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
std::vector< AudioSampleRow >mAudioData
uint32_tmAudioChannels
uint32_tmAudioSamplingFrequency

Public Types Documentation

enum CompressedVideoFormat

EnumeratorValueDescription
kAvc
kHevc

enum PixelFormat

EnumeratorValueDescription
kUnknown
kNv12
kP016
kUyvy
kRgba
kRgba64Le

typedef AudioSampleRow

typedef std::array<float, 16> AlignedFrame::AudioSampleRow;

One audio sample in 16 channels.

Public Functions Documentation

function AlignedFrame

AlignedFrame() =default

function ~AlignedFrame

~AlignedFrame() =default

function AlignedFrame

AlignedFrame(
    AlignedFrame const & 
) =delete

function operator=

AlignedFrame & operator=(
    AlignedFrame const & 
) =delete

Public Attributes Documentation

variable mCaptureTimestamp

int64_t mCaptureTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame was captured by the ingest

variable mRenderingTimestamp

int64_t mRenderingTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame should be delivered to the rendering engine

variable mVideoFrame

std::shared_ptr< DeviceMemory > mVideoFrame = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioData

std::vector< AudioSampleRow > mAudioData;

variable mAudioChannels

uint32_t mAudioChannels = 0;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.2 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.3 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.4 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.5 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.6 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmSenderUUID
The actual message.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mSenderUUID

std::string mSenderUUID;

The actual message.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.7 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.8 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.9 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v2.1.0-231-gcd012ab”, followed by “-dirty” in case there are changes made to the Git repo.

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.10 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.11 - DeviceMemory

DeviceMemory

RAII class for a CUDA memory buffer.

#include <DeviceMemory.h>

Public Functions

Name
DeviceMemory() =default
Default constructor, creates an empty object, without allocating any memory on the device.
DeviceMemory(size_t numberOfBytes)
Constructor allocating the required number of bytes.
DeviceMemory(void * deviceMemory)
Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.
boolallocateMemory(size_t numberOfBytes)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolreallocateMemory(size_t numberOfBytes)
Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.
boolallocateAndResetMemory(size_t numberOfBytes)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolfreeMemory()
Free the device memory held by this class. Calling this when no memory is allocated is a no-op.
~DeviceMemory()
Destructor, frees the internal CUDA memory.
template
T *
getDevicePointer() const
size_tgetSize() const
DeviceMemory(DeviceMemory && other)
DeviceMemory &operator=(DeviceMemory && other)
voidswap(DeviceMemory & other)
DeviceMemory(DeviceMemory const & ) =delete
DeviceMemory is not copyable.
DeviceMemoryoperator=(DeviceMemory const & ) =delete

Public Functions Documentation

function DeviceMemory

DeviceMemory() =default

Default constructor, creates an empty object, without allocating any memory on the device.

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes
)

Constructor allocating the required number of bytes.

Parameters:

  • numberOfBytes Number of bytes to allocate

function DeviceMemory

explicit DeviceMemory(
    void * deviceMemory
)

Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.

Parameters:

  • deviceMemory CUDA memory pointer to take ownership over.

function allocateMemory

bool allocateMemory(
    size_t numberOfBytes
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function reallocateMemory

bool reallocateMemory(
    size_t numberOfBytes
)

Reallocates device memory. Already existing memory allocation will be freed before the new allocation is made. In case this DeviceMemory has no earlier memory allocation, this method will just allocate new CUDA memory and return a success status.

Parameters:

  • numberOfBytes Number of bytes to allocate in the new allocation

Return: True on success, false if CUDA free or CUDA malloc failed.

function allocateAndResetMemory

bool allocateAndResetMemory(
    size_t numberOfBytes
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function freeMemory

bool freeMemory()

Free the device memory held by this class. Calling this when no memory is allocated is a no-op.

Return: True in case the memory was successfully freed (or not allocated to begin with), false otherwise.

function ~DeviceMemory

~DeviceMemory()

Destructor, frees the internal CUDA memory.

function getDevicePointer

template <typename T  =uint8_t>
inline T * getDevicePointer() const

Template Parameters:

  • T The pointer type to return

Return: the CUDA memory pointer handled by this class. Nullptr in case no memory is allocated.

function getSize

size_t getSize() const

Return: The size of the CUDA memory allocation held by this class.

function DeviceMemory

DeviceMemory(
    DeviceMemory && other
)

function operator=

DeviceMemory & operator=(
    DeviceMemory && other
)

function swap

void swap(
    DeviceMemory & other
)

function DeviceMemory

DeviceMemory(
    DeviceMemory const & 
) =delete

DeviceMemory is not copyable.

function operator=

DeviceMemory operator=(
    DeviceMemory const & 
) =delete

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.12 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v1.0.0”, or “v2.1.0-231-gcd012ab”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.13 - IngestApplication::Settings

IngestApplication::Settings

Public Attributes

Name
boolmDebugAudio
boolmDebugVideo

Public Attributes Documentation

variable mDebugAudio

bool mDebugAudio = false;

variable mDebugVideo

bool mDebugVideo = false;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.14 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) =0
Send a request with some JSON parameters to the controller and await the response.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) =0

Send a request with some JSON parameters to the controller and await the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller.

Reimplemented by: SystemControllerConnection::sendRequest

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.15 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.16 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.17 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Types

Name
enum classTallyBorderColor { kNone, kRed, kGreen, kYellow}
Available colors for tally border in multi view.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const AlignedFramePtr &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
voidsetTallyBorder(uint32_t inputSlot, TallyBorderColor color)
Set tally border color in the multi-views for a specific input slot.
voidclearTallyBorder(uint32_t inputSlot)
Remove tally border in the multi-views for a specific input slot.
voidclearAllTallyBorders()
Remove all tally borders.
MediaReceiver::TallyBorderColorgetTallyBorder(uint32_t inputSlot) const
get tally border color for an input slot
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Public Types Documentation

enum TallyBorderColor

EnumeratorValueDescription
kNone
kRed
kGreen
kYellow

Available colors for tally border in multi view.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const AlignedFramePtr &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Precondition: The DataFrames sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function setTallyBorder

void setTallyBorder(
    uint32_t inputSlot,
    TallyBorderColor color
)

Set tally border color in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source
  • color the color to set

function clearTallyBorder

void clearTallyBorder(
    uint32_t inputSlot
)

Remove tally border in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source

function clearAllTallyBorders

void clearAllTallyBorders()

Remove all tally borders.

function getTallyBorder

MediaReceiver::TallyBorderColor getTallyBorder(
    uint32_t inputSlot
) const

get tally border color for an input slot

Parameters:

  • inputSlot the input slot to get color for

Return: the tally border color for the given input slot

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.18 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.19 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
AlignedFrame::PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDebugAudio
Set to true if this MediaReceiver should have a multi-view generator.
boolmDebugVideo
Insert a 1500 Hz sound at every other turn to a new second according to TAI.
boolmDeliverOld
Print the timestamp in the picture.

Public Attributes Documentation

variable mDecodedFormat

AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDebugAudio

bool mDebugAudio = false;

Set to true if this MediaReceiver should have a multi-view generator.

variable mDebugVideo

bool mDebugVideo = false;

Insert a 1500 Hz sound at every other turn to a new second according to TAI.

variable mDeliverOld

bool mDeliverOld = false;

Print the timestamp in the picture.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.20 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
boolhasFormatAndIsRunning() const
boolhasOpenOutputStream() const
booloutputData(const AlignedFramePtr & frame)
Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the the format reset, or if the format was not set before this method was called, false on error.

function hasFormatAndIsRunning

bool hasFormatAndIsRunning() const

Return: True if the input format is set and the OutputStreamer is running, false otherwise

function hasOpenOutputStream

bool hasOpenOutputStream() const

See:

  • outputData will be discarded without being encoded, as there is no stream to output them to. This method can be used to check if the frame even needs to be produced by the rendering engine. Note however, that the
  • outputData method will still log the frames sent to it as received, even if they are not encoded when the output stream is closed.

Return: True if the output stream of the MediaStreamer is currently open and outputting the data, false otherwise. In case this returns false all frames passed to

function outputData

bool outputData(
    const AlignedFramePtr & frame
)

Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.21 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
AlignedFrame::PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.22 - PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory

Public Functions

Name
PipelineSystemControllerInterfaceFactory(const std::string & systemControllerIP, uint16_t systemControllerPort, const std::string & systemControllerPostfix, const std::string & psk, const std::string & myIP, bool useHTTPS, bool allowInsecureHTTPS)
Constructor.
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const && ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const && ) =delete
std::shared_ptr< SystemControllerConnection >getMediaReceiverInterface(const std::string & name)
Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.
std::shared_ptr< SystemControllerConnection >createMediaStreamerInterface(const std::string & name)
Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.
std::shared_ptr< SystemControllerConnection >createControlReceiverInterface(const std::string & name)
Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Public Functions Documentation

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    const std::string & systemControllerIP,
    uint16_t systemControllerPort,
    const std::string & systemControllerPostfix,
    const std::string & psk,
    const std::string & myIP,
    bool useHTTPS,
    bool allowInsecureHTTPS
)

Constructor.

Parameters:

  • systemControllerIP The IP address of the System controller to connect to.
  • systemControllerPort The network port of the System controller to connect to.
  • systemControllerPostfix The postfix of the System controller’s address, to chose which API endpoints to use.
  • psk The Pre-shared key used for authorization at the System controller.
  • myIP The public IP address of the pipeline, i.e. the external IP used to connect to the pipeline.
  • useHTTPS If HTTPS should be used instead of HTTP
  • allowInsecureHTTPS Set to true to allow self-signed HTTPS certificates. Should normally be false.

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function getMediaReceiverInterface

std::shared_ptr< SystemControllerConnection > getMediaReceiverInterface(
    const std::string & name
)

Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.

Parameters:

  • name The human readable name of the MediaReceiver to provide to the System controller

Return: A configured connection on success, otherwise nullptr

function createMediaStreamerInterface

std::shared_ptr< SystemControllerConnection > createMediaStreamerInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the MediaStreamer to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called

Return: A configured connection on success, otherwise nullptr

function createControlReceiverInterface

std::shared_ptr< SystemControllerConnection > createControlReceiverInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the ControlReceiver to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called to generate the parent interface.

Return: A configured connection on success, otherwise nullptr


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.23 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) override
Send a JSON object to the system controller server and awaits the response.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) override

Send a JSON object to the system controller server and awaits the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller

Note: The status code might be TIMEOUT in case no response was received within the timeframe

Reimplements: ISystemControllerInterface::sendRequest

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.24 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout
boolmEnableHTTPS
boolmInsecureHTTPS

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

variable mEnableHTTPS

bool mEnableHTTPS;

variable mInsecureHTTPS

bool mInsecureHTTPS;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.25 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.1.26 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void setLevel(Level level);

} // namespace AclLog

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.2 - include/AlignedFrame.h

include/AlignedFrame.h

Classes

Name
structAlignedFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
using std::shared_ptr< AlignedFrame >AlignedFramePtr

Types Documentation

using AlignedFramePtr

using AlignedFramePtr =  std::shared_ptr<AlignedFrame>;

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <memory>
#include <vector>

#include <cuda_runtime_api.h>

#include "DeviceMemory.h"

struct AlignedFrame {

    typedef std::array<float, 16> AudioSampleRow;

    enum class CompressedVideoFormat {
        kAvc, // H264
        kHevc // H265
    };

    enum class PixelFormat {
        kUnknown,
        kNv12,    // 8 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kP016,    // 16 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kUyvy,    // 8 bit per component 4:2:2 YUV format. U-Y-V-Y bytes interleaved.
        kRgba,    // 8 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory.
        kRgba64Le // 16 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory with little endian words.
    };

    AlignedFrame() = default;

    ~AlignedFrame() = default;

    AlignedFrame(AlignedFrame const&) = delete;            // Copy construct
    AlignedFrame& operator=(AlignedFrame const&) = delete; // Copy assign

    int64_t mCaptureTimestamp = 0;

    int64_t mRenderingTimestamp = 0;

    // Video
    std::shared_ptr<DeviceMemory> mVideoFrame = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    std::vector<AudioSampleRow> mAudioData;
    uint32_t mAudioChannels = 0;
    uint32_t mAudioSamplingFrequency = 0;
};

using AlignedFramePtr = std::shared_ptr<AlignedFrame>;

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<uint8_t> mMessage; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.7 - include/DeviceMemory.h

include/DeviceMemory.h

Classes

Name
classDeviceMemory
RAII class for a CUDA memory buffer.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstddef>
#include <cstdint>

class DeviceMemory {
public:
    DeviceMemory() = default;

    explicit DeviceMemory(size_t numberOfBytes);

    explicit DeviceMemory(void* deviceMemory) noexcept;

    bool allocateMemory(size_t numberOfBytes);

    bool reallocateMemory(size_t numberOfBytes);

    bool allocateAndResetMemory(size_t numberOfBytes);

    bool freeMemory();

    ~DeviceMemory();

    template <typename T = uint8_t> [[nodiscard]] T* getDevicePointer() const {
        return reinterpret_cast<T*>(dMemory);
    }

    size_t getSize() const;

    DeviceMemory(DeviceMemory&& other) noexcept;

    DeviceMemory& operator=(DeviceMemory&& other) noexcept;

    void swap(DeviceMemory& other) noexcept;

    DeviceMemory(DeviceMemory const&) = delete;
    DeviceMemory operator=(DeviceMemory const&) = delete;

private:
    uint8_t* dMemory = nullptr;
    size_t mAllocatedBytes = 0;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.8 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {
        bool mDebugAudio = false; // Insert a 800 Hz sound at every turn to a new second according to TAI
        bool mDebugVideo = false; // Print the timestamp in the picture
    };

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.9 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.10 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual Response sendRequest(const std::string& request, const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.11 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include "AlignedFrame.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

        std::function<std::function<void(const AlignedFramePtr&)>(uint32_t inputSlot,
                                                                  const std::string& streamID,
                                                                  const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDebugAudio = false;     
        bool mDebugVideo = false;     
        bool mDeliverOld = false;     
    };

    enum class TallyBorderColor { kNone, kRed, kGreen, kYellow };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    void stop();

    std::function<void(const AlignedFramePtr&)> getCustomMultiViewSourceInput(uint32_t inputSlot,
                                                                              const std::string& name = "");

    void setTallyBorder(uint32_t inputSlot, TallyBorderColor color);

    void clearTallyBorder(uint32_t inputSlot);

    void clearAllTallyBorders();

    [[nodiscard]] MediaReceiver::TallyBorderColor getTallyBorder(uint32_t inputSlot) const;

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.12 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "AlignedFrame.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    [[nodiscard]] bool hasFormatAndIsRunning() const;

    [[nodiscard]] bool hasOpenOutputStream() const;

    bool outputData(const AlignedFramePtr& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.13 - include/PipelineSystemControllerInterfaceFactory.h

include/PipelineSystemControllerInterfaceFactory.h

Classes

Name
classPipelineSystemControllerInterfaceFactory

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <string>

#include "SystemControllerConnection.h"

class PipelineSystemControllerInterfaceFactory final {
public:
    PipelineSystemControllerInterfaceFactory(const std::string& systemControllerIP,
                                             uint16_t systemControllerPort,
                                             const std::string& systemControllerPostfix,
                                             const std::string& psk,
                                             const std::string& myIP,
                                             bool useHTTPS,
                                             bool allowInsecureHTTPS);

    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&&) = delete;

    std::shared_ptr<SystemControllerConnection> getMediaReceiverInterface(const std::string& name);

    //    /// to generate the parent interface.
    std::shared_ptr<SystemControllerConnection> createMediaStreamerInterface(const std::string& name);

    std::shared_ptr<SystemControllerConnection> createControlReceiverInterface(const std::string& name);

private:
    std::string mSystemControllerIP;
    uint16_t mSystemControllerPort = 0;
    std::string mSystemControllerPostfix;
    std::string mPsk;
    std::string mMyIP;
    bool mUseHTTPS = true;
    bool mAllowInsecureHTTPS = false;

    std::shared_ptr<SystemControllerConnection> mReceiverController;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.14 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000};           // Max time to wait on an announcement response from the server during connection
        bool mEnableHTTPS;   // Enable the communication between the system controller and a component encrypted
        bool mInsecureHTTPS; // Disable the verification of the TLS certificate if requested.
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    Response sendRequest(const std::string& request, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.15 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

TimeCommon::TAIStatus getStatus();

int64_t getTAIMicro();

std::string taiMicroToString(int64_t taiTimestamp);
} // namespace TimeCommon

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.2.16 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3 - Namespaces

Namespaces


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3.1 - AclLog

AclLog

A namespace for logging utilities.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidsetLevel(Level level)
Set global logging level.

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name-.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3.2 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3.3 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3.4 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
TimeCommon::TAIStatusgetStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.
std::stringtaiMicroToString(int64_t taiTimestamp)
Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

TimeCommon::TAIStatus getStatus()

Get TAI status.

Return: Return the TAI status

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds

function taiMicroToString

std::string taiMicroToString(
    int64_t taiTimestamp
)

Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Parameters:

  • taiTimestamp A TAI timestamp with microseconds resolution

Return: Return a human readable timestamp


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.3.3.5 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2023-01-23 at 12:02:53 +0100

1.6.4.4 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
pskpskThe Pre-shared key used to authorize components to connect to the System Controller. Must be 32 characters long""
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnParameter for token and encryption generation. N is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrParameter for token and encryption generation. R is block size factor. R constrain must satisfy R*P < 2^30. 18
security.ppParameter for token and encryption generation. P is the parallelization parameter. P constrain must satisfy R*P < 2^30, if this is exceeded, an error will be returned 11
security.keylenkeylenThe length of the generated tokens32
client_auth.enabledenabledSwitch to enable basic authentication for clients in the REST APIfalse
client_auth.usernameusernameThe username that will grant access to the REST API“admin”
client_auth.passwordpasswordPassword that will grant access to the REST API“changeme”
https.enabledenabledSwitch to enable encryption of the REST API as well as the connections between the System Controller and the connected componentsfalse
https.insecureinsecureEnable the use of self-signed and/or unsecure certificatesfalse
https.certificate_filecertificate_filePath to the certificate file. In pem format""
https.private_key_fileprivate_key_filePath to the private key file. In pem format""
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
site.portportPort on which the service is accessible8080
site.hosthostHostname on which the service is accessiblelocalhost
response_timeoutresponse_timeoutThe maximum time of a request between the System Controller and a component before the request is timed out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that are allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllow the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be made300
custom_headers.[N].keykeyCustom headers, the key of the header, e.g.: Cache-ControlNone
custom_headers.[N].valuevalueCustom headers, the value to the key of the header, e.g.: no-cacheNone

1.6.5 - Agile Live 2.0.0 developer reference

Agile Live 2.0.0 developer reference

1.6.5.1 - REST API v1

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v1.

1.6.5.2 - Agile Live Rendering Engine command documentation

Reference for the Agile Live Rendering Engine commands

This page describes all the commands available in the Agile Live Rendering Engine.

Command protocol

All commands to the Agile Live Rendering Engine is sent as human readable strings and are listed below. The Rendering Engine expect no line termination, meaning that you do not need to append any type of new line (\n) characters, or string termination (\0) characters.

Video commands

The data path graph of the video mixer in the Rendering Engine looks as follows:

The video mixer data path

There are four nodes that can be controlled using the protocol. The Transition node is used to pick which input slots to use for the program and preview output. The node also supports making transitions between the program and preview. The video mixer can overlay graphics on top of the background image using the two nodes Alpha combine and Alpha over. The Alpha combine node is used to pick two input slots (or the same input slot) to copy the color from one input and combine it with some information from the other input to form the alpha. The color will just be copied from the color input frame, but there are several modes that can be used to produce the alpha channel in the output frame in different ways. Then the Alpha over node is used to perform an “Alpha Over” operation, that is to put the overlay video stream on top of the background video stream, and let the background be seen through the overlay depending on the alpha of the overlay. The node also features fading the graphics in and out by multiplying the alpha channel by a constant factor.

The video mixer can be controlled with the following commands:

  • cut <input_slot> - Cut (hot punch) the program output to the given input slot. This won’t affect the preview output.
  • preview <input_slot> - Preview the given input slot. This won’t affect the program output.
  • cut - Cut between the current program and preview outputs, effectively swapping their place.
  • fade <duration_ms> - Perform an automatic fade from the current program output to the current preview output, lasting for <duration> milliseconds.

In addition to this the graphics pipeline can be controlled with these commands:

  • alpha_combine color <input_slot> - Set which input slot to copy the color data from in the Alpha combine node
  • alpha_combine alpha <input_slot> - Set which input slot to use to create the alpha channel of the output frame in the Alpha combine node
  • alpha_combine mode <mode> - Set which way the alpha channel of the output frame will be produced. Valid modes are:
    • copy-r - Copy the R-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-g - Copy the G-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-b - Copy the B-channel of the input “alpha frame” and use it as alpha for the output.
    • copy-a - Copy the A-channel of the input “alpha frame” and use it as alpha for the output.
    • average-rgb - Take the average of the R, G and B channels of the input “alpha frame” and use it as alpha channel for the output.
  • alpha_over factor <factor> - Manually set the transparency multiplier for the Alpha over node. The value <factor> should be a float between 0.0 and 1.0, where 0.0 means that the overlay is completely invisible and 1.0 means that the overlay is fully visible (where it should be visible according to the overlay image’s alpha channel). Default is 0.0.
  • alpha_over fade to <duration_ms> - Start an automatic fade from the current factor to a fully visible overlay over the duration of <duration_ms> milliseconds.
  • alpha_over fade from <duration_ms> - Start an automatic fade from the current factor to a fully invisible overlay over the duration of <duration_ms> milliseconds.

And before the final output, the video stream can be faded to/from black using these commands:

  • fade_to_black factor <factor> - Manually set the blackness factor on a scale from 0.0 to 1.0, where 0.0 means not black and 1.0 means fully black output.
  • fade_to_black fade to <duration_ms> - Start an automatic fade to a fully black output over the duration of <duration_ms> milliseconds.
  • fade_to_black fade from <duration_ms> - Start an automatic fade to a fully visible (non-black) output over the duration of <duration_ms> milliseconds.

Audio commands

The audio mixer has the following data path:

The audio mixer data path

In the example three sources are connected to input slots 3, 4 and 9. The audio mixer is completely separate from the video mixer, so switching image in the video mixer will not change the audio mixer in any way.

  • volume <input_slot> <level> - Set the volume level of a specific input in proportion to its original strength. Parameter <level> should be a floating point number, where 0.0 means that the input slot is not mixed into the output and 1.0 means that the volume of the input slot is kept as is for the output. The signal can also be amplified by using values > 1.0. Default is 0.0.
  • mastervolume <level> - Set the volume level of the master output, before the audio is clamped and converted from floating point samples to 16-bit integer samples. This can be used to avoid clipping of the audio when mixing multiple input sources. Parameter <level> is a floating point number where 0.0 means that all audio output is off, 1.0 means that the volume is not changed and any value above 1.0 means that the master volume is amplified.

1.6.5.3 - C++ SDK

Agile Live C++ SDK reference

1.6.5.3.1 - Classes

Classes

  • namespace AclLog
    A namespace for logging utilities.
  • struct AlignedFrame
    A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class DeviceMemory
    RAII class for a CUDA memory buffer.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class PipelineSystemControllerInterfaceFactory
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.1 - AlignedFrame

AlignedFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedFrame.h>

Public Types

Name
enum classCompressedVideoFormat { kAvc, kHevc}
enum classPixelFormat { kUnknown, kNv12, kP016, kUyvy, kRgba, kRgba64Le}
typedef std::array< float, 16 >AudioSampleRow
One audio sample in 16 channels.

Public Functions

Name
AlignedFrame() =default
~AlignedFrame() =default
AlignedFrame(AlignedFrame const & ) =delete
AlignedFrame &operator=(AlignedFrame const & ) =delete

Public Attributes

Name
int64_tmCaptureTimestamp
int64_tmRenderingTimestamp
std::shared_ptr< DeviceMemory >mVideoFrame
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
std::vector< AudioSampleRow >mAudioData
uint32_tmAudioChannels
uint32_tmAudioSamplingFrequency

Public Types Documentation

enum CompressedVideoFormat

EnumeratorValueDescription
kAvc
kHevc

enum PixelFormat

EnumeratorValueDescription
kUnknown
kNv12
kP016
kUyvy
kRgba
kRgba64Le

typedef AudioSampleRow

typedef std::array<float, 16> AlignedFrame::AudioSampleRow;

One audio sample in 16 channels.

Public Functions Documentation

function AlignedFrame

AlignedFrame() =default

function ~AlignedFrame

~AlignedFrame() =default

function AlignedFrame

AlignedFrame(
    AlignedFrame const & 
) =delete

function operator=

AlignedFrame & operator=(
    AlignedFrame const & 
) =delete

Public Attributes Documentation

variable mCaptureTimestamp

int64_t mCaptureTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame was captured by the ingest

variable mRenderingTimestamp

int64_t mRenderingTimestamp = 0;

The TAI timestamp in microseconds since the TAI epoch when this frame should be delivered to the rendering engine

variable mVideoFrame

std::shared_ptr< DeviceMemory > mVideoFrame = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioData

std::vector< AudioSampleRow > mAudioData;

variable mAudioChannels

uint32_t mAudioChannels = 0;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.2 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.3 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.4 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.5 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.6 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmSenderUUID
The actual message.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mSenderUUID

std::string mSenderUUID;

The actual message.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.7 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.8 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.9 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v2.1.0-231-gcd012ab”, followed by “-dirty” in case there are changes made to the Git repo.

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.10 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.11 - DeviceMemory

DeviceMemory

RAII class for a CUDA memory buffer.

#include <DeviceMemory.h>

Public Functions

Name
DeviceMemory() =default
Default constructor, creates an empty object, without allocating any memory on the device.
DeviceMemory(size_t numberOfBytes)
Constructor allocating the required number of bytes.
DeviceMemory(void * deviceMemory)
Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.
boolallocateMemory(size_t numberOfBytes)
Allocates device memory. The memory allocated will automatically be freed by the destructor.
boolallocateAndResetMemory(size_t numberOfBytes)
Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.
boolfreeMemory()
Free the device memory held by this class. Calling this when no memory is allocated is a no-op.
~DeviceMemory()
Destructor, frees the internal CUDA memory.
template
T *
getDevicePointer() const
DeviceMemory(DeviceMemory && other)
DeviceMemory &operator=(DeviceMemory && other)
voidswap(DeviceMemory & other)
DeviceMemory(DeviceMemory const & ) =delete
DeviceMemory is not copyable.
DeviceMemoryoperator=(DeviceMemory const & ) =delete

Public Functions Documentation

function DeviceMemory

DeviceMemory() =default

Default constructor, creates an empty object, without allocating any memory on the device.

function DeviceMemory

explicit DeviceMemory(
    size_t numberOfBytes
)

Constructor allocating the required number of bytes.

Parameters:

  • numberOfBytes Number of bytes to allocate

function DeviceMemory

explicit DeviceMemory(
    void * deviceMemory
)

Constructor taking ownership of an already allocated CUDA memory pointer. This class will free the pointer once it goes out of scope.

Parameters:

  • deviceMemory CUDA memory pointer to take ownership over.

function allocateMemory

bool allocateMemory(
    size_t numberOfBytes
)

Allocates device memory. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if the CUDA malloc failed.

function allocateAndResetMemory

bool allocateAndResetMemory(
    size_t numberOfBytes
)

Allocates device memory and resets all bytes to zeroes. The memory allocated will automatically be freed by the destructor.

Parameters:

  • numberOfBytes Number of bytes to allocate

Return: True on success, false if there is already memory allocated by this instance, or if any of the CUDA operations failed.

function freeMemory

bool freeMemory()

Free the device memory held by this class. Calling this when no memory is allocated is a no-op.

Return: True in case the memory was successfully freed (or not allocated to begin with), false otherwise.

function ~DeviceMemory

~DeviceMemory()

Destructor, frees the internal CUDA memory.

function getDevicePointer

template <typename T  =uint8_t>
inline T * getDevicePointer() const

Template Parameters:

  • T The pointer type to return

Return: the CUDA memory pointer handled by this class. Nullptr in case no memory is allocated.

function DeviceMemory

DeviceMemory(
    DeviceMemory && other
)

function operator=

DeviceMemory & operator=(
    DeviceMemory && other
)

function swap

void swap(
    DeviceMemory & other
)

function DeviceMemory

DeviceMemory(
    DeviceMemory const & 
) =delete

DeviceMemory is not copyable.

function operator=

DeviceMemory operator=(
    DeviceMemory const & 
) =delete

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.12 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetGitRevision()
Get git revision which application was built on.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getGitRevision

static std::string getGitRevision()

Get git revision which application was built on.

Return: a string with the current git revision, e.g. “v1.0.0”, or “v2.1.0-231-gcd012ab”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get the versions of the libraries available at runtime, among others, CUDA version, BMD and NDI versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.13 - IngestApplication::Settings

IngestApplication::Settings

Public Attributes

Name
boolmDebugAudio
boolmDebugVideo

Public Attributes Documentation

variable mDebugAudio

bool mDebugAudio = false;

variable mDebugVideo

bool mDebugVideo = false;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.14 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) =0
Send a request with some JSON parameters to the controller and await the response.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) =0

Send a request with some JSON parameters to the controller and await the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller.

Reimplemented by: SystemControllerConnection::sendRequest

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.15 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.16 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.17 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Types

Name
enum classTallyBorderColor { kNone, kRed, kGreen, kYellow}
Available colors for tally border in multi view.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const AlignedFramePtr &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
voidsetTallyBorder(uint32_t inputSlot, TallyBorderColor color)
Set tally border color in the multi-views for a specific input slot.
voidclearTallyBorder(uint32_t inputSlot)
Remove tally border in the multi-views for a specific input slot.
voidclearAllTallyBorders()
Remove all tally borders.
MediaReceiver::TallyBorderColorgetTallyBorder(uint32_t inputSlot) const
get tally border color for an input slot
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.
std::stringgetLibraryVersions()
Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Public Types Documentation

enum TallyBorderColor

EnumeratorValueDescription
kNone
kRed
kGreen
kYellow

Available colors for tally border in multi view.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const AlignedFramePtr &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Precondition: The DataFrames sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function setTallyBorder

void setTallyBorder(
    uint32_t inputSlot,
    TallyBorderColor color
)

Set tally border color in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source
  • color the color to set

function clearTallyBorder

void clearTallyBorder(
    uint32_t inputSlot
)

Remove tally border in the multi-views for a specific input slot.

Parameters:

  • inputSlot the input slot for a source

function clearAllTallyBorders

void clearAllTallyBorders()

Remove all tally borders.

function getTallyBorder

MediaReceiver::TallyBorderColor getTallyBorder(
    uint32_t inputSlot
) const

get tally border color for an input slot

Parameters:

  • inputSlot the input slot to get color for

Return: the tally border color for the given input slot

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies

function getLibraryVersions

static std::string getLibraryVersions()

Get versions of the libraries available at runtime, among others, CUDA runtime and driver versions.

Return: a string with the currently found versions of the libraries used by this application


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.18 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.19 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
AlignedFrame::PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDebugAudio
Set to true if this MediaReceiver should have a multi-view generator.
boolmDebugVideo
Insert a 1500 Hz sound at every other turn to a new second according to TAI.
boolmDeliverOld
Print the timestamp in the picture.

Public Attributes Documentation

variable mDecodedFormat

AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const AlignedFramePtr &)>uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDebugAudio

bool mDebugAudio = false;

Set to true if this MediaReceiver should have a multi-view generator.

variable mDebugVideo

bool mDebugVideo = false;

Insert a 1500 Hz sound at every other turn to a new second according to TAI.

variable mDeliverOld

bool mDeliverOld = false;

Print the timestamp in the picture.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.20 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
boolhasFormatAndIsRunning() const
boolhasOpenOutputStream() const
booloutputData(const AlignedFramePtr & frame)
Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the the format reset, or if the format was not set before this method was called, false on error.

function hasFormatAndIsRunning

bool hasFormatAndIsRunning() const

Return: True if the input format is set and the OutputStreamer is running, false otherwise

function hasOpenOutputStream

bool hasOpenOutputStream() const

See:

  • outputData will be discarded without being encoded, as there is no stream to output them to. This method can be used to check if the frame even needs to be produced by the rendering engine. Note however, that the
  • outputData method will still log the frames sent to it as received, even if they are not encoded when the output stream is closed.

Return: True if the output stream of the MediaStreamer is currently open and outputting the data, false otherwise. In case this returns false all frames passed to

function outputData

bool outputData(
    const AlignedFramePtr & frame
)

Output data through this streamer. The AlignedFrame::mRenderingTimestamp of the frame will be used as PTS when encoding the uncompressed frame.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.21 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
AlignedFrame::PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.22 - PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory

Public Functions

Name
PipelineSystemControllerInterfaceFactory(const std::string & systemControllerIP, uint16_t systemControllerPort, const std::string & systemControllerPostfix, const std::string & psk, const std::string & myIP, bool useHTTPS, bool allowInsecureHTTPS)
Constructor.
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const && ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const & ) =delete
PipelineSystemControllerInterfaceFactory &operator=(PipelineSystemControllerInterfaceFactory const && ) =delete
std::shared_ptr< SystemControllerConnection >getMediaReceiverInterface(const std::string & name)
Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.
std::shared_ptr< SystemControllerConnection >createMediaStreamerInterface(const std::string & name)
Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.
std::shared_ptr< SystemControllerConnection >createControlReceiverInterface(const std::string & name)
Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Public Functions Documentation

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    const std::string & systemControllerIP,
    uint16_t systemControllerPort,
    const std::string & systemControllerPostfix,
    const std::string & psk,
    const std::string & myIP,
    bool useHTTPS,
    bool allowInsecureHTTPS
)

Constructor.

Parameters:

  • systemControllerIP The IP address of the System controller to connect to.
  • systemControllerPort The network port of the System controller to connect to.
  • systemControllerPostfix The postfix of the System controller’s address, to chose which API endpoints to use.
  • psk The Pre-shared key used for authorization at the System controller.
  • myIP The public IP address of the pipeline, i.e. the external IP used to connect to the pipeline.
  • useHTTPS If HTTPS should be used instead of HTTP
  • allowInsecureHTTPS Set to true to allow self-signed HTTPS certificates. Should normally be false.

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function PipelineSystemControllerInterfaceFactory

PipelineSystemControllerInterfaceFactory(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const & 
) =delete

function operator=

PipelineSystemControllerInterfaceFactory & operator=(
    PipelineSystemControllerInterfaceFactory const && 
) =delete

function getMediaReceiverInterface

std::shared_ptr< SystemControllerConnection > getMediaReceiverInterface(
    const std::string & name
)

Get the interface to the MediaReceiver. Multiple calls to this method will return the same interface. Internally the UUID is randomly generated and the correct type is set.

Parameters:

  • name The human readable name of the MediaReceiver to provide to the System controller

Return: A configured connection on success, otherwise nullptr

function createMediaStreamerInterface

std::shared_ptr< SystemControllerConnection > createMediaStreamerInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a MediaStreamer. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the MediaStreamer to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called

Return: A configured connection on success, otherwise nullptr

function createControlReceiverInterface

std::shared_ptr< SystemControllerConnection > createControlReceiverInterface(
    const std::string & name
)

Create a new SystemControllerInterface to a ControlReceiver. Multiple calls to this method will return new interfaces each time. Internally the UUID is randomly generated, the correct type is set and the MediaReceiver is set as parent. The.

Parameters:

  • name The human readable name of the ControlReceiver to provide to the System controller

See: getMediaReceiverInterface must be called before this method is called to generate the parent interface.

Return: A configured connection on success, otherwise nullptr


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.23 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) override
Send a JSON object to the system controller server and awaits the response.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) override

Send a JSON object to the system controller server and awaits the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller

Note: The status code might be TIMEOUT in case no response was received within the timeframe

Reimplements: ISystemControllerInterface::sendRequest

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.24 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout
boolmEnableHTTPS
boolmInsecureHTTPS

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

variable mEnableHTTPS

bool mEnableHTTPS;

variable mInsecureHTTPS

bool mInsecureHTTPS;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.25 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.1.26 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void setLevel(Level level);

} // namespace AclLog

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.2 - include/AlignedFrame.h

include/AlignedFrame.h

Classes

Name
structAlignedFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
using std::shared_ptr< AlignedFrame >AlignedFramePtr

Types Documentation

using AlignedFramePtr

using AlignedFramePtr =  std::shared_ptr<AlignedFrame>;

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <memory>
#include <vector>

#include <cuda_runtime_api.h>

#include "DeviceMemory.h"

struct AlignedFrame {

    typedef std::array<float, 16> AudioSampleRow;

    enum class CompressedVideoFormat {
        kAvc, // H264
        kHevc // H265
    };

    enum class PixelFormat {
        kUnknown,
        kNv12,    // 8 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kP016,    // 16 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
        kUyvy,    // 8 bit per component 4:2:2 YUV format. U-Y-V-Y bytes interleaved.
        kRgba,    // 8 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory.
        kRgba64Le // 16 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory with little endian words.
    };

    AlignedFrame() = default;

    ~AlignedFrame() = default;

    AlignedFrame(AlignedFrame const&) = delete;            // Copy construct
    AlignedFrame& operator=(AlignedFrame const&) = delete; // Copy assign

    int64_t mCaptureTimestamp = 0;

    int64_t mRenderingTimestamp = 0;

    // Video
    std::shared_ptr<DeviceMemory> mVideoFrame = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    std::vector<AudioSampleRow> mAudioData;
    uint32_t mAudioChannels = 0;
    uint32_t mAudioSamplingFrequency = 0;
};

using AlignedFramePtr = std::shared_ptr<AlignedFrame>;

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<uint8_t> mMessage; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.7 - include/DeviceMemory.h

include/DeviceMemory.h

Classes

Name
classDeviceMemory
RAII class for a CUDA memory buffer.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <cstddef>
#include <cstdint>

class DeviceMemory {
public:
    DeviceMemory() = default;

    explicit DeviceMemory(size_t numberOfBytes);

    explicit DeviceMemory(void* deviceMemory) noexcept;

    bool allocateMemory(size_t numberOfBytes);

    bool allocateAndResetMemory(size_t numberOfBytes);

    bool freeMemory();

    ~DeviceMemory();

    template <typename T = uint8_t> [[nodiscard]] T* getDevicePointer() const {
        return reinterpret_cast<T*>(dMemory);
    }

    DeviceMemory(DeviceMemory&& other) noexcept;

    DeviceMemory& operator=(DeviceMemory&& other) noexcept;

    void swap(DeviceMemory& other) noexcept;

    DeviceMemory(DeviceMemory const&) = delete;
    DeviceMemory operator=(DeviceMemory const&) = delete;

private:
    uint8_t* dMemory = nullptr;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.8 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {
        bool mDebugAudio = false; // Insert a 800 Hz sound at every turn to a new second according to TAI
        bool mDebugVideo = false; // Print the timestamp in the picture
    };

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getGitRevision();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.9 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.10 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual Response sendRequest(const std::string& request, const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.11 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include "AlignedFrame.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        AlignedFrame::PixelFormat mDecodedFormat = AlignedFrame::PixelFormat::kRgba64Le;

        std::function<std::function<void(const AlignedFramePtr&)>(uint32_t inputSlot,
                                                                  const std::string& streamID,
                                                                  const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDebugAudio = false;     
        bool mDebugVideo = false;     
        bool mDeliverOld = false;     
    };

    enum class TallyBorderColor { kNone, kRed, kGreen, kYellow };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    void stop();

    std::function<void(const AlignedFramePtr&)> getCustomMultiViewSourceInput(uint32_t inputSlot,
                                                                              const std::string& name = "");

    void setTallyBorder(uint32_t inputSlot, TallyBorderColor color);

    void clearTallyBorder(uint32_t inputSlot);

    void clearAllTallyBorders();

    [[nodiscard]] MediaReceiver::TallyBorderColor getTallyBorder(uint32_t inputSlot) const;

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

    static std::string getLibraryVersions();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.12 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "AlignedFrame.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        AlignedFrame::PixelFormat mIncomingPixelFormat = AlignedFrame::PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    [[nodiscard]] bool hasFormatAndIsRunning() const;

    [[nodiscard]] bool hasOpenOutputStream() const;

    bool outputData(const AlignedFramePtr& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.13 - include/PipelineSystemControllerInterfaceFactory.h

include/PipelineSystemControllerInterfaceFactory.h

Classes

Name
classPipelineSystemControllerInterfaceFactory

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <string>

#include "SystemControllerConnection.h"

class PipelineSystemControllerInterfaceFactory final {
public:
    PipelineSystemControllerInterfaceFactory(const std::string& systemControllerIP,
                                             uint16_t systemControllerPort,
                                             const std::string& systemControllerPostfix,
                                             const std::string& psk,
                                             const std::string& myIP,
                                             bool useHTTPS,
                                             bool allowInsecureHTTPS);

    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory(PipelineSystemControllerInterfaceFactory const&&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&) = delete;
    PipelineSystemControllerInterfaceFactory& operator=(PipelineSystemControllerInterfaceFactory const&&) = delete;

    std::shared_ptr<SystemControllerConnection> getMediaReceiverInterface(const std::string& name);

    //    /// to generate the parent interface.
    std::shared_ptr<SystemControllerConnection> createMediaStreamerInterface(const std::string& name);

    std::shared_ptr<SystemControllerConnection> createControlReceiverInterface(const std::string& name);

private:
    std::string mSystemControllerIP;
    uint16_t mSystemControllerPort = 0;
    std::string mSystemControllerPostfix;
    std::string mPsk;
    std::string mMyIP;
    bool mUseHTTPS = true;
    bool mAllowInsecureHTTPS = false;

    std::shared_ptr<SystemControllerConnection> mReceiverController;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.14 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000};           // Max time to wait on an announcement response from the server during connection
        bool mEnableHTTPS;   // Enable the communication between the system controller and a component encrypted
        bool mInsecureHTTPS; // Disable the verification of the TLS certificate if requested.
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    Response sendRequest(const std::string& request, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.15 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

TimeCommon::TAIStatus getStatus();

int64_t getTAIMicro();

std::string taiMicroToString(int64_t taiTimestamp);
} // namespace TimeCommon

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.2.16 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3 - Namespaces

Namespaces


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3.1 - AclLog

AclLog

A namespace for logging utilities.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidsetLevel(Level level)
Set global logging level.

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name-.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3.2 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3.3 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3.4 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
TimeCommon::TAIStatusgetStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.
std::stringtaiMicroToString(int64_t taiTimestamp)
Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

TimeCommon::TAIStatus getStatus()

Get TAI status.

Return: Return the TAI status

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds

function taiMicroToString

std::string taiMicroToString(
    int64_t taiTimestamp
)

Converts the input TAI timestamp to a human readable string. Timestamp is converted to local time including leap seconds.

Parameters:

  • taiTimestamp A TAI timestamp with microseconds resolution

Return: Return a human readable timestamp


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.3.3.5 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2022-11-17 at 15:40:06 +0100

1.6.5.4 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
pskpskThe Pre-shared key used to authorize components to connect to the System Controller. Must be 32 characters long""
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnParameter for token and encryption generation. N is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrParameter for token and encryption generation. R is block size factor. R constrain must satisfy R*P < 2^30. 18
security.ppParameter for token and encryption generation. P is the parallelization parameter. P constrain must satisfy R*P < 2^30, if this is exceeded, an error will be returned 11
security.keylenkeylenThe length of the generated tokens32
client_auth.enabledenabledSwitch to enable basic authentication for clients in the REST APIfalse
client_auth.usernameusernameThe username that will grant access to the REST API“admin”
client_auth.passwordpasswordPassword that will grant access to the REST API“changeme”
https.enabledenabledSwitch to enable encryption of the REST API as well as the connections between the System Controller and the connected componentsfalse
https.insecureinsecureEnable the use of self-signed and/or unsecure certificatesfalse
https.certificate_filecertificate_filePath to the certificate file. In pem format""
https.private_key_fileprivate_key_filePath to the private key file. In pem format""
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
site.portportPort on which the service is accessible8080
site.hosthostHostname on which the service is accessiblelocalhost
response_timeoutresponse_timeoutThe maximum time of a request between the System Controller and a component before the request is timed out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that are allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllow the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be made300
custom_headers.[N].keykeyCustom headers, the key of the header, e.g.: Cache-ControlNone
custom_headers.[N].valuevalueCustom headers, the value to the key of the header, e.g.: no-cacheNone

1.6.6 - Agile Live 1.0.0 developer reference

Agile Live 1.0.0 developer reference

1.6.6.1 - REST API v1

Reference for the Agile Live System Controller REST API

The following is a rendering of the OpenAPI for the Agile Live System Controller using Swagger. It does not have a backend server, so it cannot be run interactively.

This API is available from the server at the base URL /api/v1.

1.6.6.2 - C++ SDK

Agile Live C++ SDK reference

1.6.6.2.1 - Classes

Classes

  • namespace AclLog
    A namespace for logging utilities.
  • namespace AlignedData
    • struct DataFrame
      A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.
  • namespace ControlDataCommon
  • class ControlDataReceiver
    A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
  • class ControlDataSender
    A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
  • class ISystemControllerInterface
    An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
    • struct Callbacks
      A struct containing the callbacks that needs to be registered by the component using this interface.
    • struct Response
      A response to a request, consists of a status code and an (optional) parameters JSON object.
  • class IngestApplication
  • namespace IngestUtils
  • class MediaReceiver
    A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
  • class MediaStreamer
    MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
  • class SystemControllerConnection
    An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
  • namespace TimeCommon
  • namespace UUIDUtils
    A namespace for UUID utility functions.

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.1 - AlignedData::DataFrame

AlignedData::DataFrame

A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

#include <AlignedData.h>

Public Functions

Name
DataFrame() =default
~DataFrame()
DataFrame(DataFrame const & ) =delete
DataFrame &operator=(DataFrame const & ) =delete

Public Attributes

Name
uint64_tmPTS
uint8_t *mVideoDataCudaPtr
PixelFormatmPixelFormat
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmWidth
uint32_tmHeight
std::vector< AudioSampleRow >mAudioData
uint32_tmAudioChannels
uint32_tmAudioSamplingFrequency

Public Functions Documentation

function DataFrame

DataFrame() =default

function ~DataFrame

inline ~DataFrame()

function DataFrame

DataFrame(
    DataFrame const & 
) =delete

function operator=

DataFrame & operator=(
    DataFrame const & 
) =delete

Public Attributes Documentation

variable mPTS

uint64_t mPTS;

variable mVideoDataCudaPtr

uint8_t * mVideoDataCudaPtr = nullptr;

variable mPixelFormat

PixelFormat mPixelFormat = PixelFormat::kUnknown;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mAudioData

std::vector< AudioSampleRow > mAudioData;

variable mAudioChannels

uint32_t mAudioChannels = 0;

variable mAudioSamplingFrequency

uint32_t mAudioSamplingFrequency = 0;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.2 - ControlDataCommon::ConnectionStatus

ControlDataCommon::ConnectionStatus

Connection status struct containing information about a connection event.

#include <ControlDataCommon.h>

Public Functions

Name
ConnectionStatus() =default
ConnectionStatus(ConnectionType mConnectionType, const std::string & mIp, uint16_t mPort)

Public Attributes

Name
ConnectionTypemConnectionType
std::stringmIP
uint16_tmPort

Public Functions Documentation

function ConnectionStatus

ConnectionStatus() =default

function ConnectionStatus

inline ConnectionStatus(
    ConnectionType mConnectionType,
    const std::string & mIp,
    uint16_t mPort
)

Public Attributes Documentation

variable mConnectionType

ConnectionType mConnectionType;

variable mIP

std::string mIP;

variable mPort

uint16_t mPort = 0;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.3 - ControlDataCommon::Response

ControlDataCommon::Response

A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
uint64_tmRequestId
The actual message.
std::stringmFromUUID
The ID of the request this is a response to.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mRequestId

uint64_t mRequestId = 0;

The actual message.

variable mFromUUID

std::string mFromUUID;

The ID of the request this is a response to.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.4 - ControlDataCommon::StatusMessage

ControlDataCommon::StatusMessage

A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

#include <ControlDataCommon.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmFromUUID
The actual message.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mFromUUID

std::string mFromUUID;

The actual message.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.5 - ControlDataReceiver

ControlDataReceiver

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests. More…

#include <ControlDataReceiver.h>

Public Classes

Name
structIncomingRequest
An incoming request to this ControlDataReceiver.
structReceiverResponse
A response message to a request.
structSettings
Settings for a ControlDataReceiver.

Public Functions

Name
ControlDataReceiver()
Default constructor, creates an empty object.
~ControlDataReceiver()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendStatusMessageToSender(const std::vector< uint8_t > & message)
Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.
ControlDataReceiver(ControlDataReceiver const & ) =delete
ControlDataReceiver &operator=(ControlDataReceiver const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class ControlDataReceiver;

A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.

Each ControlDataReceiver can be configured to have a certain message delay. This delay parameter is set when the System controller instructs the ControlDataReceiver to start listening for incoming connections from senders (or sending ControlDataReceiver). Each incoming request will then be delayed and delivered according to the parameter, compared to the send timestamp in the message. In case multiple receivers are chained, like sender->receiver1->receiver2, receiver1 will delay the incoming messages from the sender based on when they were sent from the sender. Furthermore, receiver2 will delay them compared to when they were sent from receiver1.

A ControlDataReceiver can send status messages back to the sender. In case of chained receivers, the message will be forwarded back to the sender. A user of the ControlDataReceiver can register callbacks to receive requests and status messages. There is also an optional “preview” callback that is useful in case the incoming messages are delayed (have a delay > 0). This callback will then be called as soon as the request message arrives, to allow the user to prepare for when the actual delayed request callback is called.

Public Functions Documentation

function ControlDataReceiver

ControlDataReceiver()

Default constructor, creates an empty object.

function ~ControlDataReceiver

~ControlDataReceiver()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataReceiver and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendStatusMessageToSender

bool sendStatusMessageToSender(
    const std::vector< uint8_t > & message
)

Send a status message to the (directly or indirectly) connected ControlDataSender. In case this ControlDataReceiver has another ControlDataReceiver as sender, that receiver will forward the status message to the sender.

Parameters:

  • message The status message

Return: True in case the message was sent successfully, false otherwise.

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to the connected ControlDataReceivers asynchronously. This request will only be sent to ControlDataReceivers on the receiving side of this receiver. In case a receiver is located between this ControlDataReceiver and the sender, neither of those will see this request. The response will be sent to the response callback asynchronously.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async response.

Return: True if the request was successfully sent, false otherwise

function ControlDataReceiver

ControlDataReceiver(
    ControlDataReceiver const & 
) =delete

function operator=

ControlDataReceiver & operator=(
    ControlDataReceiver const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.6 - ControlDataReceiver::IncomingRequest

ControlDataReceiver::IncomingRequest

An incoming request to this ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage
std::stringmSenderUUID
The actual message.
std::stringmRequesterUUID
UUID of the sender/forwarder that sent the request to this ControlDataReceiver.
uint64_tmRequestID
UUID of the requester (the original sender, creating the request)
int64_tmSenderTimestampUs
The requester’s unique id of this request.
int64_tmDeliveryTimestampUs
The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

variable mSenderUUID

std::string mSenderUUID;

The actual message.

variable mRequesterUUID

std::string mRequesterUUID;

UUID of the sender/forwarder that sent the request to this ControlDataReceiver.

variable mRequestID

uint64_t mRequestID = 0;

UUID of the requester (the original sender, creating the request)

variable mSenderTimestampUs

int64_t mSenderTimestampUs =
            0;

The requester’s unique id of this request.

variable mDeliveryTimestampUs

int64_t mDeliveryTimestampUs =
            0;

The TAI timestamp when this message was sent from the sender/forwarder in micro sec since TAI epoch.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.7 - ControlDataReceiver::ReceiverResponse

ControlDataReceiver::ReceiverResponse

A response message to a request.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::vector< uint8_t >mMessage

Public Attributes Documentation

variable mMessage

std::vector< uint8_t > mMessage;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.8 - ControlDataReceiver::Settings

ControlDataReceiver::Settings

Settings for a ControlDataReceiver.

#include <ControlDataReceiver.h>

Public Attributes

Name
std::function< void(const IncomingRequest &)>mPreviewIncomingRequestCallback
std::function< ReceiverResponse(const IncomingRequest &)>mIncomingRequestCallback
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
Callback for connection events.

Public Attributes Documentation

variable mPreviewIncomingRequestCallback

std::function< void(const IncomingRequest &)> mPreviewIncomingRequestCallback;

Callback called as soon as this ControlDataReceiver gets the request, as a “preview” of what requests will be delievered.

variable mIncomingRequestCallback

std::function< ReceiverResponse(const IncomingRequest &)> mIncomingRequestCallback;

The actual callback used when this ControlDataReceiver gets a request and wants a response back. This callback will delay and deliver the request according to this receiver’s configured delay.

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

Callback for connection events.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.9 - ControlDataSender

ControlDataSender

A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.

#include <ControlDataSender.h>

Public Classes

Name
structSettings
Settings for a ControlDataSender.

Public Functions

Name
ControlDataSender()
Default constructor, creates an empty object.
~ControlDataSender()
Destructor. Will disconnect from the connected receivers and close the System controller connection.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.
boolsendRequestToReceivers(const std::vector< uint8_t > & request, uint64_t & requestId)
Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.
ControlDataSender(ControlDataSender const & ) =delete
ControlDataSender &operator=(ControlDataSender const & ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function ControlDataSender

ControlDataSender()

Default constructor, creates an empty object.

function ~ControlDataSender

~ControlDataSender()

Destructor. Will disconnect from the connected receivers and close the System controller connection.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Configure this ControlDataSender and connect it to the System Controller. This method will fail in case the ISystemControllerInterface has already been connected to the controller by another component, as such interface can only be used by one component.

Parameters:

Return: True on success, false otherwise

function sendRequestToReceivers

bool sendRequestToReceivers(
    const std::vector< uint8_t > & request,
    uint64_t & requestId
)

Send a request to all the connected ControlDataReceivers asynchronously. The responses will be sent to the response callback.

Parameters:

  • request The request message
  • requestId The unique identifier of this request. Used to identify the async responses.

Return: True if the request was successfully sent, false otherwise

function ControlDataSender

ControlDataSender(
    ControlDataSender const & 
) =delete

function operator=

ControlDataSender & operator=(
    ControlDataSender const & 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.10 - ControlDataSender::Settings

ControlDataSender::Settings

Settings for a ControlDataSender.

#include <ControlDataSender.h>

Public Attributes

Name
std::function< void(const ControlDataCommon::ConnectionStatus &)>mConnectionStatusCallback
std::function< void(const ControlDataCommon::Response &)>mResponseCallback
std::function< void(const ControlDataCommon::StatusMessage &)>mStatusMessageCallback

Public Attributes Documentation

variable mConnectionStatusCallback

std::function< void(const ControlDataCommon::ConnectionStatus &)> mConnectionStatusCallback;

variable mResponseCallback

std::function< void(const ControlDataCommon::Response &)> mResponseCallback;

variable mStatusMessageCallback

std::function< void(const ControlDataCommon::StatusMessage &)> mStatusMessageCallback;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.11 - IngestApplication

IngestApplication

Public Classes

Name
structSettings

Public Functions

Name
IngestApplication()
Constructor, creates an empty IngestApplication without starting it.
~IngestApplication()
Destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start this IngestApplication given an interface to the System Controller and an UUID.
boolstop()
Stop this IngestApplication.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function IngestApplication

IngestApplication()

Constructor, creates an empty IngestApplication without starting it.

function ~IngestApplication

~IngestApplication()

Destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start this IngestApplication given an interface to the System Controller and an UUID.

Parameters:

  • controllerInterface The interface for communication with the System Controller
  • settings The settings for the IngestApplication

Return: True if the IngestApplication was successfully started, false otherwise

function stop

bool stop()

Stop this IngestApplication.

Return: True if the IngestApplication was successfully stopped, false otherwise

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.12 - IngestApplication::Settings

IngestApplication::Settings

Public Attributes

Name
boolmDebugAudio
boolmDebugVideo

Public Attributes Documentation

variable mDebugAudio

bool mDebugAudio = false;

variable mDebugVideo

bool mDebugVideo = false;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.13 - ISystemControllerInterface

ISystemControllerInterface

An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.

#include <ISystemControllerInterface.h>

Inherited by SystemControllerConnection

Public Classes

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types

Name
enum class uint32_tStatusCode { SUCCESS = 3001, TOO_MANY_REQUESTS = 3101, UUID_ALREADY_REGISTERED = 3201, FORMAT_ERROR = 3202, ALREADY_CONFIGURED = 3203, OUT_OF_RESOURCES = 3204, NOT_FOUND = 3205, INTERNAL_ERROR = 3206, CONNECTION_FAILED = 3207, TIMEOUT_EXCEEDED = 3208, KEY_MISMATCH = 3209, UNKNOWN_REQUEST = 3210, MALFORMED_REQUEST = 3211, ALREADY_IN_USE = 3212}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) =0
Send a request with some JSON parameters to the controller and await the response.
virtual boolregisterRequestCallback(const Callbacks & callbacks) =0
Register the callbacks to call for events in this class.
virtual boolconnect() =0
Connect to the System controller.
virtual booldisconnect() =0
Disconnect from the System controller.
virtual boolisConnected() const =0
virtual std::stringgetUUID() const =0
virtual boolhasParent() const =0
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const =0

Public Types Documentation

enum StatusCode

EnumeratorValueDescription
SUCCESS30013000-3099 Info/Notifications
TOO_MANY_REQUESTS31013100-3199 Warnings
UUID_ALREADY_REGISTERED32013200-3299 Error
FORMAT_ERROR3202
ALREADY_CONFIGURED3203
OUT_OF_RESOURCES3204
NOT_FOUND3205
INTERNAL_ERROR3206
CONNECTION_FAILED3207
TIMEOUT_EXCEEDED3208
KEY_MISMATCH3209
UNKNOWN_REQUEST3210
MALFORMED_REQUEST3211
ALREADY_IN_USE3212

Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions Documentation

function ~ISystemControllerInterface

virtual ~ISystemControllerInterface() =default

Virtual destructor.

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) =0

Send a request with some JSON parameters to the controller and await the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller.

Reimplemented by: SystemControllerConnection::sendRequest

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) =0

Register the callbacks to call for events in this class.

Parameters:

  • callbacks The callbacks to use when events in this class happen

Return: True on successful registration, false if some callback is not set or if already connected

Reimplemented by: SystemControllerConnection::registerRequestCallback

function connect

virtual bool connect() =0

Connect to the System controller.

Return: True on successful connection, false on error or if already connected

Reimplemented by: SystemControllerConnection::connect

function disconnect

virtual bool disconnect() =0

Disconnect from the System controller.

Return: True on successful disconnection, false on error or if not connected

Reimplemented by: SystemControllerConnection::disconnect

function isConnected

virtual bool isConnected() const =0

Return: True if connected to the System controller, false otherwise

Reimplemented by: SystemControllerConnection::isConnected

function getUUID

virtual std::string getUUID() const =0

Return: The UUID of this interface to the System controller

Reimplemented by: SystemControllerConnection::getUUID

function hasParent

virtual bool hasParent() const =0

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplemented by: SystemControllerConnection::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const =0

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplemented by: SystemControllerConnection::getParentInterface


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.14 - ISystemControllerInterface::Callbacks

ISystemControllerInterface::Callbacks

A struct containing the callbacks that needs to be registered by the component using this interface.

#include <ISystemControllerInterface.h>

Public Attributes

Name
std::function< Response(const std::string &, const nlohmann::json &)>mRequestCallback
std::function< void(uint32_t, const std::string &, const std::error_code &)>mConnectionClosedCallback

Public Attributes Documentation

variable mRequestCallback

std::function< Response(const std::string &, const nlohmann::json &)> mRequestCallback;

variable mConnectionClosedCallback

std::function< void(uint32_t, const std::string &, const std::error_code &)> mConnectionClosedCallback;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.15 - ISystemControllerInterface::Response

ISystemControllerInterface::Response

A response to a request, consists of a status code and an (optional) parameters JSON object.

#include <ISystemControllerInterface.h>

Public Attributes

Name
StatusCodemCode
nlohmann::jsonmParameters

Public Attributes Documentation

variable mCode

StatusCode mCode;

variable mParameters

nlohmann::json mParameters;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.16 - MediaReceiver

MediaReceiver

A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.

#include <MediaReceiver.h>

Public Classes

Name
structNewStreamParameters
A struct containing information on the format of an incoming stream.
structSettings
Settings for a MediaReceiver.

Public Functions

Name
MediaReceiver()
Default constructor.
~MediaReceiver()
Default destructor.
boolstart(const std::shared_ptr< ISystemControllerInterface > & controllerInterface, const Settings & settings)
Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.
voidstop()
Stop the MediaReceiver.
std::function< void(const std::shared_ptr< AlignedData::DataFrame > &)>getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string & name ="")
This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.
MediaReceiver(MediaReceiver const & ) =delete
MediaReceiver is neither copyable nor movable.
MediaReceiver(MediaReceiver && ) =delete
MediaReceiver &operator=(MediaReceiver const & ) =delete
MediaReceiver &operator=(MediaReceiver && ) =delete
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Public Functions Documentation

function MediaReceiver

MediaReceiver()

Default constructor.

function ~MediaReceiver

~MediaReceiver()

Default destructor.

function start

bool start(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface,
    const Settings & settings
)

Start the MediaReceiver. This method will call connect on the System controller interface and set up the callbacks from the interface to call internal methods.

Parameters:

  • controllerInterface The ISystemControllerInterface to use for this MediaReceiver. The interface should be configured (Such as setting the IP address and port of the System Controller if a server based System Controller is used) but not connected before passed to this method. This method will internally set the callbacks before connecting to the controller. If the controller is already connected or if the controller is not configured, this method will return false. This class will take ownership of the smart pointer.
  • settings The settings to use for the MediaReceiver.

Return: True if the MediaReceiver was started successfully, false otherwise.

function stop

void stop()

Stop the MediaReceiver.

function getCustomMultiViewSourceInput

std::function< void(const std::shared_ptr< AlignedData::DataFrame > &)> getCustomMultiViewSourceInput(
    uint32_t inputSlot,
    const std::string & name =""
)

This method allows the Rendering Engine to provide custom input sources to the Multi-view generator to send video streams that can be added to the multi-views. This could for instance be used for adding a “preview” of the video stream the rendering engine is about to cut to.

Parameters:

  • inputSlot The input slot this source will be “plugged in” to. The custom input sources share the input slots with the streams connected from Ingests. This means that it is probably a good idea to use higher numbered slots for these custom inputs, such as numbers from 1000, so that the lower numbers, 1 and up, can be used by the connected video cameras, as the input slot number will also be used when cutting.
  • name Optional human readable name of this stream, to be presented to the System Controller.

See: MediaReceiver::Settings::mDecodedFormat.

Return: A function to where the Rendering Engine should send the frames. In case the requested inputSlot is already used by another custom input source, or a stream from an ingest, the returned function will be nullptr.

Precondition: The DataFrames sent to this function must have the same pixel format as this MediaReceiver is configured to deliver to the Rendering Engine,

function MediaReceiver

MediaReceiver(
    MediaReceiver const & 
) =delete

MediaReceiver is neither copyable nor movable.

function MediaReceiver

MediaReceiver(
    MediaReceiver && 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver const & 
) =delete

function operator=

MediaReceiver & operator=(
    MediaReceiver && 
) =delete

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.17 - MediaReceiver::NewStreamParameters

MediaReceiver::NewStreamParameters

A struct containing information on the format of an incoming stream.

#include <MediaReceiver.h>

Public Attributes

Name
uint32_tmVideoHeight
uint32_tmVideoWidth
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate

Public Attributes Documentation

variable mVideoHeight

uint32_t mVideoHeight = 0;

variable mVideoWidth

uint32_t mVideoWidth = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 1;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.18 - MediaReceiver::Settings

MediaReceiver::Settings

Settings for a MediaReceiver.

#include <MediaReceiver.h>

Public Attributes

Name
AlignedData::PixelFormatmDecodedFormat
The pixel format delivered to the rendering engine.
std::function< std::function< void(const std::shared_ptr< AlignedData::DataFrame > &)> uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)>mNewConnectionCallback
std::function< void(uint32_t inputSlot)>mClosedConnectionCallback
boolmUseMultiViewer
boolmDebugAudio
Set to true if this MediaReceiver should have a multi-view generator.
boolmDebugVideo
Insert a 1500 Hz sound at every other turn to a new second according to TAI.
boolmDeliverOld
Print the timestamp in the picture.

Public Attributes Documentation

variable mDecodedFormat

AlignedData::PixelFormat mDecodedFormat = AlignedData::PixelFormat::kRgba64Le;

The pixel format delivered to the rendering engine.

variable mNewConnectionCallback

std::function< std::function< void(const std::shared_ptr< AlignedData::DataFrame > &)> uint32_t inputSlot, const std::string &streamID, const NewStreamParameters &newStreamParameters)> mNewConnectionCallback;

Parameters:

  • inputSlot can be seen as a virtual SDI input on a hardware mixer and should be used by the Rendering engine to identify sources. For example, if a source is connected to input slot 5, the button “Cut to camera 5” on the control panel ought to cut to this stream. The MediaReceiver is responsible for making sure only one stream can be connected to an input slot at a time. This callback might be called multiple times with the same input slot, however, in case the stream has been disconnected and the mClosedConnectionCallback has been called for that input slot earlier.
  • streamID is the identification string of the video/audio source on the Ingest. A Rendering engine might have the same StreamID connected multiple times (for instance if two different alignments are used for the same source) so this should not be used as an unique identifier for the stream.
  • newStreamParameters contains information on the pending incoming stream to allow the Rendering engine to decide if it can receive it or not.

A callback called by the MediaReceiver whenever a new connection from an Ingest is set up. The callback should return a function to which the data will be delivered. In case the Rendering engine does not want to accept the pending incoming stream (due to a format not supported, etc) the Rendering engine can return nullptr.

variable mClosedConnectionCallback

std::function< void(uint32_t inputSlot)> mClosedConnectionCallback;

Parameters:

  • inputSlot The input slot that was disconnected

A callback called whenever a connection from an Ingest has been stopped. When receiving this callback, the callback function returned by the mNewConnectionCallback will not be called anymore and can be discarded if required by the application. After this function has been called, the input slot might be reused by another incoming stream after a call to the mNewConnectionCallback.

variable mUseMultiViewer

bool mUseMultiViewer = false;

variable mDebugAudio

bool mDebugAudio = false;

Set to true if this MediaReceiver should have a multi-view generator.

variable mDebugVideo

bool mDebugVideo = false;

Insert a 1500 Hz sound at every other turn to a new second according to TAI.

variable mDeliverOld

bool mDeliverOld = false;

Print the timestamp in the picture.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.19 - MediaStreamer

MediaStreamer

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to. More…

#include <MediaStreamer.h>

Public Classes

Name
structConfiguration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Public Functions

Name
MediaStreamer()
Default constructor.
~MediaStreamer()
Destructor. This will stop the output stream if not already done by calling.
boolconfigure(const std::shared_ptr< ISystemControllerInterface > & controllerInterface)
Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.
boolsetInputFormatAndStart(const Configuration & configuration)
Set the input format of this MediaStreamer and start the streamer. The.
boolstopAndResetFormat()
Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.
booloutputData(const std::shared_ptr< AlignedData::DataFrame > & frame)
Output data through this streamer.
std::stringgetVersion()
Get application version.
std::stringgetBuildInfo()
Get application build information.

Detailed Description

class MediaStreamer;

MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.

See: outputData is made.

Public Functions Documentation

function MediaStreamer

MediaStreamer()

Default constructor.

function ~MediaStreamer

~MediaStreamer()

Destructor. This will stop the output stream if not already done by calling.

See: stop.

function configure

bool configure(
    const std::shared_ptr< ISystemControllerInterface > & controllerInterface
)

Configure this MediaStreamer and connect it to the System controller. This must be called before any call to the.

Parameters:

  • controllerInterface The interface to the System controller, used for communicating with this MediaStreamer

See:

Return: True if the streamer was successfully connected to the System controller

function setInputFormatAndStart

bool setInputFormatAndStart(
    const Configuration & configuration
)

Set the input format of this MediaStreamer and start the streamer. The.

Parameters:

  • configuration The configuration with the format of the frames that will be sent to this MediaReceiver

See:

  • configure method must be called before this method is called. This method must be called before any call to
  • outputData. If the format should be reset, the
  • stopAndResetFormat method should be called first and then this method can be called again to reset the format.

Return: True if the streamer was successfully started, false otherwise

function stopAndResetFormat

bool stopAndResetFormat()

Stop streaming and reset the format. A call to this method will stop any output streams set up by the ISystemControllerInterface and reset the input format set by the.

See: setInputFormatAndStart method. The connection to the ISystemControllerInterface will be kept.

Return: True if the stream was successfully stopped and the the format reset, or if the format was not set before this method was called, false on error.

function outputData

bool outputData(
    const std::shared_ptr< AlignedData::DataFrame > & frame
)

Output data through this streamer.

Parameters:

  • frame The data frame to output, with video data in CUDA memory

See: setInputFormatAndStart method, or if the format has not been set by a call to that method.

Return: True if the frame was accepted (but not necessarily streamed, in case the output stream has not been set up by the ISystemControllerInterface), false in case the frame did not match the configuration made in the

function getVersion

static std::string getVersion()

Get application version.

Return: a string with the current version, e.g. “1.0.0”

function getBuildInfo

static std::string getBuildInfo()

Get application build information.

Return: a string with the current build information such as git hashes of all direct dependencies


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.20 - MediaStreamer::Configuration

MediaStreamer::Configuration

The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

#include <MediaStreamer.h>

Public Attributes

Name
AlignedData::PixelFormatmIncomingPixelFormat
uint32_tmWidth
uint32_tmHeight
uint32_tmFrameRateN
uint32_tmFrameRateD
uint32_tmAudioSampleRate
uint32_tmNumAudioChannels

Public Attributes Documentation

variable mIncomingPixelFormat

AlignedData::PixelFormat mIncomingPixelFormat = AlignedData::PixelFormat::kUnknown;

variable mWidth

uint32_t mWidth = 0;

variable mHeight

uint32_t mHeight = 0;

variable mFrameRateN

uint32_t mFrameRateN = 0;

variable mFrameRateD

uint32_t mFrameRateD = 0;

variable mAudioSampleRate

uint32_t mAudioSampleRate = 0;

variable mNumAudioChannels

uint32_t mNumAudioChannels = 0;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.21 - SystemControllerConnection

SystemControllerConnection

An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.

#include <SystemControllerConnection.h>

Inherits from ISystemControllerInterface

Public Classes

Name
structSettings
Settings for a SystemControllerConnection.

Public Types

Name
enum class uint32_tComponentType { kIngest, kMediaReceiver, kMediaStreamer, kControlDataReceiver, kControlDataSender}
Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions

Name
SystemControllerConnection()
~SystemControllerConnection() override
boolconfigure(const Settings & settings, const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr)
Configure this connection. This method should be called before calling.
virtual boolconnect() override
Connect to the server using the settings set with the.
virtual boolisConnected() const override
virtual std::stringgetUUID() const override
virtual ResponsesendRequest(const std::string & request, const nlohmann::json & parameters) override
Send a JSON object to the system controller server and awaits the response.
virtual booldisconnect() override
Disconnect from the server.
virtual boolregisterRequestCallback(const Callbacks & callbacks) override
Register callbacks to call when getting requests from the server or the server connection is lost.
virtual boolhasParent() const override
virtual std::shared_ptr< ISystemControllerInterface >getParentInterface() const override
SystemControllerConnection(SystemControllerConnection const & ) =delete
SystemControllerConnection(SystemControllerConnection && ) =delete
SystemControllerConnection &operator=(SystemControllerConnection const & ) =delete
SystemControllerConnection &operator=(SystemControllerConnection && ) =delete

Additional inherited members

Public Classes inherited from ISystemControllerInterface

Name
structCallbacks
A struct containing the callbacks that needs to be registered by the component using this interface.
structResponse
A response to a request, consists of a status code and an (optional) parameters JSON object.

Public Types inherited from ISystemControllerInterface

Name
enum class uint32_tStatusCode { SUCCESS, TOO_MANY_REQUESTS, UUID_ALREADY_REGISTERED, FORMAT_ERROR, ALREADY_CONFIGURED, OUT_OF_RESOURCES, NOT_FOUND, INTERNAL_ERROR, CONNECTION_FAILED, TIMEOUT_EXCEEDED, KEY_MISMATCH, UNKNOWN_REQUEST, MALFORMED_REQUEST, ALREADY_IN_USE}
Status codes used in JSON response messages for Websockets. These are starting at 3000 since the 1000 - 2000 range is taken up by the Spec: https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1.

Public Functions inherited from ISystemControllerInterface

Name
virtual~ISystemControllerInterface() =default
Virtual destructor.

Public Types Documentation

enum ComponentType

EnumeratorValueDescription
kIngest
kMediaReceiver
kMediaStreamer
kControlDataReceiver
kControlDataSender

Enumeration of component types the component using this SystemControllerConnection can tell the System Controller to be seen as.

Public Functions Documentation

function SystemControllerConnection

SystemControllerConnection()

function ~SystemControllerConnection

~SystemControllerConnection() override

function configure

bool configure(
    const Settings & settings,
    const std::shared_ptr< ISystemControllerInterface > & parentInterface =nullptr
)

Configure this connection. This method should be called before calling.

Parameters:

  • settings The settings to use when connecting to the server
  • parentInterface Optional parent interface that this interface is a child of. Setting this to nullptr means that this interface does not have a parent interface

See: connect.

Return: True if successfully configured, false otherwise

function connect

virtual bool connect() override

Connect to the server using the settings set with the.

See: configure method.

Return: True if connection was successful, false otherwise

Reimplements: ISystemControllerInterface::connect

function isConnected

virtual bool isConnected() const override

Return: True if this class is connected to the server, false otherwise

Reimplements: ISystemControllerInterface::isConnected

function getUUID

virtual std::string getUUID() const override

Return: The UUID of this interface to the System controller

Reimplements: ISystemControllerInterface::getUUID

function sendRequest

virtual Response sendRequest(
    const std::string & request,
    const nlohmann::json & parameters
) override

Send a JSON object to the system controller server and awaits the response.

Parameters:

  • request The name of the request command
  • parameters The parameters part of the JSON message

Return: The response from the controller

Note: The status code might be TIMEOUT in case no response was received within the timeframe

Reimplements: ISystemControllerInterface::sendRequest

function disconnect

virtual bool disconnect() override

Disconnect from the server.

Return: True if successfully disconnected, false on internal error

Reimplements: ISystemControllerInterface::disconnect

function registerRequestCallback

virtual bool registerRequestCallback(
    const Callbacks & callbacks
) override

Register callbacks to call when getting requests from the server or the server connection is lost.

Parameters:

  • callbacks The callbacks to set

Return: True if successfully registered, false if a callback is not set, or if already connected to the server

Reimplements: ISystemControllerInterface::registerRequestCallback

function hasParent

virtual bool hasParent() const override

Return: True if this component has a parent ISystemControllerInterface, false otherwise

Reimplements: ISystemControllerInterface::hasParent

function getParentInterface

virtual std::shared_ptr< ISystemControllerInterface > getParentInterface() const override

Return: A pointer to parent’s ISystemControllerInterface, if any. Returns nullptr in case there is no parent

Reimplements: ISystemControllerInterface::getParentInterface

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection const & 
) =delete

function SystemControllerConnection

SystemControllerConnection(
    SystemControllerConnection && 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection const & 
) =delete

function operator=

SystemControllerConnection & operator=(
    SystemControllerConnection && 
) =delete

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.22 - SystemControllerConnection::Settings

SystemControllerConnection::Settings

Settings for a SystemControllerConnection.

#include <SystemControllerConnection.h>

Public Attributes

Name
std::stringmSystemControllerIP
uint16_tmSystemControllerPort
std::stringmSystemControllerPostfix
std::stringmPSK
std::stringmUUID
ComponentTypemType
std::stringmName
std::stringmMyIP
std::chrono::millisecondsmConnectTimeout

Public Attributes Documentation

variable mSystemControllerIP

std::string mSystemControllerIP;

variable mSystemControllerPort

uint16_t mSystemControllerPort;

variable mSystemControllerPostfix

std::string mSystemControllerPostfix;

variable mPSK

std::string mPSK;

variable mUUID

std::string mUUID;

variable mType

ComponentType mType;

variable mName

std::string mName;

variable mMyIP

std::string mMyIP;

variable mConnectTimeout

std::chrono::milliseconds mConnectTimeout {
            3000};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.23 - TimeCommon::TAIStatus

TimeCommon::TAIStatus

Public Attributes

Name
StratumLevelmStratum
boolmHasLock

Public Attributes Documentation

variable mStratum

StratumLevel mStratum = StratumLevel::UnknownStratum;

variable mHasLock

bool mHasLock = false;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.1.24 - TimeCommon::TimeStructure

TimeCommon::TimeStructure

Public Attributes

Name
uint64_tt1
uint64_tt2
uint64_tt3
uint64_tt4
uint64_ttoken
uint64_tdummy1
uint64_tdummy2
uint64_tdummy3

Public Attributes Documentation

variable t1

uint64_t t1 = 0;

variable t2

uint64_t t2 = 0;

variable t3

uint64_t t3 = 0;

variable t4

uint64_t t4 = 0;

variable token

uint64_t token = 0;

variable dummy1

uint64_t dummy1 = 0;

variable dummy2

uint64_t dummy2 = 0;

variable dummy3

uint64_t dummy3 = 0;

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.1 - include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void setLevel(Level level);

} // namespace AclLog

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.2 - include/AlignedData.h

include/AlignedData.h

Namespaces

Name
AlignedData

Classes

Name
structAlignedData::DataFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <array>
#include <iostream>
#include <vector>

#include <cuda_runtime_api.h>

namespace AlignedData {

typedef std::array<float, 16> AudioSampleRow;

enum class CompressedVideoFormat {
    kAvc, // H264
    kHevc // H265
};

enum class PixelFormat {
    kUnknown,
    kNv12,    // 8 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
    kP016,    // 16 bit per component 4:2:0 YUV format. Y plane followed by interleaved UV plane.
    kUyvy,    // 8 bit per component 4:2:2 YUV format. U-Y-V-Y bytes interleaved.
    kRgba,    // 8 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory.
    kRgba64Le // 16 bit per component RGBA, ordered as R-G-B-A-R-G.. in memory with little endian words.
};

struct DataFrame {

    DataFrame() = default;

    ~DataFrame() {
        if (mVideoDataCudaPtr) {
            cudaError_t cudaStatus = cudaFree(mVideoDataCudaPtr);
            mVideoDataCudaPtr = nullptr;
            if (cudaStatus != cudaSuccess) {
                std::cout << "AlignedData::~DataFrame: Failed to release cuda memory: " << cudaStatus << std::endl;
            }
        }
    }

    DataFrame(DataFrame const&) = delete;            // Copy construct
    DataFrame& operator=(DataFrame const&) = delete; // Copy assign

    uint64_t mPTS;

    // Video
    uint8_t* mVideoDataCudaPtr = nullptr;
    PixelFormat mPixelFormat = PixelFormat::kUnknown;
    uint32_t mFrameRateN = 0;
    uint32_t mFrameRateD = 0;
    uint32_t mWidth = 0;
    uint32_t mHeight = 0;

    // Audio
    std::vector<AudioSampleRow> mAudioData;
    uint32_t mAudioChannels = 0;
    uint32_t mAudioSamplingFrequency = 0;
};

} // namespace AlignedData

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.3 - include/Base64.h

include/Base64.h

Functions

Name
std::stringencodeBase64(const uint8_t * data, size_t size)
Base64 encode some data.
std::stringencodeBase64(const std::vector< uint8_t > & data)
Base64 encode some data.
std::vector< uint8_t >decodeBase64(const std::string & data)
Decode some Base64 encoded data.

Functions Documentation

function encodeBase64

std::string encodeBase64(
    const uint8_t * data,
    size_t size
)

Base64 encode some data.

Parameters:

  • data Pointer to the data to encode with Base64
  • size The length of the data to encode with Base64

Return: The resulting Base64 encoded string

function encodeBase64

std::string encodeBase64(
    const std::vector< uint8_t > & data
)

Base64 encode some data.

Parameters:

  • data The data to encode with Base64

Return: The resulting Base64 encoded string

function decodeBase64

std::vector< uint8_t > decodeBase64(
    const std::string & data
)

Decode some Base64 encoded data.

Parameters:

  • data The Base64 encoded string to decode

Return: The resulting decoded data

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>
#include <vector>

std::string encodeBase64(const uint8_t* data, size_t size);

std::string encodeBase64(const std::vector<uint8_t>& data);

std::vector<uint8_t> decodeBase64(const std::string& data);

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.4 - include/ControlDataCommon.h

include/ControlDataCommon.h

Namespaces

Name
ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace ControlDataCommon {

enum class ConnectionType { CONNECTED, DISCONNECTED };

struct ConnectionStatus {

    ConnectionStatus() = default;

    ConnectionStatus(ConnectionType mConnectionType, const std::string& mIp, uint16_t mPort)
        : mConnectionType(mConnectionType)
        , mIP(mIp)
        , mPort(mPort) {
    }

    ConnectionType mConnectionType;
    std::string mIP;
    uint16_t mPort = 0;
};

struct Response {
    std::vector<uint8_t> mMessage; 
    uint64_t mRequestId = 0;       
    std::string mFromUUID;         
};

struct StatusMessage {
    std::vector<uint8_t> mMessage; 
    std::string mFromUUID;         
};

} // namespace ControlDataCommon

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.5 - include/ControlDataReceiver.h

include/ControlDataReceiver.h

Classes

Name
classControlDataReceiver
A ControlDataReceiver can receive messages from a sender or another ControlDataReceiver using a network connection. It can also connect to and forward the incoming request messages to other receivers. The connections to the sender and the other receivers are controlled by an ISystemControllerInterface instance. The ControlDataReceiver has a receiving or listening side, as well as a sending side. The listening side can listen to one single network port and have multiple ControlDataSenders and ControlDataReceivers connected to that port to receive requests from them. On the sending side of the ControlDataReceiver, it can be connected to the listening side of other ControlDataReceivers, used to forward all incoming messages to that receiver, as well as sending its own requests.
structControlDataReceiver::IncomingRequest
An incoming request to this ControlDataReceiver.
structControlDataReceiver::ReceiverResponse
A response message to a request.
structControlDataReceiver::Settings
Settings for a ControlDataReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataReceiver final {
public:
    struct IncomingRequest {
        std::vector<uint8_t> mMessage; 
        std::string mSenderUUID;    
        std::string mRequesterUUID; 
        uint64_t mRequestID = 0;    
        int64_t mSenderTimestampUs =
            0; 
        int64_t mDeliveryTimestampUs =
            0; 
    };

    struct ReceiverResponse {
        std::vector<uint8_t> mMessage; 
    };

    struct Settings {
        std::function<void(const IncomingRequest&)> mPreviewIncomingRequestCallback;
        std::function<ReceiverResponse(const IncomingRequest&)> mIncomingRequestCallback;

        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; 
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; 
    };

    ControlDataReceiver();

    ~ControlDataReceiver();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendStatusMessageToSender(const std::vector<uint8_t>& message);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataReceiver is not copyable
    ControlDataReceiver(ControlDataReceiver const&) = delete;            // Copy construct
    ControlDataReceiver& operator=(ControlDataReceiver const&) = delete; // Copy assign
private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.6 - include/ControlDataSender.h

include/ControlDataSender.h

Classes

Name
classControlDataSender
A ControlDataSender can send control signals to one or more receivers using a network connection. A single ControlDataSender can connect to multiple receivers, all identified by a UUID. The class is controlled using an ISystemControllerInterface; this interface is responsible for setting up connections to receivers. The ControlDataSender can send asynchronous requests to (all) the receivers and get a response back. Each response is identified with a request ID as well as the UUID of the responding receiver. The ControlDataSender can also receive status messages from the receivers.
structControlDataSender::Settings
Settings for a ControlDataSender.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include <ISystemControllerInterface.h>

#include "ControlDataCommon.h"

class ControlDataSender final {
public:
    struct Settings {
        std::function<void(const ControlDataCommon::ConnectionStatus&)>
            mConnectionStatusCallback; // Callback for receiver connection/disconnection events
        std::function<void(const ControlDataCommon::Response&)>
            mResponseCallback; // Callback for response messages from receivers
        std::function<void(const ControlDataCommon::StatusMessage&)>
            mStatusMessageCallback; // Callback for status messages from receivers
    };

    ControlDataSender();

    ~ControlDataSender();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool sendRequestToReceivers(const std::vector<uint8_t>& request, uint64_t& requestId);

    static std::string getVersion();

    static std::string getBuildInfo();

    // ControlDataSender is not copyable
    ControlDataSender(ControlDataSender const&) = delete;            // Copy construct
    ControlDataSender& operator=(ControlDataSender const&) = delete; // Copy assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.7 - include/IngestApplication.h

include/IngestApplication.h

Classes

Name
classIngestApplication
structIngestApplication::Settings

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include "ISystemControllerInterface.h"

class IngestApplication {
public:
    struct Settings {
        bool mDebugAudio = false; // Insert a 800 Hz sound at every turn to a new second according to TAI
        bool mDebugVideo = false; // Print the timestamp in the picture
    };

    IngestApplication();

    ~IngestApplication();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    bool stop();

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.8 - include/IngestUtils.h

include/IngestUtils.h

Namespaces

Name
IngestUtils

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

namespace IngestUtils {

bool isRunningWithRootPrivileges();

} // namespace IngestUtils

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.9 - include/ISystemControllerInterface.h

include/ISystemControllerInterface.h

Classes

Name
classISystemControllerInterface
An ISystemControllerInterface is the interface between a component and the System controller controlling the component. The interface allows for two-way communication between the component and the system controller by means of sending requests and getting responses. Classes deriving from the ISystemControllerInterface should provide the component side implementation of the communication with the system controller. This interface can be inherited and implemented by developers to connect to custom system controllers, or to directly control a component programmatically, without the need for connecting to a remote server. An ISystemControllerInterface can have a parent-child relationship with other interfaces, where the children are aware of which their parent interface is. This is useful for components that provides extra features for another component, but where the components are still to be considered as two separate entities with separate connections to the System controller.
structISystemControllerInterface::Response
A response to a request, consists of a status code and an (optional) parameters JSON object.
structISystemControllerInterface::Callbacks
A struct containing the callbacks that needs to be registered by the component using this interface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <functional>
#include <json.hpp>
#include <string>

class ISystemControllerInterface {
public:
    enum class StatusCode : uint32_t {
        SUCCESS = 3001, // Accept / Success

        TOO_MANY_REQUESTS = 3101, // Too many requests, try again later

        UUID_ALREADY_REGISTERED = 3201, // UUID is already registered
        FORMAT_ERROR = 3202,            // Message formatting error
        ALREADY_CONFIGURED = 3203,      // The requested thing to configure is already configured
        OUT_OF_RESOURCES = 3204,  // Out of resources (CPU/GPU close to max utilization, all available slots used, etc.)
        NOT_FOUND = 3205,         // The requested thing was not found
        INTERNAL_ERROR = 3206,    // Internal error when trying to serve the request
        CONNECTION_FAILED = 3207, // Connection failure
        TIMEOUT_EXCEEDED = 3208,  // Timeout exceeded
        KEY_MISMATCH = 3209,      // Key mismatch (might be a timeout, 3007 in the future)
        UNKNOWN_REQUEST = 3210,   // The name of the request was not known
        MALFORMED_REQUEST = 3211, // The request is not correctly formatted
        ALREADY_IN_USE = 3212,    // The requested resource is already in use

        // None, yet
    };

    struct Response {
        StatusCode mCode;
        nlohmann::json mParameters; // Can be empty
    };

    struct Callbacks {
        std::function<Response(const std::string&, const nlohmann::json&)>
            mRequestCallback; // Callback called when then controller has sent a request
        std::function<void(uint32_t, const std::string&, const std::error_code&)>
            mConnectionClosedCallback; // Callback called when the connection to the controller is closed
    };

    virtual ~ISystemControllerInterface() = default;

    virtual Response sendRequest(const std::string& request, const nlohmann::json& parameters) = 0;

    virtual bool registerRequestCallback(const Callbacks& callbacks) = 0;

    virtual bool connect() = 0;

    virtual bool disconnect() = 0;

    virtual bool isConnected() const = 0;

    virtual std::string getUUID() const = 0;

    virtual bool hasParent() const = 0;

    virtual std::shared_ptr<ISystemControllerInterface> getParentInterface() const = 0;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.10 - include/MediaReceiver.h

include/MediaReceiver.h

Classes

Name
classMediaReceiver
A MediaReceiver contains the logic for receiving, decoding and aligning incoming media sources from the Ingests. The aligned data is then delivered to the Rendering Engine which is also responsible for setting up the MediaReceiver. The MediaReceiver has a builtin multi view generator, which can create output streams containing composited subsets of the incoming video sources. This class is controlled using an ISystemControllerInterface provided when starting it.
structMediaReceiver::NewStreamParameters
A struct containing information on the format of an incoming stream.
structMediaReceiver::Settings
Settings for a MediaReceiver.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>
#include <utility>

#include "AlignedData.h"
#include "ISystemControllerInterface.h"

class MediaReceiver {
public:
    struct NewStreamParameters {
        uint32_t mVideoHeight = 0;     // Height of the video in pixels. 0 if the stream does not contain any video
        uint32_t mVideoWidth = 0;      // Width of the video in pixels. 0 if the stream does not contain any video
        uint32_t mFrameRateN = 0;      // Frame rate numerator
        uint32_t mFrameRateD = 1;      // Frame rate denominator
        uint32_t mAudioSampleRate = 0; // Sample rate of the audio in Hz. 0 if the stream does not contain any audio
    };

    struct Settings {
        AlignedData::PixelFormat mDecodedFormat = AlignedData::PixelFormat::kRgba64Le;

        std::function<std::function<void(const std::shared_ptr<AlignedData::DataFrame>&)>(
            uint32_t inputSlot,
            const std::string& streamID,
            const NewStreamParameters& newStreamParameters)>
            mNewConnectionCallback;

        std::function<void(uint32_t inputSlot)> mClosedConnectionCallback;

        bool mUseMultiViewer = false; 
        bool mDebugAudio = false;     
        bool mDebugVideo = false;     
        bool mDeliverOld = false;     
    };

    MediaReceiver();

    ~MediaReceiver();

    bool start(const std::shared_ptr<ISystemControllerInterface>& controllerInterface, const Settings& settings);

    void stop();

    std::function<void(const std::shared_ptr<AlignedData::DataFrame>&)>
    getCustomMultiViewSourceInput(uint32_t inputSlot, const std::string& name = "");

    MediaReceiver(MediaReceiver const&) = delete;            // Copy construct
    MediaReceiver(MediaReceiver&&) = delete;                 // Move construct
    MediaReceiver& operator=(MediaReceiver const&) = delete; // Copy assign
    MediaReceiver& operator=(MediaReceiver&&) = delete;      // Move assign

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.11 - include/MediaStreamer.h

include/MediaStreamer.h

Classes

Name
classMediaStreamer
MediaStreamer is a class that can take a single stream of uncompressed video and/or audio frames and encode and output it in some way to some interface. This interface can either be a stream to a network or writing down the data to a file on the hard drive. This class is configured from two interfaces. The input configuration (input video resolution, frame rate, pixel format, number of audio channels…) is made through this C++ API. The output stream is then started from the System Controller. Any of these configurations can be made first. The actual stream to output will start once the first call to.
structMediaStreamer::Configuration
The input configuration of the frames that will be sent to this MediaStreamer. The output stream configuration is made from the System controller via the ISystemControllerInterface.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <memory>

#include <ISystemControllerInterface.h>

#include "AlignedData.h"

class MediaStreamer final {
public:
    struct Configuration {
        // Video
        AlignedData::PixelFormat mIncomingPixelFormat = AlignedData::PixelFormat::kUnknown;
        uint32_t mWidth = 0;      // Width of the incoming video frames in pixels
        uint32_t mHeight = 0;     // Height of the incoming video frames in pixels
        uint32_t mFrameRateN = 0; // Frame rate numerator of the incoming video frames
        uint32_t mFrameRateD = 0; // Frame rate denominator of the incoming video frames

        // Audio
        uint32_t mAudioSampleRate = 0;  // Audio sample rate of the incoming frames in Hz
        uint32_t mNumAudioChannels = 0; // Number of audio channels in the incoming frames
    };

    MediaStreamer();

    ~MediaStreamer();

    bool configure(const std::shared_ptr<ISystemControllerInterface>& controllerInterface);

    bool setInputFormatAndStart(const Configuration& configuration);

    bool stopAndResetFormat();

    bool outputData(const std::shared_ptr<AlignedData::DataFrame>& frame);

    static std::string getVersion();

    static std::string getBuildInfo();

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.12 - include/SystemControllerConnection.h

include/SystemControllerConnection.h

Classes

Name
classSystemControllerConnection
An implementation of the ISystemControllerInterface for a System controller residing in a remote server. The connection to the server uses a Websocket.
structSystemControllerConnection::Settings
Settings for a SystemControllerConnection.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>

#include "ISystemControllerInterface.h"
#include "json.hpp"

class SystemControllerConnection final : public ISystemControllerInterface {
public:
    enum class ComponentType : uint32_t {
        kIngest,
        kMediaReceiver,
        kMediaStreamer,
        kControlDataReceiver,
        kControlDataSender,
    };

    struct Settings {
        std::string mSystemControllerIP;      // IP of the server
        uint16_t mSystemControllerPort;       // Port of the server
        std::string mSystemControllerPostfix; // Postfix of the address that the backend uses if any
        std::string mPSK;    // The pre shared key used for authorization with the system controller server
        std::string mUUID;   // The UUID of the device using this library
        ComponentType mType; // The component type of the component using this SystemControllerConnection
        std::string mName;   // The component name (optional)
        std::string mMyIP;   // The external IP of the system the component is running on. Will be sent to the system
                             // controller server in the announce message (optional)
        std::chrono::milliseconds mConnectTimeout{
            3000}; // Max time to wait on an announcement response from the server during connection
    };

    SystemControllerConnection();
    ~SystemControllerConnection() override;

    bool configure(const Settings& settings,
                   const std::shared_ptr<ISystemControllerInterface>& parentInterface = nullptr);

    bool connect() override;

    bool isConnected() const override;

    std::string getUUID() const override;

    Response sendRequest(const std::string& request, const nlohmann::json& parameters) override;

    bool disconnect() override;

    bool registerRequestCallback(const Callbacks& callbacks) override;

    bool hasParent() const override;

    std::shared_ptr<ISystemControllerInterface> getParentInterface() const override;

    SystemControllerConnection(SystemControllerConnection const&) = delete;            // Copy construct
    SystemControllerConnection(SystemControllerConnection&&) = delete;                 // Move construct
    SystemControllerConnection& operator=(SystemControllerConnection const&) = delete; // Copy assign
    SystemControllerConnection& operator=(SystemControllerConnection&&) = delete;      // Move assign

private:
    class Impl;
    std::unique_ptr<Impl> pImpl;
};

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.13 - include/TimeCommon.h

include/TimeCommon.h

Namespaces

Name
TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <chrono>
#include <cstdint>
#include <fstream>
#include <sstream>

namespace TimeCommon {

enum class StratumLevel {
    UnknownStratum,
    stratum0,
    stratum1,
    stratum2,
    stratum3,
    stratum4,
};

struct TAIStatus {
    StratumLevel mStratum = StratumLevel::UnknownStratum;
    bool mHasLock = false;
};

// Little endian
// Minimum size packet is 64 - bytes
struct TimeStructure {
    uint64_t t1 = 0;     // 8-bytes / Total 8-bytes  == Client time T1
    uint64_t t2 = 0;     // 8-bytes / Total 16-bytes == Server
    uint64_t t3 = 0;     // 8-bytes / Total 24-bytes
    uint64_t t4 = 0;     // 8-bytes / Total 32-bytes
    uint64_t token = 0;  // 8-bytes / Total 40-bytes == t1 ^ key
    uint64_t dummy1 = 0; // 8-bytes / Total 48-bytes == for future use
    uint64_t dummy2 = 0; // 8-bytes / Total 56-bytes == for future use
    uint64_t dummy3 = 0; // 8-bytes / Total 64-bytes == for future use
};

uint64_t getMonotonicClockMicro();

TimeCommon::TAIStatus getStatus();

int64_t getTAIMicro();
} // namespace TimeCommon

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.2.14 - include/UUIDUtils.h

include/UUIDUtils.h

Namespaces

Name
UUIDUtils
A namespace for UUID utility functions.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <string>

namespace UUIDUtils {

std::string generateRandomUUID();

bool isValidUUIDString(const std::string& uuid);

} // namespace UUIDUtils

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3 - Namespaces

Namespaces


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.1 - AclLog

AclLog

A namespace for logging utilities.

Types

Name
enum classLevel { kTrace, kDebug, kInfo, kWarning, kError, kCritical, kOff}
Log levels.

Functions

Name
voidinit(const std::string & name)
Initialize logging.
voidsetLevel(Level level)
Set global logging level.

Types Documentation

enum Level

EnumeratorValueDescription
kTrace
kDebug
kInfo
kWarning
kError
kCritical
kOff

Log levels.

Functions Documentation

function init

void init(
    const std::string & name
)

Initialize logging.

Parameters:

  • name The name of the component (used for log prefix and filename)

By default two sinks are created. The first sink writes messages to the console. The second sink attempts to create a log file in the path set by the environment variable ACL_LOG_PATH (’/tmp’ if unset). The name of the log file is ’name.log’. The default logging level is ‘info’ (‘debug’ for debug builds) and can be changed by setting the ACL_LOG_LEVEL environment variable.

function setLevel

void setLevel(
    Level level
)

Set global logging level.

Parameters:

  • level Logging level to set

Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.2 - AlignedData

AlignedData

Classes

Name
structAlignedData::DataFrame
A frame of aligned data that is passed to the rendering engine from the MediaReceiver. A DataFrame contains a time stamped frame of media, which might be video, audio and auxiliary data such as subtitles. A single DataFrame can contain one or multiple types of media. Which media types are included can be probed by nullptr-checking/size checking the data members. The struct has ownership of all data pointers included. The struct includes all logic for freeing the resources held by this struct and the user should therefore just make sure the struct itself is deallocated to ensure all resources are freed.

Types

Name
enum classCompressedVideoFormat { kAvc, kHevc}
enum classPixelFormat { kUnknown, kNv12, kP016, kUyvy, kRgba, kRgba64Le}
typedef std::array< float, 16 >AudioSampleRow
One audio sample in 16 channels.

Types Documentation

enum CompressedVideoFormat

EnumeratorValueDescription
kAvc
kHevc

enum PixelFormat

EnumeratorValueDescription
kUnknown
kNv12
kP016
kUyvy
kRgba
kRgba64Le

typedef AudioSampleRow

typedef std::array<float, 16> AlignedData::AudioSampleRow;

One audio sample in 16 channels.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.3 - ControlDataCommon

ControlDataCommon

Classes

Name
structControlDataCommon::ConnectionStatus
Connection status struct containing information about a connection event.
structControlDataCommon::Response
A response from a ControlDataReceiver to a request. The UUID tells which receiver the response is sent from.
structControlDataCommon::StatusMessage
A status message from a ControlDataReceiver. The UUID tells which receiver the message is sent from.

Types

Name
enum classConnectionType { CONNECTED, DISCONNECTED}
The connection types.

Types Documentation

enum ConnectionType

EnumeratorValueDescription
CONNECTED
DISCONNECTED

The connection types.


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.4 - IngestUtils

IngestUtils

Functions

Name
boolisRunningWithRootPrivileges()

Functions Documentation

function isRunningWithRootPrivileges

bool isRunningWithRootPrivileges()

Return: true if this application is executing with root privileges, false otherwise


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.5 - TimeCommon

TimeCommon

Classes

Name
structTimeCommon::TAIStatus
structTimeCommon::TimeStructure

Types

Name
enum classStratumLevel { UnknownStratum, stratum0, stratum1, stratum2, stratum3, stratum4}

Functions

Name
uint64_tgetMonotonicClockMicro()
Get current time since epoch.
TimeCommon::TAIStatusgetStatus()
Get TAI status.
int64_tgetTAIMicro()
Get current TAI time.

Types Documentation

enum StratumLevel

EnumeratorValueDescription
UnknownStratum
stratum0
stratum1
stratum2
stratum3
stratum4

Functions Documentation

function getMonotonicClockMicro

uint64_t getMonotonicClockMicro()

Get current time since epoch.

Return: Return current time since epoch in microseconds

function getStatus

TimeCommon::TAIStatus getStatus()

Get TAI status.

Return: Return the TAI status

function getTAIMicro

int64_t getTAIMicro()

Get current TAI time.

Return: Return current TAI time in microseconds


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.2.3.6 - UUIDUtils

UUIDUtils

A namespace for UUID utility functions.

Functions

Name
std::stringgenerateRandomUUID()
Generates a completely randomized UUID string.
boolisValidUUIDString(const std::string & uuid)
Checks if a string is a valid UUID string.

Functions Documentation

function generateRandomUUID

std::string generateRandomUUID()

Generates a completely randomized UUID string.

Return: A random generated UUID string

function isValidUUIDString

bool isValidUUIDString(
    const std::string & uuid
)

Checks if a string is a valid UUID string.

Parameters:

  • uuid The string to check

Return: True if uuid is a valid UUID string, otherwise false


Updated on 2022-06-22 at 16:53:25 +0200

1.6.6.3 - System controller config

Reference for the Agile Live System Controller configuration file

This page describes the configuration settings possible to set via the acl_sc_settings.json file.

Expanded Config nameConfig nameDescriptionDefault value
security.saltsaltSalt string for the generation of tokens and encryption keys“Some random string”
security.nnN is CPU/memory cost parameter, must be a power of 2, greater than 1. 165536
security.rrR constrain must satisfy R*P < 2^30. 18
security.ppP constrain must satisfy R*P < 2^30, if exceeded this an error will be returned 11
security.keylenkeylenThe length of the generated token32
logger.levellevelThe level that the logging will produce output, available in ascending order: debug, info, warn, errorinfo
site.portportPort on which the service is accessible8080
site.hosthostThe hostname that the service is accessiblelocalhost
response_timeoutresponse_timeoutHow long a request between the system controller and a component is allowed before it times out5000ms
cors.allowed_originsallowed_originsComma-separated list of origin addresses that is allowed["*"]
cors.allowed_methodsallowed_methodsComma-separated list of HTTP methods that the service accepts[“GET”, “POST”, “PUT”, “PATCH”, “DELETE”]
cors.allowed_headersallowed_headersComma-separated list of headers that are allowed["*"]
cors.exposed_headersexposed_headersComma-separated list of headers that are allowed for exposure[""]
cors.allow_credentialsallow_credentialsAllowing the xKHR to set credentials cookiesfalse
cors.max_agemax_ageHow long the preflight cache is stored before a new must be done again300
custom_headers.[N].keykeyThe key of the header, eg: nameNone
custom_headers.[N].valuevalueThe value to the key of the headerNone

1.7 - Troubleshooting

Troubleshooting problems with the production setup

If you have problems running the Agile Live components, check this troubleshooting guide for some common underlying reasons and proposed steps to diagnose and solve them. If your problem isn’t mentioned here or you have a different fix to contribute please contact Agile Content support about including it here.

Ingest

Intel encoder problems

While the Ingest supports both Intel and NVidia GPU-based encoding of video streams depending on available hardware and drivers, for full functionality (e.g. the ability to save thumbnail images) the Intel encoder must be functional. Use this guide to check what’s wrong with the current setup.

Intel processor too old

If the Intel processor is too old the hardware will not support all required GPU features. It is required that you have at least a 6th Generation (Skylake) processor. You can check the model name with (one listing per core):

cat /proc/cpuinfo | grep "model name"

The marketing name of the microarchitecture can be found with:

cat /sys/devices/cpu/caps/pmu_name

You can use this name and the model number to find out more details about your processor capabilities by consulting e.g. https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures

Intel GPU is not found

First, check that the Intel GPU is actually mapped to device handle /dev/dri/renderD128. A common problem when running systems with both Intel GPU and Nvidia GPU is that the Nvidia GPU will map to /dev/dri/renderD128 and the Intel GPU to /dev/dri/renderD129. The underlying libraries used by Agile Live is however hardcoded to use the Intel GPU via /dev/dri/renderD128. Check this by running:

sudo cat /sys/kernel/debug/dri/128/name

This should output a line starting with i915 if the Intel GPU is mapped to that device handle. In case the line starts with nvidia-drm, the Nvidia card is the primary GPU. Also check that the device renderD129 is present in that case:

sudo cat /sys/kernel/debug/dri/129/name

In case this returns a string starting with i915 the priority order of the GPUs are the wrong way around. In case there is no renderD129 device at all, the Intel GPU is likely disabled in BIOS/UEFI.

To swap the priority order of the devices and/or enable the Intel GPU, check your BIOS/UEFI settings and see if you can change your primary graphics adapter from “PCI Express” to “Onboard” (i.e. the Intel processor rather than a separate graphics card), or enable “Integrated Graphics” or similar (appearance of the setting varies depending on your motherboard manufacturer), and reboot.

Intel driver not active

In case the Intel GPU is mapped to device renderD128, check what display drivers are active on the system. An easy way to check is to install the pciutils package and check with the following command:

lspci -k | grep -EA3 'VGA|3D|Display'

You should see at least one VGA compatible controller listed, described as “Intel Corporation” followed by the model name of the integrated GPU. The listed kernel driver in use should be i915. If you have an NVidia card installed it may be selected as the primary and only active device.

You can also check that LibVA finds the Intel GPU by using the utility application vainfo. Install it using sudo apt install vainfo. When running the program, it should output something like this in case it successfully finds the Intel GPU:

$ vainfo
error: can't connect to X server!
libva info: VA-API version 1.13.0
libva info: User environment variable requested driver 'iHD'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_13
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.13 (libva 2.12.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 21.4.1 (be92568)
vainfo: Supported profile and entrypoints
      VAProfileNone                   :	VAEntrypointVideoProc
      VAProfileNone                   :	VAEntrypointStats
      VAProfileMPEG2Simple            :	VAEntrypointVLD
....
(long list of entrypoints)

Note that the X server error message is nothing to be worried about, as this just means you have no screen connected to the machine.

In case LibVA found the driver, but could not communicate with the Intel GPU because the Nvidia GPU is mapped to renderD128 as described in the previous section, the output will look something like this:

$ vainfo
error: can't connect to X server!
libva info: VA-API version 1.14.0
libva info: User environment variable requested driver 'iHD'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_14
DRM_IOCTL_I915_GEM_APERTURE failed: Invalid argument
Assuming 131072kB available aperture size.
May lead to reduced performance or incorrect rendering.
get chip id failed: -1 [22]
param: 4, val: 0
libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
libva info: va_openDriver() returns 18
vaInitialize failed with error code 18 (invalid parameter),exit

Here LibVA reported it finds the Intel iHD driver, but it cannot communicate with the GPU chip (as it is a Nvidia GPU mapped to renderD128, The integrated Intel GPU was disabled in BIOS/UEFI in this case). See the previous section on how to solve this.

In case vainfo does not report iHD as the User environment variable requested driver, or cannot find iHD_drv_video.so check that the following libva environment variables are set correctly (you should have them in /etc/environment):

LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
LIBVA_DRIVER_NAME=iHD

In case they are missing, double check your oneVPL installation in the next section.

oneVPL not installed or setup correctly for the current user

In case LibVA finds the driver and can communicate with the Intel GPU, check that oneVPL was correctly installed as per the instructions at https://docs.agilecontent.com/docs/acl/installation/#onevpl. You can see if you have version 2022.1.0 or later installed (latest should be a symlink to the used version) with:

ls -la /opt/intel/oneapi/vpl

In case the oneVPL library was installed by another user, the problem likely lies in the configuration for the current user. The user running the ingest binary must be in the groups video and render to be able to use the Intel encoder. Check what groups your user belongs to with:

groups

If video and render are not both in the listed groups, add them with:

sudo usermod -aG video,render ${USER}

Finally, a number of oneAPI environment variables must be set in the shell from which the Ingest application is started, otherwise it will not be able to find the runtime library (libvpl.so) when trying to use the encoder in the Ingest. This is typically done by adding the following line to your ~/.bashrc file:

source /opt/intel/oneapi/setvars.sh > /dev/null

1.8 - Credits

Third party libraries used in the system and their licenses

1.8.1 - C++ SDK Credits

Third party libraries used in Agile Live C++ SDK and their licenses

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryModifiedLinkedLicenseChecked At
avahinodynamicLGPL-2.12022-12-28
brotlinodynamicMIT2022-12-28
bsdnodynamicBSD-3-Clause2022-12-30
caironodynamicMPL-1.12022-05-16
cefnodynamicBSD-3-Clause2023-08-15
cpprestsdknodynamicMIT2022-02-23
cudanodynamicProprietary2022-02-23
drmnodynamicMIT2022-05-16
dbusnodynamicAFL-2.12023-01-10
ebur128nostaticMIT2023-08-15
efpnostaticMIT2022-02-23
efpbondnostaticMIT2022-02-23
expatnodynamicMIT2023-01-03
fdk-aacnodynamicProprietary2022-02-23
ffmpegnodynamicLGPL-2.12023-12-19
fmtlibnostaticMIT2022-12-29
fontconfignodynamicProprietary2023-01-03
freetypenodynamicFTL2022-05-23
gcryptnodynamicLGPL-2.12023-01-03
glibcnodynamicLGPL-2.12023-01-02
gpg-errornodynamicLGPL-2.12023-01-03
kissnetnostaticMIT2022-12-29
libcapnodynamicBSD-3-Clause2022-12-29
libgccnodynamicGCC RUNTIME LIBRARY EXCEPTION2023-01-11
libpngnodynamiclibpng2023-01-05
lz4nodynamicBSD-2-Clause2022-02-23
lzmanodynamicPublic Domain2023-01-03
mdnodynamicBSD-3-Clause2023-01-03
mpegtsnostaticMIT2022-02-23
ndinodynamicProprietary2022-02-23
nlohmann-jsonnostaticMIT2022-12-29
nppnodynamicProprietary2023-01-04
nvidia-codecyesdynamicProprietary2022-02-23
onevplnodynamicMIT2022-02-23
opensslnodynamicOpenSSL2022-02-23
opusnodynamicBSD-3-Clause2023-04-21
pixmannodynamicMIT2023-06-13
ristnostaticBSD-2-Clause2022-02-23
rist-cppnostaticBSD-2-Clause2022-02-23
spdlognostaticMIT2022-12-29
srtnostaticMPL-22022-02-23
srt-cppnostaticMIT2022-02-23
systemdnodynamicLGPL-2.12022-05-19
uuidnodynamicBSD-3-clause2023-01-12
vanodynamicMIT2022-04-28
zlibnodynamiczlib2022-12-30
zstandardnodynamicBSD-3-Clause2022-02-23

License Details

This section includes all the licenses/notices for each dependency verbatim

avahi


                  GNU LESSER GENERAL PUBLIC LICENSE
                       Version 2.1, February 1999

 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
	51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.

  When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard.  To achieve this, non-free programs must
be allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

                  GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.

  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at least
    three years, to give the same user the materials specified in
    Subsection 6a, above, for a charge no more than the cost of
    performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

                            NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

                     END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).

  To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.


    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James
  Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!

brotli

Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

bsd

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

cairo

                          MOZILLA PUBLIC LICENSE
                                Version 1.1

                              ---------------

1. Definitions.

     1.0.1. "Commercial Use" means distribution or otherwise making the
     Covered Code available to a third party.

     1.1. "Contributor" means each entity that creates or contributes to
     the creation of Modifications.

     1.2. "Contributor Version" means the combination of the Original
     Code, prior Modifications used by a Contributor, and the Modifications
     made by that particular Contributor.

     1.3. "Covered Code" means the Original Code or Modifications or the
     combination of the Original Code and Modifications, in each case
     including portions thereof.

     1.4. "Electronic Distribution Mechanism" means a mechanism generally
     accepted in the software development community for the electronic
     transfer of data.

     1.5. "Executable" means Covered Code in any form other than Source
     Code.

     1.6. "Initial Developer" means the individual or entity identified
     as the Initial Developer in the Source Code notice required by Exhibit
     A.

     1.7. "Larger Work" means a work which combines Covered Code or
     portions thereof with code not governed by the terms of this License.

     1.8. "License" means this document.

     1.8.1. "Licensable" means having the right to grant, to the maximum
     extent possible, whether at the time of the initial grant or
     subsequently acquired, any and all of the rights conveyed herein.

     1.9. "Modifications" means any addition to or deletion from the
     substance or structure of either the Original Code or any previous
     Modifications. When Covered Code is released as a series of files, a
     Modification is:
          A. Any addition to or deletion from the contents of a file
          containing Original Code or previous Modifications.

          B. Any new file that contains any part of the Original Code or
          previous Modifications.

     1.10. "Original Code" means Source Code of computer software code
     which is described in the Source Code notice required by Exhibit A as
     Original Code, and which, at the time of its release under this
     License is not already Covered Code governed by this License.

     1.10.1. "Patent Claims" means any patent claim(s), now owned or
     hereafter acquired, including without limitation,  method, process,
     and apparatus claims, in any patent Licensable by grantor.

     1.11. "Source Code" means the preferred form of the Covered Code for
     making modifications to it, including all modules it contains, plus
     any associated interface definition files, scripts used to control
     compilation and installation of an Executable, or source code
     differential comparisons against either the Original Code or another
     well known, available Covered Code of the Contributor's choice. The
     Source Code can be in a compressed or archival form, provided the
     appropriate decompression or de-archiving software is widely available
     for no charge.

     1.12. "You" (or "Your")  means an individual or a legal entity
     exercising rights under, and complying with all of the terms of, this
     License or a future version of this License issued under Section 6.1.
     For legal entities, "You" includes any entity which controls, is
     controlled by, or is under common control with You. For purposes of
     this definition, "control" means (a) the power, direct or indirect,
     to cause the direction or management of such entity, whether by
     contract or otherwise, or (b) ownership of more than fifty percent
     (50%) of the outstanding shares or beneficial ownership of such
     entity.

2. Source Code License.

     2.1. The Initial Developer Grant.
     The Initial Developer hereby grants You a world-wide, royalty-free,
     non-exclusive license, subject to third party intellectual property
     claims:
          (a)  under intellectual property rights (other than patent or
          trademark) Licensable by Initial Developer to use, reproduce,
          modify, display, perform, sublicense and distribute the Original
          Code (or portions thereof) with or without Modifications, and/or
          as part of a Larger Work; and

          (b) under Patents Claims infringed by the making, using or
          selling of Original Code, to make, have made, use, practice,
          sell, and offer for sale, and/or otherwise dispose of the
          Original Code (or portions thereof).

          (c) the licenses granted in this Section 2.1(a) and (b) are
          effective on the date Initial Developer first distributes
          Original Code under the terms of this License.

          (d) Notwithstanding Section 2.1(b) above, no patent license is
          granted: 1) for code that You delete from the Original Code; 2)
          separate from the Original Code;  or 3) for infringements caused
          by: i) the modification of the Original Code or ii) the
          combination of the Original Code with other software or devices.

     2.2. Contributor Grant.
     Subject to third party intellectual property claims, each Contributor
     hereby grants You a world-wide, royalty-free, non-exclusive license

          (a)  under intellectual property rights (other than patent or
          trademark) Licensable by Contributor, to use, reproduce, modify,
          display, perform, sublicense and distribute the Modifications
          created by such Contributor (or portions thereof) either on an
          unmodified basis, with other Modifications, as Covered Code
          and/or as part of a Larger Work; and

          (b) under Patent Claims infringed by the making, using, or
          selling of  Modifications made by that Contributor either alone
          and/or in combination with its Contributor Version (or portions
          of such combination), to make, use, sell, offer for sale, have
          made, and/or otherwise dispose of: 1) Modifications made by that
          Contributor (or portions thereof); and 2) the combination of
          Modifications made by that Contributor with its Contributor
          Version (or portions of such combination).

          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
          effective on the date Contributor first makes Commercial Use of
          the Covered Code.

          (d)    Notwithstanding Section 2.2(b) above, no patent license is
          granted: 1) for any code that Contributor has deleted from the
          Contributor Version; 2)  separate from the Contributor Version;
          3)  for infringements caused by: i) third party modifications of
          Contributor Version or ii)  the combination of Modifications made
          by that Contributor with other software  (except as part of the
          Contributor Version) or other devices; or 4) under Patent Claims
          infringed by Covered Code in the absence of Modifications made by
          that Contributor.

3. Distribution Obligations.

     3.1. Application of License.
     The Modifications which You create or to which You contribute are
     governed by the terms of this License, including without limitation
     Section 2.2. The Source Code version of Covered Code may be
     distributed only under the terms of this License or a future version
     of this License released under Section 6.1, and You must include a
     copy of this License with every copy of the Source Code You
     distribute. You may not offer or impose any terms on any Source Code
     version that alters or restricts the applicable version of this
     License or the recipients' rights hereunder. However, You may include
     an additional document offering the additional rights described in
     Section 3.5.

     3.2. Availability of Source Code.
     Any Modification which You create or to which You contribute must be
     made available in Source Code form under the terms of this License
     either on the same media as an Executable version or via an accepted
     Electronic Distribution Mechanism to anyone to whom you made an
     Executable version available; and if made available via Electronic
     Distribution Mechanism, must remain available for at least twelve (12)
     months after the date it initially became available, or at least six
     (6) months after a subsequent version of that particular Modification
     has been made available to such recipients. You are responsible for
     ensuring that the Source Code version remains available even if the
     Electronic Distribution Mechanism is maintained by a third party.

     3.3. Description of Modifications.
     You must cause all Covered Code to which You contribute to contain a
     file documenting the changes You made to create that Covered Code and
     the date of any change. You must include a prominent statement that
     the Modification is derived, directly or indirectly, from Original
     Code provided by the Initial Developer and including the name of the
     Initial Developer in (a) the Source Code, and (b) in any notice in an
     Executable version or related documentation in which You describe the
     origin or ownership of the Covered Code.

     3.4. Intellectual Property Matters
          (a) Third Party Claims.
          If Contributor has knowledge that a license under a third party's
          intellectual property rights is required to exercise the rights
          granted by such Contributor under Sections 2.1 or 2.2,
          Contributor must include a text file with the Source Code
          distribution titled "LEGAL" which describes the claim and the
          party making the claim in sufficient detail that a recipient will
          know whom to contact. If Contributor obtains such knowledge after
          the Modification is made available as described in Section 3.2,
          Contributor shall promptly modify the LEGAL file in all copies
          Contributor makes available thereafter and shall take other steps
          (such as notifying appropriate mailing lists or newsgroups)
          reasonably calculated to inform those who received the Covered
          Code that new knowledge has been obtained.

          (b) Contributor APIs.
          If Contributor's Modifications include an application programming
          interface and Contributor has knowledge of patent licenses which
          are reasonably necessary to implement that API, Contributor must
          also include this information in the LEGAL file.

               (c)    Representations.
          Contributor represents that, except as disclosed pursuant to
          Section 3.4(a) above, Contributor believes that Contributor's
          Modifications are Contributor's original creation(s) and/or
          Contributor has sufficient rights to grant the rights conveyed by
          this License.

     3.5. Required Notices.
     You must duplicate the notice in Exhibit A in each file of the Source
     Code.  If it is not possible to put such notice in a particular Source
     Code file due to its structure, then You must include such notice in a
     location (such as a relevant directory) where a user would be likely
     to look for such a notice.  If You created one or more Modification(s)
     You may add your name as a Contributor to the notice described in
     Exhibit A.  You must also duplicate this License in any documentation
     for the Source Code where You describe recipients' rights or ownership
     rights relating to Covered Code.  You may choose to offer, and to
     charge a fee for, warranty, support, indemnity or liability
     obligations to one or more recipients of Covered Code. However, You
     may do so only on Your own behalf, and not on behalf of the Initial
     Developer or any Contributor. You must make it absolutely clear than
     any such warranty, support, indemnity or liability obligation is
     offered by You alone, and You hereby agree to indemnify the Initial
     Developer and every Contributor for any liability incurred by the
     Initial Developer or such Contributor as a result of warranty,
     support, indemnity or liability terms You offer.

     3.6. Distribution of Executable Versions.
     You may distribute Covered Code in Executable form only if the
     requirements of Section 3.1-3.5 have been met for that Covered Code,
     and if You include a notice stating that the Source Code version of
     the Covered Code is available under the terms of this License,
     including a description of how and where You have fulfilled the
     obligations of Section 3.2. The notice must be conspicuously included
     in any notice in an Executable version, related documentation or
     collateral in which You describe recipients' rights relating to the
     Covered Code. You may distribute the Executable version of Covered
     Code or ownership rights under a license of Your choice, which may
     contain terms different from this License, provided that You are in
     compliance with the terms of this License and that the license for the
     Executable version does not attempt to limit or alter the recipient's
     rights in the Source Code version from the rights set forth in this
     License. If You distribute the Executable version under a different
     license You must make it absolutely clear that any terms which differ
     from this License are offered by You alone, not by the Initial
     Developer or any Contributor. You hereby agree to indemnify the
     Initial Developer and every Contributor for any liability incurred by
     the Initial Developer or such Contributor as a result of any such
     terms You offer.

     3.7. Larger Works.
     You may create a Larger Work by combining Covered Code with other code
     not governed by the terms of this License and distribute the Larger
     Work as a single product. In such a case, You must make sure the
     requirements of this License are fulfilled for the Covered Code.

4. Inability to Comply Due to Statute or Regulation.

     If it is impossible for You to comply with any of the terms of this
     License with respect to some or all of the Covered Code due to
     statute, judicial order, or regulation then You must: (a) comply with
     the terms of this License to the maximum extent possible; and (b)
     describe the limitations and the code they affect. Such description
     must be included in the LEGAL file described in Section 3.4 and must
     be included with all distributions of the Source Code. Except to the
     extent prohibited by statute or regulation, such description must be
     sufficiently detailed for a recipient of ordinary skill to be able to
     understand it.

5. Application of this License.

     This License applies to code to which the Initial Developer has
     attached the notice in Exhibit A and to related Covered Code.

6. Versions of the License.

     6.1. New Versions.
     Netscape Communications Corporation ("Netscape") may publish revised
     and/or new versions of the License from time to time. Each version
     will be given a distinguishing version number.

     6.2. Effect of New Versions.
     Once Covered Code has been published under a particular version of the
     License, You may always continue to use it under the terms of that
     version. You may also choose to use such Covered Code under the terms
     of any subsequent version of the License published by Netscape. No one
     other than Netscape has the right to modify the terms applicable to
     Covered Code created under this License.

     6.3. Derivative Works.
     If You create or use a modified version of this License (which you may
     only do in order to apply it to code which is not already Covered Code
     governed by this License), You must (a) rename Your license so that
     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
     "MPL", "NPL" or any confusingly similar phrase do not appear in your
     license (except to note that your license differs from this License)
     and (b) otherwise make it clear that Your version of the license
     contains terms which differ from the Mozilla Public License and
     Netscape Public License. (Filling in the name of the Initial
     Developer, Original Code or Contributor in the notice described in
     Exhibit A shall not of themselves be deemed to be modifications of
     this License.)

7. DISCLAIMER OF WARRANTY.

     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.

8. TERMINATION.

     8.1.  This License and the rights granted hereunder will terminate
     automatically if You fail to comply with terms herein and fail to cure
     such breach within 30 days of becoming aware of the breach. All
     sublicenses to the Covered Code which are properly granted shall
     survive any termination of this License. Provisions which, by their
     nature, must remain in effect beyond the termination of this License
     shall survive.

     8.2.  If You initiate litigation by asserting a patent infringement
     claim (excluding declatory judgment actions) against Initial Developer
     or a Contributor (the Initial Developer or Contributor against whom
     You file such action is referred to as "Participant")  alleging that:

     (a)  such Participant's Contributor Version directly or indirectly
     infringes any patent, then any and all rights granted by such
     Participant to You under Sections 2.1 and/or 2.2 of this License
     shall, upon 60 days notice from Participant terminate prospectively,
     unless if within 60 days after receipt of notice You either: (i)
     agree in writing to pay Participant a mutually agreeable reasonable
     royalty for Your past and future use of Modifications made by such
     Participant, or (ii) withdraw Your litigation claim with respect to
     the Contributor Version against such Participant.  If within 60 days
     of notice, a reasonable royalty and payment arrangement are not
     mutually agreed upon in writing by the parties or the litigation claim
     is not withdrawn, the rights granted by Participant to You under
     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
     the 60 day notice period specified above.

     (b)  any software, hardware, or device, other than such Participant's
     Contributor Version, directly or indirectly infringes any patent, then
     any rights granted to You by such Participant under Sections 2.1(b)
     and 2.2(b) are revoked effective as of the date You first made, used,
     sold, distributed, or had made, Modifications made by that
     Participant.

     8.3.  If You assert a patent infringement claim against Participant
     alleging that such Participant's Contributor Version directly or
     indirectly infringes any patent where such claim is resolved (such as
     by license or settlement) prior to the initiation of patent
     infringement litigation, then the reasonable value of the licenses
     granted by such Participant under Sections 2.1 or 2.2 shall be taken
     into account in determining the amount or value of any payment or
     license.

     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
     all end user license agreements (excluding distributors and resellers)
     which have been validly granted by You or any distributor hereunder
     prior to termination shall survive termination.

9. LIMITATION OF LIABILITY.

     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.

10. U.S. GOVERNMENT END USERS.

     The Covered Code is a "commercial item," as that term is defined in
     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
     software" and "commercial computer software documentation," as such
     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
     all U.S. Government End Users acquire Covered Code with only those
     rights set forth herein.

11. MISCELLANEOUS.

     This License represents the complete agreement concerning subject
     matter hereof. If any provision of this License is held to be
     unenforceable, such provision shall be reformed only to the extent
     necessary to make it enforceable. This License shall be governed by
     California law provisions (except to the extent applicable law, if
     any, provides otherwise), excluding its conflict-of-law provisions.
     With respect to disputes in which at least one party is a citizen of,
     or an entity chartered or registered to do business in the United
     States of America, any litigation relating to this License shall be
     subject to the jurisdiction of the Federal Courts of the Northern
     District of California, with venue lying in Santa Clara County,
     California, with the losing party responsible for costs, including
     without limitation, court costs and reasonable attorneys' fees and
     expenses. The application of the United Nations Convention on
     Contracts for the International Sale of Goods is expressly excluded.
     Any law or regulation which provides that the language of a contract
     shall be construed against the drafter shall not apply to this
     License.

12. RESPONSIBILITY FOR CLAIMS.

     As between Initial Developer and the Contributors, each party is
     responsible for claims and damages arising, directly or indirectly,
     out of its utilization of rights under this License and You agree to
     work with Initial Developer and Contributors to distribute such
     responsibility on an equitable basis. Nothing herein is intended or
     shall be deemed to constitute any admission of liability.

13. MULTIPLE-LICENSED CODE.

     Initial Developer may designate portions of the Covered Code as
     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
     Developer permits you to utilize portions of the Covered Code under
     Your choice of the NPL or the alternative licenses, if any, specified
     by the Initial Developer in the file described in Exhibit A.

EXHIBIT A -Mozilla Public License.

     ``The contents of this file are subject to the Mozilla Public License
     Version 1.1 (the "License"); you may not use this file except in
     compliance with the License. You may obtain a copy of the License at
     http://www.mozilla.org/MPL/

     Software distributed under the License is distributed on an "AS IS"
     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
     License for the specific language governing rights and limitations
     under the License.

     The Original Code is ______________________________________.

     The Initial Developer of the Original Code is ________________________.
     Portions created by ______________________ are Copyright (C) ______
     _______________________. All Rights Reserved.

     Contributor(s): ______________________________________.

     Alternatively, the contents of this file may be used under the terms
     of the _____ license (the  "[___] License"), in which case the
     provisions of [______] License are applicable instead of those
     above.  If you wish to allow use of your version of this file only
     under the terms of the [____] License and not to allow others to use
     your version of this file under the MPL, indicate your decision by
     deleting  the provisions above and replace  them with the notice and
     other provisions required by the [___] License.  If you do not delete
     the provisions above, a recipient may use your version of this file
     under either the MPL or the [___] License."

     [NOTE: The text of this Exhibit A may differ slightly from the text of
     the notices in the Source Code files of the Original Code. You should
     use the text of this Exhibit A rather than the text found in the
     Original Code Source Code for Your Modifications.]

cef

// Copyright (c) 2008-2020 Marshall A. Greenblatt. Portions Copyright (c)
// 2006-2009 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

cpprestsdk

C++ REST SDK

The MIT License (MIT)

Copyright (c) Microsoft Corporation

All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

cuda

End User License Agreements (EULA)

DR-06739-001_v01_v11.7

|

May 2022

Preface

The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain
license terms and conditions that govern the use of NVIDIA software. By accepting this
agreement, you agree to comply with all the terms and conditions applicable to the product(s)
included herein.

NVIDIA Driver
Description
This package contains the operating system driver and fundamental system software
components for NVIDIA GPUs.

NVIDIA CUDA Toolkit
Description
The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging
and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and
math libraries, and documentation including programming guides, user manuals, and API
references.

Default Install Location of CUDA Toolkit
Windows platform:
%ProgramFiles%\NVIDIA GPU Computing Toolkit\CUDA\v#.#

Linux platform:
/usr/local/cuda-#.#

Mac platform:
/Developer/NVIDIA/CUDA-#.#

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | ii

Preface

NVIDIA CUDA Samples
Description
CUDA Samples are now located in https://github.com/nvidia/cuda-samples, which includes
instructions for obtaining, building, and running the samples. They are no longer included in
the CUDA toolkit.

NVIDIA Nsight Visual Studio Edition
(Windows only)
Description
NVIDIA Nsight Development Platform, Visual Studio Edition is a development environment
integrated into Microsoft Visual Studio that provides tools for debugging, profiling, analyzing
and optimizing your GPU computing and graphics applications.

Default Install Location of Nsight Visual Studio Edition
Windows platform:
%ProgramFiles(x86)%\NVIDIA Corporation\Nsight Visual Studio Edition #.#

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | iii

Preface

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | iv

Chapter 1.

License Agreement
for NVIDIA Software
Development Kits

Important Notice—Read before downloading, installing, copying or using the
licensed software:
This license agreement, including exhibits attached ("Agreement”) is a legal agreement
between you and NVIDIA Corporation ("NVIDIA") and governs your use of a NVIDIA software
development kit (“SDK”).
Each SDK has its own set of software and materials, but here is a description of the types
of items that may be included in a SDK: source code, header files, APIs, data sets and
assets (examples include images, textures, models, scenes, videos, native API input/output
files), binary software, sample code, libraries, utility programs, programming code and
documentation.
This Agreement can be accepted only by an adult of legal age of majority in the country in
which the SDK is used.
If you are entering into this Agreement on behalf of a company or other legal entity, you
represent that you have the legal authority to bind the entity to this Agreement, in which case
“you” will mean the entity you represent.
If you don’t have the required age or authority to accept this Agreement, or if you don’t accept
all the terms and conditions of this Agreement, do not download, install or use the SDK.
You agree to use the SDK only for purposes that are permitted by (a) this Agreement, and (b)
any applicable law, regulation or generally accepted practices or guidelines in the relevant
jurisdictions.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 1

License Agreement for NVIDIA Software Development Kits

1.1.

License

1.1.1.

License Grant

Subject to the terms of this Agreement, NVIDIA hereby grants you a non-exclusive, nontransferable license, without the right to sublicense (except as expressly provided in this
Agreement) to:
1. Install and use the SDK,
2. Modify and create derivative works of sample source code delivered in the SDK, and
3. Distribute those portions of the SDK that are identified in this Agreement as distributable,
as incorporated in object code format into a software application that meets the
distribution requirements indicated in this Agreement.

1.1.2.

Distribution Requirements

These are the distribution requirements for you to exercise the distribution grant:
1. Your application must have material additional functionality, beyond the included portions
of the SDK.
2. The distributable portions of the SDK shall only be accessed by your application.
3. The following notice shall be included in modifications and derivative works of sample
source code distributed: “This software contains source code provided by NVIDIA
Corporation.”
4. Unless a developer tool is identified in this Agreement as distributable, it is delivered for
your internal use only.
5. The terms under which you distribute your application must be consistent with the terms
of this Agreement, including (without limitation) terms relating to the license grant and
license restrictions and protection of NVIDIA’s intellectual property rights. Additionally, you
agree that you will protect the privacy, security and legal rights of your application users.
6. You agree to notify NVIDIA in writing of any known or suspected distribution or use of the
SDK not in compliance with the requirements of this Agreement, and to enforce the terms
of your agreements with respect to distributed SDK.

1.1.3.

Authorized Users

You may allow employees and contractors of your entity or of your subsidiary(ies) to access
and use the SDK from your secure network to perform work on your behalf.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 2

License Agreement for NVIDIA Software Development Kits

If you are an academic institution you may allow users enrolled or employed by the academic
institution to access and use the SDK from your secure network.
You are responsible for the compliance with the terms of this Agreement by your authorized
users. If you become aware that your authorized users didn’t follow the terms of this
Agreement, you agree to take reasonable steps to resolve the non-compliance and prevent
new occurrences.

1.1.4.

Pre-Release SDK

The SDK versions identified as alpha, beta, preview or otherwise as pre-release, may not
be fully functional, may contain errors or design flaws, and may have reduced or different
security, privacy, accessibility, availability, and reliability standards relative to commercial
versions of NVIDIA software and materials. Use of a pre-release SDK may result in unexpected
results, loss of data, project delays or other unpredictable damage or loss.
You may use a pre-release SDK at your own risk, understanding that pre-release SDKs are not
intended for use in production or business-critical systems.
NVIDIA may choose not to make available a commercial version of any pre-release SDK.
NVIDIA may also choose to abandon development and terminate the availability of a prerelease SDK at any time without liability.

1.1.5.

Updates

NVIDIA may, at its option, make available patches, workarounds or other updates to this SDK.
Unless the updates are provided with their separate governing terms, they are deemed part of
the SDK licensed to you as provided in this Agreement. You agree that the form and content of
the SDK that NVIDIA provides may change without prior notice to you. While NVIDIA generally
maintains compatibility between versions, NVIDIA may in some cases make changes that
introduce incompatibilities in future versions of the SDK.

1.1.6.

Components Under Other Licenses

The SDK may come bundled with, or otherwise include or be distributed with, NVIDIA or thirdparty components with separate legal notices or terms as may be described in proprietary
notices accompanying the SDK. If and to the extent there is a conflict between the terms
in this Agreement and the license terms associated with the component, the license terms
associated with the components control only to the extent necessary to resolve the conflict.
Subject to the other terms of this Agreement, you may use the SDK to develop and test
applications released under Open Source Initiative (OSI) approved open source software
licenses.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 3

License Agreement for NVIDIA Software Development Kits

1.1.7.

Reservation of Rights

NVIDIA reserves all rights, title, and interest in and to the SDK, not expressly granted to you
under this Agreement.

1.2.

Limitations

The following license limitations apply to your use of the SDK:
1. You may not reverse engineer, decompile or disassemble, or remove copyright or other
proprietary notices from any portion of the SDK or copies of the SDK.
2. Except as expressly provided in this Agreement, you may not copy, sell, rent, sublicense,
transfer, distribute, modify, or create derivative works of any portion of the SDK. For
clarity, you may not distribute or sublicense the SDK as a stand-alone product.
3. Unless you have an agreement with NVIDIA for this purpose, you may not indicate that an
application created with the SDK is sponsored or endorsed by NVIDIA.
4. You may not bypass, disable, or circumvent any encryption, security, digital rights
management or authentication mechanism in the SDK.
5. You may not use the SDK in any manner that would cause it to become subject to an
open source software license. As examples, licenses that require as a condition of use,
modification, and/or distribution that the SDK be:
a). Disclosed or distributed in source code form;
b). Licensed for the purpose of making derivative works; or
c). Redistributable at no charge.
6. You acknowledge that the SDK as delivered is not tested or certified by NVIDIA for use in
connection with the design, construction, maintenance, and/or operation of any system
where the use or failure of such system could result in a situation that threatens the
safety of human life or results in catastrophic damages (each, a "Critical Application").
Examples of Critical Applications include use in avionics, navigation, autonomous vehicle
applications, ai solutions for automotive products, military, medical, life support or other
life critical applications. NVIDIA shall not be liable to you or any third party, in whole or
in part, for any claims or damages arising from such uses. You are solely responsible for
ensuring that any product or service developed with the SDK as a whole includes sufficient
features to comply with all applicable legal and regulatory standards and requirements.
7. You agree to defend, indemnify and hold harmless NVIDIA and its affiliates, and their
respective employees, contractors, agents, officers and directors, from and against
any and all claims, damages, obligations, losses, liabilities, costs or debt, fines,
restitutions and expenses (including but not limited to attorney’s fees and costs incident to

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 4

License Agreement for NVIDIA Software Development Kits

establishing the right of indemnification) arising out of or related to products or services
that use the SDK in or for Critical Applications, and for use of the SDK outside of the scope
of this Agreement or not in compliance with its terms.
8. You may not reverse engineer, decompile or disassemble any portion of the output
generated using SDK elements for the purpose of translating such output artifacts to
target a non-NVIDIA platform.

1.3.

Ownership

1. NVIDIA or its licensors hold all rights, title and interest in and to the SDK and its
modifications and derivative works, including their respective intellectual property rights,
subject to your rights under Section 1.3.2. This SDK may include software and materials
from NVIDIA’s licensors, and these licensors are intended third party beneficiaries that
may enforce this Agreement with respect to their intellectual property rights.
2. You hold all rights, title and interest in and to your applications and your derivative works
of the sample source code delivered in the SDK, including their respective intellectual
property rights, subject to NVIDIA’s rights under Section 1.3.1.
3. You may, but don’t have to, provide to NVIDIA suggestions, feature requests or other
feedback regarding the SDK, including possible enhancements or modifications to the
SDK. For any feedback that you voluntarily provide, you hereby grant NVIDIA and its
affiliates a perpetual, non-exclusive, worldwide, irrevocable license to use, reproduce,
modify, license, sublicense (through multiple tiers of sublicensees), and distribute (through
multiple tiers of distributors) it without the payment of any royalties or fees to you. NVIDIA
will use feedback at its choice. NVIDIA is constantly looking for ways to improve its
products, so you may send feedback to NVIDIA through the developer portal at https://
developer.nvidia.com.

1.4.

No Warranties

THE SDK IS PROVIDED BY NVIDIA “AS IS” AND “WITH ALL FAULTS.” TO THE MAXIMUM
EXTENT PERMITTED BY LAW, NVIDIA AND ITS AFFILIATES EXPRESSLY DISCLAIM ALL
WARRANTIES OF ANY KIND OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY,
INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, OR THE ABSENCE OF ANY DEFECTS
THEREIN, WHETHER LATENT OR PATENT. NO WARRANTY IS MADE ON THE BASIS OF TRADE
USAGE, COURSE OF DEALING OR COURSE OF TRADE.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 5

License Agreement for NVIDIA Software Development Kits

1.5.

Limitation of Liability

TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND ITS AFFILIATES SHALL NOT
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR
ANY LOST PROFITS, LOSS OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS
OF PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION WITH THIS
AGREEMENT OR THE USE OR PERFORMANCE OF THE SDK, WHETHER SUCH LIABILITY
ARISES FROM ANY CLAIM BASED UPON BREACH OF CONTRACT, BREACH OF WARRANTY,
TORT (INCLUDING NEGLIGENCE), PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR
THEORY OF LIABILITY. IN NO EVENT WILL NVIDIA’S AND ITS AFFILIATES TOTAL CUMULATIVE
LIABILITY UNDER OR ARISING OUT OF THIS AGREEMENT EXCEED US$10.00. THE NATURE
OF THE LIABILITY OR THE NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR EXTEND
THIS LIMIT.
These exclusions and limitations of liability shall apply regardless if NVIDIA or its affiliates
have been advised of the possibility of such damages, and regardless of whether a remedy
fails its essential purpose. These exclusions and limitations of liability form an essential
basis of the bargain between the parties, and, absent any of these exclusions or limitations of
liability, the provisions of this Agreement, including, without limitation, the economic terms,
would be substantially different.

1.6.

Termination

1. This Agreement will continue to apply until terminated by either you or NVIDIA as
described below.
2. If you want to terminate this Agreement, you may do so by stopping to use the SDK.
3. NVIDIA may, at any time, terminate this Agreement if:
a). (i) you fail to comply with any term of this Agreement and the non-compliance is not
fixed within thirty (30) days following notice from NVIDIA (or immediately if you violate
NVIDIA’s intellectual property rights);
b). (ii) you commence or participate in any legal proceeding against NVIDIA with respect to
the SDK; or
c). (iii) NVIDIA decides to no longer provide the SDK in a country or, in NVIDIA’s sole
discretion, the continued use of it is no longer commercially viable.
4. Upon any termination of this Agreement, you agree to promptly discontinue use of the SDK
and destroy all copies in your possession or control. Your prior distributions in accordance
with this Agreement are not affected by the termination of this Agreement. Upon written
request, you will certify in writing that you have complied with your commitments under

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 6

License Agreement for NVIDIA Software Development Kits

this section. Upon any termination of this Agreement all provisions survive except for the
license grant provisions.

1.7.

General

If you wish to assign this Agreement or your rights and obligations, including by merger,
consolidation, dissolution or operation of law, contact NVIDIA to ask for permission. Any
attempted assignment not approved by NVIDIA in writing shall be void and of no effect. NVIDIA
may assign, delegate or transfer this Agreement and its rights and obligations, and if to a nonaffiliate you will be notified.
You agree to cooperate with NVIDIA and provide reasonably requested information to verify
your compliance with this Agreement.
This Agreement will be governed in all respects by the laws of the United States and of the
State of Delaware as those laws are applied to contracts entered into and performed entirely
within Delaware by Delaware residents, without regard to the conflicts of laws principles.
The United Nations Convention on Contracts for the International Sale of Goods is specifically
disclaimed. You agree to all terms of this Agreement in the English language.
The state or federal courts residing in Santa Clara County, California shall have exclusive
jurisdiction over any dispute or claim arising out of this Agreement. Notwithstanding this, you
agree that NVIDIA shall still be allowed to apply for injunctive remedies or an equivalent type
of urgent legal relief in any jurisdiction.
If any court of competent jurisdiction determines that any provision of this Agreement is
illegal, invalid or unenforceable, such provision will be construed as limited to the extent
necessary to be consistent with and fully enforceable under the law and the remaining
provisions will remain in full force and effect. Unless otherwise specified, remedies are
cumulative.
Each party acknowledges and agrees that the other is an independent contractor in the
performance of this Agreement.
The SDK has been developed entirely at private expense and is “commercial items” consisting
of “commercial computer software” and “commercial computer software documentation”
provided with RESTRICTED RIGHTS. Use, duplication or disclosure by the U.S. Government
or a U.S. Government subcontractor is subject to the restrictions in this Agreement pursuant
to DFARS 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of the Commercial
Computer Software - Restricted Rights clause at FAR 52.227-19, as applicable. Contractor/
manufacturer is NVIDIA, 2788 San Tomas Expressway, Santa Clara, CA 95051.
The SDK is subject to United States export laws and regulations. You agree that you will not
ship, transfer or export the SDK into any country, or use the SDK in any manner, prohibited
by the United States Bureau of Industry and Security or economic sanctions regulations
administered by the U.S. Department of Treasury’s Office of Foreign Assets Control (OFAC),
or any applicable export laws, restrictions or regulations. These laws include restrictions on

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 7

License Agreement for NVIDIA Software Development Kits

destinations, end users and end use. By accepting this Agreement, you confirm that you are
not a resident or citizen of any country currently embargoed by the U.S. and that you are not
otherwise prohibited from receiving the SDK.
Any notice delivered by NVIDIA to you under this Agreement will be delivered via mail, email
or fax. You agree that any notices that NVIDIA sends you electronically will satisfy any legal
communication requirements. Please direct your legal notices or other correspondence to
NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, California 95051, United States
of America, Attention: Legal Department.
This Agreement and any exhibits incorporated into this Agreement constitute the entire
agreement of the parties with respect to the subject matter of this Agreement and supersede
all prior negotiations or documentation exchanged between the parties relating to this SDK
license. Any additional and/or conflicting terms on documents issued by you are null, void,
and invalid. Any amendment or waiver under this Agreement shall be in writing and signed by
representatives of both parties.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 8

Chapter 2.

CUDA Toolkit Supplement
to Software License
Agreement for NVIDIA
Software Development Kits

The terms in this supplement govern your use of the NVIDIA CUDA Toolkit SDK under the
terms of your license agreement (“Agreement”) as modified by this supplement. Capitalized
terms used but not defined below have the meaning assigned to them in the Agreement.
This supplement is an exhibit to the Agreement and is incorporated as an integral part of the
Agreement. In the event of conflict between the terms in this supplement and the terms in the
Agreement, the terms in this supplement govern.

2.1.

License Scope

The SDK is licensed for you to develop applications only for use in systems with NVIDIA GPUs.

2.2.

Distribution

The portions of the SDK that are distributable under the Agreement are listed in Attachment A.

2.3.

Operating Systems

Those portions of the SDK designed exclusively for use on the Linux or FreeBSD operating
systems, or other operating systems derived from the source code to these operating systems,
may be copied and redistributed for use in accordance with this Agreement, provided that the
object code files are not modified in any way (except for unzipping of compressed files).

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 9

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

2.4.

Audio and Video Encoders and
Decoders

You acknowledge and agree that it is your sole responsibility to obtain any additional thirdparty licenses required to make, have made, use, have used, sell, import, and offer for sale
your products or services that include or incorporate any third-party software and content
relating to audio and/or video encoders and decoders from, including but not limited to,
Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A., MPEG-LA, and Coding Technologies. NVIDIA
does not grant to you under this Agreement any necessary patent or other rights with respect
to any audio and/or video encoders and decoders.

2.5.

Licensing

If the distribution terms in this Agreement are not suitable for your organization, or for any
questions regarding this Agreement, please contact NVIDIA at nvidia-compute-licensequestions@nvidia.com.

2.6.

Attachment A

The following CUDA Toolkit files may be distributed with Licensee Applications developed
by you, including certain variations of these files that have version number or architecture
specific information embedded in the file name - as an example only, for release version 9.0 of
the 64-bit Windows software, the file cudart64_90.dll is redistributable.
Component

CUDA Runtime

Windows

cudart.dll, cudart_static.lib, cudadevrt.lib

Mac OSX

libcudart.dylib, libcudart_static.a, libcudadevrt.a

Linux

libcudart.so, libcudart_static.a, libcudadevrt.a

Android

libcudart.so, libcudart_static.a, libcudadevrt.a

Component

CUDA FFT Library

Windows

cufft.dll, cufftw.dll, cufft.lib, cufftw.lib

Mac OSX

libcufft.dylib, libcufft_static.a, libcufftw.dylib,
libcufftw_static.a

Linux

libcufft.so, libcufft_static.a, libcufftw.so,
libcufftw_static.a

Android

libcufft.so, libcufft_static.a, libcufftw.so,
libcufftw_static.a

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 10

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

Component

CUDA BLAS Library

Windows

cublas.dll, cublasLt.dll

Mac OSX

libcublas.dylib, libcublasLt.dylib,
libcublas_static.a, libcublasLt_static.a

Linux

libcublas.so, libcublasLt.so, libcublas_static.a,
libcublasLt_static.a

Android

libcublas.so, libcublasLt.so, libcublas_static.a,
libcublasLt_static.a

Component

NVIDIA "Drop-in" BLAS Library

Windows

nvblas.dll

Mac OSX

libnvblas.dylib

Linux

libnvblas.so

Component

CUDA Sparse Matrix Library

Windows

cusparse.dll, cusparse.lib

Mac OSX

libcusparse.dylib, libcusparse_static.a

Linux

libcusparse.so, libcusparse_static.a

Android

libcusparse.so, libcusparse_static.a

Component

CUDA Linear Solver Library

Windows

cusolver.dll, cusolver.lib

Mac OSX

libcusolver.dylib, libcusolver_static.a

Linux

libcusolver.so, libcusolver_static.a

Android

libcusolver.so, libcusolver_static.a

Component

CUDA Random Number Generation Library

Windows

curand.dll, curand.lib

Mac OSX

libcurand.dylib, libcurand_static.a

Linux

libcurand.so, libcurand_static.a

Android

libcurand.so, libcurand_static.a

Component

NVIDIA Performance Primitives Library

Windows

nppc.dll, nppc.lib, nppial.dll, nppial.lib, nppicc.dll,
nppicc.lib, nppicom.dll, nppicom.lib, nppidei.dll,
nppidei.lib, nppif.dll, nppif.lib, nppig.dll, nppig.lib,
nppim.dll, nppim.lib, nppist.dll, nppist.lib,
nppisu.dll, nppisu.lib, nppitc.dll, nppitc.lib,
npps.dll, npps.lib

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 11

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

Mac OSX

libnppc.dylib, libnppc_static.a, libnppial.dylib,
libnppial_static.a, libnppicc.dylib,
libnppicc_static.a, libnppicom.dylib,
libnppicom_static.a, libnppidei.dylib,
libnppidei_static.a, libnppif.dylib, libnppif_static.a,
libnppig.dylib, libnppig_static.a, libnppim.dylib,
libnppisu_static.a, libnppitc.dylib,
libnppitc_static.a, libnpps.dylib, libnpps_static.a

Linux

libnppc.so, libnppc_static.a, libnppial.so,
libnppial_static.a, libnppicc.so, libnppicc_static.a,
libnppicom.so, libnppicom_static.a, libnppidei.so,
libnppidei_static.a, libnppif.so, libnppif_static.a
libnppig.so, libnppig_static.a, libnppim.so,
libnppim_static.a, libnppist.so, libnppist_static.a,
libnppisu.so, libnppisu_static.a, libnppitc.so
libnppitc_static.a, libnpps.so, libnpps_static.a

Android

libnppc.so, libnppc_static.a, libnppial.so,
libnppial_static.a, libnppicc.so, libnppicc_static.a,
libnppicom.so, libnppicom_static.a, libnppidei.so,
libnppidei_static.a, libnppif.so, libnppif_static.a
libnppig.so, libnppig_static.a, libnppim.so,
libnppim_static.a, libnppist.so, libnppist_static.a,
libnppisu.so, libnppisu_static.a, libnppitc.so
libnppitc_static.a, libnpps.so, libnpps_static.a

Component

NVIDIA JPEG Library

Windows

nvjpeg.lib, nvjpeg.dll

Linux

libnvjpeg.so, libnvjpeg_static.a

Component

Internal common library required for statically
linking to cuBLAS, cuSPARSE, cuFFT, cuRAND,
nvJPEG and NPP

Mac OSX

libculibos.a

Linux

libculibos.a

Component

NVIDIA Runtime Compilation Library and Header

All

nvrtc.h

Windows

nvrtc.dll, nvrtc-builtins.dll

Mac OSX

libnvrtc.dylib, libnvrtc-builtins.dylib

Linux

libnvrtc.so, libnvrtc-builtins.so

Component

NVIDIA Optimizing Compiler Library

Windows

nvvm.dll

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 12

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

Mac OSX

libnvvm.dylib

Linux

libnvvm.so

Component

NVIDIA Common Device Math Functions Library

Windows

libdevice.10.bc

Mac OSX

libdevice.10.bc

Linux

libdevice.10.bc

Component

CUDA Occupancy Calculation Header Library

All

cuda_occupancy.h

Component

CUDA Half Precision Headers

All

cuda_fp16.h, cuda_fp16.hpp

Component

CUDA Profiling Tools Interface (CUPTI) Library

Windows

cupti.dll

Mac OSX

libcupti.dylib

Linux

libcupti.so

Component

NVIDIA Tools Extension Library

Windows

nvToolsExt.dll, nvToolsExt.lib

Mac OSX

libnvToolsExt.dylib

Linux

libnvToolsExt.so

Component

NVIDIA CUDA Driver Libraries

Linux

libcuda.so, libnvidia-ptxjitcompiler.so

Component

NVIDIA CUDA File IO Libraries and Header

All

cufile.h

Linux

libcufile.so, libcufile_rdma.so, libcufile_static.a,
libcufile_rdma_static.a

The NVIDIA CUDA Driver Libraries are only distributable in applications that meet this criteria:
1. The application was developed starting from a NVIDIA CUDA container obtained from
Docker Hub or the NVIDIA GPU Cloud, and
2. The resulting application is packaged as a Docker container and distributed to users on
Docker Hub or the NVIDIA GPU Cloud only.
In addition to the rights above, for parties that are developing software intended solely for use
on Jetson development kits or Jetson modules, and running Linux for Tegra software, the
following shall apply:

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 13

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

‣ The SDK may be distributed in its entirety, as provided by NVIDIA, and without separation
of its components, for you and/or your licensees to create software development kits for
use only on the Jetson platform and running Linux for Tegra software.

2.7.

Attachment B

Additional Licensing Obligations
The following third party components included in the SOFTWARE are licensed to Licensee
pursuant to the following terms and conditions:
1. Licensee's use of the GDB third party component is subject to the terms and conditions of
GNU GPL v3:
This product includes copyrighted third-party software licensed
under the terms of the GNU General Public License v3 ("GPL v3").
All third-party software packages are copyright by their respective
authors. GPL v3 terms and conditions are hereby incorporated into
the Agreement by this reference: http://www.gnu.org/licenses/gpl.txt

Consistent with these licensing requirements, the software listed below is provided
under the terms of the specified open source software licenses. To obtain source code
for software provided under licenses that require redistribution of source code, including
the GNU General Public License (GPL) and GNU Lesser General Public License (LGPL),
contact oss-requests@nvidia.com. This offer is valid for a period of three (3) years from the
date of the distribution of this product by NVIDIA CORPORATION.
Component
CUDA-GDB

License
GPL v3

2. Licensee represents and warrants that any and all third party licensing and/or royalty
payment obligations in connection with Licensee's use of the H.264 video codecs are solely
the responsibility of Licensee.
3. Licensee's use of the Thrust library is subject to the terms and conditions of the Apache
License Version 2.0. All third-party software packages are copyright by their respective
authors. Apache License Version 2.0 terms and conditions are hereby incorporated into the
Agreement by this reference. http://www.apache.org/licenses/LICENSE-2.0.html
In addition, Licensee acknowledges the following notice: Thrust includes source code from
the Boost Iterator, Tuple, System, and Random Number libraries.
Boost Software License - Version 1.0 - August 17th, 2003
. . . .
Permission is hereby granted, free of charge, to any person or
organization obtaining a copy of the software and accompanying
documentation covered by this license (the "Software") to use,
reproduce, display, distribute, execute, and transmit the Software,

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 14

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

and to prepare derivative works of the Software, and to permit
third-parties to whom the Software is furnished to do so, all
subject to the following:
The copyright notices in the Software and this entire statement,
including the above license grant, this restriction and the following
disclaimer, must be included in all copies of the Software, in whole
or in part, and all derivative works of the Software, unless such
copies or derivative works are solely in the form of machine-executable
object code generated by a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

4. Licensee's use of the LLVM third party component is subject to the following terms and
conditions:
======================================================
LLVM Release License
======================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal with the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
*

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.

*

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.

*

Neither the names of the LLVM Team, University of Illinois at UrbanaChampaign, nor the names of its contributors may be used to endorse or
promote products derived from this Software without specific prior
written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 15

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

DEALINGS WITH THE SOFTWARE.

5. Licensee's use of the PCRE third party component is subject to the following terms and
conditions:
-----------PCRE LICENCE
-----------PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
specified below. The documentation for PCRE, supplied in the "doc"
directory, is distributed under the same terms as the software itself. The
basic library functions are written in C and are freestanding. Also
included in the distribution is a set of C++ wrapper functions, and a justin-time compiler that can be used to optimize pattern matching. These are
both optional features that can be omitted when the library is built.
THE BASIC LIBRARY FUNCTIONS
--------------------------Written by:
Philip Hazel
Email local part: ph10
Email domain:
cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2012 University of Cambridge
All rights reserved.
PCRE JUST-IN-TIME COMPILATION SUPPORT
------------------------------------Written by:
Zoltan Herczeg
Email local part: hzmester
Emain domain:
freemail.hu
Copyright(c) 2010-2012 Zoltan Herczeg
All rights reserved.
STACK-LESS JUST-IN-TIME COMPILER
-------------------------------Written by:
Zoltan Herczeg
Email local part: hzmester
Emain domain:
freemail.hu
Copyright(c) 2009-2012 Zoltan Herczeg
All rights reserved.
THE C++ WRAPPER FUNCTIONS
------------------------Contributed by:
Google Inc.
Copyright (c) 2007-2012, Google Inc.
All rights reserved.
THE "BSD" LICENCE
----------------Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the name of Google
Inc. nor the names of their contributors may be used to endorse or

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 16

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

6. Some of the cuBLAS library routines were written by or derived from code written by Vasily
Volkov and are subject to the Modified Berkeley Software Distribution License as follows:
Copyright (c) 2007-2009, Regents of the University of California
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the University of California, Berkeley nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

7. Some of the cuBLAS library routines were written by or derived from code written by
Davide Barbieri and are subject to the Modified Berkeley Software Distribution License as
follows:
Copyright (c) 2008-2009 Davide Barbieri @ University of Rome Tor Vergata.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 17

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

disclaimer in the documentation and/or other materials provided
with the distribution.
* The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

8. Some of the cuBLAS library routines were derived from code developed by the University
of Tennessee and are subject to the Modified Berkeley Software Distribution License as
follows:
Copyright (c) 2010 The University of Tennessee.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer listed in this license in the documentation and/or
other materials provided with the distribution.
* Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

9. Some of the cuBLAS library routines were written by or derived from code written by
Jonathan Hogg and are subject to the Modified Berkeley Software Distribution License as
follows:
Copyright (c) 2012, The Science and Technology Facilities Council (STFC).
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 18

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the STFC nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE STFC BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

10.Some of the cuBLAS library routines were written by or derived from code written by
Ahmad M. Abdelfattah, David Keyes, and Hatem Ltaief, and are subject to the Apache
License, Version 2.0, as follows:
-- (C) Copyright 2013 King Abdullah University of Science and Technology
Authors:
Ahmad Abdelfattah (ahmad.ahmad@kaust.edu.sa)
David Keyes (david.keyes@kaust.edu.sa)
Hatem Ltaief (hatem.ltaief@kaust.edu.sa)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the King Abdullah University of Science and
Technology nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

11.Some of the cuSPARSE library routines were written by or derived from code written by LiWen Chang and are subject to the NCSA Open Source License as follows:
Copyright (c) 2012, University of Illinois.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 19

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

All rights reserved.
Developed by: IMPACT Group, University of Illinois, http://
impact.crhc.illinois.edu
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimers in the documentation and/or other materials provided
with the distribution.
* Neither the names of IMPACT Group, University of Illinois, nor
the names of its contributors may be used to endorse or promote
products derived from this Software without specific prior
written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

12.Some of the cuRAND library routines were written by or derived from code written by
Mutsuo Saito and Makoto Matsumoto and are subject to the following license:
Copyright (c) 2009, 2010 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University. All rights reserved.
Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima
University and University of Tokyo. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Hiroshima University nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 20

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

13.Some of the cuRAND library routines were derived from code developed by D. E. Shaw
Research and are subject to the following license:
Copyright 2010-2011, D. E. Shaw Research.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions, and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of D. E. Shaw Research nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

14.Some of the Math library routines were written by or derived from code developed by
Norbert Juffa and are subject to the following license:
Copyright (c) 2015-2017, Norbert Juffa
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 21

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

15.Licensee's use of the lz4 third party component is subject to the following terms and
conditions:
Copyright (C) 2011-2013, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

16.The NPP library uses code from the Boost Math Toolkit, and is subject to the following
license:
Boost Software License - Version 1.0 - August 17th, 2003
. . . .
Permission is hereby granted, free of charge, to any person or
organization obtaining a copy of the software and accompanying
documentation covered by this license (the "Software") to use,
reproduce, display, distribute, execute, and transmit the Software,
and to prepare derivative works of the Software, and to permit
third-parties to whom the Software is furnished to do so, all
subject to the following:
The copyright notices in the Software and this entire statement,
including the above license grant, this restriction and the following
disclaimer, must be included in all copies of the Software, in whole
or in part, and all derivative works of the Software, unless such
copies or derivative works are solely in the form of machine-executable
object code generated by a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

17.Portions of the Nsight Eclipse Edition is subject to the following license:
The Eclipse Foundation makes available all content in this plug-in
("Content"). Unless otherwise indicated below, the Content is provided
End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 22

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

to you under the terms and conditions of the Eclipse Public License
Version 1.0 ("EPL"). A copy of the EPL is available at http://
www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program"
will mean the Content.
If you did not receive this Content directly from the Eclipse
Foundation, the Content is being redistributed by another party
("Redistributor") and different terms and conditions may apply to your
use of any object code in the Content. Check the Redistributor's
license that was provided with the Content. If no such license exists,
contact the Redistributor. Unless otherwise indicated below, the terms
and conditions of the EPL still apply to any source code in the
Content and such source code may be obtained at http://www.eclipse.org.

18.Some of the cuBLAS library routines uses code from OpenAI, which is subject to the
following license:
License URL
https://github.com/openai/openai-gemm/blob/master/LICENSE
License Text
The MIT License
Copyright (c) 2016 OpenAI (http://openai.com), 2016 Google Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

19.Licensee's use of the Visual Studio Setup Configuration Samples is subject to the following
license:
The MIT License (MIT)
Copyright (C) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 23

CUDA Toolkit Supplement to Software License Agreement for NVIDIA Software Development Kits

AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

20.Licensee's use of linmath.h header for CPU functions for GL vector/matrix operations
from lunarG is subject to the Apache License Version 2.0.
21.The DX12-CUDA sample uses the d3dx12.h header, which is subject to the MIT license .

End User License Agreements (EULA)

DR-06739-001_v01_v11.7 | 24



drm

Copyright © 2017-2018 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

dbus

License: AFL-2.1
 The Academic Free License
 v. 2.1
 .
 This Academic Free License (the "License") applies to any original
 work of authorship (the "Original Work") whose owner (the "Licensor")
 has placed the following notice immediately following the copyright
 notice for the Original Work:
 .
 Licensed under the Academic Free License version 2.1
 .
 1) Grant of Copyright License. Licensor hereby grants You a
 world-wide, royalty-free, non-exclusive, perpetual, sublicenseable
 license to do the following:
 .
 a) to reproduce the Original Work in copies;
 .
 b) to prepare derivative works ("Derivative Works") based upon the
 Original Work;
 .
 c) to distribute copies of the Original Work and Derivative Works to
 the public;
 .
 d) to perform the Original Work publicly; and
 .
 e) to display the Original Work publicly.
 .
 2) Grant of Patent License. Licensor hereby grants You a world-wide,
 royalty-free, non-exclusive, perpetual, sublicenseable license, under
 patent claims owned or controlled by the Licensor that are embodied in
 the Original Work as furnished by the Licensor, to make, use, sell and
 offer for sale the Original Work and Derivative Works.
 .
 3) Grant of Source Code License. The term "Source Code" means the
 preferred form of the Original Work for making modifications to it and
 all available documentation describing how to modify the Original
 Work. Licensor hereby agrees to provide a machine-readable copy of the
 Source Code of the Original Work along with each copy of the Original
 Work that Licensor distributes. Licensor reserves the right to satisfy
 this obligation by placing a machine-readable copy of the Source Code
 in an information repository reasonably calculated to permit
 inexpensive and convenient access by You for as long as Licensor
 continues to distribute the Original Work, and by publishing the
 address of that information repository in a notice immediately
 following the copyright notice that applies to the Original Work.
 .
 4) Exclusions From License Grant. Neither the names of Licensor, nor
 the names of any contributors to the Original Work, nor any of their
 trademarks or service marks, may be used to endorse or promote
 products derived from this Original Work without express prior written
 permission of the Licensor. Nothing in this License shall be deemed to
 grant any rights to trademarks, copyrights, patents, trade secrets or
 any other intellectual property of Licensor except as expressly stated
 herein. No patent license is granted to make, use, sell or offer to
 sell embodiments of any patent claims other than the licensed claims
 defined in Section 2. No right is granted to the trademarks of
 Licensor even if such marks are included in the Original Work. Nothing
 in this License shall be interpreted to prohibit Licensor from
 licensing under different terms from this License any Original Work
 that Licensor otherwise would have a right to license.
 .
 5) This section intentionally omitted.
 .
 6) Attribution Rights. You must retain, in the Source Code of any
 Derivative Works that You create, all copyright, patent or trademark
 notices from the Source Code of the Original Work, as well as any
 notices of licensing and any descriptive text identified therein as an
 "Attribution Notice." You must cause the Source Code for any
 Derivative Works that You create to carry a prominent Attribution
 Notice reasonably calculated to inform recipients that You have
 modified the Original Work.
 .
 7) Warranty of Provenance and Disclaimer of Warranty. Licensor
 warrants that the copyright in and to the Original Work and the patent
 rights granted herein by Licensor are owned by the Licensor or are
 sublicensed to You under the terms of this License with the permission
 of the contributor(s) of those copyrights and patent rights. Except as
 expressly stated in the immediately proceeding sentence, the Original
 Work is provided under this License on an "AS IS" BASIS and WITHOUT
 WARRANTY, either express or implied, including, without limitation,
 the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
 PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL
 WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential
 part of this License. No license to Original Work is granted hereunder
 except under this disclaimer.
 .
 8) Limitation of Liability. Under no circumstances and under no legal
 theory, whether in tort (including negligence), contract, or
 otherwise, shall the Licensor be liable to any person for any direct,
 indirect, special, incidental, or consequential damages of any
 character arising as a result of this License or the use of the
 Original Work including, without limitation, damages for loss of
 goodwill, work stoppage, computer failure or malfunction, or any and
 all other commercial damages or losses. This limitation of liability
 shall not apply to liability for death or personal injury resulting
 from Licensor's negligence to the extent applicable law prohibits such
 limitation. Some jurisdictions do not allow the exclusion or
 limitation of incidental or consequential damages, so this exclusion
 and limitation may not apply to You.
 .
 9) Acceptance and Termination. If You distribute copies of the
 Original Work or a Derivative Work, You must make a reasonable effort
 under the circumstances to obtain the express assent of recipients to
 the terms of this License. Nothing else but this License (or another
 written agreement between Licensor and You) grants You permission to
 create Derivative Works based upon the Original Work or to exercise
 any of the rights granted in Section 1 herein, and any attempt to do
 so except under the terms of this License (or another written
 agreement between Licensor and You) is expressly prohibited by
 U.S. copyright law, the equivalent laws of other countries, and by
 international treaty. Therefore, by exercising any of the rights
 granted to You in Section 1 herein, You indicate Your acceptance of
 this License and all of its terms and conditions.
 .
 10) Termination for Patent Action. This License shall terminate
 automatically and You may no longer exercise any of the rights granted
 to You by this License as of the date You commence an action,
 including a cross-claim or counterclaim, against Licensor or any
 licensee alleging that the Original Work infringes a patent. This
 termination provision shall not apply for an action alleging patent
 infringement by combinations of the Original Work with other software
 or hardware.
 .
 11) Jurisdiction, Venue and Governing Law. Any action or suit relating
 to this License may be brought only in the courts of a jurisdiction
 wherein the Licensor resides or in which Licensor conducts its primary
 business, and under the laws of that jurisdiction excluding its
 conflict-of-law provisions. The application of the United Nations
 Convention on Contracts for the International Sale of Goods is
 expressly excluded. Any use of the Original Work outside the scope of
 this License or after its termination shall be subject to the
 requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101
 et seq., the equivalent laws of other countries, and international
 treaty. This section shall survive the termination of this License.
 .
 12) Attorneys Fees. In any action to enforce the terms of this License
 or seeking damages relating thereto, the prevailing party shall be
 entitled to recover its costs and expenses, including, without
 limitation, reasonable attorneys' fees and costs incurred in
 connection with such action, including any appeal of such action. This
 section shall survive the termination of this License.
 .
 13) Miscellaneous. This License represents the complete agreement
 concerning the subject matter hereof. If any provision of this License
 is held to be unenforceable, such provision shall be reformed only to
 the extent necessary to make it enforceable.
 .
 14) Definition of "You" in This License. "You" throughout this
 License, whether in upper or lower case, means an individual or a
 legal entity exercising rights under, and complying with all of the
 terms of, this License. For legal entities, "You" includes any entity
 that controls, is controlled by, or is under common control with
 you. For purposes of this definition, "control" means (i) the power,
 direct or indirect, to cause the direction or management of such
 entity, whether by contract or otherwise, or (ii) ownership of fifty
 percent (50%) or more of the outstanding shares, or (iii) beneficial
 ownership of such entity.
 .
 15) Right to Use. You may use the Original Work in all ways not
 otherwise restricted or conditioned by this License or by law, and
 Licensor promises not to interfere with or be responsible for such
 uses by You.
 .
 This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights
 reserved. Permission is hereby granted to copy and distribute this
 license without modification. This license may not be modified without
 the express written permission of its copyright owner.

ebur128

Copyright (c) 2011 Jan Kokemüller

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

efp

MIT License

Copyright (c) 2020 Edgeware AB

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

efpbond

Copyright (c) 2019-2020 Edgeware AB, Agile Content 2021-2022

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

expat

Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
Copyright (c) 2001-2022 Expat maintainers

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

fdk-aac

Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de

ffmpeg

                  GNU LESSER GENERAL PUBLIC LICENSE
                       Version 2.1, February 1999

 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.

  When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

                  GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.

  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded.  In such case, this License incorporates the limitation as if
written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

                            NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

                     END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!

fmtlib

Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

--- Optional exception to the license ---

As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

fontconfig

This package was debianized by Colin Walters <walters@debian.org> on
Sun, 13 Oct 2002 15:01:50 -0400

It was downloaded from http://www.fontconfig.org/

Upstream Author: Keith Packard

Copyright:

Copyright © 2001,2003 Keith Packard

Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of Keith Packard not be used in
advertising or publicity pertaining to distribution of the software without
specific, written prior permission.  Keith Packard makes no
representations about the suitability of this software for any purpose.  It
is provided "as is" without express or implied warranty.

KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

freetype

                    The FreeType Project LICENSE
                    ----------------------------

                            2006-Jan-27

                    Copyright 1996-2002, 2006 by
          David Turner, Robert Wilhelm, and Werner Lemberg



Introduction
============

  The FreeType  Project is distributed in  several archive packages;
  some of them may contain, in addition to the FreeType font engine,
  various tools and  contributions which rely on, or  relate to, the
  FreeType Project.

  This  license applies  to all  files found  in such  packages, and
  which do not  fall under their own explicit  license.  The license
  affects  thus  the  FreeType   font  engine,  the  test  programs,
  documentation and makefiles, at the very least.

  This  license   was  inspired  by  the  BSD,   Artistic,  and  IJG
  (Independent JPEG  Group) licenses, which  all encourage inclusion
  and  use of  free  software in  commercial  and freeware  products
  alike.  As a consequence, its main points are that:

    o We don't promise that this software works. However, we will be
      interested in any kind of bug reports. (`as is' distribution)

    o You can  use this software for whatever you  want, in parts or
      full form, without having to pay us. (`royalty-free' usage)

    o You may not pretend that  you wrote this software.  If you use
      it, or  only parts of it,  in a program,  you must acknowledge
      somewhere  in  your  documentation  that  you  have  used  the
      FreeType code. (`credits')

  We  specifically  permit  and  encourage  the  inclusion  of  this
  software, with  or without modifications,  in commercial products.
  We  disclaim  all warranties  covering  The  FreeType Project  and
  assume no liability related to The FreeType Project.


  Finally,  many  people  asked  us  for  a  preferred  form  for  a
  credit/disclaimer to use in compliance with this license.  We thus
  encourage you to use the following text:

   """
    Portions of this software are copyright © <year> The FreeType
    Project (www.freetype.org).  All rights reserved.
   """

  Please replace <year> with the value from the FreeType version you
  actually use.


Legal Terms
===========

0. Definitions
--------------

  Throughout this license,  the terms `package', `FreeType Project',
  and  `FreeType  archive' refer  to  the  set  of files  originally
  distributed  by the  authors  (David Turner,  Robert Wilhelm,  and
  Werner Lemberg) as the `FreeType Project', be they named as alpha,
  beta or final release.

  `You' refers to  the licensee, or person using  the project, where
  `using' is a generic term including compiling the project's source
  code as  well as linking it  to form a  `program' or `executable'.
  This  program is  referred to  as  `a program  using the  FreeType
  engine'.

  This  license applies  to all  files distributed  in  the original
  FreeType  Project,   including  all  source   code,  binaries  and
  documentation,  unless  otherwise  stated   in  the  file  in  its
  original, unmodified form as  distributed in the original archive.
  If you are  unsure whether or not a particular  file is covered by
  this license, you must contact us to verify this.

  The FreeType  Project is copyright (C) 1996-2000  by David Turner,
  Robert Wilhelm, and Werner Lemberg.  All rights reserved except as
  specified below.

1. No Warranty
--------------

  THE FREETYPE PROJECT  IS PROVIDED `AS IS' WITHOUT  WARRANTY OF ANY
  KIND, EITHER  EXPRESS OR IMPLIED,  INCLUDING, BUT NOT  LIMITED TO,
  WARRANTIES  OF  MERCHANTABILITY   AND  FITNESS  FOR  A  PARTICULAR
  PURPOSE.  IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
  BE LIABLE  FOR ANY DAMAGES CAUSED  BY THE USE OR  THE INABILITY TO
  USE, OF THE FREETYPE PROJECT.

2. Redistribution
-----------------

  This  license  grants  a  worldwide, royalty-free,  perpetual  and
  irrevocable right  and license to use,  execute, perform, compile,
  display,  copy,   create  derivative  works   of,  distribute  and
  sublicense the  FreeType Project (in  both source and  object code
  forms)  and  derivative works  thereof  for  any  purpose; and  to
  authorize others  to exercise  some or all  of the  rights granted
  herein, subject to the following conditions:

    o Redistribution of  source code  must retain this  license file
      (`FTL.TXT') unaltered; any  additions, deletions or changes to
      the original  files must be clearly  indicated in accompanying
      documentation.   The  copyright   notices  of  the  unaltered,
      original  files must  be  preserved in  all  copies of  source
      files.

    o Redistribution in binary form must provide a  disclaimer  that
      states  that  the software is based in part of the work of the
      FreeType Team,  in  the  distribution  documentation.  We also
      encourage you to put an URL to the FreeType web page  in  your
      documentation, though this isn't mandatory.

  These conditions  apply to any  software derived from or  based on
  the FreeType Project,  not just the unmodified files.   If you use
  our work, you  must acknowledge us.  However, no  fee need be paid
  to us.

3. Advertising
--------------

  Neither the  FreeType authors and  contributors nor you  shall use
  the name of the  other for commercial, advertising, or promotional
  purposes without specific prior written permission.

  We suggest,  but do not require, that  you use one or  more of the
  following phrases to refer  to this software in your documentation
  or advertising  materials: `FreeType Project',  `FreeType Engine',
  `FreeType library', or `FreeType Distribution'.

  As  you have  not signed  this license,  you are  not  required to
  accept  it.   However,  as  the FreeType  Project  is  copyrighted
  material, only  this license, or  another one contracted  with the
  authors, grants you  the right to use, distribute,  and modify it.
  Therefore,  by  using,  distributing,  or modifying  the  FreeType
  Project, you indicate that you understand and accept all the terms
  of this license.

4. Contacts
-----------

  There are two mailing lists related to FreeType:

    o freetype@nongnu.org

      Discusses general use and applications of FreeType, as well as
      future and  wanted additions to the  library and distribution.
      If  you are looking  for support,  start in  this list  if you
      haven't found anything to help you in the documentation.

    o freetype-devel@nongnu.org

      Discusses bugs,  as well  as engine internals,  design issues,
      specific licenses, porting, etc.

  Our home page can be found at

    https://www.freetype.org


--- end of FTL.TXT ---

gcrypt

GNU LESSER GENERAL PUBLIC LICENSE

Version 2.1, February 1999

Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.

When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.

To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.

To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.

Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.

Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.
    b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
    c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
    d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

    a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
    b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
    c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
    d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
    e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
    b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).

To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the library's name and an idea of what it does.
Copyright (C) year  name of author

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.

signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice

That's all there is to it!

glibc

GNU LESSER GENERAL PUBLIC LICENSE

Version 2.1, February 1999

Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.

When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.

To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.

To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.

Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.

Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.
    b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
    c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
    d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

    a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
    b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
    c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
    d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
    e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
    b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).

To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the library's name and an idea of what it does.
Copyright (C) year  name of author

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.

signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice

That's all there is to it!

gpg-error

GNU LESSER GENERAL PUBLIC LICENSE

Version 2.1, February 1999

Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.

When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.

To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.

To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.

Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.

Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.
    b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
    c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
    d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

    a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
    b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
    c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
    d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
    e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
    b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).

To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the library's name and an idea of what it does.
Copyright (C) year  name of author

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.

signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice

That's all there is to it!

kissnet

MIT License

Copyright (c) 2018-2021 Arthur Brainville (Ybalrid)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

libcap

Unless otherwise *explicitly* stated, the following text describes the
licensed conditions under which the contents of this libcap release
may be used and distributed:

-------------------------------------------------------------------------
Redistribution and use in source and binary forms of libcap, with
or without modification, are permitted provided that the following
conditions are met:

1. Redistributions of source code must retain any existing copyright
   notice, and this entire permission notice in its entirety,
   including the disclaimer of warranties.

2. Redistributions in binary form must reproduce all prior and current
   copyright notices, this list of conditions, and the following
   disclaimer in the documentation and/or other materials provided
   with the distribution.

3. The name of any author may not be used to endorse or promote
   products derived from this software without their specific prior
   written permission.

libgcc

GCC RUNTIME LIBRARY EXCEPTION

Version 3.1, 31 March 2009

Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

This GCC Runtime Library Exception ("Exception") is an additional
permission under section 7 of the GNU General Public License, version
3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
bears a notice placed by the copyright holder of the file stating that
the file is governed by GPLv3 along with this Exception.

When you use GCC to compile a program, GCC may combine portions of
certain GCC header files and runtime libraries with the compiled
program. The purpose of this Exception is to allow compilation of
non-GPL (including proprietary) programs to use, in this way, the
header files and runtime libraries covered by this Exception.

0. Definitions.

A file is an "Independent Module" if it either requires the Runtime
Library for execution after a Compilation Process, or makes use of an
interface provided by the Runtime Library, but is not otherwise based
on the Runtime Library.

"GCC" means a version of the GNU Compiler Collection, with or without
modifications, governed by version 3 (or a specified later version) of
the GNU General Public License (GPL) with the option of using any
subsequent versions published by the FSF.

"GPL-compatible Software" is software whose conditions of propagation,
modification and use would permit combination with GCC in accord with
the license of GCC.

"Target Code" refers to output from any compiler for a real or virtual
target processor architecture, in executable form or suitable for
input to an assembler, loader, linker and/or execution
phase. Notwithstanding that, Target Code does not include data in any
format that is used as a compiler intermediate representation, or used
for producing a compiler intermediate representation.

The "Compilation Process" transforms code entirely represented in
non-intermediate languages designed for human-written code, and/or in
Java Virtual Machine byte code, into Target Code. Thus, for example,
use of source code generators and preprocessors need not be considered
part of the Compilation Process, since the Compilation Process can be
understood as starting with the output of the generators or
preprocessors.

A Compilation Process is "Eligible" if it is done using GCC, alone or
with other GPL-compatible software, or if it is done without using any
work based on GCC. For example, using non-GPL-compatible Software to
optimize any GCC intermediate representations would not qualify as an
Eligible Compilation Process.

1. Grant of Additional Permission.

You have permission to propagate a work of Target Code formed by
combining the Runtime Library with Independent Modules, even if such
propagation would otherwise violate the terms of GPLv3, provided that
all Target Code was generated by Eligible Compilation Processes. You
may then convey such a combination under terms of your choice,
consistent with the licensing of the Independent Modules.

2. No Weakening of GCC Copyleft.

The availability of this Exception does not imply any general
presumption that third-party software is unaffected by the copyleft
requirements of the license of GCC.

libpng

License: libpng
 Here is the copyright and license for libpng:
 .
   libpng versions 1.2.6, August 15, 2004, through 1.5.2, March 31, 2011, are
   Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-1.2.5
   with the following individual added to the list of Contributing Authors
 .
     Cosmin Truta
 .
   libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
   Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-1.0.6
   with the following individuals added to the list of Contributing Authors
 .
     Simon-Pierre Cadieux
     Eric S. Raymond
     Gilles Vollant
 .
   and with the following additions to the disclaimer:
 .
   There is no warranty against interference with your enjoyment of the
   library or against infringement.  There is no warranty that our
   efforts or the library will fulfill any of your particular purposes
   or needs.  This library is provided with all faults, and the entire
   risk of satisfactory quality, performance, accuracy, and effort is with
   the user.
 .
   libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
   Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-0.96,
   with the following individuals added to the list of Contributing Authors:
 .
     Tom Lane
     Glenn Randers-Pehrson
     Willem van Schaik
 .
   (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
   (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
 .
   Authors and maintainers:
   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
   libpng versions 0.97, January 1998, through 1.2.26 - April 2, 2008: Glenn
   See also "Contributing Authors", below.
 .
 .
   COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
 .
   If you modify libpng you may insert additional notices immediately following
   this sentence.
 .
   libpng versions 1.2.6, August 15, 2004, through 1.2.26, April 2, 2008, are
   Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-1.2.5
   with the following individual added to the list of Contributing Authors:
 .
      Cosmin Truta
 .
   libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
   Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-1.0.6
   with the following individuals added to the list of Contributing Authors:
 .
      Simon-Pierre Cadieux
      Eric S. Raymond
      Gilles Vollant
 .
   and with the following additions to the disclaimer:
 .
      There is no warranty against interference with your enjoyment of the
      library or against infringement.  There is no warranty that our
      efforts or the library will fulfill any of your particular purposes
      or needs.  This library is provided with all faults, and the entire
      risk of satisfactory quality, performance, accuracy, and effort is with
      the user.
 .
   libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
   Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
   distributed according to the same disclaimer and license as libpng-0.96,
   with the following individuals added to the list of Contributing Authors:
 .
      Tom Lane
      Glenn Randers-Pehrson
      Willem van Schaik
 .
   libpng versions 0.89, June 1996, through 0.96, May 1997, are
   Copyright (c) 1996, 1997 Andreas Dilger
   Distributed according to the same disclaimer and license as libpng-0.88,
   with the following individuals added to the list of Contributing Authors:
 .
      John Bowler
      Kevin Bracey
      Sam Bushell
      Magnus Holmgren
      Greg Roelofs
      Tom Tanner
 .
   libpng versions 0.5, May 1995, through 0.88, January 1996, are
   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
 .
   For the purposes of this copyright and license, "Contributing Authors"
   is defined as the following set of individuals:
 .
      Andreas Dilger
      Dave Martindale
      Guy Eric Schalnat
      Paul Schmidt
      Tim Wegner
 .
   The PNG Reference Library is supplied "AS IS".  The Contributing Authors
   and Group 42, Inc. disclaim all warranties, expressed or implied,
   including, without limitation, the warranties of merchantability and of
   fitness for any purpose.  The Contributing Authors and Group 42, Inc.
   assume no liability for direct, indirect, incidental, special, exemplary,
   or consequential damages, which may result from the use of the PNG
   Reference Library, even if advised of the possibility of such damage.
 .
   Permission is hereby granted to use, copy, modify, and distribute this
   source code, or portions hereof, for any purpose, without fee, subject
   to the following restrictions:
 .
   1. The origin of this source code must not be misrepresented.
 .
   2. Altered versions must be plainly marked as such and
      must not be misrepresented as being the original source.
 .
   3. This Copyright notice may not be removed or altered from
      any source or altered source distribution.
 .
   The Contributing Authors and Group 42, Inc. specifically permit, without
   fee, and encourage the use of this source code as a component to
   supporting the PNG file format in commercial products.  If you use this
   source code in a product, acknowledgment is not required but would be
   appreciated.
 .
   contrib/pngsuite:
   --------
   (c) Willem van Schaik, 1999, 2011
 .
   Permission to use, copy, modify, and distribute these images for any
   purpose and without fee is hereby granted.

lz4

LZ4 Library
Copyright (c) 2011-2020, Yann Collet
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

lzma

LZMA SDK is placed in the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute the original LZMA SDK code, either in source code form or
as a compiled binary, for any purpose, commercial or non-commercial,
and by any means.

md

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

mpegts

MIT License

Copyright (c) 2019 akanchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

ndi

NewTek’s NDI® Software Development Kit (SDK) License Agreement

Please read this document carefully before proceeding. You (the undersigned Licensee) hereby agree to the terms of this NDI® Software Development Kit (SDK) License Agreement (the "License") in order to use the SDK. NewTek, Inc. (“NewTek”) agrees to license you certain rights as set forth herein under these terms.

1. Definitions
a. "SDK" means the entire NewTek NDI® Software Development Kit, including those portions pertaining to the Specific SDK, provided to you pursuant to this License, including any source code, compiled executables or libraries, and all documentation provided to you to assist you in building tools that use the NDI® Software for data transfer over a local network.
b. "Products" means your software product(s) and/or service(s) that you develop or that are developed on your behalf through the use of the SDK and that are designed to be, and/or are, used, sold and/or distributed to work closely with other NewTek Products or Third Party Video Products.
c. “NewTek Products refers to NewTek’s video line of products distributed by NewTek and any upgrades.
d. “SDK Documentation” refers to the documentation included with the Software Development Kit including that portion pertaining to the Specific SDK.
e.  “Specific SDK” refers to the specific SDK for which you intend to use the NewTek SDK and this license (for example: NDI® Send, NDI®  Receive, NDI® Find, or other SDK’s that are available from time to time.  These are examples only and NewTek may add or subtract to this list at its discretion, and you agree to use them only in accordance with this Agreement), and includes the documentation relating to it.
f. “Third Party Video Products” refers to products of third parties developed by or for them also using the NewTek NDI® Software Development Kit in any way.

2. License
a. Pursuant to the terms, conditions and requirements of this License and the SDK Documentation, you are hereby granted a nonexclusive royalty-free license to use the sample code, object code and documentation included in the SDK for the sole purpose of developing Products using the Specific SDK, and to distribute, only in accordance with the SDK Documentation requirements, object code included in the SDK solely as used by such Products (your Product and compiled sample code referred to as the “Bundled Product”).
b. If you are making a product release you must use a version of the SDK that is less than thirty (30) days old if there is one.
c. This is a License only, and no employment, joint venture, partnership, or other business venture is created by this License.
d. Unless otherwise stated in the SDK, no files within the SDK and the Specific SDK may be distributed.  Certain files within the SDK or the Specific SDK may be distributed, said files and their respective distribution license are individually identified within the SDK documentation. This is not a license to create revisions or other derivative works of any NewTek software or technology.
e. You agree to comply with the steps outlined in the SDK Documentation, including the SDK manual for the Specific SDK. Different obligations and restrictions may be imposed by NewTek with respect to different Specific SDK’s. NewTek will not agree to sponsor your Product or show affiliation; however NewTek shall have the right to test the Product, and if it does not work or operate to NewTek’s satisfaction, NewTek may terminate this license pursuant to Section 10. Notwithstanding that NewTek may test the Product, it does not warrant the test; it is for NewTek’s benefit, and you agree not to promote in your Product marketing or elsewhere any results or that NewTek has tested the Product.
f. You acknowledge that information provided to NewTek to induce NewTek to enter into this license with you about your experience in the industry, sales, distribution, SDK experience or otherwise, whether such information is provided to NewTek verbally or in writing, is true.
g. NewTek makes the SDK available for developers for developing Products only, under these specific conditions herein, and if  any, or all, of the terms of this license are not enforceable within your legal jurisdiction in any way, or if any clause is voided or modified in any way, then you may not enter into this agreement, any license and permission granted herein is revoked and withdrawn as of the date you first downloaded and/or used the SDK, and you are then unauthorized to  copy, create derivative works,  or otherwise use the SDK in any way.


3. Restrictions and Confidentiality.
a. “Confidential Information” includes the SDK and all specifications, source code, example code, tools and documentation provided within the SDK, and any support thereof, and any other proprietary information provided by NewTek and identified as Confidential in the course of assisting You with your NDI® implementation.  Confidential Information does not include information that: 1) is or becomes generally available to the public other than as a result of a disclosure by You, or 2) becomes available to You on a non-confidential basis from a source that was not prohibited from disclosing such information. Except as authorized herein, or in the SDK Documentation, or as otherwise approved in writing by NewTek: 1) The disclosure to you of the SDK and all other Confidential Information shall not be disclosed to any third party 2)You agree not to  commercialize the Confidential Information  for yours or others benefit in any way; 3) You will not make or distribute copies of the SDK, or other Confidential Information or electronically transfer the SDK to any individual within your business or company who does not need to know or view the SDK, and under no circumstances shall you disclose it, or any part of it, to any company, or any other individual not employed directly by the business or company you represent, without express written permission of NewTek.
b. You will not modify, sell, rent, transfer, resell for profit, distribute, or create derivative works based upon the SDK or any part thereof other than as set forth herein, and you will not allow independent contractors to create derivative works; however, you may use the SDK to create your own program for the primary purpose of making it or your Product compatible with the NDI® network APIs, a NewTek Product, or for other purposes expressly set forth by you in advance in writing and agreed to in writing by NewTek.  In the case of your derivative works based upon the SDK, you may create and revise your Product using the SDK, and sell, rent, transfer, resell for profit and distribute, so long as it is for the Principal objective for which you were provided the SDK and it otherwise complies with this agreement, including the requirement that your Product or any other Third Party Product using any portion of the SDK continues to  use the current SDK as required herein and functions properly using the SDK.  NewTek reserves the right to determine at any time the compliance of your Product or any Third Party Product as properly using the SDK including maintaining current and complete NDI® compatability. Notwithstanding anything to the contrary herein, no intellectual property claim, whether in patent, trademark, copyright, or otherwise, is made by NewTek in or to your Product   (except as to the SDK including software code and/or Libraries, and copyright rights therein, and any Confidential Information used in or with the Product).
c. You will comply with applicable export control and trade sanctions laws, rules, regulations and licenses and will not export or re-export, directly or indirectly, the SDK into any country, to any organization or individual prohibited by the United States Export Administration Act and the regulations thereunder.
d. Any direct or indirect distribution of your Product or any Bundled Products by you that include your Product,  shall be under the terms of a license agreement containing terms that: (i) prohibit any modifications to the SDK or any part thereof, (ii) prohibit any reverse engineering, disassembly or recompilation of the the SDK or any part thereof, or any protocols used in the SDK, and further prohibit any attempt to do so; (iii) disclaim any and all warranties on behalf of NewTek and each of its licensors, (iv) disclaim, to the extent permitted by applicable law, liability of NewTek and/or its licensors for any damages, whether direct, indirect, incidental or consequential, arising from the use of the Product or Bundled Products, (v) comply fully with all relevant export laws and regulations of the United States to assure that the Bundled Products or any part thereof is not exported, directly or indirectly, in violation of United States law; (vi) include the appropriate copyright notice showing NewTek, Inc. as copyright owner; (vii) require all third party developers using your Product to develop Third Party Products to comply with the terms of the NewTek SDK license, including that such Third Party Products have current and complete NDI®  compatability, and further require such third party developers to include in their End User License Agreement the terms of this paragraph 3d.
e. You agree not to use the SDK for any unlawful propose or in any way to cause injury, harm or damage to NewTek, Inc., or its Products, trademarks, reputation and/or goodwill, or use information provided pursuant to the SDK, to interfere with NewTek in the commercialization of NewTek Products.
f. You agree to use NewTek trademarks (NewTek trademarks include, but are not limited to NDI®, NDI|HX™, NewTek™, TriCaster®, and LightWave 3D®), only in accordance with applicable policies of NewTek for such trademark usage by software developers in effect from time to time, which policy may be amended at any time with or without notice.  NewTek’s trademarks shall not be utilized within the Product itself, or on the Product packaging or promotion, or on websites, except to identify that the Product is compatible with NewTek’s pertinent Video Product, and in all cases where NewTek trademarks are utilized, special and clear notations shall be provided that the marks are NewTek trademarks.  Your Product is not a product of NewTek and no promotion, packaging, or use of NewTek trademarks shall suggest sponsorship by NewTek of your Products, except where specifically authorized by NewTek in writing.   Any distribution of your Product in a fraudulent manner, or in any other manner or method that violates any civil or criminal laws shall constitute a default under this agreement and result in immediate revocation of any right to utilize NewTek’s marks.
g. NewTek owns or has licensed copyright rights to the SDK. To the extent any of the SDK is incorporated into your Product, you agree to include all applicable copyright notices, along with yours, indicating NewTek’s copyright rights as applicable and as requested by NewTek.
h. You agree that by using the SDK, or any portion or part of the NDI® Software, in your Products, that you shall not at any time during the term create, use or distribute Products utilizing the NDI® SDK that are not interoperable with, or have significantly degraded performance of functionality when working with, NewTek Products or Third Party Video Products that are created with or utilize in whole or in part the SDK.  Your Products and Third Party Products must maintain current and complete NDI® compatability at all times.
i. You agree to not to reverse engineer, disassemble or recompile the SDK or any part thereof, or any protocols used in the SDK, or attempt to do so.
j. You agree not to use the SDK, or cause the SDK to be used, for any purpose that it was not designed for, and in particular, you agree not to use the SDK for any purpose but for the precise purposes as expressly identified to NewTek in writing that is the basis of the SDK and this license, and you agree you will not attempt to violate any of the foregoing, or encourage third parties to do so.

4. Software Defect Reporting
If you find software defects in the SDK, you agree to make reasonable effort to report them to NewTek in accordance with the SDK documentation or in such other manner as NewTek directs in writing.  NewTek will evaluate and, at its sole discretion, may address them in a future revision of the SDK. NewTek does not warrant the SDK to be free of defects.

5. Updates
You understand and agree that NewTek may amend, modify, change, and/or cease distribution or production of the SDK at any time. You understand that you are not entitled to receive any upgrades, updates, or future versions of the SDK under this License.  NewTek does not warrant or represent that its future updates and revisions will be compatible with your Product, and NewTek does not warrant that its updates and/or revisions will allow your Product to be compatible with or without modifications to your Product.

6. Ownership
Nothing herein is intended to convey to you any patent, trademark, copyright, trade secret or other Intellectual Property owned by NewTek or its Licensors in the SDK or in any NewTek software, hardware, products, trade names, or trademarks. NewTek and its suppliers or licensors shall retain all right, title, and interest to the foregoing Intellectual Property and to the SDK.  All rights not expressly granted herein are reserved by NewTek.

7. Indemnity and Limitations
You agree to indemnify and hold NewTek harmless from any third party claim, loss, or damage (including attorney's fees) related to your use, sale or distribution of the SDK.  THE SDK IS PROVIDED TO YOU FREE OF CHARGE, AND ON AN "AS IS" BASIS AND "WITH ALL FAULTS", WITHOUT ANY TECHNICAL SUPPORT OR WARRANTY OF ANY KIND FROM NEWTEK. YOU ASSUME ALL RISKS THAT THE SDK IS SUITABLE OR ACCURATE FOR YOUR NEEDS AND YOUR USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK. NEWTEK AND ITS LICENSORS DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES FOR THE SDK INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ALSO, THERE IS NO WARRANTY OF NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT.  SOME STATES DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY FROM STATE TO STATE.

8. Limitation of Damages
NEITHER NEWTEK NOR ITS SUPPLIERS OR LICENSORS SHALL BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOSS (INCLUDING DAMAGES FOR LOSS OF BUSINESS, LOSS OF PROFITS, OR THE LIKE), ARISING OUT OF THIS LICENSE WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, PRODUCT LIABILITY OR OTHERWISE, EVEN IF NEWTEK OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU. The limited warranty, exclusive remedies and limited liability set forth above are fundamental elements of the basis of the bargain between NewTek and you. You agree that NewTek would not be able to provide the Software on an economic basis without such limitations. IN NO EVENT WILL NEWTEK BE LIABLE FOR ANY AMOUNT GREATER THAN WHAT YOU ACTUALLY PAID FOR THE SDK.

9. US Government - Restricted Rights
The SDK and accompanying materials are provided with Restricted Rights. Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in this License and as provided in Federal Regulations, as applicable.  (Manufacturer: NewTek, Inc., 5131 Beckwith Blvd., San Antonio, TX 78249).

10. Termination
Either party may terminate this License upon thirty (30) days written notice.  Either party may also terminate if the other party materially defaults in the performance of any provision of this License, the non-defaulting party gives written notice to the other party of such default, and the defaulting party fails to cure such default within ten (10) days after receipt of such notice. Upon the termination of this License, the rights and licenses granted to you by NewTek pursuant to this License will automatically cease.   Nothing herein shall prevent either party from pursuing any injunctive relief at any time if necessary, or seeking any other remedies available in equity.  Each party reserves the right to pursue all legal and equitable remedies available. Upon termination, all SDK materials shall be promptly returned to NewTek, and any and all copies stored in electronic or other format shall be deleted and destroyed, and any rights to use NewTek’s trademarks are revoked. If this License is terminated for any reason, the provisions of Sections 1, 3, 6, 7, 8, 9, 10, and 11 shall survive such termination.

11. General
Notices given hereunder may be sent to either party at the address below by either overnight mail or by email and are deemed effective when sent. This License shall be governed by the laws of the State of Texas, without regard to its choice of law rules and you agree to exclusive jurisdiction therein.  This License contains the complete agreement between you and NewTek with respect to the subject matter (SDK) of this License, and supersedes all prior or contemporaneous agreements or understandings, whether oral or written.  It does not replace any licenses accompanying NewTek Products.  You may not assign this SDK License.

Jan 2020		NDI®  Technology License Agreement

nlohmann-json

MIT License

Copyright (c) 2013-2022 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

npp

End User License Agreement
--------------------------

NVIDIA Software License Agreement and CUDA Supplement to
Software License Agreement. Last updated: October 8, 2021

The CUDA Toolkit End User License Agreement applies to the
NVIDIA CUDA Toolkit, the NVIDIA CUDA Samples, the NVIDIA
Display Driver, NVIDIA Nsight tools (Visual Studio Edition),
and the associated documentation on CUDA APIs, programming
model and development tools. If you do not agree with the
terms and conditions of the license agreement, then do not
download or use the software.

Last updated: October 8, 2021.


Preface
-------

The Software License Agreement in Chapter 1 and the Supplement
in Chapter 2 contain license terms and conditions that govern
the use of NVIDIA software. By accepting this agreement, you
agree to comply with all the terms and conditions applicable
to the product(s) included herein.


NVIDIA Driver


Description

This package contains the operating system driver and
fundamental system software components for NVIDIA GPUs.


NVIDIA CUDA Toolkit


Description

The NVIDIA CUDA Toolkit provides command-line and graphical
tools for building, debugging and optimizing the performance
of applications accelerated by NVIDIA GPUs, runtime and math
libraries, and documentation including programming guides,
user manuals, and API references.


Default Install Location of CUDA Toolkit

Windows platform:

%ProgramFiles%\NVIDIA GPU Computing Toolkit\CUDA\v#.#

Linux platform:

/usr/local/cuda-#.#

Mac platform:

/Developer/NVIDIA/CUDA-#.#


NVIDIA CUDA Samples


Description

CUDA Samples are now located in
https://github.com/nvidia/cuda-samples, which includes
instructions for obtaining, building, and running the samples.
They are no longer included in the CUDA toolkit.


NVIDIA Nsight Visual Studio Edition (Windows only)


Description

NVIDIA Nsight Development Platform, Visual Studio Edition is a
development environment integrated into Microsoft Visual
Studio that provides tools for debugging, profiling, analyzing
and optimizing your GPU computing and graphics applications.


Default Install Location of Nsight Visual Studio Edition

Windows platform:

%ProgramFiles(x86)%\NVIDIA Corporation\Nsight Visual Studio Edition #.#


1. License Agreement for NVIDIA Software Development Kits
---------------------------------------------------------


Important Notice—Read before downloading, installing,
copying or using the licensed software:
-------------------------------------------------------

This license agreement, including exhibits attached
("Agreement”) is a legal agreement between you and NVIDIA
Corporation ("NVIDIA") and governs your use of a NVIDIA
software development kit (“SDK”).

Each SDK has its own set of software and materials, but here
is a description of the types of items that may be included in
a SDK: source code, header files, APIs, data sets and assets
(examples include images, textures, models, scenes, videos,
native API input/output files), binary software, sample code,
libraries, utility programs, programming code and
documentation.

This Agreement can be accepted only by an adult of legal age
of majority in the country in which the SDK is used.

If you are entering into this Agreement on behalf of a company
or other legal entity, you represent that you have the legal
authority to bind the entity to this Agreement, in which case
“you” will mean the entity you represent.

If you don’t have the required age or authority to accept
this Agreement, or if you don’t accept all the terms and
conditions of this Agreement, do not download, install or use
the SDK.

You agree to use the SDK only for purposes that are permitted
by (a) this Agreement, and (b) any applicable law, regulation
or generally accepted practices or guidelines in the relevant
jurisdictions.


1.1. License


1.1.1. License Grant

Subject to the terms of this Agreement, NVIDIA hereby grants
you a non-exclusive, non-transferable license, without the
right to sublicense (except as expressly provided in this
Agreement) to:

  1. Install and use the SDK,

  2. Modify and create derivative works of sample source code
    delivered in the SDK, and

  3. Distribute those portions of the SDK that are identified
    in this Agreement as distributable, as incorporated in
    object code format into a software application that meets
    the distribution requirements indicated in this Agreement.


1.1.2. Distribution Requirements

These are the distribution requirements for you to exercise
the distribution grant:

  1. Your application must have material additional
    functionality, beyond the included portions of the SDK.

  2. The distributable portions of the SDK shall only be
    accessed by your application.

  3. The following notice shall be included in modifications
    and derivative works of sample source code distributed:
    “This software contains source code provided by NVIDIA
    Corporation.”

  4. Unless a developer tool is identified in this Agreement
    as distributable, it is delivered for your internal use
    only.

  5. The terms under which you distribute your application
    must be consistent with the terms of this Agreement,
    including (without limitation) terms relating to the
    license grant and license restrictions and protection of
    NVIDIA’s intellectual property rights. Additionally, you
    agree that you will protect the privacy, security and
    legal rights of your application users.

  6. You agree to notify NVIDIA in writing of any known or
    suspected distribution or use of the SDK not in compliance
    with the requirements of this Agreement, and to enforce
    the terms of your agreements with respect to distributed
    SDK.


1.1.3. Authorized Users

You may allow employees and contractors of your entity or of
your subsidiary(ies) to access and use the SDK from your
secure network to perform work on your behalf.

If you are an academic institution you may allow users
enrolled or employed by the academic institution to access and
use the SDK from your secure network.

You are responsible for the compliance with the terms of this
Agreement by your authorized users. If you become aware that
your authorized users didn’t follow the terms of this
Agreement, you agree to take reasonable steps to resolve the
non-compliance and prevent new occurrences.


1.1.4. Pre-Release SDK

The SDK versions identified as alpha, beta, preview or
otherwise as pre-release, may not be fully functional, may
contain errors or design flaws, and may have reduced or
different security, privacy, accessibility, availability, and
reliability standards relative to commercial versions of
NVIDIA software and materials. Use of a pre-release SDK may
result in unexpected results, loss of data, project delays or
other unpredictable damage or loss.

You may use a pre-release SDK at your own risk, understanding
that pre-release SDKs are not intended for use in production
or business-critical systems.

NVIDIA may choose not to make available a commercial version
of any pre-release SDK. NVIDIA may also choose to abandon
development and terminate the availability of a pre-release
SDK at any time without liability.


1.1.5. Updates

NVIDIA may, at its option, make available patches, workarounds
or other updates to this SDK. Unless the updates are provided
with their separate governing terms, they are deemed part of
the SDK licensed to you as provided in this Agreement. You
agree that the form and content of the SDK that NVIDIA
provides may change without prior notice to you. While NVIDIA
generally maintains compatibility between versions, NVIDIA may
in some cases make changes that introduce incompatibilities in
future versions of the SDK.


1.1.6. Components Under Other Licenses

The SDK may come bundled with, or otherwise include or be
distributed with, NVIDIA or third-party components with
separate legal notices or terms as may be described in
proprietary notices accompanying the SDK. If and to the extent
there is a conflict between the terms in this Agreement and
the license terms associated with the component, the license
terms associated with the components control only to the
extent necessary to resolve the conflict.

Subject to the other terms of this Agreement, you may use the
SDK to develop and test applications released under Open
Source Initiative (OSI) approved open source software
licenses.


1.1.7. Reservation of Rights

NVIDIA reserves all rights, title, and interest in and to the
SDK, not expressly granted to you under this Agreement.


1.2. Limitations

The following license limitations apply to your use of the
SDK:

  1. You may not reverse engineer, decompile or disassemble,
    or remove copyright or other proprietary notices from any
    portion of the SDK or copies of the SDK.

  2. Except as expressly provided in this Agreement, you may
    not copy, sell, rent, sublicense, transfer, distribute,
    modify, or create derivative works of any portion of the
    SDK. For clarity, you may not distribute or sublicense the
    SDK as a stand-alone product.

  3. Unless you have an agreement with NVIDIA for this
    purpose, you may not indicate that an application created
    with the SDK is sponsored or endorsed by NVIDIA.

  4. You may not bypass, disable, or circumvent any
    encryption, security, digital rights management or
    authentication mechanism in the SDK.

  5. You may not use the SDK in any manner that would cause it
    to become subject to an open source software license. As
    examples, licenses that require as a condition of use,
    modification, and/or distribution that the SDK be:

      a. Disclosed or distributed in source code form;

      b. Licensed for the purpose of making derivative works;
        or

      c. Redistributable at no charge.

  6.  You acknowledge that the SDK as delivered is not tested
    or certified by NVIDIA for use in connection with the
    design, construction, maintenance, and/or operation of any
    system where the use or failure of such system could
    result in a situation that threatens the safety of human
    life or results in catastrophic damages (each, a "Critical
    Application"). Examples of Critical Applications include
    use in avionics, navigation, autonomous vehicle
    applications, ai solutions for automotive products,
    military, medical, life support or other life critical
    applications. NVIDIA shall not be liable to you or any
    third party, in whole or in part, for any claims or
    damages arising from such uses. You are solely responsible
    for ensuring that any product or service developed with
    the SDK as a whole includes sufficient features to comply
    with all applicable legal and regulatory standards and
    requirements.

  7.  You agree to defend, indemnify and hold harmless NVIDIA
    and its affiliates, and their respective employees,
    contractors, agents, officers and directors, from and
    against any and all claims, damages, obligations, losses,
    liabilities, costs or debt, fines, restitutions and
    expenses (including but not limited to attorney’s fees
    and costs incident to establishing the right of
    indemnification) arising out of or related to products or
    services that use the SDK in or for Critical Applications,
    and for use of the SDK outside of the scope of this
    Agreement or not in compliance with its terms.

  8. You may not reverse engineer, decompile or disassemble
    any portion of the output generated using SDK elements for
    the purpose of translating such output artifacts to target
    a non-NVIDIA platform.


1.3. Ownership

  1.  NVIDIA or its licensors hold all rights, title and
    interest in and to the SDK and its modifications and
    derivative works, including their respective intellectual
    property rights, subject to your rights under Section
    1.3.2. This SDK may include software and materials from
    NVIDIA’s licensors, and these licensors are intended
    third party beneficiaries that may enforce this Agreement
    with respect to their intellectual property rights.

  2.  You hold all rights, title and interest in and to your
    applications and your derivative works of the sample
    source code delivered in the SDK, including their
    respective intellectual property rights, subject to
    NVIDIA’s rights under Section 1.3.1.

  3. You may, but don’t have to, provide to NVIDIA
    suggestions, feature requests or other feedback regarding
    the SDK, including possible enhancements or modifications
    to the SDK. For any feedback that you voluntarily provide,
    you hereby grant NVIDIA and its affiliates a perpetual,
    non-exclusive, worldwide, irrevocable license to use,
    reproduce, modify, license, sublicense (through multiple
    tiers of sublicensees), and distribute (through multiple
    tiers of distributors) it without the payment of any
    royalties or fees to you. NVIDIA will use feedback at its
    choice. NVIDIA is constantly looking for ways to improve
    its products, so you may send feedback to NVIDIA through
    the developer portal at https://developer.nvidia.com.


1.4. No Warranties

THE SDK IS PROVIDED BY NVIDIA “AS IS” AND “WITH ALL
FAULTS.” TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND
ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND
OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING,
BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, OR THE
ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO
WARRANTY IS MADE ON THE BASIS OF TRADE USAGE, COURSE OF
DEALING OR COURSE OF TRADE.


1.5. Limitation of Liability

TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND ITS
AFFILIATES SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
PUNITIVE OR CONSEQUENTIAL DAMAGES, OR ANY LOST PROFITS, LOSS
OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS OF
PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION
WITH THIS AGREEMENT OR THE USE OR PERFORMANCE OF THE SDK,
WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH
OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE),
PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF
LIABILITY. IN NO EVENT WILL NVIDIA’S AND ITS AFFILIATES
TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS
AGREEMENT EXCEED US$10.00. THE NATURE OF THE LIABILITY OR THE
NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR EXTEND THIS
LIMIT.

These exclusions and limitations of liability shall apply
regardless if NVIDIA or its affiliates have been advised of
the possibility of such damages, and regardless of whether a
remedy fails its essential purpose. These exclusions and
limitations of liability form an essential basis of the
bargain between the parties, and, absent any of these
exclusions or limitations of liability, the provisions of this
Agreement, including, without limitation, the economic terms,
would be substantially different.


1.6. Termination

  1. This Agreement will continue to apply until terminated by
    either you or NVIDIA as described below.

  2. If you want to terminate this Agreement, you may do so by
    stopping to use the SDK.

  3. NVIDIA may, at any time, terminate this Agreement if:

      a. (i) you fail to comply with any term of this
        Agreement and the non-compliance is not fixed within
        thirty (30) days following notice from NVIDIA (or
        immediately if you violate NVIDIA’s intellectual
        property rights);

      b. (ii) you commence or participate in any legal
        proceeding against NVIDIA with respect to the SDK; or

      c. (iii) NVIDIA decides to no longer provide the SDK in
        a country or, in NVIDIA’s sole discretion, the
        continued use of it is no longer commercially viable.

  4. Upon any termination of this Agreement, you agree to
    promptly discontinue use of the SDK and destroy all copies
    in your possession or control. Your prior distributions in
    accordance with this Agreement are not affected by the
    termination of this Agreement. Upon written request, you
    will certify in writing that you have complied with your
    commitments under this section. Upon any termination of
    this Agreement all provisions survive except for the
    license grant provisions.


1.7. General

If you wish to assign this Agreement or your rights and
obligations, including by merger, consolidation, dissolution
or operation of law, contact NVIDIA to ask for permission. Any
attempted assignment not approved by NVIDIA in writing shall
be void and of no effect. NVIDIA may assign, delegate or
transfer this Agreement and its rights and obligations, and if
to a non-affiliate you will be notified.

You agree to cooperate with NVIDIA and provide reasonably
requested information to verify your compliance with this
Agreement.

This Agreement will be governed in all respects by the laws of
the United States and of the State of Delaware as those laws
are applied to contracts entered into and performed entirely
within Delaware by Delaware residents, without regard to the
conflicts of laws principles. The United Nations Convention on
Contracts for the International Sale of Goods is specifically
disclaimed. You agree to all terms of this Agreement in the
English language.

The state or federal courts residing in Santa Clara County,
California shall have exclusive jurisdiction over any dispute
or claim arising out of this Agreement. Notwithstanding this,
you agree that NVIDIA shall still be allowed to apply for
injunctive remedies or an equivalent type of urgent legal
relief in any jurisdiction.

If any court of competent jurisdiction determines that any
provision of this Agreement is illegal, invalid or
unenforceable, such provision will be construed as limited to
the extent necessary to be consistent with and fully
enforceable under the law and the remaining provisions will
remain in full force and effect. Unless otherwise specified,
remedies are cumulative.

Each party acknowledges and agrees that the other is an
independent contractor in the performance of this Agreement.

The SDK has been developed entirely at private expense and is
“commercial items” consisting of “commercial computer
software” and “commercial computer software
documentation” provided with RESTRICTED RIGHTS. Use,
duplication or disclosure by the U.S. Government or a U.S.
Government subcontractor is subject to the restrictions in
this Agreement pursuant to DFARS 227.7202-3(a) or as set forth
in subparagraphs (c)(1) and (2) of the Commercial Computer
Software - Restricted Rights clause at FAR 52.227-19, as
applicable. Contractor/manufacturer is NVIDIA, 2788 San Tomas
Expressway, Santa Clara, CA 95051.

The SDK is subject to United States export laws and
regulations. You agree that you will not ship, transfer or
export the SDK into any country, or use the SDK in any manner,
prohibited by the United States Bureau of Industry and
Security or economic sanctions regulations administered by the
U.S. Department of Treasury’s Office of Foreign Assets
Control (OFAC), or any applicable export laws, restrictions or
regulations. These laws include restrictions on destinations,
end users and end use. By accepting this Agreement, you
confirm that you are not a resident or citizen of any country
currently embargoed by the U.S. and that you are not otherwise
prohibited from receiving the SDK.

Any notice delivered by NVIDIA to you under this Agreement
will be delivered via mail, email or fax. You agree that any
notices that NVIDIA sends you electronically will satisfy any
legal communication requirements. Please direct your legal
notices or other correspondence to NVIDIA Corporation, 2788
San Tomas Expressway, Santa Clara, California 95051, United
States of America, Attention: Legal Department.

This Agreement and any exhibits incorporated into this
Agreement constitute the entire agreement of the parties with
respect to the subject matter of this Agreement and supersede
all prior negotiations or documentation exchanged between the
parties relating to this SDK license. Any additional and/or
conflicting terms on documents issued by you are null, void,
and invalid. Any amendment or waiver under this Agreement
shall be in writing and signed by representatives of both
parties.


2. CUDA Toolkit Supplement to Software License Agreement for
NVIDIA Software Development Kits
------------------------------------------------------------

The terms in this supplement govern your use of the NVIDIA
CUDA Toolkit SDK under the terms of your license agreement
(“Agreement”) as modified by this supplement. Capitalized
terms used but not defined below have the meaning assigned to
them in the Agreement.

This supplement is an exhibit to the Agreement and is
incorporated as an integral part of the Agreement. In the
event of conflict between the terms in this supplement and the
terms in the Agreement, the terms in this supplement govern.


2.1. License Scope

The SDK is licensed for you to develop applications only for
use in systems with NVIDIA GPUs.


2.2. Distribution

The portions of the SDK that are distributable under the
Agreement are listed in Attachment A.


2.3. Operating Systems

Those portions of the SDK designed exclusively for use on the
Linux or FreeBSD operating systems, or other operating systems
derived from the source code to these operating systems, may
be copied and redistributed for use in accordance with this
Agreement, provided that the object code files are not
modified in any way (except for unzipping of compressed
files).


2.4. Audio and Video Encoders and Decoders

You acknowledge and agree that it is your sole responsibility
to obtain any additional third-party licenses required to
make, have made, use, have used, sell, import, and offer for
sale your products or services that include or incorporate any
third-party software and content relating to audio and/or
video encoders and decoders from, including but not limited
to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A.,
MPEG-LA, and Coding Technologies. NVIDIA does not grant to you
under this Agreement any necessary patent or other rights with
respect to any audio and/or video encoders and decoders.


2.5. Licensing

If the distribution terms in this Agreement are not suitable
for your organization, or for any questions regarding this
Agreement, please contact NVIDIA at
nvidia-compute-license-questions@nvidia.com.


2.6. Attachment A

The following CUDA Toolkit files may be distributed with
Licensee Applications developed by you, including certain
variations of these files that have version number or
architecture specific information embedded in the file name -
as an example only, for release version 9.0 of the 64-bit
Windows software, the file cudart64_90.dll is redistributable.

Component

CUDA Runtime

Windows

cudart.dll, cudart_static.lib, cudadevrt.lib

Mac OSX

libcudart.dylib, libcudart_static.a, libcudadevrt.a

Linux

libcudart.so, libcudart_static.a, libcudadevrt.a

Android

libcudart.so, libcudart_static.a, libcudadevrt.a

Component

CUDA FFT Library

Windows

cufft.dll, cufftw.dll, cufft.lib, cufftw.lib

Mac OSX

libcufft.dylib, libcufft_static.a, libcufftw.dylib,
libcufftw_static.a

Linux

libcufft.so, libcufft_static.a, libcufftw.so,
libcufftw_static.a

Android

libcufft.so, libcufft_static.a, libcufftw.so,
libcufftw_static.a

Component

CUDA BLAS Library

Windows

cublas.dll, cublasLt.dll

Mac OSX

libcublas.dylib, libcublasLt.dylib, libcublas_static.a,
libcublasLt_static.a

Linux

libcublas.so, libcublasLt.so, libcublas_static.a,
libcublasLt_static.a

Android

libcublas.so, libcublasLt.so, libcublas_static.a,
libcublasLt_static.a

Component

NVIDIA "Drop-in" BLAS Library

Windows

nvblas.dll

Mac OSX

libnvblas.dylib

Linux

libnvblas.so

Component

CUDA Sparse Matrix Library

Windows

cusparse.dll, cusparse.lib

Mac OSX

libcusparse.dylib, libcusparse_static.a

Linux

libcusparse.so, libcusparse_static.a

Android

libcusparse.so, libcusparse_static.a

Component

CUDA Linear Solver Library

Windows

cusolver.dll, cusolver.lib

Mac OSX

libcusolver.dylib, libcusolver_static.a

Linux

libcusolver.so, libcusolver_static.a

Android

libcusolver.so, libcusolver_static.a

Component

CUDA Random Number Generation Library

Windows

curand.dll, curand.lib

Mac OSX

libcurand.dylib, libcurand_static.a

Linux

libcurand.so, libcurand_static.a

Android

libcurand.so, libcurand_static.a

Component

NVIDIA Performance Primitives Library

Windows

nppc.dll, nppc.lib, nppial.dll, nppial.lib, nppicc.dll,
nppicc.lib, nppicom.dll, nppicom.lib, nppidei.dll,
nppidei.lib, nppif.dll, nppif.lib, nppig.dll, nppig.lib,
nppim.dll, nppim.lib, nppist.dll, nppist.lib, nppisu.dll,
nppisu.lib, nppitc.dll, nppitc.lib, npps.dll, npps.lib

Mac OSX

libnppc.dylib, libnppc_static.a, libnppial.dylib,
libnppial_static.a, libnppicc.dylib, libnppicc_static.a,
libnppicom.dylib, libnppicom_static.a, libnppidei.dylib,
libnppidei_static.a, libnppif.dylib, libnppif_static.a,
libnppig.dylib, libnppig_static.a, libnppim.dylib,
libnppisu_static.a, libnppitc.dylib, libnppitc_static.a,
libnpps.dylib, libnpps_static.a

Linux

libnppc.so, libnppc_static.a, libnppial.so,
libnppial_static.a, libnppicc.so, libnppicc_static.a,
libnppicom.so, libnppicom_static.a, libnppidei.so,
libnppidei_static.a, libnppif.so, libnppif_static.a
libnppig.so, libnppig_static.a, libnppim.so,
libnppim_static.a, libnppist.so, libnppist_static.a,
libnppisu.so, libnppisu_static.a, libnppitc.so
libnppitc_static.a, libnpps.so, libnpps_static.a

Android

libnppc.so, libnppc_static.a, libnppial.so,
libnppial_static.a, libnppicc.so, libnppicc_static.a,
libnppicom.so, libnppicom_static.a, libnppidei.so,
libnppidei_static.a, libnppif.so, libnppif_static.a
libnppig.so, libnppig_static.a, libnppim.so,
libnppim_static.a, libnppist.so, libnppist_static.a,
libnppisu.so, libnppisu_static.a, libnppitc.so
libnppitc_static.a, libnpps.so, libnpps_static.a

Component

NVIDIA JPEG Library

Windows

nvjpeg.lib, nvjpeg.dll

Linux

libnvjpeg.so, libnvjpeg_static.a

Component

Internal common library required for statically linking to
cuBLAS, cuSPARSE, cuFFT, cuRAND, nvJPEG and NPP

Mac OSX

libculibos.a

Linux

libculibos.a

Component

NVIDIA Runtime Compilation Library and Header

All

nvrtc.h

Windows

nvrtc.dll, nvrtc-builtins.dll

Mac OSX

libnvrtc.dylib, libnvrtc-builtins.dylib

Linux

libnvrtc.so, libnvrtc-builtins.so

Component

NVIDIA Optimizing Compiler Library

Windows

nvvm.dll

Mac OSX

libnvvm.dylib

Linux

libnvvm.so

Component

NVIDIA Common Device Math Functions Library

Windows

libdevice.10.bc

Mac OSX

libdevice.10.bc

Linux

libdevice.10.bc

Component

CUDA Occupancy Calculation Header Library

All

cuda_occupancy.h

Component

CUDA Half Precision Headers

All

cuda_fp16.h, cuda_fp16.hpp

Component

CUDA Profiling Tools Interface (CUPTI) Library

Windows

cupti.dll

Mac OSX

libcupti.dylib

Linux

libcupti.so

Component

NVIDIA Tools Extension Library

Windows

nvToolsExt.dll, nvToolsExt.lib

Mac OSX

libnvToolsExt.dylib

Linux

libnvToolsExt.so

Component

NVIDIA CUDA Driver Libraries

Linux

libcuda.so, libnvidia-ptxjitcompiler.so

Component

NVIDIA CUDA File IO Libraries and Header

All

cufile.h

Linux

libcufile.so, libcufile_rdma.so, libcufile_static.a,
libcufile_rdma_static.a

The NVIDIA CUDA Driver Libraries are only distributable in
applications that meet this criteria:

  1. The application was developed starting from a NVIDIA CUDA
    container obtained from Docker Hub or the NVIDIA GPU
    Cloud, and

  2. The resulting application is packaged as a Docker
    container and distributed to users on Docker Hub or the
    NVIDIA GPU Cloud only.

In addition to the rights above, for parties that are
developing software intended solely for use on Jetson
development kits or Jetson modules, and running Linux for
Tegra software, the following shall apply:

  * The SDK may be distributed in its entirety, as provided by
    NVIDIA, and without separation of its components, for you
    and/or your licensees to create software development kits
    for use only on the Jetson platform and running Linux for
    Tegra software.


2.7. Attachment B


Additional Licensing Obligations

The following third party components included in the SOFTWARE
are licensed to Licensee pursuant to the following terms and
conditions:

  1. Licensee's use of the GDB third party component is
    subject to the terms and conditions of GNU GPL v3:

    This product includes copyrighted third-party software licensed
    under the terms of the GNU General Public License v3 ("GPL v3").
    All third-party software packages are copyright by their respective
    authors. GPL v3 terms and conditions are hereby incorporated into
    the Agreement by this reference:     http://www.gnu.org/licenses/gpl.txt

    Consistent with these licensing requirements, the software
    listed below is provided under the terms of the specified
    open source software licenses. To obtain source code for
    software provided under licenses that require
    redistribution of source code, including the GNU General
    Public License (GPL) and GNU Lesser General Public License
    (LGPL), contact oss-requests@nvidia.com. This offer is
    valid for a period of three (3) years from the date of the
    distribution of this product by NVIDIA CORPORATION.

    Component          License
    CUDA-GDB           GPL v3

  2. Licensee represents and warrants that any and all third
    party licensing and/or royalty payment obligations in
    connection with Licensee's use of the H.264 video codecs
    are solely the responsibility of Licensee.

  3. Licensee's use of the Thrust library is subject to the
    terms and conditions of the Apache License Version 2.0.
    All third-party software packages are copyright by their
    respective authors. Apache License Version 2.0 terms and
    conditions are hereby incorporated into the Agreement by
    this reference.
    http://www.apache.org/licenses/LICENSE-2.0.html

    In addition, Licensee acknowledges the following notice:
    Thrust includes source code from the Boost Iterator,
    Tuple, System, and Random Number libraries.

    Boost Software License - Version 1.0 - August 17th, 2003
    . . . .

    Permission is hereby granted, free of charge, to any person or
    organization obtaining a copy of the software and accompanying
    documentation covered by this license (the "Software") to use,
    reproduce, display, distribute, execute, and transmit the Software,
    and to prepare derivative works of the Software, and to permit
    third-parties to whom the Software is furnished to do so, all
    subject to the following:

    The copyright notices in the Software and this entire statement,
    including the above license grant, this restriction and the following
    disclaimer, must be included in all copies of the Software, in whole
    or in part, and all derivative works of the Software, unless such
    copies or derivative works are solely in the form of machine-executable
    object code generated by a source language processor.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
    NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
    ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
    OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

  4. Licensee's use of the LLVM third party component is
    subject to the following terms and conditions:

    ======================================================
    LLVM Release License
    ======================================================
    University of Illinois/NCSA
    Open Source License

    Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
    All rights reserved.

    Developed by:

        LLVM Team

        University of Illinois at Urbana-Champaign

        http://llvm.org

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to
    deal with the Software without restriction, including without limitation the
    rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    sell copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    *  Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimers.

    *  Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimers in the
       documentation and/or other materials provided with the distribution.

    *  Neither the names of the LLVM Team, University of Illinois at Urbana-
       Champaign, nor the names of its contributors may be used to endorse or
       promote products derived from this Software without specific prior
       written permission.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS WITH THE SOFTWARE.

  5. Licensee's use of the PCRE third party component is
    subject to the following terms and conditions:

    ------------
    PCRE LICENCE
    ------------
    PCRE is a library of functions to support regular expressions whose syntax
    and semantics are as close as possible to those of the Perl 5 language.
    Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
    specified below. The documentation for PCRE, supplied in the "doc"
    directory, is distributed under the same terms as the software itself. The
    basic library functions are written in C and are freestanding. Also
    included in the distribution is a set of C++ wrapper functions, and a just-
    in-time compiler that can be used to optimize pattern matching. These are
    both optional features that can be omitted when the library is built.

    THE BASIC LIBRARY FUNCTIONS
    ---------------------------
    Written by:       Philip Hazel
    Email local part: ph10
    Email domain:     cam.ac.uk
    University of Cambridge Computing Service,
    Cambridge, England.
    Copyright (c) 1997-2012 University of Cambridge
    All rights reserved.

    PCRE JUST-IN-TIME COMPILATION SUPPORT
    -------------------------------------
    Written by:       Zoltan Herczeg
    Email local part: hzmester
    Emain domain:     freemail.hu
    Copyright(c) 2010-2012 Zoltan Herczeg
    All rights reserved.

    STACK-LESS JUST-IN-TIME COMPILER
    --------------------------------
    Written by:       Zoltan Herczeg
    Email local part: hzmester
    Emain domain:     freemail.hu
    Copyright(c) 2009-2012 Zoltan Herczeg
    All rights reserved.

    THE C++ WRAPPER FUNCTIONS
    -------------------------
    Contributed by:   Google Inc.
    Copyright (c) 2007-2012, Google Inc.
    All rights reserved.

    THE "BSD" LICENCE
    -----------------
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

      * Redistributions of source code must retain the above copyright notice,
        this list of conditions and the following disclaimer.

      * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.

      * Neither the name of the University of Cambridge nor the name of Google
        Inc. nor the names of their contributors may be used to endorse or
        promote products derived from this software without specific prior
        written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

  6. Some of the cuBLAS library routines were written by or
    derived from code written by Vasily Volkov and are subject
    to the Modified Berkeley Software Distribution License as
    follows:

    Copyright (c) 2007-2009, Regents of the University of California

    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimer in the documentation and/or other materials provided
          with the distribution.
        * Neither the name of the University of California, Berkeley nor
          the names of its contributors may be used to endorse or promote
          products derived from this software without specific prior
          written permission.

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

  7. Some of the cuBLAS library routines were written by or
    derived from code written by Davide Barbieri and are
    subject to the Modified Berkeley Software Distribution
    License as follows:

    Copyright (c) 2008-2009 Davide Barbieri @ University of Rome Tor Vergata.

    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimer in the documentation and/or other materials provided
          with the distribution.
        * The name of the author may not be used to endorse or promote
          products derived from this software without specific prior
          written permission.

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

  8. Some of the cuBLAS library routines were derived from
    code developed by the University of Tennessee and are
    subject to the Modified Berkeley Software Distribution
    License as follows:

    Copyright (c) 2010 The University of Tennessee.

    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimer listed in this license in the documentation and/or
          other materials provided with the distribution.
        * Neither the name of the copyright holders nor the names of its
          contributors may be used to endorse or promote products derived
          from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  9. Some of the cuBLAS library routines were written by or
    derived from code written by Jonathan Hogg and are subject
    to the Modified Berkeley Software Distribution License as
    follows:

    Copyright (c) 2012, The Science and Technology Facilities Council (STFC).

    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimer in the documentation and/or other materials provided
          with the distribution.
        * Neither the name of the STFC nor the names of its contributors
          may be used to endorse or promote products derived from this
          software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE STFC BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
    OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  10. Some of the cuBLAS library routines were written by or
    derived from code written by Ahmad M. Abdelfattah, David
    Keyes, and Hatem Ltaief, and are subject to the Apache
    License, Version 2.0, as follows:

     -- (C) Copyright 2013 King Abdullah University of Science and Technology
      Authors:
      Ahmad Abdelfattah (ahmad.ahmad@kaust.edu.sa)
      David Keyes (david.keyes@kaust.edu.sa)
      Hatem Ltaief (hatem.ltaief@kaust.edu.sa)

      Redistribution  and  use  in  source and binary forms, with or without
      modification,  are  permitted  provided  that the following conditions
      are met:

      * Redistributions  of  source  code  must  retain  the above copyright
        notice,  this  list  of  conditions  and  the  following  disclaimer.
      * Redistributions  in  binary  form must reproduce the above copyright
        notice,  this list of conditions and the following disclaimer in the
        documentation  and/or other materials provided with the distribution.
      * Neither  the  name of the King Abdullah University of Science and
        Technology nor the names of its contributors may be used to endorse
        or promote products derived from this software without specific prior
        written permission.

      THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      ``AS IS''  AND  ANY  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      LIMITED  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      A  PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT NOT
      LIMITED  TO,  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      DATA,  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      THEORY  OF  LIABILITY,  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      OF  THIS  SOFTWARE,  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

  11. Some of the cuSPARSE library routines were written by or
    derived from code written by Li-Wen Chang and are subject
    to the NCSA Open Source License as follows:

    Copyright (c) 2012, University of Illinois.

    All rights reserved.

    Developed by: IMPACT Group, University of Illinois, http://impact.crhc.illinois.edu

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal with the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimers in the documentation and/or other materials provided
          with the distribution.
        * Neither the names of IMPACT Group, University of Illinois, nor
          the names of its contributors may be used to endorse or promote
          products derived from this Software without specific prior
          written permission.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
    IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
    SOFTWARE.

  12. Some of the cuRAND library routines were written by or
    derived from code written by Mutsuo Saito and Makoto
    Matsumoto and are subject to the following license:

    Copyright (c) 2009, 2010 Mutsuo Saito, Makoto Matsumoto and Hiroshima
    University. All rights reserved.

    Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima
    University and University of Tokyo.  All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions and the following
          disclaimer in the documentation and/or other materials provided
          with the distribution.
        * Neither the name of the Hiroshima University nor the names of
          its contributors may be used to endorse or promote products
          derived from this software without specific prior written
          permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  13. Some of the cuRAND library routines were derived from
    code developed by D. E. Shaw Research and are subject to
    the following license:

    Copyright 2010-2011, D. E. Shaw Research.

    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions, and the following disclaimer.
        * Redistributions in binary form must reproduce the above
          copyright notice, this list of conditions, and the following
          disclaimer in the documentation and/or other materials provided
          with the distribution.
        * Neither the name of D. E. Shaw Research nor the names of its
          contributors may be used to endorse or promote products derived
          from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  14. Some of the Math library routines were written by or
    derived from code developed by Norbert Juffa and are
    subject to the following license:

    Copyright (c) 2015-2017, Norbert Juffa
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  15. Licensee's use of the lz4 third party component is
    subject to the following terms and conditions:

    Copyright (C) 2011-2013, Yann Collet.
    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are
    met:

        * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following disclaimer
    in the documentation and/or other materials provided with the
    distribution.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  16. The NPP library uses code from the Boost Math Toolkit,
    and is subject to the following license:

    Boost Software License - Version 1.0 - August 17th, 2003
    . . . .

    Permission is hereby granted, free of charge, to any person or
    organization obtaining a copy of the software and accompanying
    documentation covered by this license (the "Software") to use,
    reproduce, display, distribute, execute, and transmit the Software,
    and to prepare derivative works of the Software, and to permit
    third-parties to whom the Software is furnished to do so, all
    subject to the following:

    The copyright notices in the Software and this entire statement,
    including the above license grant, this restriction and the following
    disclaimer, must be included in all copies of the Software, in whole
    or in part, and all derivative works of the Software, unless such
    copies or derivative works are solely in the form of machine-executable
    object code generated by a source language processor.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
    NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
    ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
    OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

  17. Portions of the Nsight Eclipse Edition is subject to the
    following license:

    The Eclipse Foundation makes available all content in this plug-in
    ("Content"). Unless otherwise indicated below, the Content is provided
    to you under the terms and conditions of the Eclipse Public License
    Version 1.0 ("EPL"). A copy of the EPL is available at http://
    www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program"
    will mean the Content.

    If you did not receive this Content directly from the Eclipse
    Foundation, the Content is being redistributed by another party
    ("Redistributor") and different terms and conditions may apply to your
    use of any object code in the Content. Check the Redistributor's
    license that was provided with the Content. If no such license exists,
    contact the Redistributor. Unless otherwise indicated below, the terms
    and conditions of the EPL still apply to any source code in the
    Content and such source code may be obtained at http://www.eclipse.org.

  18. Some of the cuBLAS library routines uses code from
    OpenAI, which is subject to the following license:

    License URL
    https://github.com/openai/openai-gemm/blob/master/LICENSE

    License Text
    The MIT License

    Copyright (c) 2016 OpenAI (http://openai.com), 2016 Google Inc.

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

  19. Licensee's use of the Visual Studio Setup Configuration
    Samples is subject to the following license:

    The MIT License (MIT)
    Copyright (C) Microsoft Corporation. All rights reserved.

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without restriction,
    including without limitation the rights to use, copy, modify, merge,
    publish, distribute, sublicense, and/or sell copies of the Software,
    and to permit persons to whom the Software is furnished to do so,
    subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

  20. Licensee's use of linmath.h header for CPU functions for
    GL vector/matrix operations from lunarG is subject to the
    Apache License Version 2.0.

  21. The DX12-CUDA sample uses the d3dx12.h header, which is
    subject to the MIT license .

-----------------

nvidia-codec

DESIGNWORKS NVIDIA SDKS,
SAMPLES AND TOOLS AGREEMENT,
DISTRIBUTION RIGHTS (V.13.06.2017)
License

v13.06.2017

|

October 2021

Table of Contents
Chapter 1. SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE
AGREEMENT (with distribution rights)............................................................................ 1
Chapter 2. NOTICES............................................................................................................. 8

DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | ii

Chapter 1.

SOFTWARE
DEVELOPER
KITS, SAMPLES AND TOOLS
LICENSE AGREEMENT (with
distribution rights)

IMPORTANT – READ BEFORE DOWNLOADING, INSTALLING, COPYING OR USING THE
LICENSED SOFTWARE
READ CAREFULLY: This Software Developer Kits, Samples and Tools License Agreement
("Agreement”), made and entered into as of the time and date of click through action (“Effective
Date”), is a legal agreement between you and NVIDIA Corporation ("NVIDIA") and governs the
use of the following NVIDIA deliverables to the extent provided to you under this Agreement:
API’s, source code and header files, data sets and assets (examples include images, textures,
models, scenes, videos, native API input/output files), binary software and/or documentation
(collectively, "Licensed Software"). By downloading, installing, copying, or otherwise using the
Licensed Software, you agree to be bound by the terms of this Agreement. If you do NOT AGREE
TO THE TERMS OF THIS AGREEMENT, DO NOT DOWNLOAD, INSTALL, COPY OR USE THE
NVIDIA LICENSED SOFTWARE. IF YOU ARE ENTERING INTO THIS AGREEMENT ON BEHALF
OF A COMPANY OR OTHER LEGAL ENTITY, YOU REPRESENT THAT YOU HAVE THE LEGAL
AUTHORITY TO BIND THE ENTITY TO THIS AGREEMENT, IN WHICH CASE “YOU” WILL MEAN
THE ENTITY YOU REPRESENT. IF YOU DON’T HAVE SUCH AUTHORITY, OR IF YOU DON’T
ACCEPT ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT, THEN NVIDIA IS UNWILLING
TO LICENSE THE LICENSED SOFTWARE TO YOU, AND YOU MAY NOT DOWNLOAD, INSTALL,
COPY OR USE IT.
1. LICENSE.
1.1 License Grant. Subject to the terms of this Agreement, NVIDIA hereby grants you a
nonexclusive, non-transferable, worldwide, revocable, limited, royalty-free, fully paid-up license
during the term of this Agreement to:
(i) install, use and reproduce the Licensed Software delivered by NVIDIA plus make modifications
and create derivative works of the source code and header files delivered by NVIDIA, provided that
the software is executed only in hardware products as specified by NVIDIA in the accompanying
documentation (such as release notes) as supported, to develop, test and service your products
(each, a “Customer Product”) that are interoperable with supported hardware products. If the
NVIDIA documentation is silent, the supported hardware consists of certain NVIDIA GPUs; and

DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 1

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

(ii) incorporate Licensed Software as delivered by NVIDIA (including source code and header files
as modified by you) into a Customer Product in binary format only and sub-license and distribute
a Customer Product for use by your recipients only in the hardware products specified by NVIDIA
as supported, provided that: (a) all such distributions by you or your distribution channels are
consistent with the terms of this Agreement; and (b) you must enter into enforceable agreements
with your recipients that binds them to terms that are consistent with the terms set forth in this
Agreement for their use of the software binaries, including (without limitation) terms relating to
the license grant and license restrictions, confidentiality and protection of NVIDIA’s intellectual
property rights in and to the software you distributed. You are liable for the distribution and the
use of distributed software if you failed to comply or enforce the distribution requirements of this
Agreement. You agree to notify NVIDIA in writing of any known or suspected use or distribution
of the Licensed Software that are not in compliance with the terms of this Agreement.
1.2 Enterprise and Contractor Usage. Under this Agreement you may allow (i) your Enterprise
employees, and (ii) individuals who work primarily for your Enterprise on a contractor basis
and from your secure network (each a "Contractor") to access and use the Licensed Software
pursuant to the terms in Section 1 solely to perform work on your behalf, provided further
that with respect to Contractors: (i) you obtain a written agreement from the Contractor which
contains terms and obligations with respect to access to or use of Licensed Software no less
protective of NVIDIA than those set forth in this Agreement, and (ii) such Contractor’s access
and use expressly excludes any sublicensing or distribution rights for the Licensed Software.
You are responsible for the compliance with the terms and conditions of this Agreement by your
Enterprise and Contractors. Any act or omission that if committed by you would constitute a
breach of this Agreement shall be deemed to constitute a breach of this Agreement if committed
by your Enterprise or Contractors. “Enterprise” means you or any company or legal entity for
which you accepted the terms of this Agreement, and their subsidiaries of which your company
or legal entity owns more than fifty percent (50%) of the issued and outstanding equity.
1.3 No Support. NVIDIA is under no obligation to provide support for the Licensed Software or to
provide any error corrections or updates to the Licensed Software under this Agreement.
1.4 Product Specific Terms. With respect to the Iray Developer Edition Licensed Software, a
separate license is required from NVIDIA to enable or use the Iray runtime in any given machine.
1.5 Notification. You are required to notify NVIDIA prior to use of the NVIDIA DesignWorks
Licensed Software in a commercial application (including a plug-in to a commercial application).
Please send notification by visiting https://developer.nvidia.com/sw-notification and submitting
the web form requested information. NVIDIA will request company name, DesignWorks software
and version used, platform, commercial application release date, and weblink to product/video.
Failure to notify NVIDIA pursuant to this section shall be considered a material breach of this
Agreement.
2. LIMITATIONS.
2.1 License Restrictions. Except as expressly authorized in this Agreement, you agree that
you will not (nor authorize third parties to): (i) copy and use software that was licensed to
you for use in one or more devices in other unlicensed devices (provided that copies solely
for backup purposes are allowed); (ii) reverse engineer, decompile, disassemble (except to
the extent applicable laws specifically require that such activities be permitted) or attempt to
derive the source code, underlying ideas, algorithm or structure of software provided to you in
object code form; (iii) sell, transfer, assign, distribute, rent, loan, lease, sublicense or otherwise
make available the Licensed Software or its functionality to third parties (a) as an application
DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 2

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

services provider or service bureau, (b) by operating hosted/virtual system environments, (c) by
hosting, time sharing or providing any other type of services, or (d) otherwise by means of the
internet; (iv) modify, translate or otherwise create any derivative works of any of the Licensed
Software; (v) remove, alter, cover or obscure any proprietary notice that appears on or with the
Licensed Software or any copies thereof; (vi) use the Licensed Software, or allow its use, transfer,
transmission or export in violation of any applicable export control laws, rules or regulations;
(vii) distribute, permit access to, or sublicense the Licensed Software as a stand-alone product;
(viii) bypass, disable, circumvent or remove any form of copy protection, encryption, security or
digital rights management or authentication mechanism used by NVIDIA in connection with the
Licensed Software, or use the Licensed Software together with any authorization code, serial
number, or other copy protection device not supplied by NVIDIA directly or through an authorized
reseller; (ix) use the Licensed Software for the purpose of developing competing products or
technologies or assisting a third party in such activities; (x) use the Licensed Software with any
system or application where the use or failure of such system or application can reasonably be
expected to threaten or result in personal injury, death, or catastrophic loss including, without
limitation, use in connection with any nuclear, avionics, navigation, military, medical, life support
or other life critical application (“Critical Applications”), unless the parties have entered into a
Critical Applications agreement; (xi) distribute any modification or derivative work you make to
the Licensed Software under or by reference to the same name as used by NVIDIA; or (xii) use the
Licensed Software in any manner that would cause the Licensed Software to become subject to
an Open Source License. Nothing in this Agreement shall be construed to give you a right to use,
or otherwise obtain access to, any source code from which the software or any portion thereof
is compiled or interpreted. You acknowledge that NVIDIA does not design, test, manufacture or
certify the Licensed Software for use in the context of a Critical Application and NVIDIA shall
not be liable to you or any third party, in whole or in part, for any claims or damages arising
from such use. You agree to defend, indemnify and hold harmless NVIDIA and its affiliates, and
their respective employees, contractors, agents, officers and directors, from and against any
and all claims, damages, obligations, losses, liabilities, costs or debt, fines, restitutions and
expenses (including but not limited to attorney’s fees and costs incident to establishing the right
of indemnification) arising out of or related to you and your Enterprise, and their respective
employees, contractors, agents, distributors, resellers, end users, officers and directors use of
Licensed Software outside of the scope of this Agreement or any other breach of the terms of this
Agreement. “Open Source License” includes, without limitation, a software license that requires
as a condition of use, modification, and/or distribution of such software that the software be (x)
disclosed or distributed in source code form; (y) be licensed for the purpose of making derivative
works; or (z) be redistributable at no charge.
2.2 Third Party License Obligations. You acknowledge and agree that the Licensed Software
may include or incorporate third party technology (collectively “Third Party Components”), which
is provided for use in or with the software and not otherwise used separately. If the Licensed
Software includes or incorporates Third Party Components, then the third-party pass-through
terms and conditions (“Third Party Terms”) for the particular Third Party Component will be
bundled with the software or otherwise made available online as indicated by NVIDIA and will be
incorporated by reference into this Agreement. In the event of any conflict between the terms
in this Agreement and the Third Party Terms, the Third Party Terms shall govern. Copyright
to Third Party Components are held by the copyright holders indicated in the copyright notices
indicated in the Third Party Terms.
Audio/Video Encoders and Decoders. You acknowledge and agree that it is your sole
responsibility to obtain any additional third party licenses required to make, have made, use,
DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 3

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

have used, sell, import, and offer for sale your products or services that include or incorporate
any Third Party Components and content relating to audio and/or video encoders and decoders
from, including but not limited to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A., MPEG-LA,
and Coding Technologies as NVIDIA does not grant to you under this Agreement any necessary
patent rights with respect to audio and/or video encoders and decoders.
2.3 Limited Rights. Your rights in the Licensed Software are limited to those expressly granted
in Section 1 and no other licenses are granted whether by implication, estoppel or otherwise.
NVIDIA reserves all rights, title and interest in and to the Licensed Software not expressly
granted under this Agreement.
3. CONFIDENTIALITY. Neither party will use the other party’s Confidential Information, except as
necessary for the performance of this Agreement, nor will either party disclose such Confidential
Information to any third party, except to personnel of NVIDIA and its affiliates, you, your
Enterprise, your Enterprise Contractors, and each party’s legal and financial advisors that have
a need to know such Confidential Information for the performance of this Agreement, provided
that each such personnel, employee and Contractor is subject to a written agreement that
includes confidentiality obligations consistent with those set forth herein. Each party will use
all reasonable efforts to maintain the confidentiality of all of the other party’s Confidential
Information in its possession or control, but in no event less than the efforts that it ordinarily
uses with respect to its own Confidential Information of similar nature and importance. The
foregoing obligations will not restrict either party from disclosing the other party’s Confidential
Information or the terms and conditions of this Agreement as required under applicable
securities regulations or pursuant to the order or requirement of a court, administrative agency,
or other governmental body, provided that the party required to make such disclosure (i) gives
reasonable notice to the other party to enable it to contest such order or requirement prior to its
disclosure (whether through protective orders or otherwise), (ii) uses reasonable effort to obtain
confidential treatment or similar protection to the fullest extent possible to avoid such public
disclosure, and (iii) discloses only the minimum amount of information necessary to comply with
such requirements.
“Confidential Information” means the Licensed Software (unless made publicly available
by NVIDIA without confidentiality obligations), and any NVIDIA business, marketing, pricing,
research and development, know-how, technical, scientific, financial status, proposed new
products or other information disclosed by NVIDIA to you which, at the time of disclosure,
is designated in writing as confidential or proprietary (or like written designation), or orally
identified as confidential or proprietary or is otherwise reasonably identifiable by parties
exercising reasonable business judgment as confidential. Confidential Information does not and
will not include information that: (i) is or becomes generally known to the public through no fault
of or breach of this Agreement by the receiving party; (ii) is rightfully known by the receiving
party at the time of disclosure without an obligation of confidentiality; (iii) is independently
developed by the receiving party without use of the disclosing party’s Confidential Information;
or (iv) is rightfully obtained by the receiving party from a third party without restriction on use
or disclosure.
4. OWNERSHIP.
4.1 Ownership of Licensed Software. The Licensed Software, and the respective intellectual
property rights therein, is and will remain the sole and exclusive property of NVIDIA and its
licensors, whether the Licensed Software is separate from or combined with any other products
or materials. You shall not knowingly engage in any act or omission that would impair NVIDIA’s
DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 4

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

and/or its licensors’ intellectual property rights in the Licensed Software or any other materials,
information, processes or subject matter proprietary to NVIDIA. NVIDIA’s licensors are intended
third party beneficiaries with the right to enforce provisions of this Agreement with respect to
their Confidential Information and/or intellectual property rights.
4.2 Modifications. You have no obligation to provide your permitted modifications to NVIDIA.
You hold all rights, title and interest in and to the modifications to and derivative works of
the NVIDIA source code and header files that you create as permitted hereunder, subject
to NVIDIA’s underlying intellectual property rights in and to the NVIDIA software; provided,
however that you grant NVIDIA, its affiliates and their respective customers an irrevocable,
perpetual, nonexclusive, worldwide, royalty-free paid-up license to make, have made, use, have
used, reproduce, sell, license, distribute, sublicense, transfer and otherwise commercialize
modifications and derivative works including (without limitation) with the Licensed Software or
other products, technologies or materials.
5. FEEDBACK. You have no obligation to provide Feedback to NVIDIA. However, NVIDIA and/or its
affiliates may use and include any Feedback that you provide to improve the Licensed Software
or other NVIDIA products, technologies or materials. Accordingly, if you provide Feedback,
you agree that NVIDIA and/or its affiliates may at their option, and may permit its licensees,
to make, have made, use, have used, reproduce, sell, license, distribute, sublicense, transfer
and otherwise commercialize the Feedback in the Licensed Software or in other products,
technologies or materials without the payment of any royalties or fees to you. All Feedback
becomes the sole property of NVIDIA and may be used in any manner NVIDIA sees fit, and you
hereby assign to NVIDIA all of your right, title and interest in and to any Feedback. NVIDIA has
no obligation to respond to Feedback or to incorporate Feedback into the Licensed Software.
“Feedback” means any and all suggestions, feature requests, comments or other feedback
relating to the Licensed Software, including possible enhancements or modifications thereto.
6. NO WARRANTIES. THE LICENSED SOFTWARE IS PROVIDED BY NVIDIA “AS IS” AND “WITH
ALL FAULTS,” AND NVIDIA EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND OR
NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
TO, ANY WARRANTIES OF OPERABILITY, CONDITION, VALUE, ACCURACY OF DATA, OR
QUALITY, AS WELL AS ANY WARRANTIES OF MERCHANTABILITY, SYSTEM INTEGRATION,
WORKMANSHIP, SUITABILITY, NON-INFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
OR THE ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO WARRANTY
IS MADE BY NVIDIA ON THE BASIS OF TRADE USAGE, COURSE OF DEALING OR COURSE
OF TRADE. NVIDIA DOES NOT WARRANT THAT THE LICENSED SOFTWARE WILL MEET
YOUR REQUIREMENTS OR THAT THE OPERATION THEREOF WILL BE UNINTERRUPTED
OR ERRORFREE, OR THAT ALL ERRORS WILL BE CORRECTED. YOU ACKNOWLEDGE THAT
NVIDIA’S OBLIGATIONS UNDER THIS AGREEMENT ARE FOR THE BENEFIT OF YOU ONLY.
Nothing in this warranty section affects any statutory rights of consumers or other recipients to
the extent that they cannot be waived or limited by contract under applicable law.
7. LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY LAW NVIDIA OR
ITS LICENSORS SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL, PUNITIVE OR
CONSEQUENTIAL DAMAGES, OR ANY LOST PROFITS, LOSS OF USE, LOSS OF DATA OR
LOSS OF GOODWILL), OR THE COSTS OF PROCURING SUBSTITUTE PRODUCTS, ARISING
OUT OF OR IN CONNECTION WITH THIS AGREEMENT OR THE USE OR PERFORMANCE OF
THE LICENSED SOFTWARE, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED
UPON BREACH OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE),
PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF LIABILITY. IN NO
DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 5

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

EVENT WILL NVIDIA’S TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS
AGREEMENT EXCEED THE GREATER OF THE NET AMOUNT NVIDIA RECEIVED FOR YOUR USE
OF THE LICENSED SOFTWARE ONE HUNDRED U.S. DOLLARS (US $100). THE NATURE OF THE
LIABILITY, THE NUMBER OF CLAIMS OR SUITS OR THE NUMBER OF PARTIES WITHIN YOUR
ENTERPRISE THAT ACCEPTED THE TERMS OF THIS AGREEMENT SHALL NOT ENLARGE OR
EXTEND THIS LIMIT. THE FOREGOING LIMITATIONS SHALL APPLY REGARDLESS OF WHETHER
NVIDIA OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
REGARDLESS OF WHETHER ANY REMEDY FAILS ITS ESSENTIAL PURPOSE.
8. TERM AND TERMINATION. This Agreement and your licenses hereunder shall become
effective upon the Effective Date and shall remain in effect unless and until terminated as
follows: (i) automatically if you breach any of the terms of this Agreement; or (ii) by either party
upon written notice if the other party becomes the subject of a voluntary or involuntary petition
in bankruptcy or any proceeding relating to insolvency, receivership, liquidation or composition
for the benefit of creditors, if that petition or proceeding is not dismissed with prejudice within
sixty (60) days after filing, or if a party ceases to do business; (iii) by you, upon ceasing to use the
Licensed Software provided under this Agreement; or (iv) by NVIDIA upon written notice if you
commence or participate in any legal proceeding against NVIDIA, with respect to the Licensed
Software that is the subject of the proceeding during the pendency of such legal proceeding.
Termination of this Agreement regardless of cause or nature shall be without prejudice to any
other rights or remedies of the parties and shall be without liability for any loss or damage
occasioned thereby. Upon any expiration or termination of this Agreement (i) you must promptly
discontinue use of the Licensed Software, and (ii) you must promptly destroy or return to NVIDIA
all copies of the Licensed Software and all portions thereof in your possession or control, and
each party will promptly destroy or return to the other all of the other party’s Confidential
Information within its possession or control, provided that your prior distributions in accordance
with this Agreement are not affected by the expiration or termination of this Agreement. Upon
written request, you will certify in writing that you have complied with your obligations under
this section. Sections 2 through 9 will survive the expiration or termination of this Agreement
for any reason.
9. GENERAL. This Agreement constitutes the entire agreement of the parties with respect to
the subject matter hereto and supersedes all prior negotiations, conversations, or discussions
between the parties relating to the subject matter hereto, oral or written, and all past dealings or
industry custom. Any additional and/or conflicting terms and conditions on purchase order(s) or
any other documents issued by you are null, void, and invalid. Any amendment or waiver under
this Agreement must be in writing and signed by representatives of both parties.
This Agreement and the rights and obligations thereunder may not be assigned by you, in whole
or in part, including by merger, consolidation, dissolution, operation of law, or any other manner,
without written consent of NVIDIA, and any purported assignment in violation of this provision
shall be void and of no effect. NVIDIA may assign, delegate or transfer this Agreement and its
rights and obligations hereunder, and if to a non-affiliate you will be notified.
Each party acknowledges and agrees that the other is an independent contractor in the
performance of this Agreement, and each party is solely responsible for all of its employees,
agents, contractors, and labor costs and expenses arising in connection therewith. The parties
are not partners, joint ventures or otherwise affiliated, and neither has any authority to make any
statements, representations or commitments of any kind to bind the other party without prior
written consent.

DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 6

SOFTWARE DEVELOPER KITS, SAMPLES AND TOOLS LICENSE AGREEMENT (with distribution rights)

Neither party will be responsible for any failure or delay in its performance under this Agreement
(except for any payment obligations) to the extent due to causes beyond its reasonable control
for so long as such force majeure event continues in effect.
This Agreement will be governed by and construed under the laws of the State of Delaware and
the United States without regard to the conflicts of law provisions thereof and without regard
to the United Nations Convention on Contracts for the International Sale of Goods. The parties
consent to the personal jurisdiction of the federal and state courts located in Santa Clara County,
California. You acknowledge and agree that a breach of any of your promises or agreements
contained in this Agreement may result in irreparable and continuing injury to NVIDIA for which
monetary damages may not be an adequate remedy and therefore NVIDIA is entitled to seek
injunctive relief as well as such other and further relief as may be appropriate. If any court
of competent jurisdiction determines that any provision of this Agreement is illegal, invalid or
unenforceable, the remaining provisions will remain in full force and effect. Unless otherwise
specified, remedies are cumulative.
The Licensed Software has been developed entirely at private expense and is “commercial
items” consisting of “commercial computer software” and “commercial computer software
documentation” provided with RESTRICTED RIGHTS. Use, duplication or disclosure by the U.S.
Government or a U.S. Government subcontractor is subject to the restrictions set forth in this
Agreement pursuant to DFARS 227.7202-3(a) or as set forth in subparagraphs (c)(1) and (2) of
the Commercial Computer Software - Restricted Rights clause at FAR 52.227-19, as applicable.
Contractor/manufacturer is NVIDIA, 2701 San Tomas Expressway, Santa Clara, CA 95050.
You acknowledge that the Licensed Software described under this Agreement is subject to
export control under the U.S. Export Administration Regulations (EAR) and economic sanctions
regulations administered by the U.S. Department of Treasury’s Office of Foreign Assets Control
(OFAC). Therefore, you may not export, reexport or transfer in-country the Licensed Software
without first obtaining any license or other approval that may be required by BIS and/or OFAC.
You are responsible for any violation of the U.S. or other applicable export control or economic
sanctions laws, regulations and requirements related to the Licensed Software. By accepting
this SLA, you confirm that you are not a resident or citizen of any country currently embargoed
by the U.S. and that you are not otherwise prohibited from receiving the Licensed Software.
Any notice delivered by NVIDIA to you under this Agreement will be delivered via mail, email or
fax. Please direct your legal notices or other correspondence to NVIDIA Corporation, 2701 San
Tomas Expressway, Santa Clara, California 95050, United States of America, Attention: Legal
Department.

DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 7

Chapter 2.

NOTICES

This SDK includes portions of FFMPEG under GNU LESSER GENERAL PUBLIC LICENSE
(Version 3, 29 June 2007) license. A copy of the license is present in the SDK package

DESIGNWORKS NVIDIA SDKS, SAMPLES AND TOOLS
AGREEMENT, DISTRIBUTION RIGHTS (V.13.06.2017)

v13.06.2017 | 8

onevpl

MIT License

Copyright (c) 2020 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

openssl


  LICENSE ISSUES
  ==============

  The OpenSSL toolkit stays under a double license, i.e. both the conditions of
  the OpenSSL License and the original SSLeay license apply to the toolkit.
  See below for the actual license texts.

  OpenSSL License
  ---------------

/* ====================================================================
 * Copyright (c) 1998-2019 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

 Original SSLeay License
 -----------------------

/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

opus

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pixman

The following is the MIT license, agreed upon by most contributors.
Copyright holders of new code should use this license statement where
possible. They may also add themselves to the list below.

/*
 * Copyright 1987, 1988, 1989, 1998  The Open Group
 * Copyright 1987, 1988, 1989 Digital Equipment Corporation
 * Copyright 1999, 2004, 2008 Keith Packard
 * Copyright 2000 SuSE, Inc.
 * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
 * Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
 * Copyright 2004 Nicholas Miell
 * Copyright 2005 Lars Knoll & Zack Rusin, Trolltech
 * Copyright 2005 Trolltech AS
 * Copyright 2007 Luca Barbato
 * Copyright 2008 Aaron Plattner, NVIDIA Corporation
 * Copyright 2008 Rodrigo Kumpera
 * Copyright 2008 André Tupinambá
 * Copyright 2008 Mozilla Corporation
 * Copyright 2008 Frederic Plourde
 * Copyright 2009, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2009, 2010 Nokia Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

rist

Copyright © 2019-2020, VideoLAN and librist authors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

rist-cpp

Copyright © 2019-2020, VideoLAN and librist authors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

spdlog

The MIT License (MIT)

Copyright (c) 2016 Gabi Melman.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

-- NOTE: Third party dependency used by this software --
This software depends on the fmt lib (MIT License),
and users must comply to its license: https://raw.githubusercontent.com/fmtlib/fmt/master/LICENSE

srt

Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to
    the creation of, or owns Covered Software.

1.2. "Contributor Version"
    means the combination of the Contributions of others (if any) used
    by a Contributor and that particular Contributor's Contribution.

1.3. "Contribution"
    means Covered Software of a particular Contributor.

1.4. "Covered Software"
    means Source Code Form to which the initial Contributor has attached
    the notice in Exhibit A, the Executable Form of such Source Code
    Form, and Modifications of such Source Code Form, in each case
    including portions thereof.

1.5. "Incompatible With Secondary Licenses"
    means

    (a) that the initial Contributor has attached the notice described
        in Exhibit B to the Covered Software; or

    (b) that the Covered Software was made available under the terms of
        version 1.1 or earlier of the License, but not also under the
        terms of a Secondary License.

1.6. "Executable Form"
    means any form of the work other than Source Code Form.

1.7. "Larger Work"
    means a work that combines Covered Software with other material, in
    a separate file or files, that is not Covered Software.

1.8. "License"
    means this document.

1.9. "Licensable"
    means having the right to grant, to the maximum extent possible,
    whether at the time of the initial grant or subsequently, any and
    all of the rights conveyed by this License.

1.10. "Modifications"
    means any of the following:

    (a) any file in Source Code Form that results from an addition to,
        deletion from, or modification of the contents of Covered
        Software; or

    (b) any new file in Source Code Form that contains any Covered
        Software.

1.11. "Patent Claims" of a Contributor
    means any patent claim(s), including without limitation, method,
    process, and apparatus claims, in any patent Licensable by such
    Contributor that would be infringed, but for the grant of the
    License, by the making, using, selling, offering for sale, having
    made, import, or transfer of either its Contributions or its
    Contributor Version.

1.12. "Secondary License"
    means either the GNU General Public License, Version 2.0, the GNU
    Lesser General Public License, Version 2.1, the GNU Affero General
    Public License, Version 3.0, or any later versions of those
    licenses.

1.13. "Source Code Form"
    means the form of the work preferred for making modifications.

1.14. "You" (or "Your")
    means an individual or a legal entity exercising rights under this
    License. For legal entities, "You" includes any entity that
    controls, is controlled by, or is under common control with You. For
    purposes of this definition, "control" means (a) the power, direct
    or indirect, to cause the direction or management of such entity,
    whether by contract or otherwise, or (b) ownership of more than
    fifty percent (50%) of the outstanding shares or beneficial
    ownership of such entity.

2. License Grants and Conditions
--------------------------------

2.1. Grants

Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:

(a) under intellectual property rights (other than patent or trademark)
    Licensable by such Contributor to use, reproduce, make available,
    modify, display, perform, distribute, and otherwise exploit its
    Contributions, either on an unmodified basis, with Modifications, or
    as part of a Larger Work; and

(b) under Patent Claims of such Contributor to make, use, sell, offer
    for sale, have made, import, and otherwise transfer either its
    Contributions or its Contributor Version.

2.2. Effective Date

The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.

2.3. Limitations on Grant Scope

The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:

(a) for any code that a Contributor has removed from Covered Software;
    or

(b) for infringements caused by: (i) Your and any other third party's
    modifications of Covered Software, or (ii) the combination of its
    Contributions with other software (except as part of its Contributor
    Version); or

(c) under Patent Claims infringed by Covered Software in the absence of
    its Contributions.

This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).

2.4. Subsequent Licenses

No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).

2.5. Representation

Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.

2.6. Fair Use

This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.

2.7. Conditions

Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.

3. Responsibilities
-------------------

3.1. Distribution of Source Form

All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.

3.2. Distribution of Executable Form

If You distribute Covered Software in Executable Form then:

(a) such Covered Software must also be made available in Source Code
    Form, as described in Section 3.1, and You must inform recipients of
    the Executable Form how they can obtain a copy of such Source Code
    Form by reasonable means in a timely manner, at a charge no more
    than the cost of distribution to the recipient; and

(b) You may distribute such Executable Form under the terms of this
    License, or sublicense it under different terms, provided that the
    license for the Executable Form does not attempt to limit or alter
    the recipients' rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).

3.4. Notices

You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.

4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------

If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.

5. Termination
--------------

5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.

************************************************************************
*                                                                      *
*  6. Disclaimer of Warranty                                           *
*  -------------------------                                           *
*                                                                      *
*  Covered Software is provided under this License on an "as is"       *
*  basis, without warranty of any kind, either expressed, implied, or  *
*  statutory, including, without limitation, warranties that the       *
*  Covered Software is free of defects, merchantable, fit for a        *
*  particular purpose or non-infringing. The entire risk as to the     *
*  quality and performance of the Covered Software is with You.        *
*  Should any Covered Software prove defective in any respect, You     *
*  (not any Contributor) assume the cost of any necessary servicing,   *
*  repair, or correction. This disclaimer of warranty constitutes an   *
*  essential part of this License. No use of any Covered Software is   *
*  authorized under this License except under this disclaimer.         *
*                                                                      *
************************************************************************

************************************************************************
*                                                                      *
*  7. Limitation of Liability                                          *
*  --------------------------                                          *
*                                                                      *
*  Under no circumstances and under no legal theory, whether tort      *
*  (including negligence), contract, or otherwise, shall any           *
*  Contributor, or anyone who distributes Covered Software as          *
*  permitted above, be liable to You for any direct, indirect,         *
*  special, incidental, or consequential damages of any character      *
*  including, without limitation, damages for lost profits, loss of    *
*  goodwill, work stoppage, computer failure or malfunction, or any    *
*  and all other commercial damages or losses, even if such party      *
*  shall have been informed of the possibility of such damages. This   *
*  limitation of liability shall not apply to liability for death or   *
*  personal injury resulting from such party's negligence to the       *
*  extent applicable law prohibits such limitation. Some               *
*  jurisdictions do not allow the exclusion or limitation of           *
*  incidental or consequential damages, so this exclusion and          *
*  limitation may not apply to You.                                    *
*                                                                      *
************************************************************************

8. Litigation
-------------

Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.

9. Miscellaneous
----------------

This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.

10. Versions of the License
---------------------------

10.1. New Versions

Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.

10.2. Effect of New Versions

You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.

10.3. Modified Versions

If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses

If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice
-------------------------------------------

  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------

  This Source Code Form is "Incompatible With Secondary Licenses", as
  defined by the Mozilla Public License, v. 2.0.

srt-cpp

Copyright (c) 2020 Anders Cedronius

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

systemd

GNU LESSER GENERAL PUBLIC LICENSE

Version 2.1, February 1999

Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.

When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.

To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.

To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.

Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.

Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.
    b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
    c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
    d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

    a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
    b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
    c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
    d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
    e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
    b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).

To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the library's name and an idea of what it does.
Copyright (C) year  name of author

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.

signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice

That's all there is to it!

uuid

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

va

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sub license, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:

    The above copyright notice and this permission notice (including the
    next paragraph) shall be included in all copies or substantial portions
    of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
    IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

zlib

/* zlib.h -- interface of the 'zlib' general purpose compression library
  version 1.2.12, March 27th, 2022

  Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Jean-loup Gailly        Mark Adler
  jloup@gzip.org          madler@alumni.caltech.edu

*/

zstandard

BSD License

For Zstandard software

Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither the name Facebook, nor Meta, nor the names of its contributors may
   be used to endorse or promote products derived from this software without
   specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

1.8.2 - REST API Credits

Third party libraries used in Agile Live System Controller REST API and their licenses

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryLicenseChecked At
github.com/ajg/formBSD-3-Clause2024-01-25
github.com/beorn7/perks/quantileMIT2024-01-25
github.com/cespare/xxhash/v2MIT2024-01-25
github.com/gabriel-vasile/mimetypeMIT2024-01-25
github.com/go-chi/chi/v5MIT2024-01-25
github.com/go-chi/corsMIT2024-01-25
github.com/go-chi/httplogMIT2024-01-25
github.com/go-chi/renderMIT2024-01-25
github.com/go-openapi/jsonpointerApache-2.02024-01-25
github.com/go-openapi/jsonreferenceApache-2.02024-01-25
github.com/go-openapi/specApache-2.02024-01-25
github.com/go-openapi/swagApache-2.02024-01-25
github.com/go-playground/localesMIT2024-01-25
github.com/go-playground/universal-translatorMIT2024-01-25
github.com/go-playground/validator/v10MIT2024-01-25
github.com/gofrs/uuidMIT2024-01-25
github.com/gorilla/websocketBSD-3-Clause2024-01-25
github.com/josharian/internMIT2024-01-25
github.com/kkyr/figApache-2.02024-01-25
github.com/KyleBanks/depthMIT2024-01-25
github.com/leodido/go-urnMIT2024-01-25
github.com/mailru/easyjsonMIT2024-01-25
github.com/mattn/go-colorableMIT2024-01-25
github.com/mattn/go-isattyMIT2024-01-25
github.com/mitchellh/mapstructureMIT2024-01-25
github.com/pelletier/go-toml/v2MIT2024-01-25
github.com/prometheus/client_golang/prometheusApache-2.02024-01-25
github.com/prometheus/client_model/goApache-2.02024-01-25
github.com/prometheus/common/internal/bitbucket.org/ww/goautonegBSD-3-Clause2024-01-25
github.com/prometheus/commonApache-2.02024-01-25
github.com/prometheus/procfsApache-2.02024-01-25
github.com/rs/zerologMIT2024-01-25
github.com/swaggo/filesMIT2024-01-25
github.com/swaggo/http-swaggerMIT2024-01-25
github.com/swaggo/swagMIT2024-01-25
github.com/wagslane/go-password-validatorMIT2024-01-25
golang.org/x/cryptoBSD-3-Clause2024-01-25
golang.org/x/netBSD-3-Clause2024-01-25
golang.org/x/sys/unixBSD-3-Clause2024-01-25
golang.org/x/textBSD-3-Clause2024-01-25
golang.org/x/time/rateBSD-3-Clause2024-01-25
golang.org/x/toolsBSD-3-Clause2024-01-25
google.golang.org/protobufBSD-3-Clause2024-01-25
gopkg.in/natefinch/lumberjack.v2MIT2024-01-25
gopkg.in/yaml.v3MIT2024-01-25

License Details

This section includes all the licenses/notices for each dependency verbatim

github.com/ajg/form

LICENSE

Copyright (c) 2014 Alvaro J. Genial. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/beorn7/perks/quantile

LICENSE

Copyright (C) 2013 Blake Mizerany

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/cespare/xxhash/v2

LICENSE

Copyright (c) 2016 Caleb Spare

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/gabriel-vasile/mimetype

LICENSE

MIT License

Copyright (c) 2018-2020 Gabriel Vasile

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/chi/v5

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/cors

LICENSE

Copyright (c) 2014 Olivier Poitrey rs@dailymotion.com Copyright (c) 2016-Present https://github.com/go-chi authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/httplog

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka).

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/render

LICENSE

Copyright (c) 2016-Present https://github.com/go-chi authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonpointer

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/jsonreference

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/spec

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/swag

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/locales

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/universal-translator

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/validator/v10

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Dean Karn

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/gofrs/uuid

LICENSE

Copyright (C) 2013-2018 by Maxim Bublis b@codemonkey.ru

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/gorilla/websocket

LICENSE

Copyright (c) 2023 The Gorilla Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright

notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/josharian/intern

license

MIT License

Copyright (c) 2019 Josh Bleecher Snyder

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/kkyr/fig

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright 2020 Kyriacos Kyriacou contact@kkyr.io

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/KyleBanks/depth

LICENSE

MIT License

Copyright (c) 2017 Kyle Banks

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/leodido/go-urn

LICENSE

MIT License

Copyright (c) 2018 Leonardo Di Donato

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mailru/easyjson

LICENSE

Copyright (c) 2016 Mail.Ru Group

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mattn/go-colorable

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Yasuhiro Matsumoto

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mattn/go-isatty

LICENSE

Copyright (c) Yasuhiro MATSUMOTO mattn.jp@gmail.com

MIT License (Expat)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mitchellh/mapstructure

LICENSE

The MIT License (MIT)

Copyright (c) 2013 Mitchell Hashimoto

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/pelletier/go-toml/v2

LICENSE

The MIT License (MIT)

go-toml v2 Copyright (c) 2021 - 2023 Thomas Pelletier

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_golang/prometheus

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

The following components are included in this product:

perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.

Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.

Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0

github.com/prometheus/client_model/go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/common

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg

README

PACKAGE

package goautoneg import “bitbucket.org/ww/goautoneg”

HTTP Content-Type Autonegotiation.

The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FUNCTIONS

func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.

func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses

TYPES

type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header

SUBDIRECTORIES

.hg

github.com/prometheus/procfs

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.

Copyright 2014-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/rs/zerolog

LICENSE

MIT License

Copyright (c) 2017 Olivier Poitrey

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/files

LICENSE

MIT License

Copyright (c) 2019 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/http-swagger

LICENSE

MIT License

Copyright (c) 2018 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/swag

license

MIT License

Copyright (c) 2017 Eason Lin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/wagslane/go-password-validator

LICENSE

MIT License

Copyright (c) 2020 Lane Wagner

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

golang.org/x/crypto

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/net

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/sys/unix

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/text

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/time/rate

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/tools

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

google.golang.org/protobuf

LICENSE

Copyright (c) 2018 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

gopkg.in/natefinch/lumberjack.v2

LICENSE

The MIT License (MIT)

Copyright (c) 2014 Nate Finch

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

gopkg.in/yaml.v3

LICENSE

This project is covered by two different licenses: MIT and Apache.

MIT License

The following files were ported to Go from C files of libyaml, and thus are still covered by their original MIT license, with the additional copyright staring in 2011 when the project was ported over:

apic.go emitterc.go parserc.go readerc.go scannerc.go
writerc.go yamlh.go yamlprivateh.go

Copyright (c) 2006-2010 Kirill Simonov Copyright (c) 2006-2011 Kirill Simonov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Apache License

All the remaining project files are covered by the Apache license:

Copyright (c) 2011-2019 Canonical Ltd

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2011-2016 Canonical Ltd.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

2 - ACP

ACP - Product Documentation

2.1 - Overview

StreamBuilder components

This is the new public documentation of Edgeware’s StreamBuilder. StreamBuilder is a platform for streaming HLS, MPEG-DASH and MSS from a common intermediate CMAF format.

Benefits

With StreamBuilder you can store a single copy of your media and stream it in many different formats like HLS, DASH and MSS with different kinds of encryption and different types of manifests and SCTE markers.

New Components

We are currently developing a couple of new components, and at the same time we make the documentation public here. These components are:

The ESB3019 ew-vod2cbm service is a good source for creating FAST channels with ads from VoD assets.

The ESB3020 ew-manip service can manipulate DASH and HLS manifests.

Older components

StreamBuilder have many services whose documentation is delivered together with the software. These include

  • ESB3003 - live ingest and circular buffer manager
  • ESB3002 - the repackager
  • ESB3005 - recorder and VoD ingest
  • ESB3009 - DRM Gateway

The intention is that the documentation for these components and for use cases where the different components are combined will be published here as well.

2.2 - VoD to Linear (ew-vod2cbm)

Make linear channels with ads and ad markers from VoD and file assets

2.2.1 - General

General description of ESB3019 - the ew-vod2cbm service

The core of the ESB3019 product is ew-vod2cbm. The ew-vod2cbm service provides linear video or audio channels via the Edgeware CBM HTTP interface from playlists of VoD assets.

The benefit of using the CBM interface is that the EW repackager sees the source as an ordinary live channel as a normal Edgeware live channel as would originate from the Catchup Buffer Manager (CBM) and can thereby encrypt and package content in all its usual output formats.

The HTTP interface also allows for running the ew-vod2cbm service on a different machine than the EW repackager ESB3002.

Main concepts

To get an efficient and versatile service, it is essential to prepare content in a stream-lined way so that playlists and other metadata content can be minimal and stitching of content can be done on GoP boundaries with no alignment issues.

The main concepts for such a solution are:

  1. Prepare content in a homogeneous way.
  2. Ingest content using ESB3005 into CMAF/ESF format or use DASH OnDemand assets
  3. Start up the server with or without assets and channels configured
  4. Use CBM HTTP interface for repackager integration
  5. Update the assets, channels, and schedules of the channels dynamically via the REST API.

Step 1 and 2 may be fulfilled by a recording of a live channel. Such a recording can be made using the ew-recorder tool of ESB3005 as described in the ESB3005 user guide.

You can also start with VoD assets. If the VoD asset is already in DASH OnDemand format it may work as it is, but otherwise it needs to be converted to ESF format using the ESB3005 ew-recorder component. If the asset consists of SMIL + mp4 + subtitle files, it can also be ingested using the new ESB3021 ew-vodingest tool. That tool can also ingest a directory containing mp4 and subtitle files without referring to a SMIL file.

Supported codecs and formats

The VoD assets must be in DASH OnDemand or Edgeware’s ESF format. In both cases, the audio and video should be in CMAF track files. For subtitles, the DASH OnDemand ingest uses one complete non-segmented side-car file per language, while ESF uses a CMAF track with wvtt segments

The supported codecs are

  • video: AVC/H.264 and HEVC/H.265
  • audio: AAC-LC, HE-AACv1, HE-AACv2
  • DASH OnDemand subtitles: TTML, WebVTT, SRT, STL
  • ESF subtitles: wvtt

2.2.2 - Details

More details on how the ew-vod2cbm service works

1. Prepare content

All content must be reasonably similar in order to be stitched into a continuous channel. For each channel a content template is used to define how the output linear channel will look when it comes to signaled tracks, codecs, languages, bitrate, variant names etc. The content template format is described in the Content Templates section.

For flexible content handling, the restrictions are rather loose and should be fulfilled by much content out there

  1. Constant video GoP duration, such as 1.92s, 2s, or 2.002s
  2. Constant sample duration (frame rate) in all input MP4 files
  3. Compatible tracks in all ingested content that should go into one channel. The track matching is described in the Asset Track Matching section

These requirements are quite relaxed compared to the early restrictions (v0.6.x) that required that audio and video had exactly the same segment duration, and segments were built by combining these.

2. Store content as ESF VoD assets

To get content in ESF/CMAF format, one can either use a recording or ingest video using the Edgeware ESB3005 tool CMAF/ESF. One can also ingest using the new ESB3021 ew-vodingest tool.

However, it is beneficial that all VoD assets are very similar when it comes to resolutions, bit rates, SPS/PPS etc., so using a fixed encoding recipe is recommended.

To make it possible to combine sources with somewhat different video parameter sets, the parameter sets are extracted for each asset and signaled in band. This makes it possible for most players to handle possible changes in encoding parameters. Signaling-wise, this means that our output is compatible with inband parameter codec configurations corresponding to avc3 and hev1, respectively.

Alternatively, DASH OnDemand assets may be used.

3. Create channels as schedule playlists with ad periods

The live channels are defined by some fixed parameters and a schedule that may be dynamically updated via a REST API.

All entries in the schedule are specified in units of GoPs. The playlist supports arbitrary GoP intervals of an asset and will wrap if going beyond end of asset. One can also specify the full asset by giving length=0, or specify to start with the n last GoPs by specifying the negative offset -n.

A slate or filler asset of duration 1 GoP, may be set to length N and thereby repeat N times.

An important part is to be able to split and rebuild output segments from input GoPs. For example, one may have 4s segments with 2s GoPs as input and desire 6s segments as output. This is achieved by splitting the input segments into GoPs and build new segments from these GoPs. This is specified by the parameters for a channel: gopDurMS=2000 and nrGopsPerSegment=3. At an ad boundary, the actual duration of a segment will be changed so that an ad period always start and end at a combined segment boundary. For this to work, each ad asset and asset between ads must consist of at least nrGopsPerSegment GoPs.

An ad in the schedule is indicated by a non-zero scteEventID value. If two “programs” in a row have the same scteEventID, they are considered to be one ad “pod”, with a CUE-OUT at the start of the pod, and a CUE-IN at the end of the pod. When updating the schedule to remove ads, it is important that full pods are removed. If scteEventID is set to -1, a unique event ID corresponding to the GoP number where the ad break starts will be inserted in the output.

The assets referred to in the schedule need to be located and fetched. This done by creating a map that maps assetIDs to assetPaths. An initial mapping can be provided in config file, but more importantly, the asset paths can be updated using a REST API. The assetPaths supports can be mounted file systems, HTTP URLs, and S3 URLs. The metadata of the assets is loaded in an LRU cache as part of the scanning of the schedule of a schedule. Asset paths can be removed from the asset cache by sending a DELETE command via the REST API, but only if the assets are not included in any schedule.

4. CBM HTTP interface for repackager integration

The EW repackager gets upstream live channels via an HTTP interface towards CBM. The HTTP interface provides list of channels, content_info.json, segment_times.json and actual “live” segments. Since ew-vod2cbm provides the same interface as the CBM, no change is needed in the repackager to support ew-vod2cbm.

The CBM segment_times.json data should be enough for signaling ads. The emsg boxes in segments should not be needed and are not added to the segments.

5. Repackager configuration

An ingestServer needs to be configured in order for the repackager to know where to fetch the vod2live channel. That configuration is described in Configuration Repackager.

Finally, content should now be available from the repackager as

 https://<server>/__cl/cg:vod2live/__c/<channel>/__op/default/__f/index.m3u8

where the cg:vod2live is the channel group for the vod2live channel.

6. Schedule update of a channel

Once a channel is created, its top level parameters cannot be changed. However, it is possible to change the schedule of a channel, but replacing it. The replacement must be done in a careful way to achieve a manifest which are consistently changed over time. There are more details on how to do this in the Dynamic Channels How-To guide.

2.2.3 - Installation

Installation and service operation

The vod2cbm service is distributed as a CentOS/Red Hat RPM and is available as ew-vod2cbm.service when installed. It works both on RH 7 and 8 and compatible versions.

To install version x.y.z, the rpm command can be used as follows:

yum install ./ew-vod2cbm-x.y.z-1.el8.x86_64.rpm

The service can be controlled with the standard systemctl commands:

systemctl start ew-vod2cbm
systemctl stop ew-vod2cbm
systemctl status ew-vod2cbm

Logs from the service can be seen using journalctl -u ew-vod2cbm.

The unit file is available in /usr/lib/systemd/system/ew-vod2cbm.service and starts ew-vod2cbm, serving port 8090 by default.

When run as a service, ew-vod2cbm reads its initial configuration from /etc/edgeware/ew-vod2cbm/config.json. The configuration may contain a schedule for looping channels. Non-looping channels must be created over the Channel REST API. For details on scheduling please refer to the API Reference

To uninstall the service, do:

yum remove ew-vod2cbm

When uninstalling or upgrading it is recommended to first stop the service.

2.2.3.1 - Upgrades

Upgrade of ew-vod2cbm

Upgrade to v1.2.x from v1.0.x

There is a new parameter padLastGop in the REST API, as well as the local JSON configuration for a channel/schedule. If that is not set, a last shorter GoP will be truncated from an asset. Set it if you want the new padding functionality to be applied.

Upgrade to v1.0.x from v0.10.x

The main new thing is the online license file that must be available in order to run the service fully.

Upgrade to v0.10.x from v.0.8.x

The command-line parameter -gopdurms is no longer needed or supported. The config file is also no longer mandatory.

The command-line parameter -s3 has changed name to -s3file.

Upgrade to v0.8.x from v.0.6.x

The segmentation and splicing is now based on GoPs instead of segments. There is a new mandatory parameter, defaultGopDurMS that must be provided in the configuration file, or provided as a command line option -gopdurms.

The config file has changed to be based on GoPs instead of segments. Therefore, there are a few new parameters for each channel:

        "segDurMS"  -> "gopDurMS"
        "combineNrSegs" -> "nrGopsPerSegment":

Here, the gopDurMS must be the GoP duration for all input video variants of all input content. The actual segment duration of the content is not relevant. The end GoP may be shorter, but is then dropped.

The input segment duration is not fixed, as long each video segment consists of an integral number of GoP. The output segments are generated by combining nrGopsPerSegment GoPs, with a possible adjustment where ads start and stop.

Another update of the channel configuration is inside “schedule” where

 "Programs" -> "Entries"

For dynamics schedules, it is recommended to use the REST API to handle channels.

2.2.4 - Configuration and command-line arguments

Configuration and command-line

The ew-vod2cbm global service parameters can be specified in the following ways:

  1. On the command-line
  2. As environment variables
  3. In the configuration file (when specified by the command-line)
  4. Default values

This also shows the order of precedence from top to bottom, where values on the command-line will override all other values.

The global service parameters cannot change during execution, except for logging.

An example configuration file is available in Example Configuration.

Note that the typical way of creating and configuring channels and assets is over the REST API. It is also possible to configure assets and channels in the configuration file. This can be handy mostly for testing. A channel parameter, when present, will override the corresponding global parameter. For example the global parameter defaultMaxliveWin would be overridden by the channel parameter maxLiveWindowS.

The command-line

All command line parameters and environment variables can be seen by running:

ew-vod2cbm -h
Usage of ew-vod2cbm:

ew-vod2cbm produces linear video channels from VoD assets
with the same interface as the ESB3003 catchup buffer mgr (CBM).

Run ew-vod2cbm with options:

  -cachedcfg string
        Location of cached channel/assetpath configuration file
  -cfg string
        Config file
  -defaultMaxBitratePercentAbove int
        Global fallback percentage value for max higher allowed bitrate compared to a matching master track
  -defaultMaxBitratePercentBelow int
        Global fallback percentage value for max lower allowed bitrate compared to a matching master track
  -defaultMaxliveWin int
        Max live window [seconds] (default 14400)
  -licenseFile string
        Location of ew-vod2cbm license file (default "/etc/edgeware/ew-vod2cbm/license.json")
  -logformat string
        Format and type of log: [consolejson consolepretty journald discard] (default "consolejson")
  -loglevel string
        Initial log level (default "info")
  -port int
        Server TCP port (default 8090)
  -routes
        Generate a markdown file with HTTP routes
  -s3file string
        S3 credentials file
  -timeout int
        Maximum time in seconds before HTTP requests fail. Set to 0 to disable (default 60)
  -timesubs
        Generate time subtitles
  -version
        Get version, date, and possible expiration date

The corresponding environment variables are:
EW_ESB3019_PORT     EW_ESB3019_DEFAULT_MAX_LIVE_WIN               EW_ESB3019_TIMEOUT     EW_ESB3019_LICENSE_PATH
EW_ESB3019_CFG      EW_ESB3019_DEFAULT_MAX_BITRATE_PERCENT_ABOVE  EW_ESB3019_LOG_FORMAT  EW_ESB3019_CACHED_CFG_PATH
EW_ESB3019_S3_FILE  EW_ESB3019_DEFAULT_MAX_BITRATE_PERCENT_BELOW  EW_ESB3019_LOG_LEVEL

Command-line parameters will always override envirionment variables and configured values.

2.2.4.1 - Startup Configuration

Startup configuration for configuring ew-vod2cbm

When starting the ew-vod2cbm service, a configuration file may be provided. This file enables starting ew-vod2cbm with predefined assets, channels and schedules. These items can also be added and updated via the REST API when the service is running.

If a path to a cached configuration is set, any change of the configuration via the REST API results in that the complete configuration of asset paths, channels and their schedules are written to a file at that path. On restart, an existing file at this path is used to restore the last dynamic configuration, while any static configuration of these settings is skipped.

However, if a path to a cached configuration is set, either via a command line parameter -cachedcfg or the corresponding environment variable, such a file will be used to restore the last dynamic configuration of asset paths and channels. The static configuration of these entities will then be ignored, unless the parsing of the cache configuration fails.

JSON Schema for configuration file

The JSON snippet below provides a description of the schema and the parameters that applies to configuration file for ew-vod2cbm.

The masterAssetID will be deprecated in a future release.

{
    "defaultMaxBitratePercentAbove": {
        "description": "When matching a variant, this sets the maximum upper boundary in percent for the bitrate",
        "type": "integer",
        "minimum": 0,
    },
    "defaultMaxBitratePercentBelow": {
        "description": "When matching a variant, this sets the maximum lower boundary in percent for the bitrate",
        "type": "integer",
        "minimum": 0,
        "maximum": 100,
    },
    "defaultMaxLiveWindowS": {
        "description": "The maximum length of the live window in seconds",
        "type": "integer",
        "minimum": 10,
        "maximum": 36000,
    },
    "assets": {
        "description": "list of assets",
        "type": "array",
        "items": {
            "type": "object",
            "required": [
                "id",
                "path"
            ],
            "properties": {
                "id": {
                    "type": "string"
                },
                "path": {
                    "type": "string"
                }
            }
        }
    },
    "channels": {
        "description": "Channels for ew-vod2cbm at startup",
        "type": "array",
        "items": {
            "type": "object",
            "required": [
                "gopDurMS",
                "name",
                "nrGopsPerSegment",
                "schedule"
            ],
            "properties": {
                "doLoop": {
                    "description": "Loop schedule or not",
                    "type": "boolean"
                },
                "gopDurMS": {
                    "description": "Exact millisecond duration of all video GoPs in all assets",
                    "type": "integer",
                    "minimum": 320,
                    "example": 2000
                }
                "contentTemplatePath": {
                    "description": "Path to the content template file. If this is used, masterAssetID should not be specified.",
                     "type": "string"
                 },
                 "masterAssetID": {
                     "description": "ID of the asset to use as a content template. If this is used, contentTemplatePath should not be specified.",
                    "type": "string"
                },
                "maxBitratePercentAbove": {
                    "description": "Percent diff above for when matching a track from the content template",
                    "type": "integer"
                },
                "maxBitratePercentBelow": {
                    "description": "Percent diff below for when matching a track from the content template",
                    "type": "integer"
                },
                "name": {
                    "description": "Unique name",
                    "type": "string",
                    "minLength": 2,
                    "example": "Channel 1"
                },
                "nrGopsPerSegment": {
                    "description": "How many GoPs to include in an average output segment",
                    "type": "integer",
                    "minimum": 1,
                    "example": 3
                },
                "schedule": {
                    "description": "The current scedule of the channel",
                    "type": "object",
                    "required": [
                        "entries"
                    ],
                    "properties": {
                        "entries": {
                            "description": "list of programs or other entries",
                            "type": "array",
                            "items": {
                                "type": "object",
                                "required": [
                                    "assetID",
                                    "length",
                                    "name"
                                ],
                                "properties": {
                                    "assetID": {
                                        "description": "Asset identifier",
                                        "type": "string",
                                        "minLength": 2,
                                        "example": "asset1234568-22"
                                    },
                                    "length": {
                                        "description": "How many GoPs to play in asset. 0 is until end of asset. Beyond end results in wrap to start",
                                        "type": "integer",
                                        "example": 2400
                                    },
                                    "name": {
                                        "description": "Name to include in EPG",
                                        "type": "string",
                                        "minLength": 2,
                                        "example": "The Shark"
                                    },
                                    "offset": {
                                        "description": "Zero-based GoP nr to start in asset. Negative value means from end",
                                        "type": "integer"
                                    },
                                    "scteEventID": {
                                        "description": "SCTE-35 Event ID in SCTE message. A non-zero value signals an ad. If scteEventID is set to -1, a unique event ID corresponding to the GoP number where the ad break starts will be inserted in the output.",
                                        "type": "integer",
                                        "minimum": -1
                                    }
                                }
                            }
                        },
                        "gopNrAfterLastAd": {
                            "type": "integer"
                        },
                        "gopNrAtScheduleStart": {
                            "type": "integer"
                        }
                    }
                },
                "startTimeS": {
                    "description": "Start time relative epoch (1970-01-01) in seconds",
                    "type": "integer",
                    "minimum": 0
                }
            }
        }
    }
}

Example configuration

An example configuration file for two channels where all assets have relative paths may look like:

{
    "defaultMaxBitratePercentAbove": 5,
    "defaultMaxBitratePercentBelow": 20,
    "assets": [
        {"id": "bbb", "path": "app/testdata/assets/bbb"},
        {"id": "slates/slate_pre_ad", "path": "app/testdata/assets/slates/slate_pre_ad"},
        {"id": "slates/slate_post_ad", "path": "app/testdata/assets/slates/slate_post_ad"},
        {"id": "slates/slate_black", "path": "app/testdata/assets/slates/slate_black"},
        {"id": "whistler", "path": "app/testdata/assets/whistler"},
        {"id": "ed", "path": "app/testdata/assets/ed"}
    ],
    "channels": [
        {
            "name": "quick",
            "gopDurMS": 1920,
            "nrGopsPerSegment": 2,
            "contentTemplatePath": "location/of/content_template.json"
            "startTimeS": 0,
            "doLoop": true,
            "maxBitratePercentAbove": 10,
            "maxBitratePercentBelow": 30,
            "schedule": {
                "GopNrAtScheduleStart": 0,
                "GopNrAfterLastAd": 0,
                "Entries": [
                    {
                        "name": "Big Buck Bunny",
                        "assetID": "bbb",
                        "offset": -3,
                        "length": 3
                    },
                    {
                        "name": "Ad upcoming",
                        "assetID": "slates/slate_pre_ad",
                        "offset": 0,
                        "length": 1,
                        "scteEventID": 123
                    },
                    {
                        "name": "Whistler ad",
                        "assetID": "whistler",
                        "offset": 0,
                        "length": 4,
                        "scteEventID": 123
                    },
                    {
                        "name": "Ad finished",
                        "assetID": "slates/slate_post_ad",
                        "offset": 0,
                        "length": 1,
                        "scteEventID": 123
                    },
                    {
                        "name": "Elephants dream",
                        "assetID": "ed",
                        "offset": 3,
                        "length": 4
                    }
                ]
            }
        },
        {
            "name": "test",
            "gopDurMS": 1920,
            "nrGopsPerSegment": 3,
            "contentTemplatePath": "location/of/content_template.json"
            "startTimeS": 0,
            "doLoop": true,
            "schedule": {
                "GopNrAtScheduleStart": 0,
                "GopNrAfterLastAd": 0,
                "Entries": [
                    {
                        "name": "Big Buck Bunny",
                        "assetID": "bbb",
                        "length": 0
                    },
                    {
                        "name": "Black 10s",
                        "assetID": "slates/slate_black",
                        "offset": 0,
                        "length": 5
                    },
                    {
                        "name": "Whistler ad",
                        "assetID": "whistler",
                        "length": 0,
                        "scteEventID": 123
                    },
                    {
                        "name": "Elephants dream",
                        "assetID": "ed",
                        "offset": 0,
                        "length": 0
                    }
                ]
            }
        }
    ]
}

2.2.4.2 - Content Templates

The role of content templates in ew-vod2cbm

Contents templates are used in ew-vod2cbm to specify the output segmentation and tracks of a channel, but also serve as measures to check if asset entries in a schedule are compatible with the channel. They are further used to generate the manifest and playlist media data properties as well as the media init segments. Therefore, bitrate, resolution, frame rate, video parameter sets, number audio channels are included in the template. The assets do not need to have exactly the same parameter values, but are allowed to vary as described later.

The generally preferred way of creating content templates, is to use ew-content-template-tool, described below.

JSON Schema for Content Template

The JSON schema of the content template contains core parameters of the content_info.json schema, and some additional parameters for bitrate matching.

It can contain variants of video, audio, and subtitles as signaled in the media_type field. The variant array can contain multiple variants of each type. The table below the schema shows the required parameters for each media type.

{
    "type": "object",
    "properties": {
        "version": {
            "type": "string"
        },
        "constant_gop_duration_ms": {
            "type": "integer"
        },
        "variants": {
            "type": "array",
            "items": [
                {
                    "type": "object",
                    "properties": {
                        "media_type": {
                            "type": "string"
                        },
                        "subtype": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        },
                        "bitrate": {
                            "type": "integer"
                        },
                        "width": {
                            "type": "integer"
                        },
                        "height": {
                            "type": "integer"
                        },
                        "sample_aspect_ratio": {
                            "type": "string"
                        },
                        "picture_aspect_ratio": {
                            "type": "string"
                        },
                        "scan_type": {
                            "type": "string"
                        },
                        "sps": {
                            "type": "string"
                        },
                        "pps": {
                            "type": "string"
                        },
                        "codec": {
                            "type": "string"
                        },
                        "frame_rate_fraction": {
                            "type": "array",
                            "items": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "integer"
                                }
                            ]
                        },
                        "num_channels": {
                            "type": "integer"
                        },
                        "samplerate": {
                            "type": "integer"
                        },
                        "decoder_config": {
                            "type": "string"
                        },
                        "lang": {
                            "type": "string"
                        },
                        "max_bitrate": {
                            "type": "integer"
                        },
                        "min_bitrate": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "media_type",
                        "name",
                        "bitrate",
                        "codec"
                    ]
                }
            ]
        }
    }
}

Depending on the media type, there are required fields for a variant. The table below lists all the required fields depending on media type.

Media typeRequired fields
Videomedia_type
subtype
name
bitrate
width
height
sample_aspect_ratio
picture_aspect_ratio
scan_type
sps
pps
codec
frame_rate_fraction
Audiomedia_type
subtype
name
bitrate
codec
num_channels
samplerate
decoder_config
lang
Subtitlesmedia_type
name
bitrate
lang
codec

The fields max_bitrate and min_bitrate are optional for all media types.

Example content template

{
    "version": "1.0",
    "constant_gop_duration_ms": 1920,
    "variants": [
        {
            "media_type": "video",
            "subtype": "h264",
            "name": "V1000",
            "bitrate": 1000000,
            "width": 640,
            "height": 360,
            "sample_aspect_ratio": "1:1",
            "picture_aspect_ratio": "16:9",
            "scan_type": "progressive",
            "sps": "6764001eacb201405ff2a0",
            "pps": "68ebccb22c",
            "codec": "avc1.64001E",
            "frame_rate_fraction": [
                25,
                1
            ],
            "max_bitrate": 1500000,
            "min_bitrate": 900000
        },
        {
            "media_type": "video",
            "subtype": "h264",
            "name": "V1500",
            "bitrate": 1500000,
            "width": 768,
            "height": 432,
            "sample_aspect_ratio": "1:1",
            "picture_aspect_ratio": "16:9",
            "scan_type": "progressive",
            "sps": "6764001eacb201806f20",
            "pps": "68ebccb22c",
            "codec": "avc1.64001E",
            "frame_rate_fraction": [
                25,
                1
            ],
            "max_bitrate": 1600000,
            "min_bitrate": 1400000
        },
        {
            "media_type": "audio",
            "subtype": "aac",
            "name": "A128",
            "bitrate": 128000,
            "codec": "mp4a.40.2",
            "num_channels": 2,
            "samplerate": 48000,
            "decoder_config": "1190",
            "lang": "eng"
        },
        {
            "media_type": "subtitles",
            "name": "eng_1",
            "bitrate": 1000,
            "lang": "eng",
            "codec": "wvtt"
        }
    ]
}

Creating a Content Template: ew-content-template-tool

A content template does not need to created by hand. It can be created from an ingested asset with:

$ ew-content-template-tool

Usage: bin/ew-content-template-tool [OPTIONS] <content info path> <content_template_path> ...
Options:
-gop-dur-ms int
        GOP Duration for template
-version
        Get version and build date

For example:

$ ew-content-template-tool  -gop-dur-ms 1920 content_info.json content_template.json

Note: The tool makes no verification that the media files actually fulfill the specified GOP duration.

Verifying Assets Before Scheduling: ew-verify-asset

Before attempting to schedule an asset, it can be verified that it matches a specific content template, with:

$ ew-verify-asset

Usage: ew-verify-asset [options]

-i, --input string      Asset path
-t, --template string   Content template file for the asset(s)

For example:

$ ew-verify-content -i media/matrix-revolutions/ -t content-templates/template_4sGOP_hevc.json

This tool will verify that the asset with regards to video-tracks, codecs etc. Missing subtitle tracks, and (secondary) audio tracks are allowed, and yield warnings.

Non-constant GOP lengths are detected, and rejected, for assets ingested with ew-vodingest. Such irregularities are not detected for assets ingested with the older ew-recorder.

2.2.4.3 - Assets

Assets (content_info.json) in ew-vod2cbm

The video content of a ew-vod2cbm consists of VoD video assets. Assets are added to the server and then added to the schedule of a channel (this is done either using the Schedule API or the Config) to the schedule of a channel. The way an asset is specified for vod2cbm, is using a file path or URL to either a directory that contains a content_info.json file or directly to a DASH OnDemand manifest (must end with file extension .mpd). The content_info or manifest file of the asset contains the necessary metadata to start processing it.

Asset requirements

The media tracks must be in one of the supported codecs and formats.

All assets of a channel must have a GoP duration that is “compatible” with the value specified in the channel configuration. Compatible here means that the channel GoP duration must be a multiple of the asset GoP duration. For example, an asset with 1s GoP duration is compatible with a channel with 2s GoP duration. That value is specified in the channel configuration as gopDurMS. As a schedule is updated, all included assets’ metadata as well as the first part of each video track is loaded in order to derive a GoP duration for that asset. The metadata is cached for future use, while the actual video and audio media data is not.

Another requirement is that all media samples in an mp4 files must have the same duration. This is normally no problem if the content has fixed frame rate and a timescale that is compatible with the frame rate and audio sample rate.

Padding the last asset GoP

It is not a requirement that the last GoP of an asset has the same duration as the others. It is natural that the last GoP is shorter. Using the boolean padLastGop parameter in the channel/schedule configuration it is possible to determine whether that last GoP will either be discarded or padded with silent audio and black video frames to become as long as the others. The GoP duration in this context is the channel’s GoP duration.

The padding influences the length of the asset. As an example, consider an asset that has 32.5s duration, and has an IDR-frame every 1s. If used in a channel with GoP duration 2s, the asset length is considered to be 32s if padLastGop is false, and 34s if padLastGopis true. In the latter case, the last 1.5s will be padded with silent audio and black video frames to achieve the full duration of an 2s GoP. The GoP duration of 1s of the actual asset, does not matter here, since all segments are built from GoPs of the duration specified in the channel’s configuration. If the channel entry for the asset specifies a length that wraps the asset to start from the beginning, the padding is included in the video so that a padded entry wraps later than a non-padded entry.

The padding content

The silent audio is built by repeating silent audio frames from the corresponding audio codec and setting the timing parameters appropriately.

The black video is built by taking frames from a 500frames long I-P-P-P- sequence of AVC or HEVC video. Since the content is just a black frame, the resolution does not influence the image quality, so a fixed resolution of 640x360 pixels is currently used. Since this content generally doesn’t match with the content of the variant being played, all video is sent using inband signaling parameter sets, that is avc3 for H.264/AVC hev1 for H.265/HEVC.

2.2.4.3.1 - Asset Track Matching

Matching of tracks in assets for ew-vod2cbm

Matching rules

For a schedule to be valid, all assets must be compatible with the content template of the channel.

The compatibility check is done by a set of matching rules when a channel is created or when its schedule is updated. If one of the assets is not matching the content template, the schedule is discarded and an error is reported.

The matching is done by comparing the asset tracks with the tracks of the content template.

The first condition is equal media type. A video track will, for example, never be matched to an audio track.

The second condition depends on the media type of the track. Some media type-specific properties of a track, must always be identical to a track found in the content template for them to match. The table below lists the properties that must be identical for the respective media types between a track in an asset and a track in the content template.

Media typeMedia properties that must match
VideoMedia type
subtype
AudioMedia type
subtype
Codec
Sample rate
SubtitlesMedia type
Language
Role

The third condition regards the bitrate range. By default, the bitrate of an asset track must be identical to the bitrate of the corresponding content template track. However, the max_bitrate and min_bitrate parameters in the content template allow for a range of matching bitrates on track level.

More generally, there are also percentage values that can be specified for bitrates in either a channel configuration, or as global parameters at the top level of the config file or as command line parameters.

The channel parameters are called maxBitratePercentAbove and maxBitratePercentBelow, while the global parameters are called defaultMaxBitratePercentAbove and defaultMaxBitratePercentBelow These are all optional with default value 0. The rules for bitrate matching are applied in the following priority order:

  1. Use the track specific bitrate range if it exists
  2. Use the channel specific bitrate percentage range if it exists
  3. Use the command-line bitrate percentage range if it exists
  4. Use the top-level JSON bitrate percentage range if it exists

Only one of the rules will be applied (the one with the highest priority that is valid for the scope of the track we are trying to match to).

Cases of non-direct match

There does not need to be a one-to-one match between tracks. An asset which deviate from the content template in the following way should be accepted:

  1. Extra tracks are allowed and will be silently discarded
  2. Subtitle tracks may be missing. This results in corresponding empty subtitle segments
  3. Audio languages may be missing. Such a track will be replaced by tracks of another language. An example would be a channel where some programs are in English and some in Spanish.

Matching algorithm

The matching occurs when a schedule is being updated for a channel. If no match is found for any variant in any asset in the new schedule, the schedule is considered invalid, and an error is returned. The matching algorithm begins by sorting the variants in the content template by their bitrate in descending order. The same is done for every asset. Finally, each variant in the sorted list of template variants, will be matched with a compatible asset variant considering media type and the compatibility values listed in the table above.

The search for a compatible variant in the asset is started from the top of the sorted variant list in the content template. This ensures that the most appropriate variant in each asset will be coupled with a corresponding variant in the content template.

2.2.4.4 - Repackager configuration

How to configure the repackager

The ESB3002 repackager needs to be configured with a new “ingestServer” corresponding to the ew-vod2cbm node.

First define a new ingestServer under ingestServers

 services.repackaging.locations.ingestServers

   "ingestServers": [
    {
      "name": "vod2cbm",
      "url": "http://127.0.0.1:8090"
     }
   ]

Then define a new group channelGroup for vod2live content:

 services.repackaging.content.channelGroups

 {
    "channelGroups": [{
            "locations": [
                "vod2cbm"
            ],
        "name": "vod2live"
        }
    ]
}

2.2.4.5 - Channels

Channel and schedule configuration

As described in the Startup Configuration section, one can start up the service with both assets and channels defined in the config file.

However, one can change this configuration by using the REST API. In this way one can

  1. Add asset paths
  2. Add channels
  3. Replace schedules of non-looping channels
  4. Delete channels
  5. Delete asset paths for assets which are not in any schedule

Schedule updates are further described in the Dynamic Channels section.

If a path to a cached configuration is set, any change of the configuration via the REST API results in that the complete configuration of asset paths, channels and their schedules are written to a file at that path. On restart, an existing file at this path is used to restore the last dynamic configuration, while any static configuration of these settings is skipped.

2.2.4.6 - Licensing

Licensing for ew-vod2cbm

ew-vod2cbm requires a valid license file to operate. The license file must be obtained from Agile Content, and copied to /etc/edgeware/ew-vod2cbm/license.json.

See further details here.

2.2.5 - Monitoring & Logging

Health, service logs and monitoring

Health check

You can check the health of the server by making a request to /healthz, which should return a 200 OK response.

Monitoring

For monitoring, ew-vod2cbm generates Prometheus data available at /metrics. There are different metrics for the response times for segments for different media types. All bucket and counter names start with ew_, or more precisely:

ew_audio_segment_request_duration_milliseconds_bucket
ew_audio_segment_requests_total
ew_subs_segment_request_duration_milliseconds_bucket
ew_subs_segment_requests_total
ew_video_segment_request_duration_milliseconds_bucket
ew_video_segment_requests_total

Logging

To provide context to each log message, structured logging is used. Thus instead of free text log messages without any specific format, the log data is to some extent divided into fields of name-value pairs, making the logs more coherent and more suitable for processing by external tools.

Log messages related to a specific HTTP request include the log field named request_id which can be used to filter out specific requests.

The log field named topic is always present and is used to separate different areas of logging. The current topics are access, messages and error, and are used to log HTTP access, debug messages and panic stack traces, respectively.

As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.

Log formats

When run from the command line ew-vod2cbm can log in one of the formats consolepretty, consolejson or journald depending on the value of the -logformat parameter. Logging can be disabled by using the value discard.

$ ew-vod2cbm -upstream http://127.0.0.1 -logformat consolejson

consolepretty logs to standard output (stdout) in a human-readable format. Each log line starts with the date and the log message followed by the context- dependent log fields:

2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...

consolejson logs to stdout using a JSON object for each message:

{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}

When run as a systemd service, ew-vod2cbm logs directly to journald using the logjournald configuration parameter. When stored in journald, field names are upper case whereas the values keep their format. Some examples:

To see entries with the topic access:

$ journalctl -u ew-vod2cbm TOPIC=access -o verbose

To see entries with a specific request ID:

$ journalctl -u ew-vod2cbm REQUEST_ID="host/B1Po0eYz1d-000006" -o verbose

To see the call stack in the event of a crash:

$ journalctl -u ew-vod2cbm TOPIC=error -o verbose

Using the verbose output includes all available name-value fields. Without this only the log message is printed. The field named JSON contains the original structured log message as sent by the service. To filter out only this field --output-fields=JSON can be used, however this requires a systemd version of at least 236.

$ journalctl -u ew-vod2cbm --output-fields=JSON TOPIC=access

To continuously monitor the service:

$ journalctl -fu ew-vod2cbm

Log levels

At startup the log level is set to info. The log level can be changed by posting a form-field named level to the loglevel endpoint on the ew-vod2cbm server:

$ curl -F level=debug ew-vod2cbm-server:8090/loglevel

The available log levels and how they relate to systemd priority values is listed below:

Log level  Systemd priority
trace      7
debug      7
info       6
warn       4
error      3
fatal      2
panic      0

To e.g. see all error and warning messages using journalctl:

$ journalctl -u ew-vod2cbm PRIORITY=3 PRIORITY=4

Use a GET request to see the current log level:

$ curl ew-vod2cbm-server:8090/loglevel

Messages with higher level than the configured one will not be logged.

2.2.6 - how-to

How To Guides for ESB3019 service

2.2.6.1 - Looping channels

How to setup a looping channel

The simplest channel to set up is a looping channel.

Such a channel has a fixed schedule and the programs of that channel are presented over and over again and will never stop.

A looping channel can be setup via the REST API, but it can also be setup using a configuration file as examplified in the Startup configuration. Such channels have the doLoop attribute set, and will run until they are stopped. One can set the startTimeS parameter to tell when the first media should be “generated”, but there is no end time.

The default value startTime == 0 means that the channel will have segments with a time relative to the start of the UNIX epoch 1970-01-01T00:00:00Z.

2.2.6.2 - Dynamic Channels

How to setup a linear channel with dynamic schedule and update it

A flexible FAST channel has a schedule that is not fixed and looped, but has a limited window in the past and future. This can for example, be two hours back in time and 10 hours into the future.

To achieve such a “sliding window” of programs, the schedule needs to be updated by adding new entries and removing old ones. At the same time, the timeline needs to be continuous, and the generated DASH and HLS manifests must be consistent over time when it comes to discontinuities and period times.

A schedule update is done by posting a complete new schedule via the REST API to “/api/v1/schedule/{channel}”.

Removing old assets from the schedule

When removing old assets, it is important to keep a long enough window of old assets so that the sliding window for players is still available. This may be the last two hours or something similar.

To keep a consistent state when removing assets from the schedule, use the following two parameters:

  • GopNrAtScheduleStart - the GoP number at which the schedule starts
  • GopNrAfterLastAd - the GoP number right after the last ad before the schedule start

These should be updated like follows when one or more entries are dropped from the start of a schedule:

  • GopNrAtSchedulStart should increase by the number of GoPs dropped
  • GoPNrAfterLastAd should increase if an ad has been dropped

The source code in the Github repo edgeware/v2l-example-scheduler provides a simple example service that updates the schedule by adding and removing random entries and ads.

2.2.6.3 - Test Output

Test HLS and DASH output without a repackager

The ew-vod2cbm service is targeted to provide a live stream to the ESB3002 repackager, but for testing purposes it is also possible to get media output that can be played directly with media players.

The supported output formats are HLS and DASH. The media segments are in CMAF/fMP4 format with subtitles in stpp/imsc1 format.

Direct HLS streams

A channel ch can be reached as an HLS live asset using the URL

/ch/index.m3u8

The HLS playlist have SCTE-35 markers at the start and end of ad periods.

Direct DASH playback (new in v0.8)

A channel ch can be reached as a DASH live asset using the URL

/ch/manifest.mpd

The DASH format is the simple SegmentTemplate with $Number$ format and does currently (v0.8) not include any SCTE-35 markers.

View as combined VoD

It is also possible to view a channel as an VoD asset by adding an extra vod=1 query string to the URLs. This provides an HLS VoD playlist or DASH static MPD. In both cases each subtitle track is provided as a single big WebVTT file including all the subtitle cues.

Subtitle time track

To investigate timing and stitching of segments, it is possible to enable an extra generated subtitle track for all channels. This is done using the command line option -timesubs.

2.2.7 - API Reference

REST API for assets, channels and schedules

2.2.7.1 - Channel REST API v1

Reference for the channel schedule API

The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.

However, an interactive Swagger API page is available directly at the ew-vod2cbm server at <server>/swagger/.

All API calls are relative to the base URL /api/v1/.

A new addition in release 1.2.0 is padding of assets. This is controlled via the boolean padLastGop parameters on channel and entry level, where the latter takes precedence over the former.

For more information about how to use this API, see the howto section.

2.2.7.2 - Old API references

Previous REST API Versions

2.2.7.2.1 - REST API v1 - release 1.0

Reference for the channel schedule API release 1.0

The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.

However, an interactive Swagger API page is available directly at the ew-vod2cbm server at <server>/swagger/.

All API calls are relative to the base URL /api/v1/.

For more information about how to use this API, see the howto section.

2.2.7.2.2 - REST API v1 - release 0.10

Reference for the channel schedule API release 0.10.0

The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.

However, an interactive Swagger API page is available directly at the ew-vod2cbm server at <server>/swagger/.

All API calls are relative to the base URL /api/v1/.

For more information about how to use this API, see the howto section.

2.2.7.2.3 - REST API v1 - release 0.8

Reference for the channel schedule API release 0.8.0

The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.

However, an interactive Swagger API page is available directly at the ew-vod2cbm server at <server>/swagger/.

All API calls are relative to the base URL /api/v1/.

For more information about how to use this API, see the howto section.

2.2.8 - Credits

Third party libraries used in ew-vod2cbm and their licenses

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryLicenseChecked At
github.com/prometheus/common/internal/bitbucket.org/ww/goautonegBSD-3-Clause2022-03-18
github.com/go-openapi/jsonreferenceApache-2.02022-03-18
github.com/swaggo/swagMIT2022-03-18
github.com/go-playground/universal-translatorMIT2022-03-18
github.com/edgeware/mp4ff/mp4MIT2022-03-18
github.com/go-playground/validatorMIT2022-03-18
github.com/leodido/go-urnMIT2022-03-18
github.com/prometheus/commonApache-2.02022-03-18
github.com/zencoder/go-dash/v3Apache-2.02022-03-18
github.com/go-openapi/specApache-2.02022-03-18
gopkg.in/yaml.v2Apache-2.02022-03-18
github.com/swaggo/http-swaggerMIT2022-03-18
github.com/edgeware/mp4ff/bitsMIT2022-03-18
github.com/PuerkitoBio/purellBSD-3-Clause2022-03-18
github.com/josharian/internMIT2022-03-18
golang.org/x/textBSD-3-Clause2022-03-18
github.com/aws/aws-sdk-go/internal/sync/singleflightBSD-3-Clause2022-03-18
github.com/asticode/go-astikitMIT2022-03-18
github.com/cespare/xxhash/v2MIT2022-03-18
github.com/prometheus/procfsApache-2.02022-03-18
google.golang.org/protobufBSD-3-Clause2022-03-18
github.com/prometheus/client_model/goApache-2.02022-03-18
golang.org/x/toolsBSD-3-Clause2022-03-18
github.com/jmespath/go-jmespathApache-2.02022-03-18
github.com/prometheus/client_golang/prometheusApache-2.02022-03-18
github.com/go-openapi/swagApache-2.02022-03-18
github.com/go-chi/chi/v5MIT2022-03-18
github.com/rs/zerologMIT2022-03-18
github.com/matttproud/golang_protobuf_extensions/pbutilApache-2.02022-03-18
github.com/go-chi/docgenMIT2022-03-18
github.com/asticode/go-astisubMIT2022-03-18
github.com/PuerkitoBio/urlescBSD-3-Clause2022-03-18
github.com/swaggo/filesMIT2022-03-18
github.com/aws/aws-sdk-goApache-2.02022-03-18
github.com/golang/protobufBSD-3-Clause2022-03-18
golang.org/x/sysBSD-3-Clause2022-03-18
github.com/go-playground/localesMIT2022-03-18
github.com/go-openapi/jsonpointerApache-2.02022-03-18
github.com/coreos/go-systemd/v22/journalApache-2.02022-03-18
github.com/beorn7/perks/quantileMIT2022-03-18
github.com/edgeware/mp4ffMIT2022-03-18
golang.org/x/netBSD-3-Clause2022-03-18
github.com/asticode/go-astitsMIT2022-03-18
github.com/mailru/easyjsonMIT2022-03-18
github.com/Comcast/gotsMIT2022-03-18
github.com/KyleBanks/depthMIT2022-03-18

License Details

This section includes all the licenses/notices for each dependency verbatim

github.com/prometheus/common

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/swaggo/swag

license

MIT License

Copyright (c) 2017 Eason Lin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Comcast/gots

LICENSE

/* MIT License

Copyright 2016 Comcast Cable Communications Management, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

NOTICE

Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).

github.com/KyleBanks/depth

LICENSE

MIT License

Copyright (c) 2017 Kyle Banks

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/PuerkitoBio/urlesc

LICENSE

Copyright (c) 2012 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/asticode/go-astikit

LICENSE

MIT License

Copyright (c) 2020 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/beorn7/perks/quantile

LICENSE

Copyright (C) 2013 Blake Mizerany

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/matttproud/golang_protobuf_extensions/pbutil

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2012 Matt T. Proud (matt.proud@gmail.com)

github.com/go-chi/chi/v5

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/docgen

LICENSE

Copyright (c) 2016-Present https://github.com/go-chi authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/josharian/intern

license

MIT License

Copyright (c) 2019 Josh Bleecher Snyder

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_model/go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/procfs

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.

Copyright 2014-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

gopkg.in/yaml.v2

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2011-2016 Canonical Ltd.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/asticode/go-astits

LICENSE

MIT License

Copyright (c) 2017 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonreference

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/swag

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/validator

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Dean Karn

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/golang/protobuf

LICENSE

Copyright 2010 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright

notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/text

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/asticode/go-astisub

LICENSE

MIT License

Copyright (c) 2016 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/cespare/xxhash/v2

LICENSE

Copyright (c) 2016 Caleb Spare

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/zencoder/go-dash/v3

LICENSE

Copyright Brightcove, Inc.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

golang.org/x/tools

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/aws/aws-sdk-go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.

github.com/coreos/go-systemd/v22/journal

LICENSE

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  1. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  1. Grant of Patent License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  1. Redistribution.

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  1. Submission of Contributions.

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  1. Trademarks.

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  1. Disclaimer of Warranty.

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  1. Limitation of Liability.

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  1. Accepting Warranty or Additional Liability.

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

CoreOS Project Copyright 2018 CoreOS, Inc

This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).

github.com/mailru/easyjson

LICENSE

Copyright (c) 2016 Mail.Ru Group

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/rs/zerolog

LICENSE

MIT License

Copyright (c) 2017 Olivier Poitrey

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

google.golang.org/protobuf

LICENSE

Copyright (c) 2018 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/sys

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/PuerkitoBio/purell

LICENSE

Copyright (c) 2012, Martin Angers All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/edgeware/mp4ff/bits

LICENSE

Copyright

Copyright (c) 2019-2020 Edgeware AB.

Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits Copyright (c) 2017 Taichi Nakashima.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/universal-translator

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/leodido/go-urn

LICENSE

MIT License

Copyright (c) 2018 Leonardo Di Donato

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_golang/prometheus

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

The following components are included in this product:

perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.

Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.

Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0

github.com/swaggo/files

LICENSE

MIT License

Copyright (c) 2019 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/aws/aws-sdk-go/internal/sync/singleflight

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/edgeware/mp4ff

LICENSE

MIT License

Copyright (c) 2019-2020 Edgeware

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonpointer

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/jmespath/go-jmespath

LICENSE

Copyright 2015 James Saryerwinnie

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/swaggo/http-swagger

LICENSE

MIT License

Copyright (c) 2018 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/edgeware/mp4ff/mp4

LICENSE

Copyright

Most code is Copyright (c) 2019-2020 Edgeware AB.

Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has Copyright (c) 2015 Jean-François Bustarret.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/spec

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/locales

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg

README

PACKAGE

package goautoneg import “bitbucket.org/ww/goautoneg”

HTTP Content-Type Autonegotiation.

The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FUNCTIONS

func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.

func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses

TYPES

type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header

SUBDIRECTORIES

.hg

golang.org/x/net

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2.2.9 - Releases

ESB3019 - ew-vod2cbm releases

2.2.9.1 - Release 1.4.0

Product release
  • Optional persistent cache of dynamic schedule and asset path configurations
  • Content verification tool, for checking asset compatibility against content templates
  • Improved handling of non-constant GoP duration

Release information

  • Date: 2023-04-06
  • Type: Product improvements

2.2.9.2 - Release 1.2.0

Product release
  • The last GoP of an asset can now be padded to same length as the others
  • Now supporting offline, as well as, online licensing
  • Improved error messages for online licensing
  • Support autofill of scteEventID [using Gop number] when configured to -1
  • Fixed timestamp wrap-around

Release information

  • Date: 2022-10-18
  • Type: Product improvements

2.2.9.3 - Release 1.0.0

Product release
  • New: Support for shorter compatible GoP durations

  • New: Added utility for creating content templates: ew-content-template-tool

  • New: The binary does not expire, it now requires a valid license to run

  • New: Support for AC-3/EC-3

  • New: Metrics for requested content

  • New: Improved GoP duration detection

  • New: Graceful service shutdown (handle outstanding requests)

  • Fix: EPG-offset for non-looping channels

  • Fix: Various scheduling bugs

Release information

  • Date: 2022-05-17
  • Type: First product release

2.2.9.4 - Release 0.10.0

New features
  • Track matching to allow for more flexibility when adding assets to a channel schedule.
  • New contentTemplatePath parameter in channel configuration for specifying compatible assets. This is intended to replace and improve on masterAssetID.
  • New parameters to fine tune track matching via bitrate:
    • max_bitrate and min_bitrate specified on a track level
    • maxBitratePercentAbove and maxBitratePercentBelow specified on channel level
    • max_bitrate and min_bitrate parameters in content template level and/or global level
    • global parameters for setting bitrate interval
  • Global parameters can be set either as command line parameters or as environment variables
  • New parameters to set maximal live window
  • Remove defaultGopDurMS parameter and auto-detect GoP duration instead
  • Automatic extraction of GoP duration from assets to allow for matching
  • Support for HEVC video
  • Support for DASH OnDemand assets without conversion to ESF format
  • New structured logging and better integration with journald
  • Assets with a missing subtitle track are allowed. An empty track will be generated automatically
  • Assets with mismatch in audio language are allowed. Another language audio track is used instead
  • Audio only support both via CBM interface and for direct HLS/DASH output

See Upgrade for information about how to upgrade

Release information

  • Date: 2022-03-17
  • Type: Beta for evaluation and testing

2.2.9.5 - Release 0.8.1

Bug fix release
  • Fix: handle assets where subtitle tracks have no cues (ESB3019-80)
  • Fix: report configuration errors with proper JSON names (SUPPORT-10099, ESB3019-81)

See Upgrade for information about how to upgrade.

Release information

  • Date: 2022-01-07
  • Type: Beta bug fix for testing

2.2.9.6 - Release 0.8.0

GoP-based stitching and REST API
  • Segmentation based on GoPs instead of full segments
  • REST API for dynamic change of channels and schedules
  • Prometheus and health monitoring
  • DASH output for testing
  • Special live-time subtitle output for demo

See Upgrade for information about how to upgrade

Release information

  • Date: 2021-12-22
  • Type: Beta for testing

2.2.9.7 - Release 0.6.1

Bug-fix release

Bug fix: too small duration in SCTE-35 marker

Release information

  • Date: 2021-06-01
  • Type: Alpha bugfix for testing

2.2.9.8 - Release 0.6.0

First release of ew-vod2cbm.

Early release for generating live test content with SCTE-35 markers from recordings or other sources with fixed segment durations.

Output segments are generated by combining N segments, with variations of +/-N at an ad boundary.

Release information

  • Date: 2021-05-30
  • Type: Alpha for testing

2.3 - Manifest Manipulation (ew-manip)

Lightweight service for manipulating HLS and DASH manifests

2.3.1 - Introduction

Introduction to ew-manip

The service ew-manip is a stateless manifest/playlist manipulator for DASH and HLS. In the following, we use the term manifest to denote either a DASH manifest or an HLS playlist.

ew-manip is meant to be integrated with the nginx front of ew-repackager (ESB3002) and can change DASH and HLS manifests depending on query parameters in the URL.

The manipulations are triggered by a special query ewm=1 which must be at the start of the query string, and will then do different manipulations depending on options in the rest of the query.

The two modifications implemented this far are insertion of pre-roll assets in VoD manifests and change of HLS target duration for “live-like” HLS manifests coming from a live channel.

2.3.2 - Installation

Installation and service operation

The ew-manip service is distributed as a CentOS / Red Hat RPM and is available as ew-manip.service when installed. It works both on RH 7 and 8 and compatible distributions.

To install version x.y.z, the yum command can be used as follows:

yum install ./ew-manip-x.y.z-1.el8.x86_64.rpm

The service can be controlled with the standard systemctl commands:

systemctl start ew-manip.service
systemctl stop ew-manip.service
systemctl status ew-manip.service

To uninstall version x.y.z using the yum command, do:

yum remove ew-manip-x.y.z-1.el8.x86_64

When uninstalling or upgrading it is recommended to first stop the service.

2.3.2.1 - Upgrades

Upgrade of ew-manip

Upgrade to v0.10.x from v.0.8.x

The nginx configuration file ew-repackager-custom.conf should no longer contain the ew-manip specific location. In regards to ew-manip, it should rather only contain an include to a newly installed file /etc/edgeware/ew-manip/ew-manip-nginx.conf. A more detailed description regarding what should be in the /etc/ew-repackager/ew-repackager-custom.conf file can be found here. The reason for this change is so we can make ew-manip specific nginx changes in the future without having users modifying an nginx file.

2.3.3 - Configuration

Configuring ew-manip and the Repackager

Configuring ew-manip

The ew-manip global service parameters can be specified in the following ways:

  1. On the command line
  2. As environment variables
  3. Default values This also shows the order of precedence, where values on the command line, will override all other values.

The repackager is normally running as an HTTP server on port 80. The ew-manip service would typically run on the same host with the default port 8094. The port can be changed in the service file at: /usr/lib/systemd/system/ew-manip.service key: ExecStart

If the repackager is not running on port 80, or on a different host from ew-manip, then this should be specified on the same line in the service file by adding: -u <repackager-hostname:port>

In the resulting combined manifest, the pre-roll content URL will point to another asset, and its URL needs to be an absolute URL. This does not have to be configured since the full absolute URL must be sent in the query string.

Repackager configuration (nginx routing)

The nginx routing must be manually configured in the repackager. To do that, add the following include entry to the nginx config file at: /etc/ew-repackager/ew-repackager-custom.conf

include /etc/edgeware/ew-manip/ew-manip-nginx.conf;

This will make requests with URLs ending with .m3u8 or .mpd containing the string ewm= at the start of the query string to be forwarded to the ew-manip server at http://localhost:8094.

2.3.3.1 - Licensing

Licensing credentials for ew-manip

ew-manip requires a valid license to operate. Some endpoints are accessible without a valid license, but endpoints retrieving a manipulated playlist/manifest are protected.

Requirements

  • An internet connection on the machine running ew-manip
  • A valid license reference provided by Agile Content

Using the license reference

The license reference along with the product name must be stored in: /etc/edgeware/ew-manip/license.json. For example:

{
    "license_ref": "this_is_an_example_license_ref",
    "product_name": "ew-manip"
}

License validation

There will be an initial and then a periodic license check every 24 hours towards a license server once the service has started. The service will initiate a grace period if, and only if, the license server cannot be reached or the license server reports an internal error. The grace period will last for 2 hours if this is the license validation made during startup, and 7 days if this was a license validation that was made after a successful validation during startup (for internal license server errors, the grace period will always be 2 hours).

If an unsuccessful validation occurs, ew-manip will do the verification more often. This starts with one minute after the first fail, two minutes after the second, doubling every time it fails. It will do so until it reaches 1024 minutes (~17 hours), and then do the verification every 1024 minutes. If the license reference is successfully verified again, it will return to verifying the reference every 24 hours.

In case license.json is changed, the ew-manip service must be restarted in order to update server data.

License information

There are mainly two ways of finding information regarding the license status in the ew-manip service, the logging, and an HTTP endpoint.

Logging

All license related logging has the topic logging. Filtered logs with regard to topic is described in Monitoring & Logging.

HTTP

The /licensing endpoint of the ew-manip service provides some information regarding the licensing status. Currently, the information provided includes:

  • A timestamp for when the last license validity verification occurred
  • Timestamp for when the next license validity verification will occur
  • Whether the current license reference is considered valid or not. If this is false, and there is no active grace period, requests to the protected endpoints will fail
  • If the license is valid, this endpoint will also show the expiry date of the license
  • If currently in a grace period, or the grace period has ended, a timestamp of when the grace period end is provided

2.3.4 - Monitoring & Logging

Health, service logs and monitoring

Health check

You can check the health of the server by making a request to /healthz, which should return a 200 OK response.

Monitoring

For monitoring, ew-manip generates Prometheus data available at /metrics. There are different metrics for the response times for segments for different media types. All bucket and counter names start with ew_, or more precisely:

ew_hls_requests_total
ew_hls_request_duration_milliseconds
ew_dash_requests_total
ew_dash_request_duration_milliseconds

Logging

To provide context to each log message, structured logging is used. Thus instead of free text log messages without any specific format, the log data is to some extent divided into fields of name-value pairs, making the logs more coherent and more suitable for processing by external tools.

Log messages related to a specific HTTP request include the log field named request_id which can be used to filter out specific requests.

The log field named topic is always present and is used to separate different areas of logging. The current topics are access, messages and error, and are used to log HTTP access, debug messages and panic stack traces, respectively.

As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.

Log formats

When run from the command line ew-manip can log in one of the formats consolepretty, consolejson or journald depending on the value of the -logformat parameter. Logging can be disabled by using the value discard.

$ ew-manip -logformat consolejson

consolepretty logs to standard output (stdout) in a human-readable format. Each log line starts with the date and the log message followed by the context- dependent log fields:

2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...

consolejson logs to stdout using a JSON object for each message:

{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}

When run as a systemd service, ew-manip logs directly to journald using the logjournald configuration parameter. When stored in journald, field names are upper case whereas the values keep their format. Some examples:

To see entries with the topic access:

$ journalctl -u ew-manip TOPIC=access -o verbose

To see entries with a specific request ID:

$ journalctl -u ew-manip REQUEST_ID="host/B1Po0eYz1d-000006" -o verbose

To see the call stack in the event of a crash:

$ journalctl -u ew-manip TOPIC=error -o verbose

Using the verbose output includes all available name-value fields. Without this only the log message is printed. The field named JSON contains the original structured log message as sent by the service. To filter out only this field --output-fields=JSON can be used, however this requires a systemd version of at least 236.

$ journalctl -u ew-manip --output-fields=JSON TOPIC=access

To continuously monitor the service:

$ journalctl -fu ew-manip

Log levels

At startup the log level is set to info. The log level can be changed at run time by posting a form-field named level to the loglevel endpoint on the ew-manip server:

$ curl -F level=debug ew-manip-server:8094/loglevel

The available log levels and how they relate to systemd priority values is listed below:

Log level  Systemd priority
trace      7
debug      7
info       6
warn       4
error      3
fatal      2
panic      0

To e.g. see all error and warning messages using journalctl:

$ journalctl -u ew-manip PRIORITY=3 PRIORITY=4

Use a GET request to see the current log level:

$ curl ew-manip-server:8094/loglevel

Messages with higher level than the configured one will not be logged.

2.3.5 - How-to guides

This section describes the supported use-cases and functionality

2.3.5.1 - Pre-rolls

Inserting pre-roll assets

The specific query-string trigger is a general escape query part ewm=1 which will make nginx forward the request to the ew-manip server. Pre-rolls assets are then added in VoD with the query parameter pre=<URL>. The <URL> must be the absolute public URL that the client uses to fetch the preroll video, since this URL will be inserted in the combined manifest delivered to the client.

A complete request, to combine preroll-bumper with program could look like this:

http://repack-host/__cl/s:vod/__c/program/__op/default/__f/index.m3u8?ewm=1&pre=https://public-repack-host/__cl/s:vod/__c/preroll-bumper/__op/default/__f/index.m3u8

Multiple pre= query parts can be added to combine more than two manifests. The service will then fetch all the manifests from the repackager and combine them into the appropriate manifest with multiple periods for DASH or multiple parts separated by discontinuities for HLS.

DASH manifest URLs look similar but must have the file extension .mpd. HLS playlist must have the file extension .m3u8.

Limitations

DASH and HLS URLs cannot be combined with each other. For DASH, any assets can be combined, but for the best user experience it is reasonable to apply similar critera as for HLS. For HLS the following criteria must be met:

HLS Playlist Matching Criteria

In brief, the main and all the pre-roll master playlist(s) must match each other.

In detail, this means that:

  • For Renditions identified by #EXT-X-MEDIA: For each rendition in the main playlist, there must be exactly one corresponding rendition in each pre-roll playlist, and the following attributes (when present) must match exactly: TYPE, and LANGUAGE. Unmatched renditions in the pre-rolls will be discarded.

    • When matching renditions, in addition to the criteria mentioned above, ew-manip will match a rendition in the main playlist with the closest bitrate (without duplicate matching)
  • For Variant streams identified by #EXT-X-STREAM-INF: For each variant stream in the main playlist, there must be exactly one corresponding variant stream in each pre-roll playlist, and the following attributes (when present) must match exactly: RESOLUTION, FRAME-RATE, CODECS, AUDIO, VIDEO and SUBTITLES. Unmatched variant streams in the pre-rolls will be discarded.

  • For I-frame playlists identified by #EXT-X-I-FRAME-STREAM-INF: For each I-frame playlist in the main master playlist, there must be exactly one corresponding I-frame playlist in each pre-roll master playlist, and the following attributes (when present) must match exactly: RESOLUTION and CODECS. Unmatched I-frame playlists in the pre-rolls will be discarded.

Playlist requests where the main and pre-roll master playlists do not meet all of the above criteria, will fail with an HTTP 400 error.

HLS Stream and Playlist Matching by Bandwidth

Typically there will be several variant streams that meet these criteria and only differ in BANDWIDTH. Within such matching groups (for example streams with the same resolution) the main and pre-roll streams are paired together by being sorted by bandwidth in decreasing order. The same pairing method is used for I-frame playlists.

2.3.5.2 - HLS Target Duration

Set HLS live target duration

A common issue when playing live HLS is the value of target duration (EXT-X-TARGETDURATION). The target duration is an integral number of seconds that correspond to the longest segment in the stream. Depending on HLS version, this value must either be higher than the longest duration, or can be rounded to the closest integer, but many players desire a lower value in order to work best. This is due to that the target-duration value influences how often the client can ask for a playlist update.

Because live ingest node (ESB3003) generates segments with a precise average segment duration, adjusted segmentation boundaries due to SCTE-35 ad markers number may result in a single segment duration being 1.5 times the average duration. These singular values then effect the target-duration to become high.

To be able to fine-tune the target duration, the ew-manip service has an option to change the #EXT-X-TARGET-DURATON value by using the special query-string trigger target-duration= once ew-manip has been triggered with the general ewm=1 trigger.

An example of a request that includes the target-duration=5 query parameter to set #EXT-X-TARGET-DURATON to 5seconds could look like this:

http://repack-host/__cl/cg:live/__c/program/__op/default/__f/index.m3u8?ewm=1&target-duration=5

This will only apply to “live-like” playlists from the repackager. With “live-like” playlists, we mean playlists which come from a live channel including an interval in the past. Such playlists can be detected by searching for the part __cl/cg: in the URL that indicates that the URL is part of a live channel group. Media playlists with the stopTime in the past are technically VoD playlists, but since there is a transition from EVENT to VOD type of playlist as the stopTime is passed, they should be treated as live playlists.

For pure VoD assets, the target-duration can simply be calculated from the longest segment in the playlist, and there is in general no limit on how fast the segments can be requested, so there is no need for target duration modifications.

2.3.6 - Releases

ESB3020 - ew-manip releases

2.3.6.1 - Release 1.0.1

Product release of ew-manip

New:

  • Licensing now incorporates a grace period in case of certain error cases described in Licensing
  • The ew-manip service now gracefully exits when the service is stopped

Release information

  • Date: 2022-05-19
  • Type: Product release

2.3.6.2 - Release 1.0.0

First product release of ew-manip

Fixes:

  • Solved a problem where the output DASH manifest was invalid if any pre-roll had DRM while the main asset had no DRM

New:

  • Manipulating manifests/playlists requires a valid license
  • Product binary has no expiry date

Release information

  • Date: 2022-05-05
  • Type: Product release

2.3.6.3 - Release 0.10.0

Beta release of ew-manip

Fixes:

  • Setting the target duration via the master playlists was not working properly
  • HLS playlist matching has been fixed for certain subtitle use cases
  • The transition from an encrypted preroll to an unencrypted asset is now signaled correctly in the HLS output

New:

  • HLS alternative rendition’s GROUP-ID does not have to be identical for matching anymore
  • Changed the way the nginx configuration is handled. See Upgrades

Release information

  • Date: 2022-04-19
  • Type: Beta for testing

2.3.6.4 - Release 0.8.1

Alpha release of ew-manip

Fixes:

  • Failing HLS media playlist matching with different leaf pathnames has been fixed

Release information

  • Date: 2022-02-16
  • Type: Alpha for testing

2.3.6.5 - Release 0.8.0

Second alpha release of ew-manip

Features:

  • Improved DASH manifest handling
  • Logging backend has been changed. The logging is now structured and is logged to journald
  • Improved HLS variant stream and alternative rendition matching. The names of the variants and the alternatives do not have to be identical anymore.
  • Prometheus counters for keeping track of number of requests received for HLS and DASH respectively

Fixes:

  • File descriptor leak has been resolved
  • For the EXT-X-MEDIA tag, the CHANNELS attribute is now preserved

Release information

  • Date: 2022-02-14
  • Type: Alpha for testing

2.3.6.6 - Release 0.6.0

Initial alpha release of ew-manip

Features:

  • Add pre-roll videos to DASH and HLS assets
  • Change HLS target-duration for live manifests

Release information

  • Date: 2022-01-12
  • Type: Alpha for testing

2.3.7 - Credits

Third party libraries used in ew-manip and their licenses

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryLicenseChecked At
github.com/prometheus/procfsApache-2.02022-03-10
github.com/cespare/xxhash/v2MIT2022-03-10
github.com/matttproud/golang_protobuf_extensions/pbutilApache-2.02022-03-10
github.com/sirupsen/logrusMIT2022-03-10
github.com/prometheus/common/internal/bitbucket.org/ww/goautonegBSD-3-Clause2022-03-10
github.com/prometheus/commonApache-2.02022-03-10
github.com/prometheus/client_model/goApache-2.02022-03-10
github.com/edgeware/m3u8BSD-3-Clause2022-03-10
github.com/rs/zerologMIT2022-03-10
google.golang.org/protobufBSD-3-Clause2022-03-10
github.com/zencoder/go-dash/v3Apache-2.02022-03-10
github.com/coreos/go-systemd/v22/journalApache-2.02022-03-10
github.com/go-chi/chi/v5MIT2022-03-10
github.com/prometheus/client_golang/prometheusApache-2.02022-03-10
github.com/beorn7/perks/quantileMIT2022-03-10
github.com/golang/protobufBSD-3-Clause2022-03-10
golang.org/x/sysBSD-3-Clause2022-03-10

License Details

This section includes all the licenses/notices for each dependency verbatim

github.com/prometheus/client_golang/prometheus

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

The following components are included in this product:

perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.

Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.

Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0

github.com/zencoder/go-dash/v3

LICENSE

Copyright Brightcove, Inc.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/beorn7/perks/quantile

LICENSE

Copyright (C) 2013 Blake Mizerany

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/common

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg

README

PACKAGE

package goautoneg import “bitbucket.org/ww/goautoneg”

HTTP Content-Type Autonegotiation.

The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FUNCTIONS

func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.

func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses

TYPES

type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header

SUBDIRECTORIES

.hg

google.golang.org/protobuf

LICENSE

Copyright (c) 2018 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/matttproud/golang_protobuf_extensions/pbutil

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2012 Matt T. Proud (matt.proud@gmail.com)

github.com/golang/protobuf

LICENSE

Copyright 2010 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright

notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/rs/zerolog

LICENSE

MIT License

Copyright (c) 2017 Olivier Poitrey

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

golang.org/x/sys

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/edgeware/m3u8

LICENSE

Copyright (c) 2013-2016 Alexander I.Grafov grafov@gmail.com Copyright (c) 2013-2016 The Project Developers.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/coreos/go-systemd/v22/journal

LICENSE

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  1. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  1. Grant of Patent License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  1. Redistribution.

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  1. Submission of Contributions.

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  1. Trademarks.

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  1. Disclaimer of Warranty.

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  1. Limitation of Liability.

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  1. Accepting Warranty or Additional Liability.

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

CoreOS Project Copyright 2018 CoreOS, Inc

This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).

github.com/go-chi/chi/v5

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_model/go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/procfs

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.

Copyright 2014-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/sirupsen/logrus

LICENSE

The MIT License (MIT)

Copyright (c) 2014 Simon Eskildsen

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/cespare/xxhash/v2

LICENSE

Copyright (c) 2016 Caleb Spare

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2.4 - VoD Ingest (ew-vodingest)

Ingest VoD assets into ESF and DASH OnDemand format

2.4.1 - Introduction

Introduction to ew-vodingest

The ew-vodingest command may be used to perform either VoD ingest or to perform live recordings from an ew-live-ingest (esb3003) circular buffer.

VoD ingest

ew-vodingest (ESB3021) reads and ingests an MP4/ts audio and video + subtitles asset defined by a SMIL file into an ESF (Edgeware Storage Format) asset in a way that is compatible with the DASH OnDemand profile. A corresponding DASH MPD file is generated. The SMIL-file syntax and usage is explained in the SMIL section.

It is also possible to specify a .ts-file, an .mp4-file or a directory-path as input.

For example:

ew-vodingest --input hitchcock/vertigo/index.smil --output esf/vertigo

Note: A main focus of this tool is to ingest VoD content that can be used to generate live content by combining VoD assets using ESB3019 ew-vod2cbm. There is therefore a restriction on the ingested content that it must be possible to discover a common constant GoP duration (sync-frame distance) for all video tracks, and that all sample durations are exactly the same in their respective timescales. The timescales may differ, but only by integer factors, for example 50 for 50Hz video and 25 for 25Hz video.

Codec and input format

Please refer to Supported codecs to get more information.

Input locations

This tables shows the possible combinations of input types and locations:

filesystemhttp/httpsS3
directoryyesnoyes
SMILyesyesyes
MP4yesnono
tsyesnono
DASH On-Demandyesyesyes
HLSyesyesyes
Unencrypted ISM/MSSyesyesyes

For ingesting large assets (or for slow locations) the --maxtime command-line parameter can be used to increase the timeout threshold.

Output locations

Output locations can always be local filesystem, or network locations, as above. By default the content_id in content_info.json of the output asset will equal the output directory. This can be overridden by specifying any other ID with the --content-id command-line parameter.

Live recordings

The input for live recordings is an ew-live-ingest (esb3003) with a circular buffer available on the instance specified by --host and --port (default localhost:8090). The output locations are the same as for VoD ingest above.

The --cbm flag triggers a live recording (and cannot be combined with --i). The start/stop times are specified in epoch seconds, and must be in the past. The recording will consist of integral segments, matching the specified time range as closely as possible. The time-stamps in the resulting VoD will be shifted to start from zero. Any “holes” in the specified intervals will be removed, thus resulting in a recording shorter than the specified interval.

SCTE-35 markers are transferred from the CBM interval and stored in a separate file.

For example:

ew-vodingest --cbm --start-epoch 1678190071 --stop-epoch 1678190099 --channel tv1 -o tv1-mar-7-2023

Usage

ew-vodingest is a command-line tool that is run as:

ew-vodingest [options]

Run as ew-vodingest [options]

-i, --input string               SMIL file, dir or file pattern defining the asset (mandatory)
-o, --output string              output directory (mandatory)
-w, --minseg int                 minimum output segment duration (milliseconds) (default 4000)
-y, --maxseg int                 maximum output segment duration (milliseconds) (default 12000)
    --cbm                        set to use esf export from cbm
    --start-epoch uint           recording start time given in epoch seconds. Only works with --cbm
    --stop-epoch uint            recording stop time given in epoch seconds. Only works with --cbm
    --channel string             channel name to record from. Only works with --cbm
    --drop-non-aligned-track     drop track with abnormal segment duration. Only works with --cbm
-c, --content-id string          explicit content-id (instead of ingest path)
-m, --maxtime int                maximal execution time to ingest asset (seconds) (default 1800)
    --hls                        output HLS playlists (experimental)
    --slim                       only output content_info and dat files
    --leavepartial               leave partial ingested content on failure
    --s3file string              path to S3 credentials file
-t, --template string            path to content template file, for asset comapatibility verification
    --licensefile string         license file path (default "/etc/edgeware/ew-vodingest/license.json")
-l, --logfile string             log file [default stdout]
    --log-file string            see above
    --logformat string           format and type of log: [consolejson consolepretty discard] (default "consolepretty")
    --loglevel string            initial log level (default "info")
-v, --version                    print version and date
    --host string                cbm host to connect to. Only works with --cbm (default "localhost")
    --port uint16                cbm port to connect to. Only works with --cbm (default 8090)
    --source-rate-limit uint32   maximum read rate in Mbps from source. Only works with --cbm. Setting 0 will disable source rate limiting
    --help                       extended tool help

The following options -i, -o, -w, -y, --cbm, --start-epoch, --stop-epoch, --channel, -l, --source-rate-limit are the same as for the ESB3005 ew-recorder.

2.4.2 - Installation

Installation

The command line tool ew-vodingest can be installed on a Linux distribution compatible with RedHat Enterprise Linux 7 or 8 with:

$ sudo yum install ew-vodingest-x.y.z-1.el8.x86_64.rpm

In addition, the tool ew-vodmod will be installed.

To uninstall, do:

$ sudo yum remove ew-vodingest.x86_64

2.4.3 - Tools

Tools bundled with ew-vodingest

The ew-vodingest rpm also contains the tool ew-vodmod.

ew-vodmod

This tool can modify subtitle and caption tracks of ingested assets.

It only works on ESF assets that are available as a mounted file directory. If the asset was ingested with ew-vodingest and has a DASH MPD file, it will also be updated. Other features from ew-vodingest like storing original subtitle files with a BaseURL link in content_info.json are also implemented.

The tool has commands like add, delete, modify, etc to allow changes to the asset. Each command has its own flags. To get help for a command, use the –help flag with the command, like $ ew-vodmod add --help or simply type ew-vodmod add.

Usage:
  ew-vodmod [command]

Available Commands:
  add         Add a new subtitle track to an asset
  completion  Generate the autocompletion script for the specified shell
  delete      Delete an existing subtitle track
  help        Help about any command
  list        Lists available subtitle tracks
  modify      Modify attributes of an existing subtitle track
  rename      Rename an existing subtitle track
  replace     Replace an existing subtitle track

Flags:
  -h, --help                help for ew-vodmod
      --log-file string     log to specified file instead of standard output
      --log-format string   format and type of log: [consolejson consolepretty discard] (default "consolepretty")
      --log-level string    log level (trace|debug|info|warn|error|fatal|panic) (default "info")
  -v, --version             version for ew-vodmod

2.4.4 - SMIL manifest

Input specification using a SMIL file

Input SMIL syntax

SMIL is an XML format for multimedia presentation. It can be used instead of an HLS master playlist or DASH Media Presentation File to tell what media files should be combined into an asset and some associated metadata parameters. The level of detail, however, is much lower than in the other formats. ew-vodingest supports the import of MP4 files for video and audio, in connection to subtitle files.

Our usage of SMIL follows legacy format of Wowza, but we have added some parameters, such as displayName for HLS and role for subtitles.

Basic structure

SMIL files should specify all relevant media files in a switch block in the body:

<?xml version="1.0" encoding="UTF-8"?>
<smil>
    <body>
        <switch>
            <video src="movie1.mp4" ... />
            <video src="audio.mp4" ... />
            <textstream ... />
            <srt ... />
        </switch>
    </body>
</smil>

Stream types

The supported stream types are <video> which either means video, audio or both, <texstream> that is a subtitle file or <srt> which is a subtitle file in SRT format.

Video/Audio streams

Audio and video streams are identified by the video tag.

Minimal configuration

The simplest variant is to just give a src attribute:

<video src="videoAndAudio.mp4"/>

If this is the only information give, all video and audio tracks will be extracted and given names following the patterns

media typepatternexample
videovideo_<codec>_<bitrate>video_hevc_9000kbps
audioaudio_<codec>_<lang>_<bitrate>audio_aac_en_256kbps

depending on what tracks and codecs are available. The bitrate is calculated from the file size and duration and the language is extracted from the mp4 file if available in an elng, of in the mdhd box as a fallback.

If multiple files are specified in the SMIL file, tracks will be extracted from all of them, but if the resulting names (mediatype_codec_bitrate_language) coincide, only one copy will be kept. This makes it possible to import files which all include the same audio bitrate and language, but different video bitrates.

Specifying the bitrate

The system-bitrate attribute is used to specify the bitrate for the stream.

<video src="video.mp4" system-bitrate="2500000" />

Optionally it is possible to specify bitrates as <param> values as

<video src="videoAndAudio.mp4">
    <param name="videoBitrate" value="2500000"/>
    <param name="audioBitrate" value="128000"/>
</video>

Track selection and track-specific parameters - mp4

To achieve higher control over the extraction of tracks, and their parameters, it is possible to add extra parameters.

In particular, one can use the audioOnly and videoOnly keys to specify that only one type of media track should be extracted.

To extract audio and video in this way, one could use the following snippet:

<video src="videoAndAudio.mp4" system-bitrate="2500000">
    <param name="videoOnly" value="TRUE"/>
</video>
<video src="videoAndAudio.mp4" system-bitrate="128000">
    <param name="audioOnly" value="TRUE"/>
</video>

In addition, one can add an audioindex query index to extract a specific audio track. The audioindex value relates to the track ID inside an mp4 file, but is zero-based. The mapping is that ?audioindex=0 refers to the audio track with the lowest track ID, ?audioindex=1 to the second, and so on.

Here is an example that extracts the first two audio tracks, and gives them different parameters for language, bitrate, and displayName:

<video src="hev1_aac_mc.mp4?audioindex=0" system-language="dk" audio-bitrate="256000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="Danish 6ch"/>
</video>
<video src="hev1_aac_mc.mp4?audioindex=1" system-language="dk" audio-bitrate="192000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="Danish 2ch"/>
</video>

Track selection and track-specific parameters - ts

For multiplexed .ts-files the audio tracks are selected by specifying the trackID parameter corresponding to the PID, as follows:

      <video src="0.ts" audio-bitrate="94000" systemLanguage="spa">
        <param name="audioOnly" value="TRUE" />
        <param name="trackID" value="482"/>
        <param name="displayName" value="español"/>
      </video>

Audio Language

The language for an audio stream can be set using the system-language attribute:

<video src="mp4:video3.mp4?audioindex=0" system-language="eng">

For legacy reasons, one can alternatively use the attribute systemLanguage or language.

If the language is not specified, 3-letter language code in the mdhd box will be used. It will in turn be overridden by the optional elng box that can contain any language code.

Subtitle input

The supported input subtitle formats are TTML, WebVTT, STL, SRT. In all cases, a complete side-loaded file is expected. As part of the ESF format, the subtitles will be transformed into segmented wvtt. A complete WebVTT file will also be generated and referred to in the generated DASH manifest. The name of the output subtitle tracks are of the form

media typepatternexample
subtitlessubtitles_wvtt_<lang>_<role>subtitles_wvtt_se_caption

The role can be either caption or subtitle. If not specified, the role will be not be in the track name.

Subtitle streams in TTML, WebVTT, STL, or STT files are specified with the <textstream> or <srt> tags. The language can be specified with language attribute, or, for textstream, with the system-language attribute like:

<textstream src="subtitles.ttml" system-language="en" />
<srt src="swedish.srt" language="se"/>

The format is auto-detected from the file extension, which must be one of:

 .ttml, .webvtt, .vtt, .stl, .srt

The case of multiple languages in the same TTML file is not supported.

There is no bitrate specified for text streams. It will always be set to 1kbps.

Extracting language from subtitle file name

For the case where the SMIL-file is missing or there is no language attribute for the subtitle files, ew-vodingest will try to extract a language from the file name. The language extraction algorithm works like this:

  1. the file extension is removed
  2. split the name on “-” characters
  3. if the last part is at most three characters, use it as a language code

If a language is not found, the subtitle languages will be denoted “und”, “und1”, “und2” etc.

Example SMIL files

In the following, we give examples to show some possible variations of supported SMIL files.

Example 1 - video and audio from all files

This example has width and height for the video. That information will be discarded. There are only two distinct combinations of language and bitrate for audio, so only two variants audio_aac_eng_128kbps and audio_aac_eng_192kbps will be generated.

<?xml version="1.0" encoding="UTF-8"?>
<smil>
    <body>
    <switch>
        <video height="360" src="profile1.mp4" systemLanguage="eng" width="480">
        <param name="videoBitrate" value="500000"/>
        <param name="audioBitrate" value="128000"/>
        </video>
        <video height="480" src="profile2.mp4" systemLanguage="eng" width="720">
        <param name="videoBitrate" value="800000"/>
        <param name="audioBitrate" value="128000"/>
        </video>
        <video height="540" src="profile3.mp4" systemLanguage="eng" width="960">
        <param name="videoBitrate" value="1300000"/>
        <param name="audioBitrate" value="128000"/>
        </video>
        <video height="720" src="profile4.mp4" systemLanguage="eng" width="1280">
        <param name="videoBitrate" value="2300000"/>
        <param name="audioBitrate" value="192000"/>
        </video>
        <video height="1080" src="profile5.mp4" systemLanguage="eng" width="1920">
        <param name="videoBitrate" value="5000000"/>
        <param name="audioBitrate" value="192000"/>
        </video>
    </switch>
    </body>
</smil>

Example 2 - audioindex queries

This example shows extraction of audio tracks using the audioindex query parameter. The mp4: “scheme” is not needed, but supported for legacy reasons. The mp4:/// scheme is also supported for the same reason.

<?xml version="1.0"?>
<smil>
    <body>
    <switch>
        <video src="mp4:video1.mp4?audioindex=0" system-language="eng" audio-bitrate="96000">
        <param name="audioOnly" value="TRUE"/>
        </video>
        <video src="mp4:video1.mp4?audioindex=1" system-language="ger" audio-bitrate="96000">
        <param name="audioOnly" value="TRUE"/>
        </video>
        <video src="video2.mp4" system-bitrate="2000000">
        <param name="videoOnly" value="TRUE"/>
        </video>
        <video src="video1.mp4" system-bitrate="5000000">
        <param name="videoOnly" value="TRUE"/>
        </video>
        <textstream src="subtitles.ttml" system-language="eng">
        </textstream>
    </switch>
    </body>
</smil>

Example 3 - displayName and role parameters

This example uses parameters for displayName for audio and subtitles, and role for subtitles.

<?xml version="1.0" encoding="utf-8"?>
<smil>
  <body>
    <switch>
      <video src="video800.mp4" system-bitrate="800000">
        <param name="videoOnly" value="TRUE"/>
      </video>
      <video src="video400.mp4" system-bitrate="400000">
        <param name="videoOnly" value="TRUE"/>
      </video>
      <video src="audio.mp4?audioindex=0" system-language="eng" audio-bitrate="256000">
        <param name="audioOnly" value="TRUE"/>
        <param name="displayName" value="English 6ch"/>
      </video>
      <video src="audio.mp4?audioindex=1" system-language="eng" audio-bitrate="192000">
        <param name="audioOnly" value="TRUE"/>
        <param name="displayName" value="English 2ch"/>
      </video>
      <srt src="swe.srt" language="swe">
        <param name="displayName" value="svenska"/>
        <param name="role" value="subtitle"/>
      </srt>
      <srt src="swe_cc.srt" language="swe">
        <param name="displayName" value="svenska (CC)"/>
        <param name="role" value="caption"/>
      </srt>
      <textstream src="eng.stl" system-language="eng">
        <param name="displayName" value="English"/>
        <param name="role" value="caption"/>
      </textstream>
    </switch>
  </body>
</smil>

Example 4 - The simplest possible - same as no SMIL

This example shows a SMIL file where all parameters are extracted automatically. In this case all video sources contain audio with language set to engin the mdhd box in the mp4 files, and the subtitle languages can be extracted from the file names.

<?xml version="1.0" encoding="UTF-8"?>
<smil>
  <body>
    <switch>
      <video src="0.mp4"/>
      <video src="1.mp4"/>
      <video src="2.mp4"/>
      <video src="3.mp4"/>
      <srt src="xyz-eng.srt"/>
      <srt src="xyz-spa.srt"/>
    </switch>
  </body>
</smil>

The generated tracks are:

  • 4 video tracks with different bitrates
  • 2 audio track with different bitrates, but the same language “eng”
  • 2 subtitle tracks with language codes “eng” and “spa”

In this particular case, the SMIL file just provides a list of files and no extra parameter. Therefore, it is also possible to specify the directory of this file as input to ew-vodingest and get exactly the same result.

2.4.5 - Supported codecs

Input supported codec

Progressive MP4

An MP4 file contains all video and audio tracks. All the tracks in that MP4 will be extracted except subtitle.

Video

H.264/AVC and H.265/HEVC with multiple bitrates.

For H.264/AVC, both avc1 and avc3 are accepted, but the result always be stored with avc1 type of video sample entry box.

For H.265/HEVC, both hev1 and hvc1 are accepted, but the result will always be stored with hev1 type of video sample entry box.

In case sync-frames among video tracks are algined and have the same distance from --minseg to --maxseg, all output video tracks will be segmented with the same segment duration, the lowest segment duration in that interval will be chosen. On the other hand, if sync-frames are not aligned among video tracks, each video track must have the sync-frames distance from --minseg to --maxseg, in this case, the segment duration of output video tracks can be different and for each video, the lowest sync-frames distance in that interval will be chosen. Video tracks timescales, as defined in mdhd box, need to be the same among videos, or differ by an integer factor like 50 and 25 with factor is 2, or 60000 and 20000 with factor is 3.

Audio

AAC, HE-AACv1, HE-AACv2, AC3, Enhanced AC3, and MP4 with multiple bitrates and languages. Language will be gotten from mdhd box.

Subtitle

Embedded subtitle are not supported.

Note: you can add subtitle track later by this tools. Or you can use Directory input method by putting MP4 files and subtitle files into the same directory.

SMIL + progressive MP4

In this case, the assets have a SMIL file describing the Progressive MP4 video, audio and text stream.

Video

The same with Progressive MP4

Audio

The same with Progressive MP4

Subtitle

The SMIL-file syntax and usage is explained in the SMIL section. In that section, you can also find the subtitle specification at Subtitle input.

MPEG2-TS

A TS file contains all video and audio tracks, and them all will be extracted except subtitle track.

Video

H.264/AVC and H.265/HEVC with multiple bitrates. In case sync-frames among video tracks are algined and have the same distance from --minseg to --maxseg, all output video track will be segmented with the same segment duration, the lowest segment duration in that interval will be chosen. On the other hand, if sync-frames are not aligned among video tracks, each video track must have the sync-frames distance from --minseg to --maxseg. In this case, the segment duration of output video tracks can be different and for each video, the lowest sync-frames distance in that interval will be chosen. The timescale in TS file must be standard, 90000.

Audio

AAC, HE-AACv1, HE-AACv2, AC3, and Enhanced AC3 with multiple bitrates and languages. Language will be gotten from stream descriptors in PMT.

Subtitle

Embedded subtitle are not supported.

Note: you can add subtitle track later by this tools. Or you can use Directory input method by putting TS files and subtitle files into the same directory.

Directory

A directory contains all the input TS, MP4 and subtitle files. ew-vodingest will scan and extract all the media tracks from the media files in that directory.

Video

The same with Progressive MP4 and MPEG2-TS sections, duplicated tracks are going to be dropped.

Audio

The same with Progressive MP4 and MPEG2-TS sections, duplicated tracks are going to be dropped.

Subtitle

Side-loaded subtitle text files are supported.

Supported formats: ttml, webvtt, srt, stl. Subtitle format will be detected by the file extension: .ttml for ttml format. .vtt and .webvtt for webvtt format. .srt for srt format. .stl for stl format.

MPEG DASH On-Demand Profile

A DASH On-Demand MPD file describes the asset.

Video

H.264/AVC and H.265/HEVC with multiple bitrates.

For H.264/AVC, both avc1 and avc3 are accepted, but the result always be stored with avc1 type of video sample entry box.

For H.265/HEVC, both hev1 and hvc1 are supported, but the result always be stored with hev1 type of video sample entry box.

All video tracks need to have the same timescale as defined in mdhd box.

Audio

AAC, HE-AACv1, HE-AACv2, AC3 and Enchaned AC3 with multiple bitrates and languagues.

Subtitle

Side-loaded subtitle text files is supported under formats: ttml, webvtt, srt.

Side loaded subtitle fragmented mp4 files is supported under formats: stpp and fragmented webvtt.

CEA608 Closed Captions is preserved from MPD manifest file.

Apple HLS

A Master Playlist file describes the asset. Multiplexed and isolate video and audio tracks are both supported in individual segment files or a concatenated files.

Video

H.264/AVC in TS encapsulation.

H.264/AVC and H.265/HEVC are supported in fMP4 encapsulation.

Audio

AAC, HE-AACv1, HE-AACv2, AC3 and Enhanced AC3 in fMP4 and TS encapsulation.

Subtitle

HLS WebVTT as side loaded, complete or segmented text files.

HLS stpp as fragmented files.

CEA608 Closed Captions are preserved from master playlist (.m3u8 file).

Microsoft SmoothStreaming

The MSS/ISM manifest file is used to define the asset.

Video

H.264/AVC with multiple bitrates.

Although it is not standard, H.265/hevc with muiltiple bitrates is supported.

Audio

AAC and HE-AAC with multiple bitrates and languages.

Subtitle

TTML as side-loaded complete files.

2.4.6 - HDR10 support

Description for HDR10 support

When ingesting TS streams, HDR10 is detected by parsing SPS. If the HDR10 info is included in the TS streams, the VUI part of SPS will contain colour_primaries with value 9, matrix_coeffs with value 9 and transfer_characteristics with value 16. If ew-vodingest detects exactly HDR10 info with these values, it will do following things:

  • Add new hdr field to video variant in content_info.json. This field currently supports only one value hdr10. The video variant info will look like this:
  "variants": [
    {
      "media_type": "video",
      "subtype": "hevc",
      "name": "video_hevc_886kbps",
....
      "hdr": "hdr10",
  • Add compatible brand “chd1” to ftyp box of video file .cfmv
[ftyp]
 - majorBrand: mp42
 - minorVersion: 512
 - compatibleBrand: chd1

Beside the VUI part of SPS, the following SEI NAL units may be present in the TS streams: Mastering display colour volume (SEI payload type 137) and Content light level information (SEI payload type 144). But this signal is optional, ew-vodingest doesn’t rely on them to detect HDR10. If these SEI NAL units are present, ew-vodingest will just add them to the hvcc box of video file .cfmv

For MP4 input, ew-vodingest does exactly the same behaviours, but the behaviour which add above SEI NAL units to hvcc box has not been tested.

2.4.7 - AWS S3 Cloud Usage

Using S3

To ingest to or from S3, the path is specified with s3://. For example:

ew-vodingest --input s3://mybucket/dir1 --output /home/myhome/esf1 --s3file /home/myhome/.aws/credentials.json

S3 credentials file

You must create a JSON file for the credentials. (The credentials file used by the AWS CLI is not used.) For example:

{
    "profile": "default",
    "region": "eu-north-1",
    "id": "AKIAQWERTYQWERTY",
    "key": "qwerty123+QWERTY123&qwerty"
}

The actual values must be obtained from the AWS administration console. Here id and key correspond to "Access key ID" and "Secret access key".

2.4.8 - Releases

ESB3021 - ew-vodingest releases

2.4.8.1 - Release 1.8.0

Major new features

Features:

  • New: Support for HLS VOD input
  • New: Support for unencrypted ISM/MSS
  • New: Support for irregular sample duration VODs (TS and MP4)
  • New: Preserve WebVTT styling
  • New: Support Audio Descriptions in VOD ingestion
  • Fix: Missing CUE-IN for one segment ad break
  • Fix: Average segment duration appears in content_info.json when common GoP cannot be detected
  • Fix: Incorrect audio language
  • Fix: Incorrect audio codec
  • Fix: Duplicate track name for HEVC HDR and SDR tracks
  • Fix: Ingest stops due to unrecognized tag in smil
  • Fix: Missing role for subtitle track
  • Fix: Cannot parse PES packet containing more than one AAC frame, causing silent audio output
  • Fix: Incorrect maximum segment duration in content_info.json
  • Fix: Redundant HLS target duration in content_info.json

Known limitations:

  • Does not preserve TTML subtitle styling
  • VoD ingest of SMIL over HTTP, does not work with query parameter audioIndex

Compatibility has been verified with the following products:

  • Sw Repackager: 1.46.2
  • Sw Live Ingest: 1.38.0
  • DRM Gateway: 2.30.1
  • Convoy: 2.36.0

Release information

  • Date: 2023-11-29
  • Type: Production release

2.4.8.2 - Release 1.6.0

Major new features

Features:

  • New: Support for DASH On-Demand
  • New: Option to throttle the reading rate from local storage
  • Fix: Incorrect subtitles timing
  • Fix: Ingestion failed when missing some samples at the end of tracks
  • Fix: Cannot stream MSS throught ew-repackager
  • Fix: Lingering .dat file after ingestion failed
  • Fix: Missing field content_duration_ms for recordings
  • Fix: Language code is not extracted from subtiles filename when ingesting from SMIL (if language is not defined in SMIL)

Known limitations:

  • Does not preserve subtitle styling
  • VoD ingest of SMIL over HTTP, does not work with query parameter audioIndex

Release information

  • Date: 2023-09-18
  • Type: Production release

2.4.8.3 - Release 1.4.0

Major new features

Features:

  • New: Support for EC-3 audio in transport streams
  • New: ew-vodmod tool to modify subtitle tracks of ingested VoD assets
  • New: Option to drop incompatible media tracks
  • Fix: ew-vodingest did not escape special character for WVTT format
  • Fix: corrected VOD-asset duration in log
  • Fix: corrected dropping of too early audio samples in TS ingest (causing “Bad box size” error)

Known limitations:

  • Does not preserve subtitle styling
  • HDR10 has not been tested fully on MP4 file
  • VoD ingest of SMIL over HTTP, does not work with query parameter audioIndex
  • live-recording-asset duration is logged as zero

Release information

  • Date: 2023-06-08
  • Type: Production release

2.4.8.4 - Release 1.2.0

Major new features

Features:

  • New: Live recordings (with esb3003 CBM)
  • New: Command-line content-id (esb3005 style)
  • New: Content template verification, for esb3019 integration
  • New: Allow non-constant GoP-durations
  • New: Improved S3 and NFS failure handling
  • Fix: Superfluous audio-track generation
  • Fix: Confused output audio bandwidths
  • Fix: ADTS headers with 2-byte CRC

Known limitations:

  • Does not preserve subtitle styling
  • HDR10 has not been tested fully on MP4 file
  • VoD ingest of SMIL over HTTP, does not work with query parameter audioIndex

Release information

  • Date: 2023-03-08
  • Type: Production release

2.4.8.5 - Release 1.0.0

First production release of ew-vodingest

Features:

  • Ingest single file TS
  • Ingest single file MP4
  • Support for HDR10
  • S3 and HTTP support
  • Timeout handling
  • Improved logging
  • Offline licensing

Known limitations:

  • Require constant GoP duration and constant sample steps
  • Does not preserve subtitle styling
  • HDR10 has not been tested fully on MP4 file

Release information

  • Date: 2022-12-02
  • Type: First production release

2.4.8.6 - Release 0.6.2

Initial beta release of ew-vodingest

Features:

  • Ingest SMIL + mp4 + subtitle assets in combined ESF + DASH OnDemand format
  • Support AVC, HEVC video
  • Support AAC, AC-3 audio
  • Support TTML, WebVTT, SRT, STL subtitles
  • Support displayName parameter for audio and subtitles
  • Support role (caption or subtitle) parameter for subtitles

Known limitations:

  • Requires mounted file system for input and output
  • Require constant GoP duration and constant sample steps
  • Does not preserve subtitle styling
  • Logging is not nice

Release information

  • Date: 2022-03-28
  • Type: Beta for testing
  • Expiration Date: 2022-09-24

2.4.9 - Licensing

Licensing for ew-vodingest

ew-vodingest requires a valid license file to operate. The license file must be obtained from Agile Content, and copied to /etc/edgeware/ew-vodingest/license.json. Note: ew-vodingest only operates with offline licenses.

See further details here.

2.5 - HLS Ingest (ew-hlsingest)

Ingest live HLS channels to Edgeware internal live format [ESF]

2.5.1 - Introduction

ESB3023 - the ew-hlsingest service

The service consumes live HLS v3 sources. The sources must be multiplexed video and audio in each variant. Separate audio, video or subtitles are not supported. Higher HLS versions are not supported.

The output segments are typically written to a RAM disk, and are to be be consumed by the edgeware CBM (esb3003) for further integration with the Edgeware repackager.

The output segments will be generated with a fixed average segment duration that is constant over time. To achieve this, it is required that the input segments have a fixed segment duration except at ad boundaries signalled by SCTE-35 markers. At such boundaries, the input segments should be split by an extra IDR-frame.

2.5.2 - Installation and Upgrades

Installation

The ew-hlsingest service is distributed as a CentOS/Red Hat RPM and is available as ew-hlsingest.service when installed. It works both on RH 7 and 8 and compatible versions.

To install version x.y.z, the rpm command can be used as follows:

yum install ./ew-hlsingest-x.y.z-1.el8.x86_64.rpm

The service can be controlled with the standard systemctl commands:

systemctl start ew-hlsingest
systemctl stop ew-hlsingest
systemctl status ew-hlsingest

Logs from the service can be seen using journalctl -u ew-hlsingest.

The unit file is available in /usr/lib/systemd/system/ew-hlsingest.service.

When run as a service, ew-hlsingest reads its initial configuration from /etc/edgeware/ew-hlsingest/config.json. To uninstall the service, do:

yum remove ew-hlsingest

When uninstalling or upgrading it is recommended to first stop the service.

Upgrades

There is only one version of ew-hlsingest so there are no configuration concerns during upgrade.

In the future, to upgrade simply run:

$ sudo yum upgrade <rpm-file>

2.5.3 - Configuration and command-line arguments

Configuration and command-line

Typically ew-hlsingest is run as a systemd service with command-line arguments specified in /usr/lib/systemd/system/ew-hlsingest.service.

In can also be started from the command-line.

Command-line arguments

ew-hlsingest -h
Usage of ew-hlsingest:
  -cfg string
    	Config file (default "/etc/edgeware/ew-hlsingest/config.json")
  -defaultConfig
    	Print default configuration
  -logFormat string
    	Format and type of log: [consolejson consolepretty journald discard] (default "consolepretty")
  -logLevel string
    	log level (default "trace")
  -version
    	Get version, date, and possible expiration date

Configuration parameters

The configuration file, in the location specified as above, controls the service.

Review note: generate JSON-schema

This is an example configuration with two channels:

{
  "outDir": "/tmp/ew-hlsingest",
  "startCatchup": 20,
  "logFormat": "journald",
  "logLevel": "info",
  "maxAdBreakDuration": 600,
  "channels": [
     {
           "name": "ch1",
           "url": "https://sometv.org/channel1",
           "configID": 0,
           "maxBandwidth": 100000000,
           "liveWindowS": 180,
           "logLevel": "info"
     },
     {
           "name": "ch2",
           "url": "https://othertv.org/channel1",
           "configID": 0,
           "maxBandwidth": 100000000,
           "liveWindowS": 180,
           "logLevel": "info"
     }
  ]
}

Some fields may need clarification:

maxAdBreakDuration Sometimes upstreams may fail to insert ad-break-end-markers (i.e. #EXT-X-CUE-IN) After the specified duration inside an ad-break ew-hlsingest will insert an end-marker.

maxBandwidth variants with bitrates above this threshold will be dropped from the output

configID allows the “downstream” CBM to distinguish between channel configurations. For example if maxBandwidth is modified the number output variants change, and configID must be incremented.

Review note: part of defaultconfig and internal struct, never referenced, remove! startCatchup

Review note: maxAdBreakDuration [etc] should have Sin its name to clarify unit

Configuration updates

Channels can be modified/added/removed without restarting the service. Any modification to the configuration file are automatically detected, and channels will be restarted/started/stopped accordingly. Changes not directly related to the service itself, such as logLevel, will not trigger a restart.

2.5.4 - Logging

service logs

Logging

To provide context to each log message, structured logging is used. Thus instead of free text log messages without any specific format, the log data is to some extent divided into fields of name-value pairs, making the logs more coherent and more suitable for processing by external tools.

Log messages related to a specific HTTP request include the log field named request_id which can be used to filter out specific requests.

The log field named topic is always present and is used to separate different areas of logging. The current topics are access, messages and error, and are used to log HTTP access, debug messages and panic stack traces, respectively.

As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.

Log formats

When run from the command line ew-hlsingest can log in one of the formats consolepretty, consolejsonorjournalddepending on the value of the-logformatparameter. Logging can be disabled by using the valuediscard`.

$ ew-hlsingest -upstream http://127.0.0.1 -logformat consolejson

consolepretty logs to standard output (stdout) in a human-readable format. Each log line starts with the date and the log message followed by the context- dependent log fields:

2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...

consolejson logs to stdout using a JSON object for each message:

{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}

When run as a systemd service, ew-hlsingest logs directly to journaldusing thelogjournaldconfiguration parameter. When stored injournald`, field names are upper case whereas the values keep their format. Some examples:

To see entries a specific channel:

$ journalctl -u ew-hlsingest CHANNEL=ch1 -o verbose

To continuously monitor the service:

$ journalctl -fu ew-hlsingest

Log levels

At startup the log level is set to info. The log level can be changed by posting a form-field named level to the loglevel endpoint on the `ew-hlsingest server:

$ curl -F level=debug ew-hlsingest-server:8090/loglevel

The available log levels and how they relate to systemd priority values is listed below:

Log level  Systemd priority
trace      7
debug      7
info       6
warn       4
error      3
fatal      2
panic      0

To e.g. see all error and warning messages using journalctl:

$ journalctl -u ew-hlsingest PRIORITY=3 PRIORITY=4

Messages with higher level than the configured one will not be logged.

2.5.5 - Credits

Third party libraries used in ew-hlsingest and their licenses

Review Note:: this list was copied from ew-vod2cbm. It is just a placeholder until we generate it here.

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryLicenseChecked At
github.com/prometheus/common/internal/bitbucket.org/ww/goautonegBSD-3-Clause2022-03-18
github.com/go-openapi/jsonreferenceApache-2.02022-03-18
github.com/swaggo/swagMIT2022-03-18
github.com/go-playground/universal-translatorMIT2022-03-18
github.com/edgeware/mp4ff/mp4MIT2022-03-18
github.com/go-playground/validatorMIT2022-03-18
github.com/leodido/go-urnMIT2022-03-18
github.com/prometheus/commonApache-2.02022-03-18
github.com/zencoder/go-dash/v3Apache-2.02022-03-18
github.com/go-openapi/specApache-2.02022-03-18
gopkg.in/yaml.v2Apache-2.02022-03-18
github.com/swaggo/http-swaggerMIT2022-03-18
github.com/edgeware/mp4ff/bitsMIT2022-03-18
github.com/PuerkitoBio/purellBSD-3-Clause2022-03-18
github.com/josharian/internMIT2022-03-18
golang.org/x/textBSD-3-Clause2022-03-18
github.com/aws/aws-sdk-go/internal/sync/singleflightBSD-3-Clause2022-03-18
github.com/asticode/go-astikitMIT2022-03-18
github.com/cespare/xxhash/v2MIT2022-03-18
github.com/prometheus/procfsApache-2.02022-03-18
google.golang.org/protobufBSD-3-Clause2022-03-18
github.com/prometheus/client_model/goApache-2.02022-03-18
golang.org/x/toolsBSD-3-Clause2022-03-18
github.com/jmespath/go-jmespathApache-2.02022-03-18
github.com/prometheus/client_golang/prometheusApache-2.02022-03-18
github.com/go-openapi/swagApache-2.02022-03-18
github.com/go-chi/chi/v5MIT2022-03-18
github.com/rs/zerologMIT2022-03-18
github.com/matttproud/golang_protobuf_extensions/pbutilApache-2.02022-03-18
github.com/go-chi/docgenMIT2022-03-18
github.com/asticode/go-astisubMIT2022-03-18
github.com/PuerkitoBio/urlescBSD-3-Clause2022-03-18
github.com/swaggo/filesMIT2022-03-18
github.com/aws/aws-sdk-goApache-2.02022-03-18
github.com/golang/protobufBSD-3-Clause2022-03-18
golang.org/x/sysBSD-3-Clause2022-03-18
github.com/go-playground/localesMIT2022-03-18
github.com/go-openapi/jsonpointerApache-2.02022-03-18
github.com/coreos/go-systemd/v22/journalApache-2.02022-03-18
github.com/beorn7/perks/quantileMIT2022-03-18
github.com/edgeware/mp4ffMIT2022-03-18
golang.org/x/netBSD-3-Clause2022-03-18
github.com/asticode/go-astitsMIT2022-03-18
github.com/mailru/easyjsonMIT2022-03-18
github.com/Comcast/gotsMIT2022-03-18
github.com/KyleBanks/depthMIT2022-03-18

License Details

This section includes all the licenses/notices for each dependency verbatim

github.com/prometheus/common

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/swaggo/swag

license

MIT License

Copyright (c) 2017 Eason Lin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Comcast/gots

LICENSE

/* MIT License

Copyright 2016 Comcast Cable Communications Management, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

NOTICE

Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).

github.com/KyleBanks/depth

LICENSE

MIT License

Copyright (c) 2017 Kyle Banks

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/PuerkitoBio/urlesc

LICENSE

Copyright (c) 2012 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/asticode/go-astikit

LICENSE

MIT License

Copyright (c) 2020 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/beorn7/perks/quantile

LICENSE

Copyright (C) 2013 Blake Mizerany

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/matttproud/golang_protobuf_extensions/pbutil

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2012 Matt T. Proud (matt.proud@gmail.com)

github.com/go-chi/chi/v5

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/docgen

LICENSE

Copyright (c) 2016-Present https://github.com/go-chi authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/josharian/intern

license

MIT License

Copyright (c) 2019 Josh Bleecher Snyder

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_model/go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/procfs

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.

Copyright 2014-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

gopkg.in/yaml.v2

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2011-2016 Canonical Ltd.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/asticode/go-astits

LICENSE

MIT License

Copyright (c) 2017 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonreference

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/swag

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/validator

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Dean Karn

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/golang/protobuf

LICENSE

Copyright 2010 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright

notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/text

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/asticode/go-astisub

LICENSE

MIT License

Copyright (c) 2016 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/cespare/xxhash/v2

LICENSE

Copyright (c) 2016 Caleb Spare

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/zencoder/go-dash/v3

LICENSE

Copyright Brightcove, Inc.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

golang.org/x/tools

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/aws/aws-sdk-go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.

github.com/coreos/go-systemd/v22/journal

LICENSE

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  1. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  1. Grant of Patent License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  1. Redistribution.

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  1. Submission of Contributions.

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  1. Trademarks.

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  1. Disclaimer of Warranty.

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  1. Limitation of Liability.

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  1. Accepting Warranty or Additional Liability.

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

CoreOS Project Copyright 2018 CoreOS, Inc

This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).

github.com/mailru/easyjson

LICENSE

Copyright (c) 2016 Mail.Ru Group

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/rs/zerolog

LICENSE

MIT License

Copyright (c) 2017 Olivier Poitrey

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

google.golang.org/protobuf

LICENSE

Copyright (c) 2018 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/sys

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/PuerkitoBio/purell

LICENSE

Copyright (c) 2012, Martin Angers All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/edgeware/mp4ff/bits

LICENSE

Copyright

Copyright (c) 2019-2020 Edgeware AB.

Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits Copyright (c) 2017 Taichi Nakashima.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/universal-translator

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/leodido/go-urn

LICENSE

MIT License

Copyright (c) 2018 Leonardo Di Donato

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/client_golang/prometheus

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

The following components are included in this product:

perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.

Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.

Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0

github.com/swaggo/files

LICENSE

MIT License

Copyright (c) 2019 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/aws/aws-sdk-go/internal/sync/singleflight

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/edgeware/mp4ff

LICENSE

MIT License

Copyright (c) 2019-2020 Edgeware

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonpointer

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/jmespath/go-jmespath

LICENSE

Copyright 2015 James Saryerwinnie

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/swaggo/http-swagger

LICENSE

MIT License

Copyright (c) 2018 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/edgeware/mp4ff/mp4

LICENSE

Copyright

Most code is Copyright (c) 2019-2020 Edgeware AB.

Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has Copyright (c) 2015 Jean-François Bustarret.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/spec

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/locales

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg

README

PACKAGE

package goautoneg import “bitbucket.org/ww/goautoneg”

HTTP Content-Type Autonegotiation.

The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FUNCTIONS

func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.

func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses

TYPES

type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header

SUBDIRECTORIES

.hg

golang.org/x/net

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2.5.6 - Releases

ESB3023 - ew-hlsingest releases

2.5.6.1 - Release 0.6.0

First release of ew-hlsingest

Early release for ingesting HLS v3 streams.

Release information

  • Date: 2022-12-31
  • Type: Beta for testing

2.6 - VoD to JIT (ew-vodjit)

Make external VoD assets available for streaming on the fly

2.6.1 - Introduction

Introduction to ESB3022 - the ew-vodjit service

Managed Content

The Repackager (ESB3002) and the VoD-to-Linear (ESB3019) require VoD assets to be available in ESF format. Assets are normally ingested into ESF with ew-vodingest (ESB3021) or ew-recorder(ESB3005). The ESF format is an internal format for efficient streaming. Such ingested assets will be referred to as managed content.

However, in some cases, for example having a big catalogue of rarely watched content, it may be unsuitable to ingest and convert all content to ESF format, and it may be preferred to keep the content as “external content”.

ew-vodjit provides a solution by being able to read such “external content”, and convert it to ESF format on-the-fly. The ESF format is then not stored on disk, but only available via HTTP. For the repackager, the asset looks like a normal (managed) ESF asset, except that some operations like getting the first metadata may take longer time.

Supported Codecs

  • video: AVC/H.264, HEVC/H.265
  • audio: AAC-LC, HE-AACv1, HE-AACv2, AC-3, EC-3
  • subtitles: WebVTT, TTML, SRT, STL

Input Locations

Assets must be directly mounted on server’s file-system. Remote storage, such as S3, is not supported.

2.6.2 - Configuration and Command Line Options

Configuring and running the server.

The ew-vodjit configuration parameters can be specified in the following ways:

  1. On the command-line
  2. In the configuration file (when specified by the command-line)
  3. Default values

They take precedence in the above order, i.e. a command-line value will override other values.

Command Line Options

The -h option will give you all available command-line options.

$ ./ew-vodjit -h
Basic usage of ew-vodjit:
ew-vodjit -cfg <config file> -port <port>

Translates assets into ESF format on-the-fly and provides
the asset via an HTTP interface with byte ranges.
Command line options will override configuration file values.

Run ew-vodjit with options:

-basepath string
        Base path to content
-cfg string
        Full path to configuration file (default "/etc/edgeware/ew-vodjit/config.json")
-help
        Print help
-licensefile string
        License file path (default "/etc/edgeware/ew-vodjit/license.json")
-logformat string
        Format and type of log: [consolejson consolepretty journald discard] (default "consolejson")
-loglevel string
        Initial logging level: debug, info, warn, error, fatal, panic
-port int
        Server TCP port (default 8092)
-version
        Get version, date, and possible expiration date

Configuration File

Most of the above parameters can be specified in the configuration file:

{
    "basePath": "/media",
    "logFormat": "consolepretty",
    "logLevel": "info"
}

Note: the server port and license file cannot be specified in this file

Downstream URLs and Configuration

Repackager Configuration

In the Repackager the ew-vodjit service needs to be configured as an HTTP server. Please refer to the section “HTTP server content locations” in the esb3002 User Guide.

Note: Request URLs to ew-vodjit for assets must be prepended with jit/.

To request an asset at <basepath>/archive1/movie1 The request URL for the above asset should be something like: http://<repackager>/__cl/s:jit/__c/jit/archive1/movie1/__op/default/__f/index.m3u8

To avoid the jit/ in the URL, an additional location can be configured in the Repackager’s ew-repackager-server.conf.

VoD to Linear [ew-vod2cbm] Configuration

In the ew-vod2cbm service, each asset must be added using the rest API /assetpaths. Where the "path" field is the full HTTP URL to the asset in the ew-vodjit service.

An entry for the above asset should be be:

    "id": "...",
    "path": "jit/archive1/movie1"

Assets can also be added in the startup configuration file. This is of course less flexible but can be suitable for testing.

2.6.3 - Credits

Third party libraries used in ew-vodjit and their licenses

License List

The table below lists the third party libraries used by this software and their respective license types.

LibraryLicenseChecked At
github.com/asticode/go-astikitMIT2023-11-22
github.com/asticode/go-astisubMIT2023-11-22
github.com/asticode/go-astitsMIT2023-11-22
github.com/aws/aws-sdk-go/internal/sync/singleflightBSD-3-Clause2023-11-22
github.com/aws/aws-sdk-goApache-2.02023-11-22
github.com/barkimedes/go-deepcopyMIT2023-11-22
github.com/beorn7/perks/quantileMIT2023-11-22
github.com/cespare/xxhash/v2MIT2023-11-22
github.com/Comcast/gotsMIT2023-11-22
github.com/coreos/go-systemd/v22/journalApache-2.02023-11-22
github.com/Eyevinn/dash-mpd/mpdMIT2023-11-22
github.com/Eyevinn/dash-mpd/xmlBSD-3-Clause2023-11-22
github.com/Eyevinn/mp4ff/bitsMIT2023-11-22
github.com/Eyevinn/mp4ff/mp4MIT2023-11-22
github.com/Eyevinn/mp4ffMIT2023-11-22
github.com/go-chi/chi/v5MIT2023-11-22
github.com/go-chi/docgenMIT2023-11-22
github.com/go-openapi/jsonpointerApache-2.02023-11-22
github.com/go-openapi/jsonreferenceApache-2.02023-11-22
github.com/go-openapi/specApache-2.02023-11-22
github.com/go-openapi/swagApache-2.02023-11-22
github.com/go-playground/localesMIT2023-11-22
github.com/go-playground/universal-translatorMIT2023-11-22
github.com/go-playground/validatorMIT2023-11-22
github.com/golang/protobuf/protoBSD-3-Clause2023-11-22
github.com/google/go-cmp/cmpBSD-3-Clause2023-11-22
github.com/hashicorp/errwrapMPL-2.02023-11-22
github.com/hashicorp/go-multierrorMPL-2.02023-11-22
github.com/jlaffaye/ftpISC2023-11-22
github.com/jmespath/go-jmespathApache-2.02023-11-22
github.com/josharian/internMIT2023-11-22
github.com/KyleBanks/depthMIT2023-11-22
github.com/leodido/go-urnMIT2023-11-22
github.com/mailru/easyjsonMIT2023-11-22
github.com/mattn/go-colorableMIT2023-11-22
github.com/mattn/go-isattyMIT2023-11-22
github.com/matttproud/golang_protobuf_extensions/pbutilApache-2.02023-11-22
github.com/prometheus/client_golang/prometheusApache-2.02023-11-22
github.com/prometheus/client_model/goApache-2.02023-11-22
github.com/prometheus/common/internal/bitbucket.org/ww/goautonegBSD-3-Clause2023-11-22
github.com/prometheus/commonApache-2.02023-11-22
github.com/prometheus/procfsApache-2.02023-11-22
github.com/rs/zerologMIT2023-11-22
github.com/swaggo/files/v2MIT2023-11-22
github.com/swaggo/http-swagger/v2MIT2023-11-22
github.com/swaggo/swagMIT2023-11-22
golang.org/x/expBSD-3-Clause2023-11-22
golang.org/x/net/htmlBSD-3-Clause2023-11-22
golang.org/x/sysBSD-3-Clause2023-11-22
golang.org/x/textBSD-3-Clause2023-11-22
golang.org/x/toolsBSD-3-Clause2023-11-22
google.golang.org/protobufBSD-3-Clause2023-11-22
gopkg.in/yaml.v3MIT2023-11-22

License Details

This section includes all the licenses/notices for each dependency verbatim

github.com/asticode/go-astikit

LICENSE

MIT License

Copyright (c) 2020 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/asticode/go-astisub

LICENSE

MIT License

Copyright (c) 2016 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/asticode/go-astits

LICENSE

MIT License

Copyright (c) 2017 Quentin Renard

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/aws/aws-sdk-go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.

github.com/aws/aws-sdk-go/internal/sync/singleflight

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/barkimedes/go-deepcopy

LICENSE

MIT License

Copyright (c) 2020 Sabrina Williams

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/beorn7/perks/quantile

LICENSE

Copyright (C) 2013 Blake Mizerany

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/cespare/xxhash/v2

LICENSE

Copyright (c) 2016 Caleb Spare

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Comcast/gots

LICENSE

/* MIT License

Copyright 2016 Comcast Cable Communications Management, LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

NOTICE

Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).

github.com/coreos/go-systemd/v22/journal

LICENSE

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  1. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  1. Grant of Patent License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  1. Redistribution.

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  1. Submission of Contributions.

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  1. Trademarks.

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  1. Disclaimer of Warranty.

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  1. Limitation of Liability.

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  1. Accepting Warranty or Additional Liability.

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

CoreOS Project Copyright 2018 CoreOS, Inc

This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).

github.com/Eyevinn/dash-mpd/mpd

LICENSE

MIT License

Copyright (c) 2023 Eyevinn Technology AB.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Eyevinn/dash-mpd/xml

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/Eyevinn/mp4ff

LICENSE

MIT License

Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Eyevinn/mp4ff/bits

LICENSE

Copyright

Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB.

Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits Copyright (c) 2017 Taichi Nakashima.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/Eyevinn/mp4ff/mp4

LICENSE

Copyright

Most code is Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB.

Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has Copyright (c) 2015 Jean-François Bustarret.

All code has the same MIT License.

License

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/chi/v5

LICENSE

Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-chi/docgen

LICENSE

Copyright (c) 2016-Present https://github.com/go-chi authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-openapi/jsonpointer

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/jsonreference

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/spec

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-openapi/swag

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/go-playground/locales

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/universal-translator

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Go Playground

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/go-playground/validator

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Dean Karn

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/golang/protobuf/proto

LICENSE

Copyright 2010 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright

notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/google/go-cmp/cmp

LICENSE

Copyright (c) 2017 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

github.com/hashicorp/errwrap

LICENSE

Mozilla Public License, version 2.0

  1. Definitions

1.1. “Contributor”

 means each individual or legal entity that creates, contributes to the
 creation of, or owns Covered Software.

1.2. “Contributor Version”

 means the combination of the Contributions of others (if any) used by a
 Contributor and that particular Contributor’s Contribution.

1.3. “Contribution”

 means Covered Software of a particular Contributor.

1.4. “Covered Software”

 means Source Code Form to which the initial Contributor has attached the
 notice in Exhibit A, the Executable Form of such Source Code Form, and
 Modifications of such Source Code Form, in each case including portions
 thereof.

1.5. “Incompatible With Secondary Licenses” means

 a. that the initial Contributor has attached the notice described in
    Exhibit B to the Covered Software; or

 b. that the Covered Software was made available under the terms of version
    1.1 or earlier of the License, but not also under the terms of a
    Secondary License.

1.6. “Executable Form”

 means any form of the work other than Source Code Form.

1.7. “Larger Work”

 means a work that combines Covered Software with other material, in a separate
 file or files, that is not Covered Software.

1.8. “License”

 means this document.

1.9. “Licensable”

 means having the right to grant, to the maximum extent possible, whether at the
 time of the initial grant or subsequently, any and all of the rights conveyed by
 this License.

1.10. “Modifications”

 means any of the following:

 a. any file in Source Code Form that results from an addition to, deletion
    from, or modification of the contents of Covered Software; or

 b. any new file in Source Code Form that contains any Covered Software.

1.11. “Patent Claims” of a Contributor

  means any patent claim(s), including without limitation, method, process,
  and apparatus claims, in any patent Licensable by such Contributor that
  would be infringed, but for the grant of the License, by the making,
  using, selling, offering for sale, having made, import, or transfer of
  either its Contributions or its Contributor Version.

1.12. “Secondary License”

  means either the GNU General Public License, Version 2.0, the GNU Lesser
  General Public License, Version 2.1, the GNU Affero General Public
  License, Version 3.0, or any later versions of those licenses.

1.13. “Source Code Form”

  means the form of the work preferred for making modifications.

1.14. “You” (or “Your”)

  means an individual or a legal entity exercising rights under this
  License. For legal entities, “You” includes any entity that controls, is
  controlled by, or is under common control with You. For purposes of this
  definition, “control” means (a) the power, direct or indirect, to cause
  the direction or management of such entity, whether by contract or
  otherwise, or (b) ownership of more than fifty percent (50%) of the
  outstanding shares or beneficial ownership of such entity.
  1. License Grants and Conditions

2.1. Grants

 Each Contributor hereby grants You a world-wide, royalty-free,
 non-exclusive license:

 a. under intellectual property rights (other than patent or trademark)
    Licensable by such Contributor to use, reproduce, make available,
    modify, display, perform, distribute, and otherwise exploit its
    Contributions, either on an unmodified basis, with Modifications, or as
    part of a Larger Work; and

 b. under Patent Claims of such Contributor to make, use, sell, offer for
    sale, have made, import, and otherwise transfer either its Contributions
    or its Contributor Version.

2.2. Effective Date

 The licenses granted in Section 2.1 with respect to any Contribution become
 effective for each Contribution on the date the Contributor first distributes
 such Contribution.

2.3. Limitations on Grant Scope

 The licenses granted in this Section 2 are the only rights granted under this
 License. No additional rights or licenses will be implied from the distribution
 or licensing of Covered Software under this License. Notwithstanding Section
 2.1(b) above, no patent license is granted by a Contributor:

 a. for any code that a Contributor has removed from Covered Software; or

 b. for infringements caused by: (i) Your and any other third party’s
    modifications of Covered Software, or (ii) the combination of its
    Contributions with other software (except as part of its Contributor
    Version); or

 c. under Patent Claims infringed by Covered Software in the absence of its
    Contributions.

 This License does not grant any rights in the trademarks, service marks, or
 logos of any Contributor (except as may be necessary to comply with the
 notice requirements in Section 3.4).

2.4. Subsequent Licenses

 No Contributor makes additional grants as a result of Your choice to
 distribute the Covered Software under a subsequent version of this License
 (see Section 10.2) or under the terms of a Secondary License (if permitted
 under the terms of Section 3.3).

2.5. Representation

 Each Contributor represents that the Contributor believes its Contributions
 are its original creation(s) or it has sufficient rights to grant the
 rights to its Contributions conveyed by this License.

2.6. Fair Use

 This License is not intended to limit any rights You have under applicable
 copyright doctrines of fair use, fair dealing, or other equivalents.

2.7. Conditions

 Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
 Section 2.1.
  1. Responsibilities

3.1. Distribution of Source Form

 All distribution of Covered Software in Source Code Form, including any
 Modifications that You create or to which You contribute, must be under the
 terms of this License. You must inform recipients that the Source Code Form
 of the Covered Software is governed by the terms of this License, and how
 they can obtain a copy of this License. You may not attempt to alter or
 restrict the recipients’ rights in the Source Code Form.

3.2. Distribution of Executable Form

 If You distribute Covered Software in Executable Form then:

 a. such Covered Software must also be made available in Source Code Form,
    as described in Section 3.1, and You must inform recipients of the
    Executable Form how they can obtain a copy of such Source Code Form by
    reasonable means in a timely manner, at a charge no more than the cost
    of distribution to the recipient; and

 b. You may distribute such Executable Form under the terms of this License,
    or sublicense it under different terms, provided that the license for
    the Executable Form does not attempt to limit or alter the recipients’
    rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

 You may create and distribute a Larger Work under terms of Your choice,
 provided that You also comply with the requirements of this License for the
 Covered Software. If the Larger Work is a combination of Covered Software
 with a work governed by one or more Secondary Licenses, and the Covered
 Software is not Incompatible With Secondary Licenses, this License permits
 You to additionally distribute such Covered Software under the terms of
 such Secondary License(s), so that the recipient of the Larger Work may, at
 their option, further distribute the Covered Software under the terms of
 either this License or such Secondary License(s).

3.4. Notices

 You may not remove or alter the substance of any license notices (including
 copyright notices, patent notices, disclaimers of warranty, or limitations
 of liability) contained within the Source Code Form of the Covered
 Software, except that You may alter any license notices to the extent
 required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

 You may choose to offer, and to charge a fee for, warranty, support,
 indemnity or liability obligations to one or more recipients of Covered
 Software. However, You may do so only on Your own behalf, and not on behalf
 of any Contributor. You must make it absolutely clear that any such
 warranty, support, indemnity, or liability obligation is offered by You
 alone, and You hereby agree to indemnify every Contributor for any
 liability incurred by such Contributor as a result of warranty, support,
 indemnity or liability terms You offer. You may include additional
 disclaimers of warranty and limitations of liability specific to any
 jurisdiction.
  1. Inability to Comply Due to Statute or Regulation

    If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.

  2. Termination

5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.

  1. Disclaimer of Warranty

    Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.

  2. Limitation of Liability

    Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.

  3. Litigation

    Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims.

  4. Miscellaneous

    This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.

  5. Versions of the License

10.1. New Versions

  Mozilla Foundation is the license steward. Except as provided in Section
  10.3, no one other than the license steward has the right to modify or
  publish new versions of this License. Each version will be given a
  distinguishing version number.

10.2. Effect of New Versions

  You may distribute the Covered Software under the terms of the version of
  the License under which You originally received the Covered Software, or
  under the terms of any subsequent version published by the license
  steward.

10.3. Modified Versions

  If you create software not governed by this License, and you want to
  create a new license for such software, you may create and use a modified
  version of this License if you rename the license and remove any
  references to the name of the license steward (except to note that such
  modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice

  This Source Code Form is subject to the
  terms of the Mozilla Public License, v.
  2.0. If a copy of the MPL was not
  distributed with this file, You can
  obtain one at
  http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - “Incompatible With Secondary Licenses” Notice

  This Source Code Form is “Incompatible
  With Secondary Licenses”, as defined by
  the Mozilla Public License, v. 2.0.

README

errwrap

errwrap is a package for Go that formalizes the pattern of wrapping errors and checking if an error contains another error.

There is a common pattern in Go of taking a returned error value and then wrapping it (such as with fmt.Errorf) before returning it. The problem with this pattern is that you completely lose the original error structure.

Arguably the correct approach is that you should make a custom structure implementing the error interface, and have the original error as a field on that structure, such as this example. This is a good approach, but you have to know the entire chain of possible rewrapping that happens, when you might just care about one.

errwrap formalizes this pattern (it doesn’t matter what approach you use above) by giving a single interface for wrapping errors, checking if a specific error is wrapped, and extracting that error.

Installation and Docs

Install using go get github.com/hashicorp/errwrap.

Full documentation is available at http://godoc.org/github.com/hashicorp/errwrap

Usage

Basic Usage

Below is a very basic example of its usage:

// A function that always returns an error, but wraps it, like a real
// function might.
func tryOpen() error {
	_, err := os.Open("/i/dont/exist")
	if err != nil {
		return errwrap.Wrapf("Doesn't exist: {{err}}", err)
	}

	return nil
}

func main() {
	err := tryOpen()

	// We can use the Contains helpers to check if an error contains
	// another error. It is safe to do this with a nil error, or with
	// an error that doesn't even use the errwrap package.
	if errwrap.Contains(err, "does not exist") {
		// Do something
	}
	if errwrap.ContainsType(err, new(os.PathError)) {
		// Do something
	}

	// Or we can use the associated `Get` functions to just extract
	// a specific error. This would return nil if that specific error doesn't
	// exist.
	perr := errwrap.GetType(err, new(os.PathError))
}

Custom Types

If you’re already making custom types that properly wrap errors, then you can get all the functionality of errwraps.Contains and such by implementing the Wrapper interface with just one function. Example:

type AppError {
  Code ErrorCode
  Err  error
}

func (e *AppError) WrappedErrors() []error {
  return []error{e.Err}
}

Now this works:

err := &AppError{Err: fmt.Errorf("an error")}
if errwrap.ContainsType(err, fmt.Errorf("")) {
	// This will work!
}

errwrap

// Package errwrap implements methods to formalize error wrapping in Go. // // All of the top-level functions that take an error are built to be able // to take any error, not just wrapped errors. This allows you to use errwrap // without having to type-check and type-cast everywhere. package errwrap

import ( “errors” “reflect” “strings” )

// WalkFunc is the callback called for Walk. type WalkFunc func(error)

// Wrapper is an interface that can be implemented by custom types to // have all the Contains, Get, etc. functions in errwrap work. // // When Walk reaches a Wrapper, it will call the callback for every // wrapped error in addition to the wrapper itself. Since all the top-level // functions in errwrap use Walk, this means that all those functions work // with your custom type. type Wrapper interface { WrappedErrors() []error }

// Wrap defines that outer wraps inner, returning an error type that // can be cleanly used with the other methods in this package, such as // Contains, GetAll, etc. // // This function won’t modify the error message at all (the outer message // will be used). func Wrap(outer, inner error) error { return &wrappedError{ Outer: outer, Inner: inner, } }

// Wrapf wraps an error with a formatting message. This is similar to using // fmt.Errorf to wrap an error. If you’re using fmt.Errorf to wrap // errors, you should replace it with this. // // format is the format of the error message. The string ‘{{err}}’ will // be replaced with the original error message. // // Deprecated: Use fmt.Errorf() func Wrapf(format string, err error) error { outerMsg := “” if err != nil { outerMsg = err.Error() }

outer := errors.New(strings.Replace(
	format, "{{err}}", outerMsg, -1))

return Wrap(outer, err)

}

// Contains checks if the given error contains an error with the // message msg. If err is not a wrapped error, this will always return // false unless the error itself happens to match this msg. func Contains(err error, msg string) bool { return len(GetAll(err, msg)) > 0 }

// ContainsType checks if the given error contains an error with // the same concrete type as v. If err is not a wrapped error, this will // check the err itself. func ContainsType(err error, v interface{}) bool { return len(GetAllType(err, v)) > 0 }

// Get is the same as GetAll but returns the deepest matching error. func Get(err error, msg string) error { es := GetAll(err, msg) if len(es) > 0 { return es[len(es)-1] }

return nil

}

// GetType is the same as GetAllType but returns the deepest matching error. func GetType(err error, v interface{}) error { es := GetAllType(err, v) if len(es) > 0 { return es[len(es)-1] }

return nil

}

// GetAll gets all the errors that might be wrapped in err with the // given message. The order of the errors is such that the outermost // matching error (the most recent wrap) is index zero, and so on. func GetAll(err error, msg string) []error { var result []error

Walk(err, func(err error) {
	if err.Error() == msg {
		result = append(result, err)
	}
})

return result

}

// GetAllType gets all the errors that are the same type as v. // // The order of the return value is the same as described in GetAll. func GetAllType(err error, v interface{}) []error { var result []error

var search string
if v != nil {
	search = reflect.TypeOf(v).String()
}
Walk(err, func(err error) {
	var needle string
	if err != nil {
		needle = reflect.TypeOf(err).String()
	}

	if needle == search {
		result = append(result, err)
	}
})

return result

}

// Walk walks all the wrapped errors in err and calls the callback. If // err isn’t a wrapped error, this will be called once for err. If err // is a wrapped error, the callback will be called for both the wrapper // that implements error as well as the wrapped error itself. func Walk(err error, cb WalkFunc) { if err == nil { return }

switch e := err.(type) {
case *wrappedError:
	cb(e.Outer)
	Walk(e.Inner, cb)
case Wrapper:
	cb(err)

	for _, err := range e.WrappedErrors() {
		Walk(err, cb)
	}
case interface{ Unwrap() error }:
	cb(err)
	Walk(e.Unwrap(), cb)
default:
	cb(err)
}

}

// wrappedError is an implementation of error that has both the // outer and inner errors. type wrappedError struct { Outer error Inner error }

func (w *wrappedError) Error() string { return w.Outer.Error() }

func (w *wrappedError) WrappedErrors() []error { return []error{w.Outer, w.Inner} }

func (w *wrappedError) Unwrap() error { return w.Inner }

github.com/hashicorp/go-multierror

LICENSE

Mozilla Public License, version 2.0

  1. Definitions

1.1. “Contributor”

 means each individual or legal entity that creates, contributes to the
 creation of, or owns Covered Software.

1.2. “Contributor Version”

 means the combination of the Contributions of others (if any) used by a
 Contributor and that particular Contributor’s Contribution.

1.3. “Contribution”

 means Covered Software of a particular Contributor.

1.4. “Covered Software”

 means Source Code Form to which the initial Contributor has attached the
 notice in Exhibit A, the Executable Form of such Source Code Form, and
 Modifications of such Source Code Form, in each case including portions
 thereof.

1.5. “Incompatible With Secondary Licenses” means

 a. that the initial Contributor has attached the notice described in
    Exhibit B to the Covered Software; or

 b. that the Covered Software was made available under the terms of version
    1.1 or earlier of the License, but not also under the terms of a
    Secondary License.

1.6. “Executable Form”

 means any form of the work other than Source Code Form.

1.7. “Larger Work”

 means a work that combines Covered Software with other material, in a separate
 file or files, that is not Covered Software.

1.8. “License”

 means this document.

1.9. “Licensable”

 means having the right to grant, to the maximum extent possible, whether at the
 time of the initial grant or subsequently, any and all of the rights conveyed by
 this License.

1.10. “Modifications”

 means any of the following:

 a. any file in Source Code Form that results from an addition to, deletion
    from, or modification of the contents of Covered Software; or

 b. any new file in Source Code Form that contains any Covered Software.

1.11. “Patent Claims” of a Contributor

  means any patent claim(s), including without limitation, method, process,
  and apparatus claims, in any patent Licensable by such Contributor that
  would be infringed, but for the grant of the License, by the making,
  using, selling, offering for sale, having made, import, or transfer of
  either its Contributions or its Contributor Version.

1.12. “Secondary License”

  means either the GNU General Public License, Version 2.0, the GNU Lesser
  General Public License, Version 2.1, the GNU Affero General Public
  License, Version 3.0, or any later versions of those licenses.

1.13. “Source Code Form”

  means the form of the work preferred for making modifications.

1.14. “You” (or “Your”)

  means an individual or a legal entity exercising rights under this
  License. For legal entities, “You” includes any entity that controls, is
  controlled by, or is under common control with You. For purposes of this
  definition, “control” means (a) the power, direct or indirect, to cause
  the direction or management of such entity, whether by contract or
  otherwise, or (b) ownership of more than fifty percent (50%) of the
  outstanding shares or beneficial ownership of such entity.
  1. License Grants and Conditions

2.1. Grants

 Each Contributor hereby grants You a world-wide, royalty-free,
 non-exclusive license:

 a. under intellectual property rights (other than patent or trademark)
    Licensable by such Contributor to use, reproduce, make available,
    modify, display, perform, distribute, and otherwise exploit its
    Contributions, either on an unmodified basis, with Modifications, or as
    part of a Larger Work; and

 b. under Patent Claims of such Contributor to make, use, sell, offer for
    sale, have made, import, and otherwise transfer either its Contributions
    or its Contributor Version.

2.2. Effective Date

 The licenses granted in Section 2.1 with respect to any Contribution become
 effective for each Contribution on the date the Contributor first distributes
 such Contribution.

2.3. Limitations on Grant Scope

 The licenses granted in this Section 2 are the only rights granted under this
 License. No additional rights or licenses will be implied from the distribution
 or licensing of Covered Software under this License. Notwithstanding Section
 2.1(b) above, no patent license is granted by a Contributor:

 a. for any code that a Contributor has removed from Covered Software; or

 b. for infringements caused by: (i) Your and any other third party’s
    modifications of Covered Software, or (ii) the combination of its
    Contributions with other software (except as part of its Contributor
    Version); or

 c. under Patent Claims infringed by Covered Software in the absence of its
    Contributions.

 This License does not grant any rights in the trademarks, service marks, or
 logos of any Contributor (except as may be necessary to comply with the
 notice requirements in Section 3.4).

2.4. Subsequent Licenses

 No Contributor makes additional grants as a result of Your choice to
 distribute the Covered Software under a subsequent version of this License
 (see Section 10.2) or under the terms of a Secondary License (if permitted
 under the terms of Section 3.3).

2.5. Representation

 Each Contributor represents that the Contributor believes its Contributions
 are its original creation(s) or it has sufficient rights to grant the
 rights to its Contributions conveyed by this License.

2.6. Fair Use

 This License is not intended to limit any rights You have under applicable
 copyright doctrines of fair use, fair dealing, or other equivalents.

2.7. Conditions

 Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
 Section 2.1.
  1. Responsibilities

3.1. Distribution of Source Form

 All distribution of Covered Software in Source Code Form, including any
 Modifications that You create or to which You contribute, must be under the
 terms of this License. You must inform recipients that the Source Code Form
 of the Covered Software is governed by the terms of this License, and how
 they can obtain a copy of this License. You may not attempt to alter or
 restrict the recipients’ rights in the Source Code Form.

3.2. Distribution of Executable Form

 If You distribute Covered Software in Executable Form then:

 a. such Covered Software must also be made available in Source Code Form,
    as described in Section 3.1, and You must inform recipients of the
    Executable Form how they can obtain a copy of such Source Code Form by
    reasonable means in a timely manner, at a charge no more than the cost
    of distribution to the recipient; and

 b. You may distribute such Executable Form under the terms of this License,
    or sublicense it under different terms, provided that the license for
    the Executable Form does not attempt to limit or alter the recipients’
    rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

 You may create and distribute a Larger Work under terms of Your choice,
 provided that You also comply with the requirements of this License for the
 Covered Software. If the Larger Work is a combination of Covered Software
 with a work governed by one or more Secondary Licenses, and the Covered
 Software is not Incompatible With Secondary Licenses, this License permits
 You to additionally distribute such Covered Software under the terms of
 such Secondary License(s), so that the recipient of the Larger Work may, at
 their option, further distribute the Covered Software under the terms of
 either this License or such Secondary License(s).

3.4. Notices

 You may not remove or alter the substance of any license notices (including
 copyright notices, patent notices, disclaimers of warranty, or limitations
 of liability) contained within the Source Code Form of the Covered
 Software, except that You may alter any license notices to the extent
 required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

 You may choose to offer, and to charge a fee for, warranty, support,
 indemnity or liability obligations to one or more recipients of Covered
 Software. However, You may do so only on Your own behalf, and not on behalf
 of any Contributor. You must make it absolutely clear that any such
 warranty, support, indemnity, or liability obligation is offered by You
 alone, and You hereby agree to indemnify every Contributor for any
 liability incurred by such Contributor as a result of warranty, support,
 indemnity or liability terms You offer. You may include additional
 disclaimers of warranty and limitations of liability specific to any
 jurisdiction.
  1. Inability to Comply Due to Statute or Regulation

    If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.

  2. Termination

5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.

  1. Disclaimer of Warranty

    Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.

  2. Limitation of Liability

    Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.

  3. Litigation

    Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims.

  4. Miscellaneous

    This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.

  5. Versions of the License

10.1. New Versions

  Mozilla Foundation is the license steward. Except as provided in Section
  10.3, no one other than the license steward has the right to modify or
  publish new versions of this License. Each version will be given a
  distinguishing version number.

10.2. Effect of New Versions

  You may distribute the Covered Software under the terms of the version of
  the License under which You originally received the Covered Software, or
  under the terms of any subsequent version published by the license
  steward.

10.3. Modified Versions

  If you create software not governed by this License, and you want to
  create a new license for such software, you may create and use a modified
  version of this License if you rename the license and remove any
  references to the name of the license steward (except to note that such
  modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice

  This Source Code Form is subject to the
  terms of the Mozilla Public License, v.
  2.0. If a copy of the MPL was not
  distributed with this file, You can
  obtain one at
  http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - “Incompatible With Secondary Licenses” Notice

  This Source Code Form is “Incompatible
  With Secondary Licenses”, as defined by
  the Mozilla Public License, v. 2.0.

Makefile

TEST?=./…

default: test

test runs the test suite and vets the code.

test: generate @echo “==> Running tests…” @go list $(TEST)
| grep -v “/vendor/”
| xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS}

testrace runs the race checker

testrace: generate @echo “==> Running tests (race)…” @go list $(TEST)
| grep -v “/vendor/”
| xargs -n1 go test -timeout=60s -race ${TESTARGS}

updatedeps installs all the dependencies needed to run and build.

updatedeps: @sh -c “’${CURDIR}/scripts/deps.sh’ ‘${NAME}’”

generate runs go generate to build the dynamically generated source files.

generate: @echo “==> Generating…” @find . -type f -name ‘.DS_Store’ -delete @go list ./…
| grep -v “/vendor/”
| xargs -n1 go generate

.PHONY: default test testrace updatedeps generate

README

go-multierror

CircleCI Go Reference GitHub go.mod Go version

go-multierror is a package for Go that provides a mechanism for representing a list of error values as a single error.

This allows a function in Go to return an error that might actually be a list of errors. If the caller knows this, they can unwrap the list and access the errors. If the caller doesn’t know, the error formats to a nice human-readable format.

go-multierror is fully compatible with the Go standard library errors package, including the functions As, Is, and Unwrap. This provides a standardized approach for introspecting on error values.

Installation and Docs

Install using go get github.com/hashicorp/go-multierror.

Full documentation is available at https://pkg.go.dev/github.com/hashicorp/go-multierror

Requires go version 1.13 or newer

go-multierror requires go version 1.13 or newer. Go 1.13 introduced error wrapping, which this library takes advantage of.

If you need to use an earlier version of go, you can use the v1.0.0 tag, which doesn’t rely on features in go 1.13.

If you see compile errors that look like the below, it’s likely that you’re on an older version of go:

/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is

Usage

go-multierror is easy to use and purposely built to be unobtrusive in existing Go applications/libraries that may not be aware of it.

Building a list of errors

The Append function is used to create a list of errors. This function behaves a lot like the Go built-in append function: it doesn’t matter if the first argument is nil, a multierror.Error, or any other error, the function behaves as you would expect.

var result error

if err := step1(); err != nil {
	result = multierror.Append(result, err)
}
if err := step2(); err != nil {
	result = multierror.Append(result, err)
}

return result

Customizing the formatting of the errors

By specifying a custom ErrorFormat, you can customize the format of the Error() string function:

var result *multierror.Error

// ... accumulate errors here, maybe using Append

if result != nil {
	result.ErrorFormat = func([]error) string {
		return "errors!"
	}
}

Accessing the list of errors

multierror.Error implements error so if the caller doesn’t know about multierror, it will work just fine. But if you’re aware a multierror might be returned, you can use type switches to access the list of errors:

if err := something(); err != nil {
	if merr, ok := err.(*multierror.Error); ok {
		// Use merr.Errors
	}
}

You can also use the standard errors.Unwrap function. This will continue to unwrap into subsequent errors until none exist.

Extracting an error

The standard library errors.As function can be used directly with a multierror to extract a specific error:

// Assume err is a multierror value
err := somefunc()

// We want to know if "err" has a "RichErrorType" in it and extract it.
var errRich RichErrorType
if errors.As(err, &errRich) {
	// It has it, and now errRich is populated.
}

Checking for an exact error value

Some errors are returned as exact errors such as the ErrNotExist error in the os package. You can check if this error is present by using the standard errors.Is function.

// Assume err is a multierror value
err := somefunc()
if errors.Is(err, os.ErrNotExist) {
	// err contains os.ErrNotExist
}

Returning a multierror only if there are errors

If you build a multierror.Error, you can use the ErrorOrNil function to return an error implementation only if there are errors to return:

var result *multierror.Error

// ... accumulate errors here

// Return the `error` only if errors were added to the multierror, otherwise
// return nil since there are no errors.
return result.ErrorOrNil()

append

package multierror

// Append is a helper function that will append more errors // onto an Error in order to create a larger multi-error. // // If err is not a multierror.Error, then it will be turned into // one. If any of the errs are multierr.Error, they will be flattened // one level into err. // Any nil errors within errs will be ignored. If err is nil, a new // *Error will be returned. func Append(err error, errs …error) *Error { switch err := err.(type) { case *Error: // Typed nils can reach here, so initialize if we are nil if err == nil { err = new(Error) }

	// Go through each error and flatten
	for _, e := range errs {
		switch e := e.(type) {
		case *Error:
			if e != nil {
				err.Errors = append(err.Errors, e.Errors...)
			}
		default:
			if e != nil {
				err.Errors = append(err.Errors, e)
			}
		}
	}

	return err
default:
	newErrs := make([]error, 0, len(errs)+1)
	if err != nil {
		newErrs = append(newErrs, err)
	}
	newErrs = append(newErrs, errs...)

	return Append(&Error{}, newErrs...)
}

}

flatten

package multierror

// Flatten flattens the given error, merging any *Errors together into // a single *Error. func Flatten(err error) error { // If it isn’t an *Error, just return the error as-is if _, ok := err.(*Error); !ok { return err }

// Otherwise, make the result and flatten away!
flatErr := new(Error)
flatten(err, flatErr)
return flatErr

}

func flatten(err error, flatErr *Error) { switch err := err.(type) { case *Error: for _, e := range err.Errors { flatten(e, flatErr) } default: flatErr.Errors = append(flatErr.Errors, err) } }

format

package multierror

import ( “fmt” “strings” )

// ErrorFormatFunc is a function callback that is called by Error to // turn the list of errors into a string. type ErrorFormatFunc func([]error) string

// ListFormatFunc is a basic formatter that outputs the number of errors // that occurred along with a bullet point list of the errors. func ListFormatFunc(es []error) string { if len(es) == 1 { return fmt.Sprintf(“1 error occurred:\n\t* %s\n\n”, es[0]) }

points := make([]string, len(es))
for i, err := range es {
	points[i] = fmt.Sprintf("* %s", err)
}

return fmt.Sprintf(
	"%d errors occurred:\n\t%s\n\n",
	len(es), strings.Join(points, "\n\t"))

}

group

package multierror

import “sync”

// Group is a collection of goroutines which return errors that need to be // coalesced. type Group struct { mutex sync.Mutex err *Error wg sync.WaitGroup }

// Go calls the given function in a new goroutine. // // If the function returns an error it is added to the group multierror which // is returned by Wait. func (g *Group) Go(f func() error) { g.wg.Add(1)

go func() {
	defer g.wg.Done()

	if err := f(); err != nil {
		g.mutex.Lock()
		g.err = Append(g.err, err)
		g.mutex.Unlock()
	}
}()

}

// Wait blocks until all function calls from the Go method have returned, then // returns the multierror. func (g *Group) Wait() *Error { g.wg.Wait() g.mutex.Lock() defer g.mutex.Unlock() return g.err }

multierror

package multierror

import ( “errors” “fmt” )

// Error is an error type to track multiple errors. This is used to // accumulate errors in cases and return them as a single “error”. type Error struct { Errors []error ErrorFormat ErrorFormatFunc }

func (e *Error) Error() string { fn := e.ErrorFormat if fn == nil { fn = ListFormatFunc }

return fn(e.Errors)

}

// ErrorOrNil returns an error interface if this Error represents // a list of errors, or returns nil if the list of errors is empty. This // function is useful at the end of accumulation to make sure that the value // returned represents the existence of errors. func (e *Error) ErrorOrNil() error { if e == nil { return nil } if len(e.Errors) == 0 { return nil }

return e

}

func (e Error) GoString() string { return fmt.Sprintf("%#v", *e) }

// WrappedErrors returns the list of errors that this Error is wrapping. It is // an implementation of the errwrap.Wrapper interface so that multierror.Error // can be used with that library. // // This method is not safe to be called concurrently. Unlike accessing the // Errors field directly, this function also checks if the multierror is nil to // prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface. func (e *Error) WrappedErrors() []error { if e == nil { return nil } return e.Errors }

// Unwrap returns an error from Error (or nil if there are no errors). // This error returned will further support Unwrap to get the next error, // etc. The order will match the order of Errors in the multierror.Error // at the time of calling. // // The resulting error supports errors.As/Is/Unwrap so you can continue // to use the stdlib errors package to introspect further. // // This will perform a shallow copy of the errors slice. Any errors appended // to this error after calling Unwrap will not be available until a new // Unwrap is called on the multierror.Error. func (e *Error) Unwrap() error { // If we have no errors then we do nothing if e == nil || len(e.Errors) == 0 { return nil }

// If we have exactly one error, we can just return that directly.
if len(e.Errors) == 1 {
	return e.Errors[0]
}

// Shallow copy the slice
errs := make([]error, len(e.Errors))
copy(errs, e.Errors)
return chain(errs)

}

// chain implements the interfaces necessary for errors.Is/As/Unwrap to // work in a deterministic way with multierror. A chain tracks a list of // errors while accounting for the current represented error. This lets // Is/As be meaningful. // // Unwrap returns the next error. In the cleanest form, Unwrap would return // the wrapped error here but we can’t do that if we want to properly // get access to all the errors. Instead, users are recommended to use // Is/As to get the correct error type out. // // Precondition: []error is non-empty (len > 0) type chain []error

// Error implements the error interface func (e chain) Error() string { return e[0].Error() }

// Unwrap implements errors.Unwrap by returning the next error in the // chain or nil if there are no more errors. func (e chain) Unwrap() error { if len(e) == 1 { return nil }

return e[1:]

}

// As implements errors.As by attempting to map to the current value. func (e chain) As(target interface{}) bool { return errors.As(e[0], target) }

// Is implements errors.Is by comparing the current value directly. func (e chain) Is(target error) bool { return errors.Is(e[0], target) }

prefix

package multierror

import ( “fmt”

"github.com/hashicorp/errwrap"

)

// Prefix is a helper function that will prefix some text // to the given error. If the error is a multierror.Error, then // it will be prefixed to each wrapped error. // // This is useful to use when appending multiple multierrors // together in order to give better scoping. func Prefix(err error, prefix string) error { if err == nil { return nil }

format := fmt.Sprintf("%s {{err}}", prefix)
switch err := err.(type) {
case *Error:
	// Typed nils can reach here, so initialize if we are nil
	if err == nil {
		err = new(Error)
	}

	// Wrap each of the errors
	for i, e := range err.Errors {
		err.Errors[i] = errwrap.Wrapf(format, e)
	}

	return err
default:
	return errwrap.Wrapf(format, err)
}

}

sort

package multierror

// Len implements sort.Interface function for length func (err Error) Len() int { return len(err.Errors) }

// Swap implements sort.Interface function for swapping elements func (err Error) Swap(i, j int) { err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i] }

// Less implements sort.Interface function for determining order func (err Error) Less(i, j int) bool { return err.Errors[i].Error() < err.Errors[j].Error() }

github.com/jlaffaye/ftp

LICENSE

Copyright (c) 2011-2013, Julien Laffaye jlaffaye@FreeBSD.org

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

github.com/jmespath/go-jmespath

LICENSE

Copyright 2015 James Saryerwinnie

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

github.com/josharian/intern

license

MIT License

Copyright (c) 2019 Josh Bleecher Snyder

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/KyleBanks/depth

LICENSE

MIT License

Copyright (c) 2017 Kyle Banks

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/leodido/go-urn

LICENSE

MIT License

Copyright (c) 2018 Leonardo Di Donato

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mailru/easyjson

LICENSE

Copyright (c) 2016 Mail.Ru Group

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mattn/go-colorable

LICENSE

The MIT License (MIT)

Copyright (c) 2016 Yasuhiro Matsumoto

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/mattn/go-isatty

LICENSE

Copyright (c) Yasuhiro MATSUMOTO mattn.jp@gmail.com

MIT License (Expat)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/matttproud/golang_protobuf_extensions/pbutil

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "{}"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright {yyyy} {name of copyright owner}

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2012 Matt T. Proud (matt.proud@gmail.com)

github.com/prometheus/client_golang/prometheus

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

The following components are included in this product:

perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.

Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.

Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0

github.com/prometheus/client_model/go

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/common

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg

README

PACKAGE

package goautoneg import “bitbucket.org/ww/goautoneg”

HTTP Content-Type Autonegotiation.

The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FUNCTIONS

func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.

func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses

TYPES

type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header

SUBDIRECTORIES

.hg

github.com/prometheus/procfs

LICENSE

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

    “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

    “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

  To apply the Apache License to your work, attach the following
  boilerplate notice, with the fields enclosed by brackets "[]"
  replaced with your own identifying information. (Don't include
  the brackets!)  The text should be enclosed in the appropriate
  comment syntax for the file format. We also recommend that a
  file or class name and description of purpose be included on the
  same "printed page" as the copyright notice for easier
  identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.

Copyright 2014-2015 The Prometheus Authors

This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).

github.com/rs/zerolog

LICENSE

MIT License

Copyright (c) 2017 Olivier Poitrey

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/files/v2

LICENSE

MIT License

Copyright (c) 2019 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/http-swagger/v2

LICENSE

MIT License

Copyright (c) 2018 Swaggo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

github.com/swaggo/swag

license

MIT License

Copyright (c) 2017 Eason Lin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

golang.org/x/exp

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/net/html

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/sys

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/text

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

golang.org/x/tools

LICENSE

Copyright (c) 2009 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

google.golang.org/protobuf

LICENSE

Copyright (c) 2018 The Go Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

gopkg.in/yaml.v3

LICENSE

This project is covered by two different licenses: MIT and Apache.

MIT License

The following files were ported to Go from C files of libyaml, and thus are still covered by their original MIT license, with the additional copyright staring in 2011 when the project was ported over:

apic.go emitterc.go parserc.go readerc.go scannerc.go
writerc.go yamlh.go yamlprivateh.go

Copyright (c) 2006-2010 Kirill Simonov Copyright (c) 2006-2011 Kirill Simonov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Apache License

All the remaining project files are covered by the Apache license:

Copyright (c) 2011-2019 Canonical Ltd

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE

Copyright 2011-2016 Canonical Ltd.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

2.6.4 - Releases

ESB3022 - ew-vodjit releases

2.6.4.1 - Release 1.0.0

First Product Release

New

  • Fundamental ESF/JITP Support

Fixes

None

Known Limitations

  • Response to first metadata request for large TS input, can be very slow
  • TTML subtitle styling is not supported
  • Input needs to be on local or mounted file system. Remote storage such as HTTP or S3, is not supported

2.6.5 - Licensing

Licensing for ew-vodjit

ew-vodjit requires a valid license file to operate. The license file must be obtained from Agile Content, and copied to /etc/edgeware/ew-vodjit/license.json.

See further details here.

2.6.6 - Logging

Logging for ew-vodjit

Details on logging can be found here.

2.7 - Technical Details

2.7.1 - CCMI URLs

Edgeware’s origin CCMI URLs

Edgeware’s origin URL format is called CCMI URLs and is the format that StreamBuilder understands. A typical URL looks like:

http://<server>/__cl/<cl>/__c/<content>/__op/<op>/__f/<pres><ext>

where the different parts are indicated by prefixes starting with two underscores, and where the file extension <ext> starts with a period if present.

The most important StreamBuilder fields are:

__cl : content location with parts prefix:name
       + cg:<live> stands for channel group <live> and denote a group
         of live channels configured with the name <live>
       + s:<vod> stands for a storage path for vod assets
__c  : the actual content or asset path (can contain slashes)
__op : output profile `<op>`, defining the encryption/DRM system or segment addressing
       Segments with different output profiles are not compatible
__f : the file path but also the way to choose a presentation.
      A presentation is a manifest variation, for example exluding some variants.
      The segments can be the same between presentation.
      The extensions ".m3u8" maps to HLS, ".mpd" maps to DASH and "Manifest" or
      ".ism/Manifest" map to MSS

The <pres> part is matched to a presentation configured in repackager. The <live>, <vod>, <op> are also defined in the repackager configuration.

For segments, the URLs are further enhanced with a config_id (for live/catchup), a variant, and a segment number (for HLS and DASH with $Number$)

__f/<cfg_id>/<variant>/<nr>.cmfv
__f/<cfg_id>/<variant>/<nr>.ts

or with a time (for DASH and MSS)

__f/<cfg_id>/<variant>/D<time>.cmfv
__f/<cfg_id>/QualityLevels({bitrate})/Fragments(video={start time})

In addition, there are other possible parts like

__dci : DRM Content ID - an id used to lookup the key from license server
__account : Account to distinguish different tenants

Finally, there are query parameters for time intervals

?startTime=
?stopTime=

and query parameters for variant flags mask

?p=<variant_flags_mask>

In addition, there may also be a part ?pre=1 that triggers ESB3020 - ew-manip.

2.7.2 - ESF Format

The Edgeware Storage Format (ESF)

2.7.2.1 - Introduction

Introduction to the Edgeware Storage Format (ESF)

ESF is Edgeware’s CMAF-based storage format for both live and VoD content. It saves media data in CMAF tracks, and has additional metadata files. It supports H.264/AVC and HEVC/H.265 video, AAC and AC-3 audio, and wvtt subtitles.

Asset media data

The media data is stored as CMAF tracks in files with extensions “.cmfv”, “.cmfa”, and “.cmft”, for video, audio, and subtitles, respectively. The subtitle format is “wvtt” which is much more storage-efficient than “stpp”.

Asset metadata

The metadata for the assets are stored in two places:

  1. a single content_info.json file describing the tracks
  2. segment info (.dat) files describing the segments, one per track

Content info

Content info is stored in a file named content_info.json inside the asset directory. It is a JSON file containing enough information about the tracks of the assets, to be able to fill in all information about media tracks in HLS, DASH, or MSS manifests. This includes codecs, languages, time scales, bitrates etc. However, it does not contain information about individual segments. Such information is stored in segment info files.

Segment info

Metadata about the segments are stored in segment info files with extension .dat. There is exactly one such file for each media file.

These files describe the data of the individual segments of the CMAF tracks with a 32-byte entry for each segment:

FieldTypeDescription
Nruint32Segment number
Timeuint64Time (normally presentationTime=DecodeTime)
Duruint32Duration of segment in timescale specified in content info
Sizeuint32Size in bytes
Offsetuint64Byte offset inside track file
Restuint32Flags for SCTE-markers and other information

For VoD assets, an init segment is stored at the start of the file. Its size is given by the Offset of the first media segment in the segment info file.

Commonalities with DASH OnDemand format

DASH OnDemand stores media data in the same type of CMAF tracks as ESF. However, the metadata is stored in other structures.

To describe the asset and its variants, there is a manifest called Media Presentation Description (MPD) which is an XML file with file extension .mpd.

It is similar to the ESF content_info.json file. It has explicit switching groups called Adaptation Sets, but is lacking some other information compared to ESF like video parameter sets which are needed to generate MSS manifests.

Similar to ESF, there is a second structure that contains the information about the segments. In the case of DASH OnDemand, this information is stored in a sidx box inside the CMAF track itself. Its position is at the beginning of the media file right after the init segment, and before the actual media data.

By generating a DASH MPD file, and inserting a sidx box in the media tracks, it is possible to make VoD assets which are both compatible with DASH OnDemand and the ESF format. The new ESB3031 ew-vodingest tool generates such combined ingested files. For DASH OnDemand, a complete WebVTT file is used instead of wvtt segments. That complete WebVTT file is generated by extracting and concatenating all subtitle cues from the wvtt subtitle tracks used in the ESF format.

Live storage using ESF

The main reason to use ESF instead of DASH OnDemand, is that the latter does not support live content, but requires a static structure. In fact, since the sidx box must be placed before the media, it is not even possible to concatenate media segments and write a sidx box at the end. With ESF we can have the same format for both VoD and live.

The SegmentInfo files are separated from the media files and use 32 bytes per segment. These are therefore easy to seek and also to grow, by just adding another 32 bytes for each segment. In the ESB3003 catchup buffer, we store live content in one-minute files.

2.8 - Monitoring & Logging

Health, service logs and monitoring

Health check

You can check the health of the server by making a request to /healthz, which should return a 200 OK response.

Structured Logging

To aid processing, structured logging is available. This makes the logs more coherent, and more suitable for processing by external tools. The log formats journald or consolejson will trigger structured logging.

Log messages related to a specific HTTP request include the log field named request_id which can be used to filter out specific requests.

The log field named topic is always present and is used to separate different areas of logging. The topics are access, messages, licensing and error. It is useful when querying the log.

Log formats

When run from the command line the application can log in one of the formats consolepretty, consolejson or journald depending on the value of the -logformat parameter. Logging can be disabled by using the value discard.

$ ew-vod2cbm -upstream http://127.0.0.1 -logformat consolejson

consolepretty logs to standard output (stdout) in a human-readable format. Each log line starts with the date and the log message followed by the context- dependent log fields:

2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...

consolejson logs to stdout using a JSON object for each message:

{level:info,topic:access,time:2022-02-07T12:06:07Z,bytes_out:27592, ...}

When running as a systemd service, it logs directly to journald. In this case field names are upper case whereas the values keep their format.

Here are a few examples of querying the logs:

$ journalctl -u ew-vodjit TOPIC=access -o verbose

To see entries with a specific request ID:

$ journalctl -u ew-vod2cbm REQUEST_ID=host/B1Po0eYz1d-000006 -o verbose

To see the call stack in the event of a crash:

$ journalctl -u ew-manip TOPIC=error -o verbose

Using the verbose output includes all available name-value fields. Without this only the log message is printed. The field named JSON contains the original structured log message as sent by the service. To filter out only this field --output-fields=JSON can be used, however this requires a systemd version of at least 236.

$ journalctl -u ew-vod2cbm --output-fields=JSON TOPIC=access

To continuously monitor the service:

$ journalctl -fu ew-vod2cbm

Log levels

The startup log level is set according to the service configuration. The log level for a running service can be changed by posting a form-field named level to the loglevel endpoint. For example:

$ curl -F level=debug ew-vod2cbm-server:8090/loglevel

The available log levels and how they relate to systemd priority values is listed below:

Log level  Systemd priority
trace      7
debug      7
info       6
warn       4
error      3
fatal      2
panic      0

To e.g. see all error [3] and warning [4] messages using journalctl:

$ journalctl -u ew-vod2cbm PRIORITY=3 PRIORITY=4

Use a GET request to see the current log level:

$ curl ew-vod2cbm-server:8090/loglevel

Messages with higher level than the configured one will not be logged.

Monitoring

The services generate Prometheus data, available at the endpoint: /metrics. The respective metrics for the services are:

ew-vod2cbm

ew_audio_segment_requests_total
ew_audio_segment_request_duration_milliseconds
ew_video_segment_requests_total
ew_video_segment_request_duration_milliseconds
ew_subs_segment_requests_total
ew_subs_segment_request_duration_milliseconds
ew_segment_times_requests_total
ew_segment_times_request_duration_milliseconds
ew_content_info_requests_total
ew_content_info_request_duration_milliseconds

ew-manip

ew_hls_requests_total
ew_hls_request_duration_milliseconds
ew_dash_requests_total
ew_dash_request_duration_milliseconds

ew-vodjit

ew_cmaf_segment_requests_total
ew_cmaf_segment_request_duration_milliseconds
ew_dat_segment_requests_total
ew_dat_segment_request_duration_milliseconds
ew_content_info_requests_total
ew_content_info_request_duration_milliseconds
ew_manifest_requests_total
ew_manifest_request_duration_milliseconds

2.9 - Licensing

Using the licensed products

All Agile Content Processing products require a valid license file to operate. For the server products a few endpoints such as /metrics and /licensing are accessible without a valid license, but the core functionality requires a license.

The license file

The license file must be obtained from Agile Content along with your software. Depending on your agreement the file will contain either an online or offline license. For online licenses, the machine running the service, must have an internet connection, in order to access the license server.

The command-line products, such as ew-vodingest only support offline licenses.

Using the license file

The license must be placed in: /etc/edgeware/<product-name>/license.json e.g: /etc/edgeware/ew-vod2cbm/license.json You must never attempt to edit the license file. When you receive a new license.json, and your product is a service, the service must be restarted.

License expiry

Your product will not work beyond the expiry date. For online as well as offline licenses the server product logs will warn you that the service is about to expire, when the expiry date is closer than 7 days. For automatic expiry monitoring, the /licensing HTTP endpoint is recommended. Please note that there will be no warning before expiry for command-line products.

When the service, under a valid service contract, is about to expire, your license must be renewed:

  • For online licenses, Agile Content should renew your service license on a central license server. The licensing status can be checked by calling the /licensing endpoint (see below).
  • For offline licenses, you should obtain a new license file.

Online licenses

Less than three minutes after a service is started it starts to query the license server periodically. In case of temporary network or license server outages (up to 2 hours), your service will continue to function.

Checking the license: /licensing endpoint

You may query status of your license by querying your service with the /licensing endpoint. The response, in JSON-format, looks like:

$ curl localhost:8090/licensing
{
    "status": "valid",
    "pending_until": "",
    "expiry": "2022-12-31T23:59:29Z",
    "invalid_reason": "",
    "license_type": "online"
}

The call will return "status": "pending" during temporary network outage and for less than three minutes after the service has been restarted. The response for an expired license looks like:

{
    "status": "invalid",
    "pending_until": "",
    "expiry": "2021-12-31T23:59:29Z",
    "invalid_reason": "expired",
    "license_type": "online"
}

Checking the license: server log

If the service has, or is about to expire, the server log will show the status under "topic":"licensing". For example:

{"level":"warn","request_id":"adam/HLYRsgfrwz-000005","topic":"licensing",
"LicenseExpiryDate":"2022-08-30T23:59:09Z","time":"2022-08-24T11:42:28Z",
"message":"License will expire in less than 7 days, please remember to get a renewed license"}

These log messages only appear when a licensed endpoint e.g. /segment_times.json is called.

3 - Agile Content Delivery

ACD - Product Documentation

3.1 - Components

Separate installable entities to combine in different ways to create solutions

3.1.1 - ESB3024 Router

Routes HTTP sessions to CDNs or cache nodes

3.1.1.1 - Getting Started

From requirements to a simple example

The Director serves as a versatile network service designed to redirect incoming HTTP(s) requests to the optimal host or Content Delivery Network (CDN) by evaluating various request properties through a set of rules. Although requests can be generic, the primary focus centers around audio-video content delivery. The rule engine allows users to construct routing configurations using predefined blocks, providing for the creation of intricate routing logic. This modular approach allows the users to tailor and streamline the content delivery process to meet their specific needs. The Director’s flexible rule engine takes into account factors such as geographical location, server load, content type, and other metadata from external sources to intelligently route incoming requests. It supports dynamic adjustments to seamlessly adapt to changing network conditions, ensuring efficient and reliable content delivery. The Director improves the overall user experience by delivering content from the most suitable and responsive sources, thereby reducing latency and enhancing performance.

Requirements

Hardware

The Director is designed to be installed and operated on commodity hardware, ensuring accessibility for a broad range of users. The minimum hardware specifications are as follows:

  • CPU: x86-64 AMD or Intel with at least 2 cores.
  • Memory: At least 2 GB free at runtime.

Operating System Compatibility

The Director is officially supported on Red Hat Enterprise Linux 8 (RHEL8) or any compatible operating system. While it is possible to install and run on Red Hat Enterprise Linux 7 (RHEL7) or compatible OS, this is provided as a convenience, and users should note the limited management capabilities on this platform.

External Internet access is necessary during the installation process for the installer to download and install additional dependencies. This ensures a seamless setup and optimal functionality of the Director on Red Hat Enterprise Linux 8. It’s worth noting that, due to the unique workings of the DNF package manager in Red Hat Enterprise Linux 8 with rolling package streams, an air-gapped installation process is not available.

Firewall Recommendations

See Firewall.

Installation

See Installation.

Operations

See Operations.

Configuration Process

Once the router is operational, it requires a valid configuration before it can route incoming requests.

There are currently three methods available for configuring the router, each catering to different levels of complexity. The first is a Web UI, suitable for the most common use-cases, providing an intuitive interface for configuration. The second involves utilizing a confd REST service, complemented by an optional command line tool, confcli, suitable for all but the most advanced scenarios. The third method involves leveraging an internal REST API, ideal for the most intricate cases where using confd proves to be less flexible. It’s essential to note that as the configuration method advances through these levels, both flexibility and complexity increase, providing users with tailored options based on their specific needs and expertise.

API Key Management

Regardless of the method used to configure the system, a unique API key is crucial for safeguarding the router’s configuration and preventing unauthorized access to the API. This key must be supplied when interacting with the API. During the router software installation, an automatically generated API key is created and can be located on the installed system at /opt/edgeware/acd/router/cache/rest-api-key.json. The structure of this file is as follows:

{"api_key": "abc123"}

When accessing the internal configuration API, the key must be included in the X-API-key header of the request, as shown below:

curl -v -k -H "X-API-Key: abc123" https://<router-host.example>:5001/v2/configuration

Modification to the authentication key and behavior can be done through the /v2/rest_api_key endpoint. To change the key, a PUT request with a JSON body of the same structure can be sent to the endpoint:

curl -v -k -X PUT -T new-key.json -H "X-API-Key: abc123" \
-H "Content-Type: application/json" https://<router-host.example>:5001/v2/rest_api_key

Additionally, key authentication can be disabled completely by sending a DELETE request to the endpoint:

curl -v -k -X DELETE -H "X-API-Key: abc123" \
https://<router-host.example>:5001/v2/rest_api_key

In the event of a lost or forgotten authentication key, it can always be retrieved at /opt/edgeware/acd/router/cache/rest-api-key.json on the machine running the router. It is critical to emphasize that the API key should remain private to prevent unauthorized access to the internal API, as it grants full access to the router’s configuration.

Configuration Basics

Upon completing the installation process and configuring the API keys, the subsequent section will provide guidance on configuring the router to route all incoming requests to a single host. For straightforward CDN Offload use cases, there is a web based user interface described here.

For further details on configuring the router using confd and confcli, please consult the Confd documentation.

The initial step involves defining the target host group. In this illustration, a singular group named all will be established, comprising two hosts.

$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 2
  Adding a 'host' element
    hostGroup : {
      name (default: ): all
      type (default: host):
      httpPort (default: 80):
      httpsPort (default: 443):
      hosts : [
        host : {
          name (default: ): host1.example.com
          hostname (default: ): host1.example.com
          ipv6_address (default: ):
        }
        Add another 'host' element to array 'hosts'? [y/N]: y
        host : {
          name (default: ): host2.example.com
          hostname (default: ): host2.example.com
          ipv6_address (default: ):
        }
        Add another 'host' element to array 'hosts'? [y/N]: n
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: n
]
Generated config:
{
  "hostGroups": [
    {
      "name": "all",
      "type": "host",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "host1.example.com",
          "hostname": "host1.example.com",
          "ipv6_address": ""
        },
        {
          "name": "host2.example.com",
          "hostname": "host2.example.com",
          "ipv6_address": ""
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]:

After defining the host group, the next step is to establish a rule that directs incoming requests to the designated host. In this example, a sole rule named random will be generated, ensuring that all incoming requests are consistently routed to the previously defined host.

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: 6
  Adding a 'random' element
    rule : {
      name (default: ): random
      type (default: random):
      targets : [
        target (default: ): host1.example.com
        Add another 'target' element to array 'targets'? [y/N]: y
        target (default: ): host2.example.com
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "random",
      "type": "random",
      "targets": [
        "host1.example.com",
        "host2.example.com"
      ]
    }
  ]
}
Merge and apply the config? [y/n]:

The last essential step involves instructing the router on which rule should serve as the entry point into the routing tree. In this example, we designate the rule random as the entrypoint for the routing process.

$ confcli services.routing.entrypoint random
services.routing.entrypoint = 'random'

Once this configuration is defined, all incoming requests will initiate their traversal through the routing rules, starting with the rule named random. This rule is designed to consistently match for every incoming request, effectively load balancing evenly between host1.example.com and host2.example.com on port 80 or 443, depending on whether the initial request was made using HTTP or HTTPS.

Integration with Convoy

The router is equipped with the capability to synchronize specific configuration metadata with a separate Convoy installation through the integrated convoy-bridge service. However, this service necessitates additional setup and configuration, and you can find comprehensive details on the process here..

Additional Resources

Additional documentation resources are included with the Director and can be accessed at the following directory: /opt/edgeware/acd/documentation/. This directory contains supplementary materials to provide users with comprehensive information and guidance for optimizing their experience with the Director.

Ready for Production

Once the Director software is completely installed and configured, there are a few additional considerations before moving to a full production environment. See the section Ready for Production for additional information.

3.1.1.2 - Installation

How to install and upgrade ESB3024 Router

3.1.1.2.1 - Installing release 1.10.x

How to install and upgrade to ESB3024 Router release 1.10.x

To install ESB3024 Router, one first needs to copy the installation ISO image to the target node where the router will be run. Due to the way the installer operates, it is necessary that the host is reachable by password-less SSH from itself for the user account that will perform the installation, and that this user has sudo access.

Prerequisites:

  1. Ensure that the current user has sudo access.

    sudo -l
    

    If the above command fails, you may need to add the user to the /etc/sudoers file.

  2. Ensure that the installer has password-less SSH access to localhost.

    If using the root user, the PermitRootLogin property of the /etc/ssh/sshd_config file must be set to ‘yes’.

    The local host key must also be included in the .ssh/authorized_keys file of the user running the installer. That can be done by issuing the following as the intended user:

    mkdir -m 0700 -p ~/.ssh
    ssh-keyscan localhost >> ~/.ssh/authorized_keys
    

    Note! The ssh-keyscan utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to this ssh-keyscan approach, establishing an SSH connection to localhost and accepting the host key will have the same result.

  3. Disable SELinux.

    The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.

    To check if SELinux is enabled:

    getenforce
    

    This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.

    setenforce 0
    

    This disables SELinux, but does not make the change persistent across reboots. To do that, edit the /etc/selinux/config file and set the SELINUX property to disabled.

    It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.

Assuming the installation ISO image is in the current working directory, the following steps need to be executed either by root user or with sudo.

  1. Mount the installation ISO image under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-esb3024-1.10.1.iso /mnt/acd
    
  2. Run the installer script.

    /mnt/acd/installer
    

Upgrade from ESB3024 Router release 1.8.0

The following steps can be used to upgrade the router from release 1.8.0 to 1.10.x. If upgrading from an earlier release it is recommended to perform the upgrade in multiple steps; for instance when upgrading from release 1.6.0 to 1.10.x, it is recommended to first upgrade to 1.8.0 and then to 1.10.x.

The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new release of the router, and applying the saved configuration.

  1. With the router running, save a backup of the configuration.

    The exact procedure to accomplish this depends on the current method of configuration, e.g. if confd is used, then the configuration should be extracted from confd, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.

    Extracting the configuration using confd is the recommend approach where available.

    confcli | tee config_backup.json
    

    To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.

    curl --insecure https://localhost:5001/v2/configuration \
      | tee config_backup.json
    

    If the API Key is required, it can be found in the file /opt/edgeware/acd/router/cache/rest-api-key.json and can be passed to the API by setting the value of the X-API-Key header.

    curl --insecure -H "X-API-Key: 1234abcd" \
      https://localhost:5001/v2/configuration \
      | tee config_backup.json
    
  2. Mount the new installation ISO under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-esb3024-1.10.1.iso /mnt/acd
    
  3. Stop the router and all associated services.

    Before upgrading the router it needs to be stopped, which can be done by typing this:

    systemctl stop 'acd-*'
    
  4. Run the installer script.

    /mnt/acd/installer
    
  5. Migrate the configuration.

    Note that this step only applies if the router is configured using confd. If it is configured using the REST API, this step is not necessary.

    The confd configuration used in version 1.8.0 is not directly compatible with 1.10.x, and may need to be converted. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.

    To determine if the configuration needs to be converted, confcli can be run like below. If it prints error messages, the configuration needs to be converted. If no error messages are printed, the configuration is valid and no further updates are necessary.

    confcli | head -n5
    [2024-04-02 14:48:37,155] [ERROR] Missing configuration key /integration
    [2024-04-02 14:48:37,162] [ERROR] Missing configuration key /services/routing/settings/qoeTracking
    [2024-04-02 14:48:37,222] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/hosts/convoy-rr-1/healthChecks
    [2024-04-02 14:48:37,222] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/hosts/convoy-rr-2/healthChecks
    [2024-04-02 14:48:37,242] [ERROR] Missing configuration key /services/routing/hostGroups/e-dns/hosts/linton-dns-1/healthChecks
    {
       "integration": {
          "convoy": {
                "bridge": {
                   "accounts": {
    

    If error messages are printed, the configuration needs to be converted. If the configuration was saved in the file config_backup.json, the conversion can be done by typing this at the command line:

    sed -E -e '/"hosts":/,/]/ s/([[:space:]]+)("hostname":.*)/\1\2\n\1"healthChecks": [],/' -e '/"apiKey":/ d' config_backup.json | \
    curl -s -X PUT -T - -H 'Content-Type: application/json' http://localhost:5000/config/__active/
    
    systemctl restart acd-router
    

    This adds empty healthChecks sections to all hosts and removes the apiKey configuration. After that, acd-confd is restarted. See Configuration changes between 1.8.0 and 1.10.x for more details about the configuration changes.

  6. Remove the Account Monitor container

    Older versions of the router installed the Account Monitor tool. This was removed in release 1.8.0, but if it is still present and unused, it can be removed by typing:

    podman rm account-monitor
    

Troubleshooting

If there is a problem running the installer, additional debug information can be output by adding -v or -vv or -vvv to the installer command, the more “v” characters, the more detailed output.

3.1.1.2.1.1 - Configuration changes between 1.8.0 and 1.10.x

This describes the configuration changes between ESB3024 Router version 1.8.0 and 1.10.x.

Confd configuration changes

Below are the major changes to the confd configuration between version 1.8.0 and 1.10.x listed.

Added integration.convoy section

An integration.convoy section has been added to the configuration. It is currently used for configuring the Convoy Bridge service.

Removed services.routing.apiKey configuration

The services.routing.apiKey configuration key has been removed. This was an obsolete way of giving the configuration access to the router. The key has to be removed from the configuration when upgrading, otherwise the configuration will not be accepted.

Added services.routing.settings.qoeTracking

A services.routing.settings.qoeTracking section has been added to the configuration.

Added healthChecks sections to the hosts

The hosts in the hostGroup entries have been extended with a healthChecks key, which is a list of functions that determine if a host is in good health.

For example, a redirecting host might look like this after the configuration has been updated:

{
    "services": {
        "routing": {
            "hostGroups": [
                {
                    "name": "convoy-rr",
                    "type": "redirecting",
                    "httpPort": 80,
                    "httpsPort": 443,
                    "forwardHostHeader": true,
                    "hosts": [
                        {
                            "name": "convoy-rr-1",
                            "hostname": "convoy-rr-1",
                            "ipv6_address": "",
                            "healthChecks": [
                                "health_check('convoy-rr-1')"
                            ]
                        }
                    ]
                }
            ],

3.1.1.2.2 - Installing release 1.8.0

How to install and upgrade to ESB3024 Router release 1.8.0

To install ESB3024 Router, one first needs to copy the installation ISO image to the target node where the router will be run. Due to the way the installer operates, it is necessary that the host is reachable by password-less SSH from itself for the user account that will perform the installation, and that this user has sudo access.

Prerequisites:

  1. Ensure that the current user has sudo access.

    sudo -l
    

    If the above command fails, you may need to add the user to the /etc/sudoers file.

  2. Ensure that the installer has password-less SSH access to localhost.

    If using the root user, the PermitRootLogin property of the /etc/ssh/sshd_config file must be set to ‘yes’.

    The local host key must also be included in the .ssh/authorized_keys file of the user running the installer. That can be done by issuing the following as the intended user:

    mkdir -m 0700 -p ~/.ssh
    ssh-keyscan localhost >> ~/.ssh/authorized_keys
    

    Note! The ssh-keyscan utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to this ssh-keyscan approach, establishing an SSH connection to localhost and accepting the host key will have the same result.

  3. Disable SELinux.

    The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.

    To check if SELinux is enabled:

    getenforce
    

    This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.

    setenforce 0
    

    It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.

Assuming the installation ISO image is in the current working directory, the following steps need to be executed either by root user or with sudo.

  1. Mount the installation ISO image under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-esb3024-1.8.0.iso /mnt/acd
    
  2. Run the installer script.

    /mnt/acd/installer
    

Upgrade

The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new version of the router, and applying the saved configuration.

  1. With the router running, save a backup of the configuration.

    The exact procedure to accomplish this depends on the current method of configuration, e.g. if confd is used, then the configuration should be extracted from confd, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.

    Extracting the configuration using confd is the recommend approach where available.

    confcli | tee config_backup.json
    

    To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.

    curl --insecure https://localhost:5001/v2/configuration \
      | tee config_backup.json
    

    If the API Key is required, it can be found in the file /opt/edgeware/acd/router/cache/rest-api-key.json and can be passed to the API by setting the value of the X-API-Key header.

    curl --insecure -H "X-API-Key: 1234abcd" \
      https://localhost:5001/v2/configuration \
      | tee config_backup.json
    
  2. Mount the new installation ISO under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-1.2.0.iso /mnt/acd
    
  3. Stop the router and all associated services.

    Before upgrading the router it needs to be stopped, which can be done by typing this:

    systemctl stop 'acd-*'
    
  4. Run the installer script.

    /mnt/acd/installer
    
  5. Migrate the configuration.

    Note that this step only applies if the router is configured using confd. If it is configured using the REST API, this step is not necessary.

    The confd configuration used in version 1.6.0 is not directly compatible with 1.8.0, and may need to have a few minor manual updates in order to be valid. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.

    To determine if the configuration needs to be manually updated, confcli can be run like below. If it prints error messages, the configuration needs to be updated. If no error messages are printed, the configuration is valid and no further updates are necessary.

    confcli services.routing | head
    [2024-02-01 19:05:10,769] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/forwardHostHeader
    [2024-02-01 19:05:10,779] [ERROR] Missing configuration key /services/routing/hostGroups/e-dns/forwardHostHeader
    [2024-02-01 19:05:10,861] [ERROR] 'forwardHostHeader'
    

    If error messages are printed, a forwardHostHeader configuration needs to be added to the hostGroups configuration. This can be done by running this at the command line:

    curl -s http://localhost:5000/config/__active/ | \
    sed -E 's/([[:space:]]+)"type": "(host|redirecting|dns)"(,?)/\1"type": "\2",\n\1"forwardHostHeader": false\3/' | \
    curl -s -X PUT -T - -H 'Content-Type: application/json' http://localhost:5000/config/__active/
    

    This reads the active configuration from the router, adds the “forwardHostHeader” configuration to all host groups, and then sends the updated configuration back to the router.

    See Configuration changes between 1.6.0 and 1.8.0 for more details about the configuration changes.

  6. Remove the Account Monitor container

    Previous versions of the router installed the Account Monitor tool. This is no longer included, but since the previous version installed, there will be a stopped Account Monitor container. If it is not used, the container can be removed by typing:

    podman rm account-monitor
    

Troubleshooting

If there is a problem running the installer, additional debug information can be output by adding -v or -vv or -vvv to the installer command, the more “v” characters, the more detailed output.

3.1.1.2.2.1 - Configuration changes between 1.6.0 and 1.8.0

This describes the configuration changes between ESB3024 Router version 1.6.0 and 1.8.0.

Confd configuration changes

Below are some of the configuration changes between version 1.4.0 and 1.6.0 listed. The list only contains the changes that might affect already existing configuration, enirely new items are not listed. Normally nothing needs to be done about this since they will be upgraded automatically, but they are listed here for reference.

Added enabled to contentPopularity

An enabled key has been added to services.routing.settings.contentPopularity. After the key has been added, the configuration looks like this:

{
    "services": {
        "routing": {
            "settings": {
                "contentPopularity": {
                    "enabled": true,
                    "algorithm": "score_based",
                    "sessionGroupNames": []
                },
                ...

Added selectionInputItemLimit to tuning

A selectionInputItemLimit key has been added to services.routing.tuning.general. After the key has been added, the configuration looks like this:

{
    "services": {
        "routing": {
            "tuning": {
                "general": {
                    ...
                    "selectionInputItemLimit": 10000,
                    ...

Added forwardHostHeader to hostGroups

All three hostGroup types (host, redirecting and dns) have been extended with a forwardHostHeader key. For example, a redirecting host might look like this after the change:

{
    "services": {
        "routing": {
            "hostGroups": [
                {
                    "name": "convoy-rr",
                    "type": "redirecting",
                    "httpPort": 80,
                    "httpsPort": 443,
                    "forwardHostHeader": true,
                    "hosts": [
                        {
                            "name": "convoy-rr-1",
                            "hostname": "convoy-rr-1",
                            "ipv6_address": ""
                        }
                    ]
                }
            ],
            ...

REST API configuration changes

The following items have been added to the REST API configuration. They will not need to be manually updated, the router will add the new keys with default values. Note that this is not a complete list of all changes, it only contains the changes that will be automatically added when upgrading the router.

If the router is configured via confd and confcli, these changes will be applied by them. This section is only relevant if the router is configured via the v2/configuration API.

  • Added the session_translation_function key.
  • Added the tuning.selection_input_item_limit key.

3.1.1.2.3 - Installing release 1.6.0

How to install and upgrade to ESB3024 Router release 1.6.0

To install ESB3024 Router, one first needs to copy the installation ISO image to the target node where the router will be run. Due to the way the installer operates, it is necessary that the host is reachable by password-less SSH from itself for the user account that will perform the installation, and that this user has sudo access.

Prerequisites:

  1. Ensure that the current user has sudo access.

    sudo -l
    

    If the above command fails, you may need to add the user to the /etc/sudoers file.

  2. Ensure that the installer has password-less SSH access to localhost.

    If using the root user, the PermitRootLogin property of the /etc/ssh/sshd_config file must be set to ‘yes’.

    The local host key must also be included in the .ssh/authorized_keys file of the user running the installer. That can be done by issuing the following as the intended user:

    mkdir -m 0700 -p ~/.ssh
    ssh-keyscan localhost >> ~/.ssh/authorized_keys
    

    Note! The ssh-keyscan utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to this ssh-keyscan approach, establishing an SSH connection to localhost and accepting the host key will have the same result.

  3. Disable SELinux.

    The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.

    To check if SELinux is enabled:

    getenforce
    

    This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.

    setenforce 0
    

    It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.

Assuming the installation ISO image is in the current working directory, the following steps need to be executed either by root user or with sudo.

  1. Mount the installation ISO image under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-esb3024-1.8.0.iso /mnt/acd
    
  2. Run the installer script.

    /mnt/acd/installer
    

Upgrade

The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new version of the router, and applying the saved configuration.

  1. With the router running, save a backup of the configuration.

    The exact procedure to accomplish this depends on the current method of configuration, e.g. if confd is used, then the configuration should be extracted from confd, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.

    Extracting the configuration using confd is the recommend approach where available.

    confcli | tee config_backup.json
    

    To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.

    curl --insecure https://localhost:5001/v2/configuration \
      | tee config_backup.json
    

    If the API Key is required, it can be found in the file /opt/edgeware/acd/router/cache/rest-api-key.json and can be passed to the API by setting the value of the X-API-Key header.

    curl --insecure -H "X-API-Key: 1234abcd" \
      https://localhost:5001/v2/configuration \
      | tee config_backup.json
    
  2. Mount the new installation ISO under /mnt/acd.

    Note: The mount-point may be any accessible path, but /mnt/acd will be used throughout this document.

    mkdir -p /mnt/acd
    mount esb3024-acd-router-1.2.0.iso /mnt/acd
    
  3. Stop the router and all associated services.

    Before upgrading the router it needs to be stopped, which can be done by typing this:

    systemctl stop 'acd-*'
    
  4. Run the installer script.

    /mnt/acd/installer
    
  5. Migrate the configuration.

    Note that this step only applies if the router is configured using confd. If it is configured using the REST API, this step is not necessary.

    See Configuration changes between 1.4.0 and 1.6.0 for instructions on how to migrate the configuration to release 1.6.0.

Troubleshooting

If there is a problem running the installer, additional debug information can be output by adding -v or -vv or -vvv to the installer command, the more “v” characters, the more detailed output.

3.1.1.2.3.1 - Configuration changes between 1.4.0 and 1.6.0

This describes the configuration changes between ESB3024 Router version 1.4.0 and 1.6.0.

confd configuration

The confd configuration used in version 1.4.0 is not directly compatible with 1.6.0, and will need to have a few minor updates in order to be valid. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes. Running confcli will cause error messages and an empty default configuration to be printed.

$ confcli services.routing.
[2023-12-12 16:08:07,120] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-12 16:08:07,122] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-12 16:08:07,122] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-12 16:08:07,123] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-12 16:08:07,123] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds
{
    "routing": {
        "apiKey": "",
        "settings": {
            "allowedProxies": [],
            "contentPopularity": {
                "algorithm": "score_based",
                "sessionGroupNames": []
            },
            "extendedContentIdentifier": {
            ...

The first thing that needs to be done is to rename the keys sessionGroupIds to sessionGroupNames. If the configuration was backed up to the file config_backup.json before upgrading, the keys can be renamed and the updated configuration can be applied by typing this:

sed 's/"sessionGroupIds"/"sessionGroupNames"/' config_backup.json | confcli -i
[2023-12-19 12:33:17,725] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-19 12:33:17,726] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds

The configuration has not yet been converted, so the error messages are still printed. The configuration will be converted when the acd-confd service is restarted.

systemctl restart acd-confd

This concludes the conversion of the configuration and the router is ready to be used.

Configuration changes

Below are all configuration changes between version 1.4.0 and 1.6.0 listed. Normally nothing needs to be done about this since they will be upgraded automatically, but they are listed here for reference.

Added translationFunctions block

services.routing.translationFunctions has been added. It can be added as a map with two empty strings as values, to make the top of the configuration look like this:

{
    "services": {
        "routing": {
            "translationFunctions": {
                "request": "",
                "response": ""
            },
            ...

Renamed sessionGroupIds to sessionGroupNames

The keys services.routing.settings.instream.dashManifestRewrite.sessionGroupIds and services.routing.settings.instream.hlsManifestRewrite.sessionGroupIds have been renamed to services.routing.settings.instream.dashManifestRewrite.sessionGroupNames and services.routing.settings.instream.hlsManifestRewrite.sessionGroupNames respectively. Any session group IDs need to be manually converted to session group names.

After the conversion, the head of the configuration file might look like this:

{
    "services": {
        "routing": {
            "apiKey": "",
            "settings": {
                "allowedProxies": [],
                "contentPopularity": {
                    "algorithm": "score_based",
                    "sessionGroupNames": []
                },
                "extendedContentIdentifier": {
                    "enabled": false,
                    "includedQueryParams": []
                },
                "instream": {
                    "dashManifestRewrite": {
                        "enabled": false,
                        "sessionGroupNames": []
                    },
                    "hlsManifestRewrite": {
                        "enabled": false,
                        "sessionGroupNames": []
                    },
                    "reversedFilenameComparison": false
                },
                ...

Added managedSessions block

A services.routing.settings.managedSessions block has been added. After adding the block, the configuration might look like this:

{
    "services": {
        "routing": {
            "apiKey": "",
            "settings": {
                "allowedProxies": [],
                "contentPopularity": {
                    "algorithm": "score_based",
                    "sessionGroupNames": []
                },
                ...
                "managedSessions": {
                    "fraction": 0.0,
                    "maxActive": 100000,
                    "sessionTypes": []
                },
                "usageLog": {
                    "enabled": false,
                    "logInterval": 3600000
                }
            },
            ...

Added recentDurationMilliseconds

A services.routing.tuning.target.recentDurationMilliseconds key has been added to the configuration file, with a default value of 500. After adding the key, the configuration might look like this:

{
    "services": {
        "routing": {
            "apiKey": "",
            ...
            "tuning": {
                "target": {
                    ...
                    "recentDurationMilliseconds": 500,
                    ...

Storing the updated configuration

After all these changes have been done to the configuration file, it can be applied to the router using confcli.

confcli will still display error messages because the stored configuration is not valid. They will not be displayed anymore after the valid configuration has been applied.

$ confcli -i < updated_config.json
[2023-12-12 18:52:05,500] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-12 18:52:05,502] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-12 18:52:05,502] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-12 18:52:05,503] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-12 18:52:05,511] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds

Raw configuration

The following changes have been made to the raw configuration. If the router is configured via confd and confcli, these changes will be applied by them. This section is only relevant if the router is configured via the v2/configuration API.

Simple changes

The following keys were added or removed. They will not need to be manually updated, the router will add the new keys with default values.

  • Removed the tuning.repeated_session_start_threshold_seconds key.
  • Removed the lua_paths key.
  • Added the tuning.target_recent_duration_milliseconds key.

EDNS proxy changes

If the router has been configured to use an EDNS server, the following has to be changed for the configuration to work.

The hosts.proxy_address key has been renamed to hosts.proxy_url and now accepts a port that is used when connecting to the proxy.

The cdns.http_port and cdns.https_port keys now configure the port that is used for connecting to the EDNS server, before they configured the port that is used for connecting to the proxy.

3.1.1.3 - Firewall

Firewall Configuration

For security reasons, the ESB3024 Installer does not automatically configure the local firewall to allow incoming traffic. It is the responsibility of the operations person to ensure that the system is protected from external access by placing it behind a suitable firewall solution. The following table describes the set of ports required for operation of the router.

ApplicationPortProtocolDirectionSourceDescription
Prometheus Alert Manager9093TCPINinternalMonitoring Services
Confd5000TCPINinternalConfiguration Services
Router80TCPINpublicIncoming HTTP Requests
Router443TCPINpublicIncoming HTTPS Requests
Router5001TCPINlocalhostAccess to router’s REST API
Router8000TCPINlocalhostInternal monitoring port
EDNS-Proxy8888TCPINlocalhostProxy EDNS Requests
Grafana3000TCPINinternalMonitoring Services
Grafana-Loki3100TCPINinternalLog monitoring daemon
Prometheus9090TCPINinternalMonitoring Service

The “Direction” column represents the direction in which the connection is established.

  • IN - The connection is originated from an outside server
  • OUT - The connection is established from the host to an external server.

Once a connection is established through the firewall, bidirectional traffic must be allowed using the established connection.

For the “Source” column, the following terms are used.

  • internal - Any host or network which is allowed to monitor or operate the system.
  • public - Any host or subnet that can access the router. This includes any customer network that will be making routing requests.
  • localhost - Access can be limited to local connections only.
  • any - All traffic from any source or to any destination.

Additional Ports

Convoy bridge integration

The optional convoy-bridge service needs the ability to access the Convoy MariaDB service, which by default runs on port 3306 on all of the Convoy Management servers. To allow this integration to run, port 3306/tcp must be allowed from the router to the configured Convoy Management node.

3.1.1.4 - API Overview

A brief description of the API:s served by ESB3024 Router

ESB3024 Router provides two different types of API:s:

  1. A content request API that is used by video clients to ask for content, normally using port 80 for HTTP and port 443 for HTTPS.
  2. A few REST API:s used by administrators to configure and monitor the router installation, using port 5001 over HTTPS by default.

The content API won’t be described further in this document, since it’s a simple HTTP interface serving content as regular files or redirect responses.

Configuration – /v2/configuration

Used to check and update the configuration of ESB3024 Router. Change the configuration by PUTing a JSON payload to the endpoint, and view the current configuration by GETing the endpoint without payload. See Configuration for more information about the configuration

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json
PUTapplication/jsonSuccess204 No Content<N/A>
PUTapplication/jsonFailure400 Bad Requestapplication/json1

Example request (GET)

Request the currently applied configuration using a simple GET request:

$ curl -i https://router.example:5001/v2/configuration
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 1234
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "id": "router.example-5fc78d",
  "version": "v2",
  "image_tag": "20221117T190005Z-2a71714b6",
  "tuning": {
    "log_level": 3,
    [...]
  },
  "rest_api_server": {
    "enable": true,
    "port": 5001
  },
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "routing": {
    [...]
  },
  [...]
}

Example request (PUT)

Updating only a part of the configuration is possible by sending a JSON snippet with the fields to change:

$ curl -i -X PUT \
    -d '{"tuning" {"log_level": 3}}' \
    -H "Content-Type: application/json" \
    https://router.example:5001/v2/configuration
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

Validate Configuration – /v2/validate_configuration

Used to determine if a JSON payload is correctly formatted without actually applying its configuration. A successful return status does not guarantee that the applied configuration will work, it only validates the JSON structure.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
PUTapplication/jsonSuccess204 No Content<N/A>
PUTapplication/jsonFailure400 Bad Requestapplication/json1

Example request

When an expected field is missing from the payload, the validation will show which one and return an appropriate error message in its payload:

$ curl -i -X PUT \
    -d '{"routing": {"log_level": 3}}' \
    -H "Content-Type: application/json" \
    https://router.example:5001/v2/validate_configuration
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Length: 132
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

"Configuration validation: Configuration parsing failed. \
  Exception: [json.exception.out_of_range.403] (/routing) key 'id' not found"

Selection Input – /v1/selection_input

Selection input API can be used to inject external key:value data into the routing engine, making the data available when making routing decisions. An arbitrary JSON structure can be pushed to the endpoint. When performing GET or DELETE requests, specific selection input values can be accessed or deleted by including a path to the request. Note that not specifying a path will select all selection input values.

One use case for selection input is to provide data on cache availability. E.g. If you send {"edge-streamer-2-online": true} to the selection input API, you can create a routing condition eq('edge-streamer-online', true) to ensure that no traffic gets routed to the streamer if it’s offline. Note that sending the same key:value data to the selection input API will overwrite the previous value.

There is a configurable limit to how many key:value items that can be injected into the router, see tuning parameter selection_input_item_limit under tuning configuration.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
PUTapplication/jsonSuccess204 No Content<N/A>
PUTapplication/jsonFailure400 Bad Requestapplication/json
GET<N/A>Success200 OKapplication/json
DELETE<N/A>Success204 No Content<N/A>
DELETE<N/A>Failure404 Not Found<N/A>

Example successful request (PUT)

$ curl -i -X PUT \
    -d '{"host1_bitrate": 13000, "host1_capacity": 50000}' \
    -H "Content-Type: application/json" \
    https://router.example:5001/v1/selection_input
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

Example unsuccessful request (PUT)

$ curl -i -X PUT \
    -d '{"cdn-status": {"session-count": 12345, "load-percent" 98}}' \
    -H "Content-Type: application/json" \
    https://router.example:5001/v1/selection_input
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Length: 169
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "error": "[json.exception.parse_error.101] parse error at line 1, column 57: \
    syntax error while parsing object separator - \
    unexpected number literal; expected ':'"
}

Example successful request (GET)

curl -i https://router.example:5001/v1/selection_input
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 129
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "host1_bitrate": 13000,
  "host1_capacity": 50000
}

Example successful specific value request (GET)

curl -i https://router.example:5001/v1/selection_input/path/to/value
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 129
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

1

Example successful request (DELETE)

curl -i -X DELETE https://router.example:5001/v1/selection_input
HTTP/1.1 204 OK
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d

Example successful specific value request (DELETE)

curl -i -X DELETE  https://router.example:5001/v1/selection_input/value/to/delete
HTTP/1.1 204 OK
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d

Example unsuccessful request (DELETE)

curl -i -X DELETE  https://router.example:5001/v1/selection_input/non/existent/value
HTTP/1.1 404 Not Found
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d

Subnets – /v1/subnets

An API for managing named subnets that can be used for routing and block lists. See Subnets for more details.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
PUTapplication/jsonSuccess204 No Content<N/A>
PUTapplication/jsonFailure400 Bad Requestapplication/json

Example request

$ curl -i -X PUT \
    -d '{"255.255.255.255/24": "test"}' \
    -H "Content-Type: application/json" \
    https://router.example:5001/v1/subnets
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

Subrunner Resource Usage – /v1/usage

Used to monitor the load on subrunners, the processes performing those tasks that are possible to run in parallel.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json

Example request

$ curl -i https://router.example:5001/v1/usage
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 1234
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "total_usage": {
    "content": {
      "lru": 0,
      "newest": "-",
      "oldest": "-",
      "total": 0
    },
    "sessions": 0,
    "subrunner_usage": {
      [...]
    }
  },
  "usage_per_subrunner": [
    {
      "subrunner_usage": {
        [...]
      }
    },
    [...]
  ]
}

Metrics – /m1/v1/metrics

An interface intended to be scraped by Prometheus. It is possible to scrape it manually to see current values, but doing so will reset some counters and cause actual Prometheus data to become faulty.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKtext/plain

Example request

$ curl -i https://router.example:5001/m1/v1/metrics
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 1234
Content-Type: text/plain
X-Service-Identity: router.example-5fc78d

# TYPE num_configuration_changes counter
num_configuration_changes 12
# TYPE num_log_errors_total counter
num_log_errors_total 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category=""} 123
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="cdn"} 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="content"} 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="generic"} 10
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="repeated_session"} 0
# TYPE num_ssl_errors_total counter
[...]

Node Visit Counters – /v1/node_visits

Used to gather statistics about the number of visits to each node in the routing tree. The returned value is a JSON object containing node ID names and their corresponding counter values.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json

See Routing Rule Evaluation Metrics for more details.

Example request

$ curl -i https://router.example:5001/v1/node_visits
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 73
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "cache1.tv": "99900",
  "offload": "100"
  "routingtable": "100000"
}

Node Visit Graph – /v1/node_visits_graph

Creates a GraphML representation of the node visitation data that can be rendered into an image to make it easier to understand the data.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/xml

See Routing Rule Evaluation Metrics for more details.

Example request

> curl -i -k https://router.example:5001/v1/node_visits_graph
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 731
Content-Type: application/xml
X-Service-Identity: router.example-5fc78d

<?xml version="1.0"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
  <key id="visits" for="node" attr.name="visits" attr.type="string" />
  <graph id="G" edgedefault="directed">
    <node id="routingtable">
      <data key="visits">100000</data>
    </node>
    <node id="cache1.tv">
      <data key="visits">99900</data>
    </node>
    <node id="offload">
      <data key="visits">100</data>
    </node>
    <edge id="e0" source="routingtable" target="cache1.tv" />
    <edge id="e1" source="routingtable" target="offload" />
  </graph>
</graphml>

Session list - /v1/sessions

Used to monitor the load on subrunners, the processes performing those tasks that are possible to run in parallel.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json

Example request

$ curl -k -i https://router.example:5001/v1/sessions
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 12345
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "sessions": [
    {
      "age_seconds": 103,
      "cdn": "edgeware",
      "cdn_is_redirecting": false,
      "client_ip": "1.2.3.4",
      "host": "cdn.example:80",
      "id": "router.example-5fc78d-00000001",
      "idle_seconds": 103,
      "last_request_time": "2022-12-02T14:05:05Z",
      "latest_request_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
      "no_of_requests": 1,
      "requested_bytes": 0,
      "requests_redirected": 0,
      "requests_served": 0,
      "session_groups": [
        "all"
      ],
      "session_groups_generation": 2,
      "session_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
      "start_time": "2022-12-02T14:05:05Z",
      "type": "instream",
      "user_agent": "libmpv"
    },
    [...]
  ]
}

Session details - /v1/sessions/<id: str>

Used to get details about a specific session from the above session list. The id part of the URL corresponds to the id field in one of the returned session entries in the above response.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json
GET<N/A>Failure404 Not Foundapplication/json

Example request

$ curl -k -i https://router.example:5001/v1/sessions/router.example-5fc78d-00000001
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 763
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "age_seconds": 183,
  "cdn": "edgeware",
  "cdn_is_redirecting": false,
  "client_ip": "1.2.3.4",
  "host": "cdn.example:80",
  "id": "router.example-5fc78d-00000001",
  "idle_seconds": 183,
  "last_request_time": "2022-12-02T14:05:05Z",
  "latest_request_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
  "no_of_requests": 1,
  "requested_bytes": 0,
  "requests_redirected": 0,
  "requests_served": 0,
  "session_groups": [
    "all"
  ],
  "session_groups_generation": 2,
  "session_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
  "start_time": "2022-12-02T14:05:05Z",
  "type": "instream",
  "user_agent": "libmpv"
}

Content List - /v1/content

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json

Example request

$ curl -k -i https://router.example:5001/v1/content
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 572
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "content": [
    [
      "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
      {
        "cached_count": 0,
        "content_requested": false,
        "content_set": false,
        "expiration_time": "2022-12-02T14:05:05Z",
        "key": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
        "listeners": 0,
        "manifest": "",
        "request_count": 4,
        "state": "HLS:MANIFEST-PENDING",
        "wait_count": 0
      }
    ]
  ]
}

Lua scripts – /v1/lua/<path str>.lua

Used to upload, retrieve and delete custom named Lua scripts on the router. Global functions in uploaded scripts automatically become available to Lua code in the configuration (which effectively may be viewed as hooks). Upload a script by PUTing a application/x-lua to the endpoint, and retrieve it by GETing the endpoint without payload.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
PUTapplication/x-luaSuccess204 No Content<N/A>
PUTapplication/x-luaFailure400 Bad Requestapplication/json
GET<N/A>Success200 OKapplication/x-lua
GET<N/A>Failure404 Not Foundapplication/json
DELETE<N/A>Success204 No Content<N/A>
DELETE<N/A>Failure400 Bad Requestapplication/json
DELETE<N/A>Failure404 Not Foundapplication/json

Example request (PUT)

Save a Lua script under the name advanced_functions/f1.lua:

$ curl -i -X PUT \
    -d 'function fun1() return 1 end' \
    -H "Content-Type: application/x-lua" \
    https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully saved Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

Example request (PUT, from file)

Upload an entire Lua file under the name advanced_functions/f1.lua:

First put your code in a file.

$ cat f1.lua
function fun1()
    return 1
end

Then upload it using the --data-binary flag to preserve newlines

$ curl -i -X PUT \
    --data-binary @f1.lua \
    -H "Content-Type: application/x-lua" \
    https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully saved Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

Example request (GET)

Request the Lua script named advanced_functions/f1.lua using a GET request:

$ curl -i https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 28
Content-Type: application/x-lua
X-Service-Identity: router.example-5fc78d

function fun1() return 1 end

Example request (DELETE)

Delete the Lua script named advanced_functions/f1.lua using a DELETE request:

$ curl -i -X DELETE \
    https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully removed Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d

List Lua scripts – /v1/lua

Used to list previously uploaded custom Lua scripts on the router, retrieving their respective paths and file checksums.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
GET<N/A>Success200 OKapplication/json

Example request

$ curl -k -i https://router.example:5001/v1/lua
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 108
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

[
  {
    "file_checksum": "d41d8cd98f00b204e9800998ecf8427e",
    "path": "advanced_functions/f1.lua"
  }
]

Debug a Lua expression – /v1/lua/debug

Used to debug an arbitrary Lua expression on the router in a “sandbox” (with no visible side effects to the state of the router), and inspect the result.

The Lua expression in the body is evaluated inside an isolated copy of the internal Lua environment including selection input. The stdout field of the resulting JSON body is populated with a concatenation of every string provided as argument to the Lua print() function during the course of evaluation. Upon a successful evaluation, as indicated by the success flag, return.value and return.lua_type_name capture the resulting Lua value. Otherwise, if valuation was aborted (e.g. due to a Lua exception), error_msg reflects any error description arising from the Lua environment.

REQUEST
Method
Content-TypeRESPONSE
Result
Status CodeContent-Type
POSTapplication/x-luaSuccess200 OKapplication/json

Example successful request

$ curl -i -X POST \
    -d 'fun1()' \
    -H "Content-Type: application/x-lua" \
    https://router.example:5001/v1/lua/debug
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 123
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "error_msg": "",
  "return": {
    "lua_type_name": "number",
    "value": 1.0
  },
  "stdout": "",
  "success": true
}

Example unsuccessful request

(attempt to invoke unknown function)

$ curl -i -X POST \
    -d 'fun5()' \
    -H "Content-Type: application/x-lua" \
    https://router.example:5001/v1/lua/debug
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 123
Content-Type: application/json
X-Service-Identity: router.example-5fc78d

{
  "error_msg": "[string \"function f0() ...\"]:2: attempt to call global 'fun5' (a nil value)",
  "return": {
    "lua_type_name": "",
    "value": null
  },
  "stdout": "",
  "success": false
}

Access logging

When the configuration parameter tuning.access_log is set to true, HTTP requests are logged in the common log format (see https://en.wikipedia.org/wiki/Common_Log_Format) and tagged with the matchable field "ACCESSLOG=1" to be retrieved with journalctl:

journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1

Example output

-- Logs begin at Tue 2023-05-23 07:57:16 UTC, end at Mon 2023-05-29 07:25:59 UTC. --
May 29 07:20:00 router[52236]: ::1 - - [29/May/2023:07:20:00 +0000] "GET /vod/batman.m3u8 HTTP/1.1" 302 0 "-" "curl/7.61.1"

Some useful optional arguments to journalctl are:

journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1 [--follow] [-o json-pretty] [--since 2022-06-06] [--until 2022-06-10]
[--grep="HTTP/1.1\" 404"]

See the journalctl documentation for further reading.

Footnotes


  1. The content type of the response is set to “application/json” but the payload is actually a regular string without JSON syntax. ↩︎ ↩︎

3.1.1.5 - Configuration

How to write and deploy configuration for ESB3024 Router

3.1.1.5.1 - Configuration JSON Overview

A brief overview of the configuration JSON and its components

Configuration of ESB3024 Router is done by PUT:ing a JSON object to a REST API located at https://<router-host>:5001/v2/configuration by default.

This document will go through the JSON object, briefly describe its fields and link to more in-depth documentation where appropriate. For information on the JSON language syntax, please refer to the official JSON documentation.

Top-level fields

Here we’ll go through all the fields that may exist at the first level of the JSON object. In the following sections we’ll explore some of them in more detail while some others are complex enough to warrant their own pages.

  • "cdns" (array, objects)
    A list of all CDNs associated with this router, described further down.
  • "content_server" (object)
    Parameters for the content HTTP interface, described further down.
  • "custom_lua" (string)
    Container-specific path to the parent folder under which the /v1/lua/<path str>.lua PUT endpoint will cache the uploaded Lua script files with relative paths as specified by the <path str>.lua argument. Uploaded Lua scripts are then loaded into the Lua environment available in request/response translation functions as well as routing weight functions. The /v1/lua/<path str>.lua PUT endpoint will attempt to create the folder and any required subdirectories on the specified path, should they not exist. Full read-write access for the router need to be maintained to the parent folder, so that the configured folder can be created by the router, to the configured folder itself, its children and every contained .lua script.
  • "hosts" (array, objects)
    A list of all hosts available in the CDNs listed above, described further down.
  • "id" (string)
    Always "ACD", read only.
  • "image_tag" (string)
    A string unique to the version of software installed, read only.
  • "managed_sessions" (object)
    Settings for how to configure managed sessions, described further down.
  • "metadata"(object)
    Contains metadata about the configuration, described further down.
  • "request_translation_function" (string)
    A Lua function body for changing incoming HTTP requests, described further down.
  • "response_translation_function" (string)
    A Lua function body for changing outgoing HTTP responses, described further down.
  • "rest_api_server" (object)
    Settings for the API endpoint used for e.g. PUT:ing the configuration, described further down.
  • "routing" (object)
    Client routing rules, described further down.
  • "session_groups" (array, objects)
    Classification rules for incoming requests, described further down.
  • "settings" (object)
    Settings for functionality that can be enabled or disabled, described further down.
  • "standard_lua" (string)
    Container-specific path to a folder containing pre-installed Lua script files that are loaded into the Lua environment available in request/response translation functions as well as routing weight functions.
  • "tuning" (object)
    Adjustments of timings, log level, thresholds etc, described further down.
  • "version" (string)
    Always "v2", read only.

"cdns"

A list containing CDN definitions. Each object contains the following data:

  • "disabled_hosts" (array, strings)
    Hostnames temporarily taken out of routing, e.g. due to maintenance or because they are known to be broken. For redirecting CDNs, these hosts are added to an Exclude-Host header telling the CDN not to use them.
  • "http_port" (integer)
    The HTTP port the hosts in the CDN listen to.
  • "https_port" (integer)
    The HTTPS port the hosts in the CDN listen to.
  • "id" (string, unique)
    Unique internal name used to reference the CDN within the router.
  • "manifest_availability_check" (object)
    Specifies if a CDN should be checked for manifest availability, and if so for which session groups.
    • "enabled" (boolean)
      Toggle availability check.
    • "session_group_ids" (array, integers)
      List of the session groups for which to perform check.
  • "redirecting" (boolean)
    Setting to true makes the router request a redirect URL from the CDN to forward to the client, otherwise the router constructs its own redirect response with the selected host in the Location header.
  • "response_code_rules" (array, objects)
    List of response actions per matching response code from redirecting CDN. Each object contains the following data:
    • "pattern" (string)
      Sequence of digits and / or wildcards in the form of the letter x. Example: "4xx" which matches response codes 400-499.
    • "action" (string)
      Specifies which action to take when the response code from a redirecting CDN matches the pattern. Valid values are "default", which lets the router proceed as-if no pattern was matching, "continue", to proceed with selecting the next host in the CDN, "redirect" to let the router redirect the request to the URL returned by the redirecting CDN, and "proxy" which returns the response from the redirecting CDN back to the client as-if the response originated from the router itself.
    • "new_response_code" (integer)
      The overridden response code to send back to the client irrespective of "action". It replaces the response code in the otherwise verbatim response for a selected "proxy" action.
  • "timeout_action" (string)
    Specifies which action to take when the request to the redirecting CDN times out without detecting a response. Valid values are "abort" which stops selection, and "continue" which continues with selecting the next host in the CDN.

"content_server"

Settings for the routing interface that clients request content through.

  • "http_enable" (boolean)
    Toggles if HTTP interface is available or not.
  • "http_port" (integer)
    Which port the HTTP interface should listen on.
  • "https_enable" (boolean)
    Toggles if encrypted HTTPS interface is available or not.
  • "https_port" (integer)
    Which port the HTTPS interface should listen on.

"hosts"

A list containing CDN host definitions. Each object contains the following data:

  • "cdn_id" (string)
    A reference to a CDN in the cdns array.
  • "host" (string)
    The IP or hostname for the host.
  • "ipv6_address" (string)
    If the client connects via IPv6 or has put an IPv6 address in the X-Forwarded-For header, then the router will connect to the CDN using the address from ipv6_address. If ipv6_address is not given, the connection will be made using the address from host.
  • "id" (string)
    A unique identifier used in the routing rule tree.
  • "proxy_url" (string)
    When using EDNS routing, the incoming request is sent to a proxy server located at proxy_url that creates and sends an EDNS request based on the client’s HTTP request. A default installation of ESB3024 includes an EDNS proxy located at http://localhost:8888.

"managed_sessions"

Settings for managed client sessions.

  • "fraction" (number)
    The fraction of sessions to be managed, between 0.0 and 1.0.
  • "max_active" (integer)
    The maximum number of active managed sessions.
  • "session_types" (array, objects)
    A list of the various types of managed sessions and their respective settings. Each object contains the following data:
    • "enabled" (boolean)
      description: Toggle this session type.
    • "max_active" (integer)
      The maximum number of active sessions belonging to this session type.
    • "session_group_ids" (array, integers)
      The session groups allowed to belong to this session type, or empty if any.
    • "type" (string)
      The type of managed session. The only valid value is "instream".

"metadata"

Metadata mostly generated from the configuration.

  • "etag" (string)
    The MD5 hash of the configuration’s size in memory.
  • "extra_info" (object)
    This field can store any arbitrary key-value pairs, e.g. to tag or name a configuration. The only configurable field in "metadata".
  • "source_ip" (string)
    The IP address from which the configuration was sent.
  • "timestamp"(string)
    The ISO-8601 formatted timestamp of when the configuration was applied.

"request_translation_function"

The content of this field is a Lua function body that can be used to modify an incoming request before passing it on to be classified and routed. See Lua Hooks for details.

"response_translation_function"

The content of this field is a Lua function body that can be used to modify an outgoing response before it is sent back to the requesting client. See Lua Hooks for details.

"rest_api_server"

Settings for the configuration REST endpoint itself.

  • "enable" (boolean)
    Determines whether the REST API is turned on or not.
  • "port" (integer)
    HTTPS port to listen to.

"routing"

A tree structure of objects setting up a routing algorithm. See Routing Engine for more details.

"session_groups"

A list containing session group definitions. See Session Groups and Classification for details.

"settings"

Various behavioral settings related to content requests and CDN requirements.

  • "reversed_filename_comparison" (object)
    Compares segment filenames from the end when trying to match requests with content. This allows the router to be compatible with CDNs that put e.g. a timestamp first in the filename.
    • "enabled" (boolean)
      Toggle Akamai support on or off.
  • "allowed_clients" (array, strings)
    If non-empty, this array contains all IP:s proxies that are allowed to use the X-Forwarded-For HTTP header.
  • "dash_manifest_rewrite" (object)
    Rewrite DASH manifests to use absolute URLs for clients that don’t support HTTP redirect properly.
    • "enabled" (boolean)
      Enable or disable DASH manifest rewrite.
    • "session_group_ids" (array, integers)
      A list of session groups for which to perform manifest rewrite so it only has to be done for e.g. a set of user agents known to be faulty.
    • "extended_content_identifier" (object)
      Sets a list of query parameters that may be used to identify a specific content along with the path, used for caching.
      • "enabled" (boolean)
        Turns on or off query parameter content identifiers.
      • "included_query_params" (array, strings)
        The list of query parameter names to allow.
  • "hls_manifest_rewrite" (object)
    Rewrite HLS manifests to use absolute URLs for clients that don’t support HTTP redirect properly.
    • "enabled" (boolean)
      Enable or disable DASH manifest rewrite.
    • "session_group_ids" (array, integers)
      A list of session groups for which to perform manifest rewrite so it only has to be done for e.g. a set of user agents known to be faulty.
  • "usage_log" (object)
    Usage logging settings. By default, usage logs such as the number of redirected requests handled during a time period are written to. "/opt/edgeware/acd/router/log/usage.log" unless the environment variable USAGE_LOGGING_DIR has been set to something else.
    • "enabled" (boolean)
      Enables usage logging.
    • "log_interval" (integer)
      Number of milliseconds between each usage log write.

"tuning"

Settings for tuning the behavior of the router.

  • "access_log" (boolean)
    Enable or disable access logging.
  • "content_cache_size_full_manifests" (integer)
    Size of cache for storing full manifests and associated metadata, in number of manifests.
  • "content_cache_size_light_manifests" (integer)
    Size of cache for storing simplified manifest metadata, in number of manifests.
  • "content_light_cache_time_milliseconds" (integer)
    Number of milliseconds before a light manifest content expires.
  • "content_live_cache_time_milliseconds" (integer)
    Number of milliseconds before a full manifest live content expires.
  • "content_vod_cache_time_milliseconds" (integer)
    Number of milliseconds before a full manifest VOD content expires.
  • "cout_flush_rate_milliseconds" (integer)
    How often to flush logs to stdout even if buffer isn’t full to make sure logs arrive at a timely fashion.
  • "cpu_load_window_size" (integer)
    Window size used to calculate a running average of the CPU load.
  • "eager_cdn_switching" (boolean)
    Tells the router to evaluate the routing tree for every request of a session, even if there are no known issues for the client.
  • "http_pipelining_enable" (boolean)
    Allows the router to send requests to the CDN while waiting for responses to earlier requests.
  • "log_level" (integer)
    The verbosity of log printouts. Higher value means more logs: 0 -> Critical, 1 -> Error, 2 -> Warnings, 3 -> Info, 4 -> Debug, 5 -> Trace.
  • "max_connections_per_host" (integer)
    The number of connections the router is allowed to have to a single CDN host.
  • "overload_threshold" (integer)
    How long the task queue may be before router is considered overloaded.
  • "ready_threshold" (integer)
    How short the task queue must become before an overloaded router is no longer considered overloaded.
  • "redirecting_cdn_manifest_download_retries" (integer)
    Number of times the router can try requesting a manifest or redirect location from a CDN before giving up.
  • "repeated_session_start_threshold_seconds" (integer)
    How long time a session must wait between requests to avoid being flagged for repeating requests too often, possibly leading to lowered quality of service.
  • "selection_input_item_limit" (integer)
    The maximum number of key:value items that can be stored on the router using the /v1/selection_input API. Only the leaf values in the input JSON object count towards this limit.
  • "selection_input_metrics_timeout_seconds" (integer)
    How many seconds a value send to the /v1/selection_input API remains before it’s considered obsolete.
  • "session_idle_deactivate_timeout_milliseconds" (integer)
    Number of milliseconds between requests before a session is considered idle.
  • "session_idle_delete_timeout_milliseconds" (integer)
    Number of milliseconds an idle session stays alive to be resumed before it is purged.
  • "target_connect_timeout_seconds" (integer)
    Number of seconds allowed to establish a connection to a CDN.
  • "target_max_idle_time_seconds" (integer)
    Number of seconds a connection to a CDN is kept alive even if no new requests occur.
  • "target_request_attempts" (integer)
    Number of times the router will make requests to different hosts, when it gets 5xx error responses, before giving up and sending an error response to the client.
  • "target_response_timeout_seconds" (integer)
    Number of seconds before a request to a CDN times out.
  • "target_retry_connect_timeout_seconds" (integer)
    Number of seconds allowed when retrying to establish a connection to a CDN.
  • "target_retry_response_timeout_seconds" (integer)
    Number of seconds before a retry request to a CDN times out.

A Full Configuration Example

{
  "cdns": [
    {
      "disabled_hosts": [],
      "http_port": 80,
      "https_port": 443,
      "id": "allowed-cdn",
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      },
      "redirecting": false
    },
    {
      "disabled_hosts": [],
      "http_port": 80,
      "https_port": 443,
      "id": "offload-cdn",
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      },
      "redirecting": false
    }
  ],
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "custom_lua": "/tmp/custom_lua",
  "hosts": [
    {
      "cdn_id": "allowed-cdn",
      "host": "allowed-host4.example",
      "id": "allowed-host-4"
    },
    {
      "cdn_id": "allowed-cdn",
      "host": "allowed-host6.example",
      "id": "allowed-host-6"
    },
    {
      "cdn_id": "offload-cdn",
      "host": "offload-host.example",
      "id": "offload-host"
    }
  ],
  "managed_sessions": {
    "fraction": 0.0,
    "max_active": 0,
    "session_types": [
      {
        "enabled": false,
        "max_active": 0,
        "session_group_ids": [],
        "type": "instream"
      }
    ]
  },
  "metadata": {
    "extra_info": {
      "field_1": "value_1",
      "config_name": "large_config",
      "purpose": "demonstration",
      "arbitrary": "value"
    }
  },
  "request_translation_function": "",
  "response_translation_function": "",
  "rest_api_server": {
    "enable": true,
    "port": 5001
  },
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "test-subnet-name",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "print(tostring(request.subnet)); return 0"
      },
      {
        "id": "test-host-4",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "retval = request.subnet == 'test_net_4' and 1 or 0;\
            if retval == 1 then print('### ipv4') end; return 0"
      },
      {
        "id": "test-host-6",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "retval = request.subnet == 'test_net_6' and 1 or 0;\
            if retval == 1 then print('### ipv6') end; return 0"
      },
      {
        "id": "test-offload",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "retval = ((request.subnet == 'test_net_6')\
            or (request.subnet == 'test_net_4')) and 1 or 0;\
            if retval == 0 then print('### offload') end; return 0"
      },
      {
        "id": "allowed-host-4",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "return request.subnet == 'test_net_4' and 1 or 0"
      },
      {
        "id": "allowed-host-6",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "return request.subnet == 'test_net_6' and 1 or 0"
      },
      {
        "id": "offlaod-host",
        "member_order": "weighted",
        "members": [],
        "url_rewrite_function": "",
        "weight_function": "return 1"
      }
    ],
    "url_rewrite_function": "",
    "weight_function": "return 100"
  },
  "session_groups": [
    {
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "hls",
            "rule": {
              "pattern": "/([^\\.]+)\\.news_reports_\\d+/\\.example\\.com.*",
              "rule_type": "regex_rule",
              "source": "session/content_url_path"
            }
          }
        ]
      ],
      "id": 1,
      "name": "hls"
    },
    {
      "classifiers": [
        [
          {
            "id": 2,
            "inverted": false,
            "name": "vod",
            "rule": {
              "pattern": "*vod*",
              "rule_type": "string_match_rule",
              "source": "session/content_url_path"
            }
          }
        ]
      ],
      "id": 2,
      "name": "vod"
    },
    {
      "classifiers": [
        [
          {
            "id": 5,
            "inverted": true,
            "name": "offload_no_peering_subnet",
            "rule": {
              "ip_ranges": [
                "158.174.0.0/16",
                "95.192.0.0/12"
              ],
              "rule_type": "ip_ranges_rule",
              "source": "session/client_ip"
            }
          }
        ]
      ],
      "id": 5,
      "name": "offload_no_peering_subnet"
    },
    {
      "classifiers": [
        [
          {
            "id": 6,
            "inverted": true,
            "name": "offload_country_name",
            "rule": {
              "country": "Sweden",
              "rule_type": "geoip_rule",
              "source": "session/client_ip"
            }
          }
        ]
      ],
      "id": 6,
      "name": "offload_country_name"
    },
    {
      "classifiers": [
        [
          {
            "id": 7,
            "inverted": false,
            "name": "onload_city_name",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip"
            }
          }
        ]
      ],
      "id": 7,
      "name": "onload_city_name"
    },
    {
      "classifiers": [
        [
          {
            "id": 8,
            "inverted": false,
            "name": "offload_no_peering_asn_name",
            "rule": {
              "asn": "Tele*",
              "rule_type": "geoip_rule",
              "source": "session/client_ip"
            }
          }
        ]
      ],
      "id": 8,
      "name": "offload_no_peering_asn_name"
    }
  ],
  "settings": {
    "reversed_filename_comparison": {
      "enabled": false
    },
    "dash_manifest_rewrite": {
      "enabled": false,
      "session_group_ids": []
    },
    "extended_content_identifier": {
      "enabled": false,
      "included_query_params": []
    },
    "hls_manifest_rewrite": {
      "enabled": false,
      "session_group_ids": []
    }
  },
  "standard_lua": "/tmp/standard_lua",
  "tuning": {
    "access_log": false,
    "content_cache_size_full_manifests": 1000,
    "content_cache_size_light_manifests": 10000,
    "content_light_cache_time_milliseconds": 86400000,
    "content_live_cache_time_milliseconds": 5000,
    "content_vod_cache_time_milliseconds": 10000,
    "cout_flush_rate_milliseconds": 1000,
    "cpu_load_window_size": 10,
    "eager_cdn_switching": false,
    "http_pipelining_enable": false,
    "log_level": 5,
    "max_connections_per_host": 5,
    "overload_threshold": 32,
    "ready_threshold": 8,
    "redirecting_cdn_manifest_download_retries": 2,
    "repeated_session_start_threshold_seconds": 30,
    "selection_input_metrics_timeout_seconds": 86400,
    "session_idle_deactivate_timeout_milliseconds": 20000,
    "session_idle_delete_timeout_milliseconds": 1800000,
    "target_connect_timeout_seconds": 1,
    "target_max_idle_time_seconds": 30,
    "target_request_attempts": 2,
    "target_response_timeout_seconds": 1,
    "target_retry_connect_timeout_seconds": 2,
    "target_retry_response_timeout_seconds": 2
  }
}

3.1.1.5.2 - WebUI Configuration

How to use the web user interface for configuration.

The web based user interface is installed as a separate component and can be used to configure many common use cases. After navigating to the UI, a login screen will be presented.

Login Screen

Enter your credentials and log in. In the top left corner is a menu to select what section of the configuration to change. The configuration that will be active on the router is added in the Routing Workflow view. However, basic elements such as classification rules and routing targets, etc must be added first. Hence the following main steps are required to produce a proper configuration:

  1. Create classifiers serving as basic elements to create session groups.
  2. Create session groups which, using the classifiers, tag requests/clients for later use in the routing logic. of the incoming traffic.
  3. Define offload rules.
  4. Define rules to control behavior of internal traffic.
  5. Define backup rules to be used if the routing targets in the above step are unavailable.
  6. Finally, create the desired routing workflow using the elements defined in the previous steps.

A simplified concrete example of the above steps could be:

  • Create two classifiers “smartphone” and “off-net”.
  • Create a session group “mobile off-net”.
  • Offload off-net traffic from mobile phones to a public CDN.
  • Route other traffic to a private CDN.
  • If the private CDN has an outage, use the public CDN for all traffic.

Hence, to start with, define the classifiers you will need. Those are based on information in the incoming request, optionally in combination with GeoIP databases or subnet information configured via the Subnet API. Here we show how to set up a GeoIP classifier. Note that the Director ships with a compatible snapshot of the GeoIP database, but for a production system a licensed and updated database is required.

GeoIP Classifier

Click the plus sign indicated in the picture above to create a new GeoIP classifier. You will be presented with the following view:

GeoIP Classifier Create

Here you can enter the geographical data on which to match, or check the “Inverted” check box to match anything except the entered geographical data.

The other kinds of classifiers are configured in a similar way.

After having added all the classifiers you need, it is time to create the session groups. Those are named filters that group incoming requests, typically video playback sessions in a video streaming CDN, and are defined with the help of the classifiers. For example, a session group “off-net mobile devices” could be composed of the classifiers “off-net traffic” and “mobile devices”.

Open the Session Groups view from the menu and hit the plus sign to add a new session group.

Session Groups Session Group Create

Define the new sessions groups by combining the previously created classifiers. It is often convenient to define an “All” session group that matches any incoming request.

Next go the “CDN Offload” view:

CDN Offload

Here you define conditions for CDN offload. Each row defines a rule for offloading a specified session group. The rule makes use of the Selection Input API. This is an integration API that provides a way to supply additional data for use in the routing decision. Common examples are current bitrates or availability status. The selection input variables to use must be defined in the “Selection Input Types” view in the “Administration” section of the menu:

Selection Input Types

Reach out to the solution engineers from Agile Content in order to perform this integration in the best way. If no external data is required, such that the offload rule can be based solely based on session groups, this is not necessary and the condition field can be set to “Always” or “Disabled”.

When clicking the plus sign to add a new CDN Offload rule, the following view is presented:

CDN Offload Create

The selection input rule is phrased in terms of a variable being above or below a threshold, but also a state such as “available” taking values 0 or 1 can be supported by for instance checking if “available” is below 1.

Moving on, if an incoming request is not offloaded, it will be handled by the Primary CDN section of the routing configuration.

Primary CDN

Add all hosts in your primary CDN, together with a weight. A row in this table will be selected by random weighted load balancing. If each weight is the same, each row will be selected with the same probability. Another example would be three rows with weights 100, 100 and 200 which would randomly balance 50% of the load on the last row and the remaining load on the first two rows, i.e. 25% on each of the first and second row. If a Primary CDN host is unavailable, that host will not take part in the random selection.

If all hosts are unavailable, as a final resort the routing evaluation will go to the final Backup CDN step:

Backup CDN

Here you can define what to do when all else fail. If not all requests are covered, for example with an “All” session group, then the request will fail with 403 Forbidden.

Now you have defined the basic elements and it is time to define the routing workflow. Select “Routing Workflow” from the menu, as pictured below. Here you can combine the elements previously created to achieve the desired routing behavior.

Routing Workflow

When everything seems correct, open the “Publish Routing” view from the menu:

Publish Routing

Hit “Publish All Changes” and verify that you get a successful result.

3.1.1.5.3 - Confd and Confcli

Using the command line tool confcli to set up routing rules

Configuration of a complex routing tree can be difficult. The command line interface tool called confcli has been developed to make it simpler. It combines building blocks, representing simple routing decisions, into complex routing trees capable of satisfying almost any routing requirements.

These blocks are translated into an ESB3024 Router configuration which is automatically sent to the router, overwriting existing routing rules, CDN list and host list.

Installation and Usage

The confcli tools are installed alongside ESB3024 Router, on the same host, and the confcli command line tool itself is made available on the host machine.

Simply type confcli in a shell on the host to see the current routing configuration:

$ confcli
{
    "services": {
        "routing": {
            "settings": {
                "allowedProxies": [],
                "contentPopularity": {
                    "algorithm": "score_based",
                    "sessionGroupNames": []
                },
                "extendedContentIdentifier": {
                    "enabled": false,
                    "includedQueryParams": []
                },
                "instream": {
                    "dashManifestRewrite": {
                        "enabled": false,
                        "sessionGroupNames": []
                    },
                    "hlsManifestRewrite": {
                        "enabled": false,
                        "sessionGroupNames": []
                    },
                    "reversedFilenameComparison": false
                },
                "usageLog": {
                    "enabled": false,
                    "logInterval": 3600000
                }
            },
            "tuning": {
                "content": {
                    "cacheSizeFullManifests": 1000,
                    "cacheSizeLightManifests": 10000,
                    "lightCacheTimeMilliseconds": 86400000,
                    "liveCacheTimeMilliseconds": 100,
                    "vodCacheTimeMilliseconds": 10000
                },
                "general": {
                    "accessLog": false,
                    "coutFlushRateMilliseconds": 1000,
                    "cpuLoadWindowSize": 10,
                    "eagerCdnSwitching": false,
                    "httpPipeliningEnable": false,
                    "logLevel": 3,
                    "maxConnectionsPerHost": 5,
                    "overloadThreshold": 32,
                    "readyThreshold": 8,
                    "redirectingCdnManifestDownloadRetries": 2,
                    "repeatedSessionStartThresholdSeconds": 30,
                    "selectionInputMetricsTimeoutSeconds": 30
                },
                "session": {
                    "idleDeactivateTimeoutMilliseconds": 20000,
                    "idleDeleteTimeoutMilliseconds": 1800000
                },
                "target": {
                    "responseTimeoutSeconds": 5,
                    "retryConnectTimeoutSeconds": 2,
                    "retryResponseTimeoutSeconds": 2,
                    "connectTimeoutSeconds": 5,
                    "maxIdleTimeSeconds": 30,
                    "requestAttempts": 3
                }
            },
            "sessionGroups": [],
            "classifiers": [],
            "hostGroups": [],
            "rules": [],
            "entrypoint": "",
            "applyConfig": true
        }
    }
}

The CLI tool can be used to modify, add and delete values by providing it with the “path” to the object to change. The path is constructed by joining the field names leading up to the value with a period between each name, e.g. the path to the entrypoint is services.routing.entrypoint since entrypoint is nested under the routing object, which in turn is under the services root object. Lists use an index number in place of a field name, where 0 indicates the very first element in the list, 1 the second element and so on.

If the list contains objects which have a field with the name name, the index number can be replaced by the unique name of the object of interest.

Tab completion is supported by confcli. Pressing tab once will complete as far as possible, and pressing tab twice will list all available alternatives at the path constructed so far.

Display the values at a specific path:

$ confcli services.routing.hostGroups
{
    "hostGroups": [
        {
            "name": "internal",
            "type": "redirecting",
            "httpPort": 80,
            "httpsPort": 443,
            "hosts": [
                {
                    "name": "rr1",
                    "hostname": "rr1.example.com",
                    "ipv6_address": ""
                }
            ]
        },
        {
            "name": "external",
            "type": "host",
            "httpPort": 80,
            "httpsPort": 443,
            "hosts": [
                {
                    "name": "offload-streamer1",
                    "hostname": "streamer1.example.com",
                    "ipv6_address": ""
                },
                {
                    "name": "offload-streamer2",
                    "hostname": "streamer2.example.com",
                    "ipv6_address": ""
                }
            ]
        }
    ]
}

Display the values in a specific list index:

$ confcli services.routing.hostGroups.1
{
    "1": {
        "name": "external",
        "type": "host",
        "httpPort": 80,
        "httpsPort": 443,
        "hosts": [
            {
                "name": "offload-streamer1",
                "hostname": "streamer1.example.com",
                "ipv6_address": ""
            },
            {
                "name": "offload-streamer2",
                "hostname": "streamer2.example.com",
                "ipv6_address": ""
            }
        ]
    }
}

Display the values in a specific list index using the object’s name:

$ confcli services.routing.hostGroups.1.hosts.offload-streamer2
{
    "offload-streamer2": {
        "name": "offload-streamer2",
        "hostname": "streamer2.example.com",
        "ipv6_address": ""
    }
}

Modify a single value:

confcli services.routing.hostGroups.1.hosts.offload-streamer2.hostname new-streamer.example.com
services.routing.hostGroups.1.hosts.offload-streamer2.hostname = 'new-streamer.example.com'

Delete an entry:

$ confcli services.routing.sessionGroups.Apple.classifiers.
{
    "classifiers": [
        "Apple",
        ""
    ]
}

$ confcli services.routing.sessionGroups.Apple.classifiers.1 -d
http://localhost:5000/config/__active/services/routing/sessionGroups/Apple/classifiers/1 reset to default/deleted

$ confcli services.routing.sessionGroups.Apple.classifiers.
{
    "classifiers": [
        "Apple"
    ]
}

Adding new values in objects and lists is done using a wizard by invoking confcli with a path and the -w argument. This will be shown extensively in the examples further down in this document rather than here.

If you have a JSON file with a previously generated confcli configuration output it can be applied to a system by typing confcli -i <file path>.

Session Classification

In order to perform routing it is necessary to classify incoming sessions according to the relevant parameters. This is done through session groups and their associated classifiers.

There are different ways of classifying a request:

  • Strings with wildcards: Simple case-insensitive string pattern with support for adding asterisks (’*’) in order to match any value at that point in the pattern.
  • String with regular expressions: A complex string matching pattern capable of matching more complicated strings than the simple wildcard matching type.

Valid string matching sources are content_url_path, content_url_query_parameters, hostname and user_agent, examples of which will be shown below.

  • GeoIP: Based on the geographic location of the client, supporting wildcard matching. Geographic location data is provided by MaxMind. The possible values to match with are any combinations of:
    • Continent
    • Country
    • Cities
    • ASN
  • IP range: Based on whether a client’s IP belongs to a set of IP ranges or not.
  • Subnet: Tests if a client’s IP belongs to a named subnet, see Subnets for more details.
  • ASN ID list: Checks to see if a client’s IP belongs to any of the specified ASN IDs.

A session group may have more than one classifier. If it does, all the classifiers must match the incoming client request for it to belong to the session group. It is also possible for a request to belong to multiple session groups, or to none.

To send certain clients to a specific host you first need to create a suitable classifier using confcli in wizard mode. The wizard will guide you through the process of creating a new entry, asking you what value to input for each field and helping you by telling you what inputs are allowed for restricted fields such as the string comparison source mentioned above:

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 3
  Adding a 'geoip' element
    classifier : {
      name (default: ): sweden_matcher
      type (default: geoip): ⏎
      inverted (default: False): ⏎
      continent (default: ): ⏎
      country (default: ): sweden
      cities : [
        city (default: ): ⏎
        Add another 'city' element to array 'cities'? [y/N]: ⏎
      ]
      asn (default: ): ⏎
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "sweden_matcher",
      "type": "geoip",
      "inverted": false,
      "continent": "",
      "country": "sweden",
      "cities": [
        ""
      ],
      "asn": ""
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 5
  Adding a 'ipranges' element
    classifier : {
      name (default: ): company_matcher
      type (default: ipranges): ⏎
      inverted (default: False): ⏎
      ipranges : [
        iprange (default: ): 90.128.0.0/12
        Add another 'iprange' element to array 'ipranges'? [y/N]: ⏎
      ]
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "company_matcher",
      "type": "ipranges",
      "inverted": false,
      "ipranges": [
        "90.128.0.0/12"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 7
  Adding a 'stringMatcher' element
    classifier : {
      name (default: ): apple_matcher
      type (default: stringMatcher): ⏎
      inverted (default: False): ⏎
      source (default: content_url_path): user_agent
      pattern (default: ): *apple*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "apple_matcher",
      "type": "stringMatcher",
      "inverted": false,
      "source": "user_agent",
      "pattern": "*apple*"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 6
  Adding a 'regexMatcher' element
    classifier : {
      name (default: ): content_matcher
      type (default: regexMatcher): ⏎
      inverted (default: False): ⏎
      source (default: content_url_path): ⏎
      pattern (default: ): .*/(live|news_channel)/.*m3u8
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "content_matcher",
      "type": "regexMatcher",
      "inverted": false,
      "source": "content_url_path",
      "pattern": ".*/(live|news_channel)/.*m3u8"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: subnet
  Adding a 'subnet' element
    classifier : {
      name (default: ): company_matcher
      type (default: subnet): ⏎
      inverted (default: False): ⏎
      pattern (default: ): company
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "company_matcher",
      "type": "subnet",
      "inverted": false,
      "pattern": "company"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 4
  Adding a 'hostName' element
    classifier : {
      name (default: ): host_name_classifier
      type (default: hostName): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *live.example*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
  "classifiers": [
    {
      "name": "host_name_classifier",
      "type": "hostName",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*live.example*"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 1
  Adding a 'contentUrlPath' element
    classifier : {
      name (default: ): vod_matcher
      type (default: contentUrlPath): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *vod*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
  "classifiers": [
    {
      "name": "vod_matcher",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*vod*"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 2
  Adding a 'contentUrlQueryParameters' element
    classifier : {
      name (default: ): bitrate_matcher
      type (default: contentUrlQueryParameters): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): regex
      pattern (default: ): .*bitrate=100000.*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
  "classifiers": [
    {
      "name": "bitrate_matcher",
      "type": "contentUrlQueryParameters",
      "inverted": false,
      "patternType": "regex",
      "pattern": ".*bitrate=100000.*"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 9
  Adding a 'userAgent' element
    classifier : {
      name (default: ): iphone_matcher
      type (default: userAgent): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): regex
      pattern (default: ): i(P|p)hone
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
  "classifiers": [
    {
      "name": "iphone_matcher",
      "type": "userAgent",
      "inverted": false,
      "patternType": "regex",
      "pattern": "i(P|p)hone"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: asnIds
    2: contentUrlPath
    3: contentUrlQueryParameters
    4: geoip
    5: hostName
    6: ipranges
    7: regexMatcher
    8: stringMatcher
    9: subnet
    10: userAgent
  Choose element index or name: asnIds
  Adding a 'asnIds' element
    classifier : {
      name (default: ): asn_matcher
      type (default: asnIds): ⏎
      inverted (default: False): ⏎
      asnIds <The list of ASN IDs to accept. (default: [])>: [
        asnId: 1
        Add another 'asnId' element to array 'asnIds'? [y/N]: y
        asnId: 2
        Add another 'asnId' element to array 'asnIds'? [y/N]: y
        asnId: 3
        Add another 'asnId' element to array 'asnIds'? [y/N]: ⏎
      ]
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "asn_matcher",
      "type": "asnIds",
      "inverted": false,
      "asnIds": [
        1,
        2,
        3
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  

These classifiers can now be used to construct session groups and properly classify clients. Using the examples above, let’s create a session group classifying clients from Sweden using an Apple device:

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): inSwedenUsingAppleDevice
    classifiers : [
      classifier (default: ): sweden_matcher
      Add another 'classifier' element to array 'classifiers'? [y/N]: y
      classifier (default: ): apple_matcher
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "inSwedenUsingAppleDevice",
      "classifiers": [
        "sweden_matcher",
        "apple_matcher"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Clients classified by the sweden_matcher and apple_matcher classifiers will now be put in the session group inSwedenUsingAppleDevice. Using session groups in routing will be demonstrated later in this document.

Advanced Classification

The above example will simply apply all classifiers in the list, and as long as they all evaluate to true for a session, that session will be tagged with the session group. For situations where this isn’t enough, classifiers can instead be combined using simple logic statements to form complex rules.

A first simple example can be a session group that accepts any viewers in either ASN 1, 2 or 3 (corresponding to the classifier asn_matcher or living in Sweden. This can be done by creating a session group, and adding the following logic statement:

'sweden_matcher' OR 'asn_matcher'

A slightly more advanced case is where a session group should only contain sessions neither in any of the three ASNs nor in Sweden. This is done by negating the previous example:

NOT ('sweden_matcher' OR 'asn_matcher')

A single classifier can also be negated, rather than the whole statement, for example to accept any Swedish viewers except those in the three ASNs:

'sweden_matcher' AND NOT 'asn_matcher'

Arbitrarily complex statements can be created using classifier names, parentheses, and the keywords AND, OR and NOT.

For example a session group accepting any Swedish viewers except those in the Stockholm region unless they are also Apple users:

'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')

Note that the classifier names must be enclosed in single quotes when using this syntax.

Applying this kind of complex classifier using confcli is no more difficult than adding a single classifier at a time:

$ confcli services.routing.sessionGroups. -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): complex_group
    classifiers : [
      classifier (default: ): 'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "complex_group",
      "classifiers": [
        "'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  

CDNs and Hosts

Configuration using confcli has no real concept of CDNs, instead it has groups of hosts that share some common settings such as HTTP(S) port and whether they return a redirection URL, serve content directly or perform a DNS lookup. Of these three variants, the two former share the same parameters, while the DNS variant is slightly different.

Each host belongs to a host group and may itself be an entire CDN using a single public hostname or a single streamer server, all depending on the needs of the user.

Host Health

When creating a host in the confd configuration, you have the option to define a list of health check functions. Each health check function must return true for a host to be selected. This means that the host will only be considered available if all the defined health check functions evaluate to true. If any of the health check functions return false, the host will be considered unavailable and will not be selected for routing. All health check functions are detailed in the section Health Check Functions.

$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 3
  Adding a 'redirecting' element
    hostGroup : {
      name (default: ): edgeware
      type (default: redirecting): ⏎
      httpPort (default: 80): ⏎
      httpsPort (default: 443): ⏎
      hosts : [
        host : {
          name (default: ): rr1
          hostname (default: ): convoy-rr1.example.com
          ipv6_address (default: ): ⏎
          healthChecks : [
            healthCheck (default: always()): basic_health_check()
            Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
          ]
        }
        Add another 'host' element to array 'hosts'? [y/N]: y
        host : {
          name (default: ): rr2
          hostname (default: ): convoy-rr2.example.com
          ipv6_address (default: ): ⏎
          healthChecks : [
            healthCheck (default: always()): ⏎
            Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
          ]
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "edgeware",
      "type": "redirecting",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "rr1",
          "hostname": "convoy-rr1.example.com",
          "ipv6_address": "",
          "healthChecks": [
            "basic_health_check()"
          ]
        },
        {
          "name": "rr2",
          "hostname": "convoy-rr2.example.com",
          "ipv6_address": "",
          "healthChecks": [
            "always()"
          ]
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 1
  Adding a 'dns' element
    hostGroup : {
      name (default: ): external-dns
      type (default: dns): ⏎
      hosts : [
        host : {
          name (default: ): dns-host
          hostname (default: ): dns.example.com
          ipv6_address (default: ): ⏎
          healthChecks : [
            healthCheck (default: always()): ⏎
            Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
          ]
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "external-dns",
      "type": "dns",
      "hosts": [
        {
          "name": "dns-host",
          "hostname": "dns.example.com",
          "ipv6_address": "",
          "healthChecks": [
            "always()"
          ]
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  

Rule Blocks

The routing configuration using confcli is done using a combination of logical building blocks, or rules. Each block evaluates the incoming request in some way and sends it on to one or more sub-blocks. If the block is of the host type described above, the client is sent to that host and the evaluation is done.

Existing blocks

Currently supported blocks are:

  • allow: Incoming requests, for which a given rule function matches, are immediately sent to the provided onMatch target.
  • consistentHashing: Splits incoming requests randomly between preferred hosts, determined by the proprietary consistent hashing algorithm. The amount of hosts to split between is controlled by the spreadFactor.
  • contentPopularity: Splits incoming requests into two sub-blocks depending on how popular the requested content is.
  • deny: Incoming requests, for which a given rule function matches, are immediately denied, and all non-matching requests are sent to the onMiss target.
  • firstMatch: Incoming requests are matched by an ordered series of rules, where the request will be handled by the first rule for which the condition evaluates to true.
  • random: Splits incoming requests randomly and equally between a list of target sub-blocks. Useful for simple load balancing.
  • split: Splits incoming requests between two sub-blocks depending on how the request is evaluated by a provided function. Can be used for sending clients to different hosts depending on e.g. geographical location or client hardware type.
  • weighted: Randomly splits incoming requests between a list of target sub-blocks, weighted according to each target’s associated weight rule. A higher weight means a higher portion of requests will be routed to a sub-block. Rules can be used to decide whether or not to pick a target.
  • rawGroup: Contains a raw ESB3024 Router configuration routing tree node, to be inserted as is in the generated configuration. This is only meant to be used in the rare cases when it’s impossible to construct the required routing behavior in any other way.
  • rawHost: A host reference for use as endpoints in rawGroup trees.
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: allow
  Adding a 'allow' element
    rule : {
      name (default: ): allow
      type (default: allow): ⏎
      condition (default: ): customFunction()
      onMatch (default: ): rr1
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "content",
      "type": "contentPopularity",
      "condition": "customFunction()",
      "onMatch": "rr1"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: consistentHashing
  Adding a 'consistentHashing' element
    rule : {
      name (default: ): consistentHashingRule
      type (default: consistentHashing): 
      spreadFactor (default: 1): 2
      targets : [
        target : {
          target (default: ): rr1
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): rr2
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): rr3
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "consistentHashingRule",
      "type": "consistentHashing",
      "spreadFactor": 2,
      "targets": [
        {
          "target": "rr1",
          "enabled": true
        },
        {
          "target": "rr2",
          "enabled": true
        },
        {
          "target": "rr3",
          "enabled": true
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: contentPopularity
  Adding a 'contentPopularity' element
    rule : {
      name (default: ): content
      type (default: contentPopularity): ⏎
      contentPopularityCutoff (default: 10): 20
      onPopular (default: ): rr1
      onUnpopular (default: ): rr2
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "content",
      "type": "contentPopularity",
      "contentPopularityCutoff": 20.0,
      "onPopular": "rr1",
      "onUnpopular": "rr2"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: deny
  Adding a 'deny' element
    rule : {
      name (default: ): deny
      type (default: deny): ⏎
      condition (default: ): customFunction()
      onMiss (default: ): rr1
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "content",
      "type": "contentPopularity",
      "condition": "customFunction()",
      "onMiss": "rr1"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): firstMatch
      type (default: firstMatch): ⏎
      targets : [
        target : {
          onMatch (default: ): rr1
          rule (default: ): customFunction()
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): rr2
          rule (default: ): otherCustomFunction()
        }
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "firstMatch",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "rr1",
          "condition": "customFunction()"
        },
        {
          "onMatch": "rr2",
          "condition": "otherCustomFunction()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: random
  Adding a 'random' element
    rule : {
      name (default: ): random
      type (default: random): ⏎
      targets : [
        target (default: ): rr1
        Add another 'target' element to array 'targets'? [y/N]: y
        target (default: ): rr2
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "random",
      "type": "random",
      "targets": [
        "rr1",
        "rr2"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): split
      type (default: split): ⏎
      condition (default: ): custom_function()
      onMatch (default: ): rr2
      onMiss (default: ): rr1
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "split",
      "type": "split",
      "condition": "custom_function()",
      "onMatch": "rr2",
      "onMiss": "rr1"
    }
  ]
}
Merge and apply the config? [y/n]: y
  
$ confcli services.routing.rules. -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: weighted
  Adding a 'weighted' element
    rule : {
      name (default: ): weight
      type (default: weighted): ⏎
      targets : [
        target : {
          target (default: ): rr1
          weight (default: 100): ⏎
          condition (default: always()): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): rr2
          weight (default: 100): si('rr2-input-weight')
          condition (default: always()): gt('rr2-bandwidth', 1000000)
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): rr2
          weight (default: 100): custom_func()
          condition (default: always()): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "weight",
      "type": "weighted",
      "targets": [
        {
          "target": "rr1",
          "weight": "100",
          "condition": "always()"
        },
        {
          "target": "rr2",
          "weight": "si('rr2-input-weight')",
          "condition": "gt('rr2-bandwith', 1000000)"
        },
        {
          "target": "rr2",
          "weight": "custom_func()",
          "condition": "always()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  
>> First add a raw host block that refers to a regular host

$ confcli services.routing.rules. -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: rawHost
  Adding a 'rawHost' element
    rule : {
      name (default: ): raw-host
      type (default: rawHost): ⏎
      hostId (default: ): rr1
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "raw-host",
      "type": "rawHost",
      "hostId": "rr1"
    }
  ]
}
Merge and apply the config? [y/n]: y

>> And then add a rule using the host node

$ confcli services.routing.rules. -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: rawGroup
  Adding a 'rawGroup' element
    rule : {
      name (default: ): raw-node
      type (default: rawGroup): ⏎
      memberOrder (default: sequential): ⏎
      members : [
        member : {
          target (default: ): raw-host
          weightFunction (default: ): return 1
        }
        Add another 'member' element to array 'members'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "raw-node",
      "type": "rawGroup",
      "memberOrder": "sequential",
      "members": [
        {
          "target": "raw-host",
          "weightFunction": "return 1"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
  

Rule Language

Some blocks, such as the split and firstMatch types, have a rule field that contains a small function in a very simple programming language. This field is used to filter any incoming client requests in order to determine how to rule block should react.

In the case of a split block, the rule is evaluated and if it is true the client is sent to the onMatch part of the block, otherwise it is sent to the onMiss part for further evaluation.

In the case of a firstMatch block, the rule for each target will be evaluated top to bottom in order until either a rule evaluates to true or the list is exhausted. If a rule evaluates to true, the client will be sent to the onMatch part of the block, otherwise the next target in the list will be tried. If all targets have been exhausted, then the entire rule evaluation will fail, and the routing tree will be restarted with the firstMatch block effectively removed.

Example of Boolean Functions

Let’s say we have an ESB3024 Router set up with a session group that matches Apple devices (named “Apple”). To route all Apple devices to a specific streamer one would simply create a split block with the following rule:

in_session_group('Apple')

In order to make more complex rules it’s possible to combine several checks like this in the same rule. Let’s extend the hypothetical ESB3024 Router above with a configured subnet with all IP addresses in Europe (named “Europe”). To make a rule that accepts any clients using an Apple device and living outside of Europe, but only as long as the reported load on the streamer (as indicated by the selection input variable “europe_load_mbps”) is less than 1000 megabits per second one could make an offload block with the following rule (without linebreaks):

in_session_group('Apple')
    and not in_subnet('Europe')
    and lt('europe_load_mbps', 1000)

In this example in_session_group('Apple') will be true if the client belongs to the session group named ‘Apple’. The function call in_subnet('Europe') is true if the client’s IP belongs to the subnet named ‘Europe’, but the word not in front of it reverses the value so the entire section ends up being false if the client is in Europe. Finally lt('europe_load_mbps', 1000) is true if there is a selection input variable named “europe_load_mbps” and its value is less than 1000.

Since the three parts are conjoined with the and keyword they must all be true for the entire rule to match. If the keyword or had been used instead it would have been enough for any of the parts to be true for the rule to match.

Example of Numeric Functions

A hypothetical CDN has two streamers with different capacity; Host_1 has roughly twice the capacity of Host_2. A simple random load balancing would put undue stress on the second host since it will receive as much traffic as the more capable Host_1.

This can be solved by using a weighted random distribution rule block with suitable rules for the two hosts:

{
    "targets": [
        {
            "target": "Host_1",
            "condition": "always()",
            "weight": "100"
        }
        {
            "target": "Host_2",
            "condition": "always()",
            "weight": "50"
        },
    ]
}

resulting in Host_1 receiving twice as many requests as Host_2 as its weight function is double that of Host_2.

If the CDN is capable of reporting the free capacity of the hosts, for example by writing to a selection input variable for each host, it’s easy to write a more intelligent load balancing rule by making the weights correspond to the amount of capacity left on each host:

{
    "targets": [
        {
            "target": "Host_1",
            "condition": "always()",
            "weight": "si('free_capacity_host_1')"
        }
        {
            "target": "Host_2",
            "condition": "always()",
            "weight": "si('free_capacity_host_2')"
        },
    ]
}

It is also possible to write custom Lua functions that return suitable weights, perhaps taking the host as an argument:

{
    "targets": [
        {
            "target": "Host_1",
            "condition": "always()",
            "weight": "intelligent_weight_function('Host_1')"
        }
        {
            "target": "Host_2",
            "condition": "always()",
            "weight": "intelligent_weight_function('Host_1')"
        },
    ]
}

These different weight rules can of course be combined in the same rule block, with one target having a hard coded number, another using a dynamically updated selection input variable and yet another having a custom-built function.

Due to limitations in the random number generator used to distribute requests, it’s better to use somewhat large values, around 100–1000 or so, than to use small values near 0.

Built-in Functions

The following built-in functions are available when writing rules:

  • in_session_group(str name): True if session belongs to session group <name>
  • in_all_session_groups(str sg_name, ...): True if session belongs to all specified session groups
  • in_any_session_group(str sg_name, ...): True if session belongs to any specified session group
  • in_subnet(str subnet_name): True if client IP belongs to the named subnet
  • gt(str si_var, number value): True if selection_inputs[si_var] > value
  • gt(str si_var1, str si_var2): True if selection_inputs[si_var1] > selection_inputs[si_var2]
  • ge(str si_var, number value): True if selection_inputs[si_var] >= value
  • ge(str si_var1, str si_var2): True if selection_inputs[si_var1] >= selection_inputs[si_var2]
  • lt(str si_var, number value): True if selection_inputs[si_var] < value
  • lt(str si_var1, str si_var2): True if selection_inputs[si_var1] < selection_inputs[si_var2]
  • le(str si_var, number value): True if selection_inputs[si_var] <= value
  • le(str si_var1, str si_var2): True if selection_inputs[si_var1] <= selection_inputs[si_var2]
  • eq(str si_var, number value): True if selection_inputs[si_var] == value
  • eq(str si_var1, str si_var2): True if selection_inputs[si_var1] == selection_inputs[si_var2]
  • neq(str si_var, number value): True if selection_inputs[si_var] != value
  • neq(str si_var1, str si_var2): True if selection_inputs[si_var1] != selection_inputs[si_var2]
  • si(str si_var): Returns the value of selection_inputs[si_var] if it is defined and non-negative, otherwise it returns 0.
  • always(): Returns true, useful when creating weighted rule blocks.
  • never(): Returns false, opposite of always().

These functions, as well as custom functions written in Lua and uploaded to the ESB3024 Router, can be combined to make suitably precise rules.

Combining Multiple Boolean Functions

In order to make the rule language easy to work with, it is fairly restricted and simple. One restriction is that it’s only possible to chain multiple function results together using either and or or, but not a combination of both conjunctions.

Statements joined with and or or keywords are evaluated one by one, starting with the left-most statement and moving right. As soon as the end result of the entire expression is certain, the evaluation ends. This means that evaluation ends with the first false statement for and expressions since a single false component means the entire expression must also be false. It also means that evaluation ends with the first true statement for or expressions since only one component must be true for the entire statement to be true as well. This is known as short-circuit or lazy evaluation.

Custom Functions

It is possible to write extremely complex Lua functions that take many parameters or calculations into consideration when evaluating an incoming client request. By writing such functions and making sure that they return only non-negative integer values and uploading them to the router they can be used from the rule language. Simply call them like any of the built-in functions listed above, using strings and numbers as arguments if necessary, and their result will be used to determine the routing path to use.

Formal Syntax

The full syntax of the language can be described in just a few lines of BNF grammar:

<rule>               := <weight_rule> | <match_rule> | <value_rule>
<weight_rule>        := "if" <compound_predicate> "then" <weight> "else" <weight>
<match_rule>         := <compound_predicate>
<value_rule>         := <weight>
<compound_predicate> := <logical_predicate> |
                        <logical_predicate> ["and" <logical_predicate> ...] |
                        <logical_predicate> ["or" <logical_predicate> ...] |
<logical_predicate>  := ["not"] <predicate>
<predicate>          := <function_name> "(" ")" |
                        <function_name> "(" <argument> ["," <argument> ...] ")"
<function_name>      := <letter> [<function_name_tail> ...]
<function_name_tail> := empty | <letter> | <digit> | "_"
<argument>           := <string> | <number>
<weight>             := integer | <predicate>
<number>             := float | integer
<string>             := "'" [<letter> | <digit> | <symbol> ...] "'"

Building a Routing Configuration

This example sets up an entire routing configuration for a system with a ESB3008 Request Router, two streamers and the Apple devices outside of Europe example used earlier in this document. Any clients not matching the criteria will be sent to an offload CDN with two streamers in a simple uniformly randomized load balancing setup.

Set up Session Group

First make a classifier and a session group that uses it:

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 9
  Adding a 'userAgent' element
    classifier : {
      name (default: ): Apple
      type (default: userAgent): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *apple*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "Apple",
      "type": "userAgent",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*apple*"
    }
  ]
}
Merge and apply the config? [y/n]: y

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): Apple
    classifiers : [
      classifier (default: ): Apple
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "Apple",
      "classifiers": [
        "Apple"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Set up Hosts

Create two host groups and add a Request Router to the first and two streamers to the second, which will be used for offload:

$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 3
  Adding a 'redirecting' element
    hostGroup : {
      name (default: ): internal
      type (default: redirecting): ⏎
      httpPort (default: 80): ⏎
      httpsPort (default: 443): ⏎
      hosts : [
        host : {
          name (default: ): rr1
          hostname (default: ): rr1.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: y
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 2
  Adding a 'host' element
    hostGroup : {
      name (default: ): external
      type (default: host): ⏎
      httpPort (default: 80): ⏎
      httpsPort (default: 443): ⏎
      hosts : [
        host : {
          name (default: ): offload-streamer1
          hostname (default: ): streamer1.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: y
        host : {
          name (default: ): offload-streamer2
          hostname (default: ): streamer2.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "internal",
      "type": "redirecting",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "rr1",
          "hostname": "rr1.example.com",
          "ipv6_address": ""
        }
      ]
    },
    {
      "name": "external",
      "type": "host",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "offload-streamer1",
          "hostname": "streamer1.example.com",
          "ipv6_address": ""
        },
        {
          "name": "offload-streamer2",
          "hostname": "streamer2.example.com",
          "ipv6_address": ""
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Create Load Balancing and Offload Block

Add both offload streamers as targets in a randomgroup block:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: deny
    2: contentPopularity
    3: firstMatch
    4: random
    5: rawGroup
    6: rawHost
    7: split
    8: weighted
    9: allow
  Choose element index or name: random
  Adding a 'random' element
    rule : {
      name (default: ): balancer
      type (default: random): ⏎
      targets : [
        target (default: ): offload-streamer1
        Add another 'target' element to array 'targets'? [y/N]: y
        target (default: ): offload-streamer2
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "balancer",
      "type": "random",
      "targets": [
        "offload-streamer1",
        "offload-streamer2"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Then create a split block with the request router and the load balanced CDN as targets:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: deny
    2: contentPopularity
    3: firstMatch
    4: random
    5: rawGroup
    6: rawHost
    7: split
    8: weighted
    9: allow
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): offload
      type (default: split): ⏎
      rule (default: ): in_session_group('Apple') and not in_subnet('Europe') and lt('europe_load_mbps', 1000)
      onMatch (default: ): rr1
      onMiss (default: ): balancer
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "offload",
      "type": "split",
      "condition": "in_session_group('Apple') and not in_subnet('Europe') and lt('europe_load_mbps', 1000)",
      "onMatch": "rr1",
      "onMiss": "balancer"
    }
  ]
}
Merge and apply the config? [y/n]: y

The last step required is to set the entrypoint of the routing tree so the router knows where to start evaluating:

$ confcli services.routing.entrypoint offload
services.routing.entrypoint = 'offload'

Evaluate

Now that all the rules have been set up properly and the router has been reconfigured. The translated configuration can be read from the router’s configuration API:

$ curl -k https://router-host:5001/v2/configuration  2> /dev/null | jq .routing
{
  "id": "offload",
  "member_order": "sequential",
  "members": [
    {
      "host_id": "rr1",
      "id": "offload.rr1",
      "weight_function": "return ((in_session_group('Apple') ~= 0) and
                          (in_subnet('Europe') == 0) and
                          (lt('europe_load_mbps', 1000) ~= 0) and 1) or 0 "
    },
    {
      "id": "offload.balancer",
      "member_order": "weighted",
      "members": [
        {
          "host_id": "offload-streamer1",
          "id": "offload.balancer.offload-streamer1",
          "weight_function": "return 100"
        },
        {
          "host_id": "offload-streamer2",
          "id": "offload.balancer.offload-streamer2",
          "weight_function": "return 100"
        }
      ],
      "weight_function": "return 1"
    }
  ],
  "weight_function": "return 100"
}

Note that the configuration language code has been translated into its Lua equivalent.

3.1.1.5.4 - Session Groups and Classification

How to classify clients into session groups and use them in routing

ESB3024 Router provides a flexible classification engine, allowing the assignment of clients into session groups that can then be used to base routing decisions on.

Session Groups

A session group is a subset of clients satisfying certain conditions. Define session groups reflecting the environment and objectives.

A client can be part of multiple session groups.

Classification

The session_groups field of the configuration comprises a list of sessions groups, each with their respective classification criteria specified in the corresponding classifiers field.

Each session group consists of the fields

  • id (number) - ID of the session group, must be globally unique from all other session group IDs
  • name (string) - name of the session group
  • classifiers (array of array of objects) - list of the session group’s classifiers.

Classification Logic

Session groups support combining classifiers using AND and OR semantics. This is achieved by nesting classifiers within evaluation groups, as seen in the pseudo-JSON below:

{
  "session_groups": [
    {
      "id": 1,
      "name": "example_AND_vs_OR",
      "classifiers": [
        [ // All classifiers within evaluation group are AND evaluated
          {
            // classifier 1
          },
          {
            // classifier 2
          }
        ],
        // Separate evaluation groups are OR evaluated
        [
          {
            // classifier 3
          }
        ]
      ]
    }
  ]
}

This particular session group defines an evaluation group containing classifier 1 and classifier 2. Both classifiers have to evaluate to true for the whole classifier group to evaluate to true.

This session group also defines another evaluation group containing classifier 3. Separate evaluation groups are OR evaluated, meaning that either the first or second evaluation group needs to evaluate to true for a client to assigned to the session group.

Logically, this session group’s classification criterion can be visualized as
( classifier 1 AND classifier 2 ) OR classifier 3.

Classifier Structure

Each classifier consists of the fields

  • id (number): ID of the classifier, must be unique within the same session group
  • name (string): name of the classifier
  • inverted (boolean): the resulting classification should be inverted (negated) before evaluation
  • rule (object): the classifier logic

rule contains different fields defining classifier behaviour. The first mandatory field is rule_type which defines the classification method and can be one of string_match_rule, geoip_rule, asn_ids_rule, regex_rule, subnet_rule and ip_ranges_rule. The second mandatory field is source, defining the data source on which the classification will be evaluated and can be one of session/content_url_path, session/content_url_query_params, session/user_agent, session/client_ip or session/hostname.

Examples of all rule types and sources can be seen in the JSON below.

{
  "session_groups": [
    {
      "id": 1,
      "name": "example_string_match_rule_live_and_subtitle",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "live_wildcard_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/content_url_path",
              "pattern": "*live*"
            }
          },
          {
            "id": 2,
            "inverted": false,
            "name": "subtitle_wildcard_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/content_url_query_params",
              "pattern": "*subtitle=eng*"
            }
          }
        ]
      ]
    },
    {
      "id": 2,
      "name": "example_string_match_rule_vod_or_hostname",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "live_wildcard_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/content_url_path",
              "pattern": "*vod*"
            }
          }
        ],
        [
          {
            "id": 3,
            "inverted": false,
            "name": "hostname_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/hostname",
              "pattern": "mycdn.com"
            }
          }
        ]
      ]
    },
    {
      "id": 3,
      "name": "example_string_match_rule_ipv4",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "ipv4_wildcard_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/client_ip",
              "pattern": "*.*"
            }
          }
        ]
      ]
    },
    {
      "id": 4,
      "name": "example_string_match_rule_ipv6",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "ipv6_wildcard_match",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/client_ip",
              "pattern": "*:*"
            }
          }
        ]
      ]
    },
    {
      "id": 5,
      "name": "example_geo_location",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "geo_location_specific",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "continent": "Europe",
              "country": "Norway",
              "region": "Innlandet",
              "cities": ["Elverum"],
              "geoname_id": 3144096,
              "asn": "Telenor Norge AS"
            }
          }
        ]
      ]
    },
    {
      "id": 6,
      "name": "example_geo_location_asn_wildcard",
      "classifiers": [
        [
          {
          "id": 1,
          "inverted": false,
          "name": "asn_wildcard_match",
          "rule": {
            "rule_type": "geoip_rule",
            "source": "session/client_ip",
            "asn": "Telia*"
            }
          }
        ]
      ]
    },
    {
      "id": 7,
      "name": "example_regex",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "ios_version_5.1.1",
            "rule": {
              "rule_type": "regex_rule",
              "source": "session/user_agent",
              "pattern": "/OS ((\\d+_?){2,3})\\s/"
            }
          }
        ]
      ]
    },
    {
      "id": 8,
      "name": "example_ip_ranges",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": true,
            "name": "offload_no_peering_subnet",
            "rule": {
              "rule_type": "ip_ranges_rule",
              "source": "session/client_ip",
              "ip_ranges": ["158.174.0.0/16", "95.192.0.0/12"]
            }
          }
        ]
      ]
    },
    {
      "id": 9,
      "name": "example_subnets",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "subnets_match",
            "rule": {
              "rule_type": "subnet_rule",
              "source": "session/client_ip",
              "pattern": "stock*"
            }
          }
        ]
      ]
    },
    {
      "id": 10,
      "name": "example_asn_list",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "asn_list_match",
            "rule": {
              "rule_type": "asn_ids_rule",
              "source": "session/client_ip",
              "asn_ids": [1, 2, 3]
            }
          }
        ]
      ]
    }
  ]
}

As seen in "pattern": "/OS ((\\d+_?){2,3})\\s/", backslash characters must always be escaped in JSON. If a tool was used to construct the JSON code, escaping should be done automatically and it must not be included it manually.

The rule types work as following:

  • string_match_rule flexible string matching on any source
    Tip: Supports wildcard matching
  • regex_rule - regex matching on the source, based on C++ regex implementation
    Tip: For basic IPv4 vs. IPv6 differentiation of client IP addresses, a simple string_match_rule on session/client_ip is more efficient and maintainable than a more expressive regex_rule (which may come with the additional benefit of validating the format of the matched field).
  • ip_ranges_rule - a list of IP ranges on the form ‘0.0.0.0/24’. Any client with an IP within any of the specified ranges will be matched by the classifier
  • subnet_rule - string matching of the pattern on all subnets the client’s IP matches. Only supports the source session/client_ip. If a client matches into multiple subnets, only one of them needs to match the pattern.
    Tip: Supports wildcard matching
  • geoip_rule allows geolocation based matching. The client’s IP address is used to poll the MaxMind GeoIP2 database for geolocations. Only supports the source session/client_ip. The possible fields within this rule are
    • continent (string) - the desired continent
    • country (string) - the desired country
    • region (string) - the desired region
    • cities (array of strings) - the desired cities
      • at least one city must match for successful classification
    • asn (string) - the desired ASN
      Tip: Supports wildcard matching
    • geoname_id (number) - MaxMind’s internal id matching
      Note: Using geoname_id requires insight into a MaxMind GeoIP2 database to find correct IDs

All fields within the GeoIP rule are optional. For successful classification, all defined fields must match.

If a client is successfully classified, it will labeled as part of that session group. The session group can be then be accessed in Lua contexts, e.g.

{
  "hosts": [
    {
      "id": "geo-location-host",
      "cdn_id": "basic-cdn",
      "host": "geo-location-host.example"
    },
    {
      "id": "ip-ranges-host",
      "cdn_id": "basic-cdn",
      "host": "ip-ranges-host.example"
    }
  ],
  "routing": {
    "id": "session_group_routing",
    "member_order": "sequential",
    "members": [
      {
        "id": "geo_location_session_group",
        "host_id": "geo-location-host",
        "weight_function": "return session_groups.example_geo_location and 1 or 0"
      },
      {
        "id": "ip_ranges_session_group",
        "host_id": "ip-ranges-host",
        "weight_function": "return session_groups.example_ip_ranges and 1 or 0"
      }
    ]
  }
}

3.1.1.5.5 - Advanced features

Detailed descriptions and examples of advanced features within ESB3024

3.1.1.5.5.1 - Content popularity

How to tune content popularity parameters and use it in routing

ESB3024 Router allows routing decisions based on content popularity. All incoming content requests are tracked to continuously update a content popularity ranking list. The popularity ranking algorithm is designed to let popular content quickly rise to the top while unpopular content decays and sinks towards the bottom.

Configuration

All configuration parameters for content popularity reside in the settings object of the configuration, an example of which can be seen below:

{
  "settings": {
    "content_popularity": {
      "algorithm": "scored_based",
      "session_group_names": ["vod_only"],
      "score_based:": {
        "requests_between_popularity_decay": 1000,
        "popularity_list_max_size": 100000,
        "popularity_prediction_factor": 2.5,
        "popularity_decay_fraction": 0.2
      },
      "time_based": {
        "intervals_per_hour": 10
      }
    }
  }
}

The field algorithm dictates which content popularity tracking algorithm to use, can either be score_based or time_based.

The field session_group_names defines the sessions for which content popularity should be tracked. In the example above, session belonging to the vod_only session group will be tracked for content popularity. If left empty, content popularity will be tracked for all sessions.

The remaining configuration parameters are algorithm specific.

Score based algorithm

The field popularity_list_max_size defines the maximum amount of unique contents to track for popularity. This can be used to limit memory growth. A single entry in the popularity ranking list will at most consume 180 B of memory, giving an upper bound memory growth of \(180n_{\text{requests}}\) bytes. E.g. using "popularity_list_max_size": 1000 would consume at most 180⋅1,000 = 180,000 B = 0.18 MB. If the content popularity list is full, a request to unique content would replace the least popular content.

Setting a very high max size won’t impact performance, it will only consume more memory.

The field requests_between_popularity_decay defines the number of requests between each popularity decay update, an integral component of this feature.

The fields popularity_prediction_factor and popularity_decay_fraction tune the behaviour of the content popularity ranking algorithm, explained further below.

Decay update

To allow for popular content to quickly rise in popularity and unpopular content to sink, a dynamic popularity ranking algorithm is used. The goal of the algorithm is to track content popularity in real time, allowing routing decisions based on the requested content’s popularity. The algorithm is applied every decay update.

The algorithm uses current trending content to predict content popularity. The field popularity_prediction_factor regulates how much the algorithm should rely on predicted popularity. A high prediction factor allows rising content to quickly rise to high popularity but can also cause unpopular content with a sudden burst of requests to wrongfully rise to the top. A low prediction factor can cause stagnation in the popularity ranking, not allowing new popular content to rise to the top.

Unpopular content decays in popularity, the magnitude of which is regulated by popularity_decay_fraction. A high value will aggressively decay content popularity every decay update while a low value will bloat the ranking, causing stagnation. Once content decays to a trivially low popularity score, it is pruned from the content popularity list.

When configuring these tuning parameters, the most crucial data to consider is the size of your asset catalog, i.e. the number of unique contents you offer. The recommended values, obtained through testing, are presented in the table below. Note that the field popularity_prediction_factor is the principal factor in controlling the algorithm’s behaviour.

Catalog size \(n\)popularity_prediction_factorpopularity_decay_fraction
\(n\) < 10002.20.2
1000 < \(n\) < 50002.30.2
5000 < \(n\) < 100002.50.2
\(n\) > 100002.60.2

Time based algorithm

The time based algorithm only requires the configuration parameter intervals_per_hour. E.g., the value "intervals_per_hour": 10 would give 10 six minute intervals per hour. During each interval, all unique content requests has an associated counter, increasing by one for each incoming request. After an hour, all intervals have been cycled through. The counters in the first interval will be reset and all incoming content requests will increase the counters in the first interval again. This cycle continues forever.

When determining a single content’s popularity, the sum of each content’s counter in all intervals is used to determine a popularity ranking.

Usage in routing

Content popularity ranking is available in Lua through the simple member session.content_global_popularity, returning the requested content’s popularity ranking. E.g., the routing configuration below will route all requests to content with a popularity ranking lower than 10, i.e. top 10 most popular content, to the host edge-streamer while requests to content outside of the top 10 most popular will be routed to the host offload.

"routing": {
  "id": "routing_table",
  "member_order": "sequential",
  "members": [
    {
      "id": "edge",
      "weight_function": "return session.content_global_popularity < 11 and 1 or 0",
      "host_id": "edge-streamer"
    },
    {
      "id": "offload",
      "weight_function": "return 1",
      "host_id": "offload"
    }
  ]
}

3.1.1.5.5.2 - Consistent Hashing

Details and configuration considerations for using consistent hashing based routing

Consistent hashing based routing is a feature that can be used to distribute requests to a set of hosts in a cache friendly manner. By using Agile Content’s consistent distributed hash algorithm, the amount of cache redistribution is minimized within a set of hosts. Requests for a content will always be routed to the same set of hosts, the amount of which is configured by the spread factor, allowing high cache usage. When adding or removing hosts, the algorithm minimizes cache redistribution.

Say you have the host group [s1, s2, s3, s4, s5] and have configured spreadFactor = 3. A request for a content asset1 would then be routed to the same three hosts with one of them being selected randomly for each request. Requests for a different content asset2 would also be routed to one of three different hosts, most likely a different combination of hosts than requests for content asset1.

Example routing results with spreadFactor = 3:

  • Request for asset1 → route to one of [s1, s3, s4].
  • Request for asset2 → route to one of [s2, s4, s5].
  • Request for asset3 → route to one of [s1, s2, s5].

Since consistent hashing based routing ensures that requests for a specific content always get routed to the same set of hosts, the risk of cache misses are lowered on the hosts since they will be served the same content requests over and over again.

Note that the maximum value of spreadFactor is 64. Consequently, the highest amount of hosts you can use in a consistentHashing rule block is 64.

Configuration

Configuring consistent hashing based routing is easily done using confcli. Let’s configure the example described above:

confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: consistentHashing
  Adding a 'consistentHashing' element
    rule : {
      name (default: ): consistentHashingRule 
      type (default: consistentHashing): 
      spreadFactor (default: 1): 3
      targets : [
        target : {
          target (default: ): s1
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): s2
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): s3
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): s4
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): s5
          enabled (default: True): 
        }
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "consistentHashingRule",
      "type": "consistentHashing",
      "spreadFactor": 3,
      "targets": [
        {
          "target": "s1",
          "enabled": true
        },
        {
          "target": "s2",
          "enabled": true
        },
        {
          "target": "s3",
          "enabled": true
        },
        {
          "target": "s4",
          "enabled": true
        },
        {
          "target": "s5",
          "enabled": true
        }
      ]
    }
  ]
}

Adding hosts

Adding a host to the list will give an additional target for the consistent hashing algorithm to route requests to. This will shift content distribution onto the new host.

confcli services.routing.rules.consistentHashingRule.targets -w
Running wizard for resource 'targets'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

targets : [
  target : {
    target (default: ): s6
    enabled (default: True): 
  }
  Add another 'target' element to array 'targets'? [y/N]: n
]
Generated config:
{
  "targets": [
    {
      "target": "s6",
      "enabled": true
    }
  ]
}
Merge and apply the config? [y/n]: y

Removing hosts

There is one very important caveat of using a consistent hashing rule block. As long as you don’t modify the list of hosts, the consistent hashing algorithm will keep routing requests to the same hosts. However, if you remove a host from the block in any position except the last, the consistent hashing algorithm’s behaviour will change and the algorithm cannot maintain a minimum amount of cache redistribution.

If you’re in a situation where you have to remove a host from the routing targets but want to keep the same consistent hashing behaviour, e.g. during very high load, you’ll have to toggle that target’s enabled field to false. E.g., disabling requests to s2 can be accomplished by:

$ confcli services.routing.rules.consistentHashingRule.targets.1.enabled false
services.routing.rules.consistentHashingRule.targets.1.enabled = False
$ confcli services.routing.rules.consistentHashingRule.targets.1
{
    "1": {
        "target": "s2",
        "enabled": false
    }
}

If you modify the list order or remove hosts, it is highly recommended to do so during moments where a higher rate of cache misses are acceptable.

3.1.1.5.5.3 - Predictive load balancing

Configuring predictive load balancing in ESB3024 Router

Why use predictive load balancing?

Predictive load balancing is a tool that can be used to avoid overloading hosts with traffic. Consider the case where a popular event starts at a certain time, let’s say 12 PM. A spike in traffic will be routed to the hosts that are streaming the content at 12 PM, most of them starting at low bitrates. A host might have sufficient bandwidth left to take on more clients but when the recently connected clients start ramping up in video quality and increase their bitrate, the host can quickly become overloaded, possibly dropping incoming requests or going offline. Predictive load balancing solves this issue by considering how many times a host recently been redirected to.

Basic configuration

The router allows predicting incoming load for individual hosts. Through the use of the selection input API, the routing engine can predict incoming load by tracking recent host selections and make routing decisions accordingly.

What is considered recent is configurable and defaults to 500 milliseconds:

$ confcli services.routing.tuning.target.recentDurationMilliseconds
{
    "recentDurationMilliseconds": 500
}
$ confcli services.routing.tuning.target.recentDurationMilliseconds 1000
services.routing.tuning.target.recentDurationMilliseconds = 1000
{
  "tuning": {
    "target_recent_duration_milliseconds": 500
  }
}

How to use predictive load balancing

The standard Lua library provides four functions for predictive load balancing that can be used when constructing conditions/weight functions: host_bitrate() , host_bitrate_custom(), host_has_bw() and host_has_bw_custom(). All require data to be supplied to the selection input API and apply only to leaf nodes in the routing tree. In order for predictive load balancing to work properly the data must be updated at regular intervals. The data needs to be supplied by the target system.

These functions are suitable to used as host health checks. To configure host health checks, see configuring CDNs and hosts.

Note that host_bitrate() and host_has_bw() rely on data supplied by metrics agents, detailed in Cache hardware metrics: monitoring and routing.

host_bitrate_custom() and host_has_bw_custom() rely on manually supplied selection input data, detailed in selection input API. The bitrate unit depends on the data submitted to the selection input API.

host_bitrate()

host_bitrate() returns the predicted bitrate (in megabits per second) of the host after the recently connected clients start ramping up in streaming quality. The function accepts up to four arguments:

  • interface: The name of the interface to use for bitrate prediction.
  • Optional avg_bitrate: the average bitrate per client, defaults to 6 megabits per second.
  • Optional num_routers: the number of routers that can route to this host, defaults to 1. This is important to accurately predict the incoming load if multiple routers are used.
  • Optional host: The name of the host to use for bitrate prediction. Defaults to the current host if not provided.

Examples of usage:

host_bitrate({interface="eths0"})
host_bitrate({avg_bitrate=1, interface="eths0"})
host_bitrate({num_routers=2, interface="eths0"})
host_bitrate({avg_bitrate=1, num_routers=4, interface="eths0"})
host_bitrate({avg_bitrate=1, num_routers=4, host="custom_host", interface="eths0"})

host_bitrate() calculates the predicted bitrate as:

predicted_host_bitrate = current_host_bitrate + (recent_connections * avg_bitrate * num_routers)

host_bitrate_custom()

Same functionality as host_bitrate() but uses a custom selection input variable as bitrate input instead of accessing hardware metrics. The function accepts up to three arguments:

  • custom_bitrate_var: The name of the selection input variable to be used for accessing current host bitrate.
  • Optional avg_bitrate: see host_bitrate() documentation above.
  • Optional num_routers: see host_bitrate() documentation above.
host_bitrate_custom({custom_bitrate_var="host1_current_bitrate"})
host_bitrate_custom({avg_bitrate=1, custom_bitrate_var="host1_current_bitrate"})
host_bitrate_custom({num_routers=4, custom_bitrate_var="host1_current_bitrate"})

host_has_bw()

Instead of accessing the predicted bitrate of a host through host_bitrate(), host_has_bw() returns 1 if the host is predicted to have enough bandwidth left to take on more clients after recent connections ramp up in bitrate, otherwise it returns 0. The function accepts up to five arguments:

  • interface: see host_bitrate() documentation above.
  • Optional avg_bitrate: see host_bitrate() documentation above.
  • Optional num_routers: see host_bitrate() documentation above.
  • Optional host: see host_bitrate() documentation above.
  • Optional margin: the bitrate (megabits per second) headroom that should be taken into account during calculation, defaults to 0.

host_has_bw() returns whether or not the following statement is true:

predicted_host_bitrate + margin < host_bitrate_capacity

Examples of usage:

host_has_bw({interface="eths0"})
host_has_bw({margin=10, interface="eth0"})
host_has_bw({avg_bitrate=1, interface="eth0"})
host_has_bw({num_routers=4, interface="eth0"})
host_has_bw({host="custom_host", interface="eth0"})

host_has_bw_custom()

Same functionality as host_has_bw() but uses a custom selection input variable as bitrate and capacity input. The function accepts up to five arguments:

  • custom_capacity_var: the name of the selection input variable to be used for accessing host capacity.
  • custom_bitrate_var: see host_bitrate_custom() documentation
  • Optional margin: see host_has_bw() documentation above. above.
  • Optional avg_bitrate: see host_bitrate() documentation above.
  • Optional num_routers: see host_bitrate() documentation above.

Examples of usage:

host_has_bw_custom({custom_capacity_var="host1_capacity", custom_bitrate_var="host1_current_bitrate"})
host_has_bw_custom({margin=10, custom_capacity_var="host1_capacity", custom_bitrate_var="host1_current_bitrate"})
host_has_bw_custom({avg_bitrate=1, custom_capacity_var="host1_capacity", custom_bitrate_var="host1_current_bitrate"})
host_has_bw_custom({num_routers=4, custom_capacity_var="host1_capacity", custom_bitrate_var="host1_current_bitrate"})

Examples in routing

When using confcli it’s not recommended to use host_bitrate() since it’s not possible to make comparisons using <, > or similar operators. Using host_has_bw() makes it easy to construct conditions utilizing predictive load balancing.

host_has_bw() and host_has_bw_custom() are excellent candidates to be used as health check functions for hosts, see configuring CDNs and hosts for more details.

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: weighted
  Adding a 'weighted' element
    rule : {
      name (default: ): weighted_and_has_bw
      type (default: weighted):
      targets : [
        target : {
          target (default: ): host1
          weight (default: 100):
          condition (default: always()): host_has_bw({interface="eths0"})
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): host2
          weight (default: 100): 100
          condition (default: always()): host_has_bw({margin=1000, interface="eths0"})
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): host3
          weight (default: 100):
          condition (default: always()): host_has_bw({avg_bitrate=1, num_routers=2, margin=5000, interface="eths0"})
        }
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "weighted_and_has_bw",
      "type": "weighted",
      "targets": [
        {
          "target": "host1",
          "weight": "100",
          "condition": "host_has_bw({interface="eths0"})"
        },
        {
          "target": "host2",
          "weight": "100",
          "condition": "host_has_bw({margin=1000, interface="eths0"})"
        },
        {
          "target": "host3",
          "weight": "100",
          "condition": "host_has_bw({avg_bitrate=1, num_routers=2, margin=5000, interface="eths0"})"
        }
      ]
    }
  ]
}
"routing": {
  "id": "weighted_and_has_bw",
  "member_order": "sorted",
  "members": [
    {
      "id": "1",
      "host_id": "host1",
      "weight_function": "return host_bitrate({interface="eths0"}) > 0 and 1 or 0"
    },
    {
      "id": "2",
      "host_id": "host2",
      "weight_function": "return host_bitrate({avg_bitrate=1, interface="eths0"}) > 10000 and 1 or 0"
    },
    {
      "id": "3",
      "host_id": "host3",
      "weight_function": "return host_has_bw({avg_bitrate=1, num_routers=2, margin=5000, interface="eths0"}) and 1 or 0"
    }
  ],
  "weight_function": "return 1"
}

3.1.1.5.5.4 - Security token verification

Only allow requests that contain a correct security token

The security token verification feature allows for ESB3024 Router to only process requests that contain a correct security token. The token is generated by the client, for example in the portal, using an algorithm that it shares with the router. The router verifies the token and rejects the request if the token is incorrect.

It is beyond the scope of this document to describe how the token is generated, that is described in the Security Tokens application note that is installed with the ESB3024 Router’s extra documentation.

Setting up a routing rule

The token verification is performed by calling the verify_security_token() function from a routing rule. The function returns 1 if the token is correct, otherwise it returns 0. It should typically be called from the first routing rule, to make requests with bad tokens fail as early as possible.

The confcli example assumes that the router already has rules configured, with an entry point named select_cdn. Token verification is enabled by inserting an “allow” rule first in the rule list.

confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: allow
  Adding a 'allow' element
    rule : {
      name (default: ): token_verification
      type (default: allow):
      condition (default: always()): verify_security_token()
      onMatch (default: ): select_cdn
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "token_verification",
      "type": "allow",
      "condition": "verify_security_token()",
      "onMatch": "select_cdn"
    }
  ]
}
Merge and apply the config? [y/n]: y

$ confcli services.routing.entrypoint token_verification
services.routing.entrypoint = 'token_verification'
"routing": {
  "id": "token_verification",
  "member_order": "sequential",
  "members": [
    {
      "id": "token_verification.0.select_cdn",
      "member_order": "weighted",
      "members": [
        ...
      ],
      "weight_function": "return verify_security_token() ~= 0"
    },
    {
      "id": "token_verification.1.rejected",
      "member_order": "sequential",
      "members": [],
      "weight_function": "return 1"
    }
  ],
  "weight_function": "return 100"
},

Configuring security token options

The secret parameter is not part of the router request, but needs to be configured separately in the router. That can be done with the host-config tool that is installed with the router.

Besides configuring the secret, host-config can also configure floating sessions and a URL prefix. Floating sessions are sessions that are not tied to a specific IP address. When that is enabled, the token verification will not take the IP address into account when verifying the token.

The security token verification is configured per host, where a host is the name of the host that the request was sent to. This makes it possible for a router to support multiple customer accounts, each with their own secret. If no configuration is found for a host, a configuration with the name default is used.

host-config supports three commands: print, set and delete.

Print

The print command prints the current configuration for a host. The following parameters are supported:

host-config print [-n <host-name>]

By default it prints the configuration for all hosts, but if the optional -n flag is given it will print the configuration for a single host.

Set

The set command sets the configuration for a host. The configuration is given as command line parameters. The following parameters are supported:

host-config set
    -n <host-name>
    [-f floating]
    [-p url-prefix]
    [-r <secret-to-remove>]
    [-s <secret-to-add>]
  • -n <host-name> - The name of the host to configure.
  • -f floating - A boolean option that specifies if floating sessions are accepted. The parameter accepts the values true and false.
  • -p url-prefix - A URL prefix that is used for identifying requests that come from a certain account. This is not used when verifying tokens.
  • -r <secret-to-remove> - A secret that should be removed from the list of secrets.
  • -s <secret-to-add> - A secret that should be added to the list of secrets.

For example, to set the secret “secret-1” and enable floating sessions for the default host, the following command can be used:

host-config set -n default -s secret-1 -f true

The set command only touches the configuration options that are mentioned on the command line, so the following command line will add a second secret to the default host without changing the floating session setting:

host-config set -n default -s secret-2

It is possible to set multiple secrets per host. This is useful when updating a secret, then both the old and the new secret can be valid during the transition period. After the transition period the old secret can be removed by typing:

host-config set -n default -r secret-1

Delete

The delete command deletes the configuration for a host. It supports the following parameters:

host-config delete -n <host-name>

For example, to delete the configuration for example.com, the following command can be used:

host-config delete -n example.com

Global options

host-config also has a few global options. They are:

  • -k <security-key> - The security key that is used when communicating with the router. This is normally retrieved automatically.
  • -h - Print a help message and exit.
  • -r <router> - The router to connect to. This default to localhost, but can be changed to connect to a remote router.
  • -v - Verbose output, can be given multiple times.

Debugging security token verification

The security token verification only logs messages when the log level is set to 4 or higher. Then it will only log some errors. It is possible to enable more verbose logging using the security-token-config that is installed together with the router.

When verbose logging is enabled, the router will log information about the token verification, including the configured token secrets, so it needs to be used with care.

The logged lines are prefixed with verify_security_token.

The security-token-config tool supports the commands print and set.

The print command prints the current configuration. If nothing is configured it will not print anything.

Set

The set command sets the configuration. The following parameters are supported:

security-token-config set
    [-d <enabled>]
  • -d <enabled> - A boolean option that specifies if debug logging should be enabled or not. The parameter accepts the values true and false.

3.1.1.5.5.5 - Subnets API

How to match clients into named subnets and use them in routing

ESB3024 Router provides utilities to quickly match clients into subnets. Any combination of IPv4 and IPv6 addresses can be used. To begin, a JSON file is needed, defining all subnets, e.g:

{
  "255.255.255.255/24": "area1",
  "255.255.255.255/16": "area2",
  "255.255.255.255/8": "area3",
  "90.90.1.3/16": "area4",
  "5.5.0.4/8": "area5",
  "2a02:2e02:9bc0::/48": "area6",
  "2a02:2e02:9bc0::/32": "area7",
  "2a02:2e02:9bc0::/16": "area8",
  "2a02:2e02:9de0::/44": "combined_area",
  "2a02:2e02:ada0::/44": "combined_area"
}

and PUT it to the endpoint :5001/v1/subnets or :5001/v2/subnets, the API version doesn’t matter for subnets:

curl -k -T subnets.json -H "Content-Type: application/json" https://router-host:5001/v1/subnets

Note that it is possible for several subnet CIDR strings to share the same label, effectively grouping them together.

This will load the subnets into the router which will then be usable within any Lua functions, accessed from the request and session tables respectively, e.g.

{
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "node1",
        "host_id": "host1",
        "weight_function": "return request.subnet == 'area1' and 1 or 0"
      }
    ]
  }
}

Subnet matching will use the client IP fetched from the request or session tables. When possible, the subnet with the longest matching subnet mask will be chosen, i.e. 255.255.255.255/28will be chosen over 255.255.255.255/24. If no matching subnets are found, the boolean value false will be returned.

NOTE: To use booleans in strings in Lua, calling tostring(bool) is required. Therefore, since subnet lookup might return false, the subnet call should be wrapped as: tostring(session.subnet) or tostring(requst.subnet).

Invalid ip-addresses will be omitted during subnet list construction accompanied by a message in the log displaying the invalid IP address.

3.1.1.5.5.6 - Lua Features

Detailed descriptions and examples of Lua features offered by ESB3024 Router.

3.1.1.5.5.6.1 - Health Check Functions

Built in Lua health check functions

This section details built in Lua functions that are meant to be used for host health checks. Note that these functions rely on data supplied by metric agents detailed in Cache hardware metrics: monitoring and routing. Make sure cache hardware metrics are supplied to the router before using any of these functions.

cpu_load_ok()

Parameters

The function accepts an optional argument table with the following keys:

  • Optional hostname: The name of the host. Defaults to the hostname of the selected host if not provided.
  • Optional cpu_load5_limit: The acceptable limit for the 5-minute CPU load. Defaults to 0.9 if not provided.

Returns

The function returns 1 if the five minute CPU load average is below their respective limits, and 0 otherwise.

Usage examples

cpu_load_ok()
cpu_load_ok({hostname = "custom_host"})
cpu_load_ok({cpu_load5_limit = 0.8})
cpu_load_ok({hostname = "custom_host", cpu_load5_limit = 0.8})

memory_usage_ok()

Parameters

The function accepts an optional argument table with the following keys:

  • Optional hostname: The name of the host. Defaults to the hostname of the selected host if not provided.
  • Optional memory_usage_limit: The acceptable limit for the memory usage. Defaults to 0.9 if not provided.

Returns

The function returns 1 if the memory usage is below the limit, and 0 otherwise.

Usage examples

memory_usage_ok()
memory_usage_ok({hostname = "custom_host"})
memory_usage_ok({memory_usage_limit = 0.7})
memory_usage_ok({hostname = "custom_host", memory_usage_limit = 0.7})

interfaces_online()

Parameters

The function accepts an argument table with the following keys:

  • Required interfaces: A string or a table of strings representing the network interfaces to check.
  • Optional hostname: The name of the host. Defaults to the hostname of the selected host if not provided.

Returns

The function returns 1 if all the specified interfaces are online, and 0 otherwise.

Usage examples

interfaces_online({interfaces = "eth0"})
interfaces_online({interfaces = {"eth0", "eth1"}})
interfaces_online({hostname = "custom_host", interfaces = "eth0"})
interfaces_online({hostname = "custom_host", interfaces = {"eth0", "eth1"}})

health_check()

Parameters

The function accepts an optional argument table with the following keys:

  • Required interfaces: A string or a table of strings representing the network interfaces to check.
  • Optional hostname: The name of the host. Defaults to the hostname of the selected host if not provided.
  • Optional cpu_load5_limit: The acceptable limit for the 5-minute CPU load. Defaults to 0.9 if not provided.
  • Optional memory_usage_limit: The acceptable limit for the memory usage. Defaults to 0.9 if not provided.

Returns

The function returns 1 if all the specified interfaces are online, and 0 otherwise.

Usage examples

health_check({interfaces = "eths0"})
health_check({hostname = "custom_host", interfaces = "eths0"})
health_check({cpu_load5_limit = 0.7, memory_usage_limit = 0.8, interfaces = "eth0"})
health_check({hostname = "custom_host", cpu_load5_limit = 0.7, memory_usage_limit = 0.8, interfaces = {"eth0", "eth1"}})

3.1.1.5.5.6.2 - Request Translation Function

Instructions for how to write a function to modify incoming requests before routing decisions are being made.

Specifies the body of a Lua function that inspects every incoming HTTP request and overwrites individual fields before further processing by the router.

Returns nil when nothing is to be changed, or HTTPRequest(t) where t is a table with any of the following optional fields:

  • Method
    • Description: Replaces the HTTP request method in the request being processed.
    • Type: string
    • Example: 'GET', 'POST'
  • Path
    • Description: Replaces the request path in the request being processed.
    • Type: string
    • Example: '/mycontent/superman.m3u8'
  • ClientIp
    • Description: Replaces client IP address in the request being processed.
    • Type: string
    • Example: '172.16.238.128'
  • Body
    • Description: Replaces body in the request being processed.
    • Type: string or nil
    • Example: '{"foo": "bar"}'
  • QueryParameters
    • Description: Adds, removes or replaces individual query parameters in the request being processed.
    • Type: nested table (indexed by number) representing an array of query parameters as {[1]='Name',[2]='Value'} pairs that are added to the request being processed, or overwriting existing query parameters with colliding names. To remove a query parameter from the request, specify nil as value, i.e. QueryParameters={..., {[1]='foo',[2]=nil} ...}. Returning a query parameter with a name but no value, such as a in the request '/index.m3u8?a&b=22' is currently not supported.
  • Headers
    • Description: Adds, removes or replaces individual headers in the request being processed.
    • Type: nested table (indexed by number) representing an array of request headers as {[1]='Name',[2]='Value'} pairs that are added to the request being processed, or overwriting existing request headers with colliding names. To remove a header from the request, specify nil as value, i.e. Headers={..., {[1]='foo',[2]=nil} ...}. Duplicate names are supported. A multi-value header such as Foo: bar1,bar2 is defined by specifying Headers={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar2'}, ...}.

Example of a request_translation_function body that sets the request path to a hardcoded value and adds the hardcoded query parameter a=b:

-- Statements go here
print('Setting hardcoded Path and QueryParameters')
return HTTPRequest({
  Path = '/content.mpd',
  QueryParameters = {
    {'a','b'}
  }
})

Arguments

The following (iterable) arguments will be known by the function:

QueryParameters

  • Type: nested table (indexed by number).

  • Description: Array of query parameters as {[1]='Name',[2]='Value'} pairs that were present in the query string of the request. Format identical to the HTTPRequest.QueryParameters-field specified for the return value above.

  • Example usage:

    for _, queryParam in pairs(QueryParameters) do
      print(queryParam[1]..'='..queryParam[2])
    end
    

Headers

  • Type: nested table (indexed by number).

  • Description: Array of request headers as {[1]='Name',[2]='Value'} pairs that were present in the request. Format identical to the HTTPRequest.Headers-field specified for the return value above. A multi-value header such as Foo: bar1,bar2 is seen in request_translation_function as Headers={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar1'}, ...}.

  • Example usage:

    for _, header in pairs(Headers) do
      print(header[1]..'='..header[2])
    end
    

Global metatables

In addition to the arguments above, the following (non-iterable) global metatables will be populated with fields that may be retrieved by the request_translation_function:

  • Note that metatables may only be accessed by already known keys:

Metatable request

  • request.method
    • Description: HTTP request method.
    • Type: string
    • Example: 'GET', 'POST'
  • request.body
    • Description: HTTP request body string.
    • Type: string or nil
    • Example: '{"foo": "bar"}'
  • request.major_version
    • Description: Major HTTP version such as x in HTTP/x.1.
    • Type: integer
    • Example: 1
  • request.minor_version
    • Description: Minor HTTP version such as x in HTTP/1.x.
    • Type: integer
    • Example: 1
  • request.protocol
    • Description: Transfer protocol variant.
    • Type: string
    • Example: 'HTTP', 'HTTPS'
  • request.client_ip
    • Description: IP address of the client issuing the request.
    • Type: string
    • Example: '172.16.238.128'
  • request.path_with_query_params
    • Description: Full request path including query parameters.
    • Type: string
    • Example: '/mycontent/superman.m3u8?b=y&c=z&a=x'
  • request.path
    • Description: Request path without query parameters.
    • Type: string
    • Example: '/mycontent/superman.m3u8'
  • request.query_params
    • Description: The query parameter string.
    • Type: string
    • Example: 'b=y&c=z&a=x'
  • request.filename
    • Description: The part of the path following the final slash, if any.
    • Type: string
    • Example: 'superman.m3u8'
  • request.subnet
    • Description: Subnet of client_ip.
    • Type: string or nil
    • Example: 'all'

Metatable request_query_params

Contains the query parameters keyed by name.

Example:

print(request_query_params.a)

Metatable request_headers

Contains the request headers keyed by name.

Example:

print(request_headers.a)

Multiple values are separated with a comma.

Global tables

In addition to the (non-iterable) metatables and (iterable) arguments above, the following global iterable tables are available from all Lua functions:

Table selection_input

Contains arbitrary, custom fields fed into the router by clients. Be careful to document any dependencies between the translation functions and selection inputs.

Example usage:

if selection_input then
    for k, v in pairs(selection_input) do
        print('here is '..'selection_input!')
        print(k..'='..v)
    end
else
    print('selection_input is nil')
end

Upon returning from request_translation_function, values in the request, request_query_params and request_headers metatables will reflect the new current status of the updated HTTP Request.

3.1.1.5.5.6.3 - Response Translation Function

Instructions for how to write a function to modify outgoing responses after a routing decision has been made.

Specifies the body of a Lua function that inspects every outgoing HTTP response and overwrites individual fields before being sent to the client.

Returns nil when nothing is to be changed, or HTTPResponse(t) where t is a table with any of the following optional fields:

  • Code
    • Description: Replaces status code in the response being sent.
    • Type: integer
    • Example: 200, 404
  • Text
    • Description: Replaces status text in the response being sent.
    • Type: string
    • Example: 'OK', 'Not found'
  • MajorVersion
    • Description: Replaces major HTTP version such as x in HTTP/x.1 in the response being sent.
    • Type: integer
    • Example: 1
  • MinorVersion
    • Description: Replaces minor HTTP version such as x in HTTP/1.x in the response being sent.
    • Type: integer
    • Example: 1
  • Protocol
    • Description: Replaces protocol in the response being sent.
    • Type: string
    • Example: 'HTTP', 'HTTPS'
  • Body
    • Description: Replaces body in the response being sent.
    • Type: string or nil
    • Example: '{"foo": "bar"}'
  • Headers
    • Description: Adds, removes or replaces individual headers in the response being sent.
    • Type: nested table (indexed by number) representing an array of response headers as {[1]='Name',[2]='Value'} pairs that are added to the response being sent, or overwriting existing request headers with colliding names. To remove a header from the response, specify nil as value, i.e. Headers={..., {[1]='foo',[2]=nil} ...}. Duplicate names are supported. A multi-value header such as Foo: bar1,bar2 is defined by specifying Headers={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar2'}, ...}.

Example of a response_translation_function body that sets the Location header to a hardcoded value:

-- Statements go here
print('Setting hardcoded Location')
return HTTPResponse({
  Headers = {
    {'Location', 'cdn1.com/content.mpd?a=b'}
  }
})

Arguments

The following (iterable) arguments will be known by the function:

Headers

  • Type: nested table (indexed by number).

  • Description: Array of response headers as {[1]='Name',[2]='Value'} pairs that are present in the response being sent. Format identical to the HTTPResponse.Headers-field specified for the return value above. A multi-value header such as Foo: bar1,bar2 is seen in response_translation_function as Headers={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar1'}, ...}.

  • Example usage:

    for _, header in pairs(Headers) do
      print(header[1]..'='..header[2])
    end
    

Global metatables

In addition to the arguments above, the following (non-iterable) global metatables will be populated with fields that may be retrieved by the response_translation_function:

Note that metatables may only be accessed by already known keys.

Metatable request

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request metatable will contain those changes.

Metatable request_query_params

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request_query_params metatable will contain those changes.

Metatable session_query_params

Alias for metatable request_query_params.

Metatable request_headers

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request_headers metatable will contain those changes.

Metatable response

Contains all the parts of the outgoing response apart from the headers.

  • response.body
    • Description: HTTP response body string.
    • Type: string or nil
    • Example: '{"foo": "bar"}'
  • response.code
    • Description: HTTP response status code.
    • Type: integer
    • Example: 200, 404
  • response.text
    • Description: HTTP response status text.
    • Type: string
    • Example: 'OK', 'Not found'
  • response.major_version
    • Description: Major HTTP version such as x in HTTP/x.1.
    • Type: integer
    • Example: 1
  • response.minor_version
    • Description: Minor HTTP version such as x in HTTP/1.x.
    • Type: integer
    • Example: 1
  • response.protocol
    • Description: Transfer protocol variant.
    • Type: string
    • Example: 'HTTP', 'HTTPS'

Metatable response_headers

Contains the response headers keyed by name. Example:

print(response_headers.a)

Multiple values are separated with a comma.

Metatable session

See documentation for session_translation_function. If the session translation function has modified the incoming request, the session metatable will contain those changes.

Metatable session_groups

See documentation for session_translation_function.

Global tables

In addition to the (non-iterable) metatables and (iterable) arguments above, the following global iterable tables are available from all Lua functions:

Table selection_input

See documentation for request_translation_function. Values in the selection_input metatable will remain unchanged since a prior call to a request_translation_function.

3.1.1.5.5.6.4 - Session Translation Function

Instructions for how to write a function to modify a client session to affect how it is handled by the router.

Specifies the body of a Lua function that inspects a newly created session and may override its suggested type from “initial” to “instream” or vice versa.

Returns nil when the session type is to remain unchanged, or Session(t) where t is a table with a single field:

  • Type
    • Description: New type of the session.
    • Type: string
    • Example: 'instream', 'initial'

Example of a session_translation_function body that unconditionally makes all sessions 'instream':

-- Statements go here
print('Modifying session type')
return Session({['Type'] = 'instream'})

Arguments

The following (iterable) arguments are passed to the function:

Type

  • Description: The suggested type of the session.
  • Type: string
  • Example: 'instream', 'initial'

Example usage:

-- Flip session type
local newType = 'initial'
if Type == 'initial' then
    newType = 'instream'
end
print('Changing session type from ' .. Type .. ' to ' .. newType)
return Session({['Type'] = newType})

Global metatables

In addition to the arguments above, the following (non-iterable) global metatables will be populated with fields that may be retrieved by the response translation function.

Metatable request

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request metatable will contain those changes.

Metatable request_query_params

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request_query_params metatable will contain those changes.

Metatable session_query_params

Alias for metatable request_query_params.

Metatable request_headers

See documentation for request_translation_function. If the request translation function has modified the incoming request, the request_headers metatable will contain those changes.

Metatable session

  • session.client_ip
  • session.path_with_query_params
  • session.path
  • session.query_params
  • session.filename
  • session.subnet
  • session.host
    • Description: ID of the currently selected host for the session.
    • Type: string or nil
    • Example: 'host1'
  • session.id
    • Description: ID of the session.
    • Type: string
    • Example: '8eb2c1bdc106-17d2ff-00000000'
  • session.session_type
    • Description: Type of the session.
    • Type: string
    • Example: 'initial' or 'instream'. Identical to the value of the Type argument of the session translation function.
  • session.is_managed
    • Description: Identifies managed sessions.
    • Type: boolean
    • Example: true if Type/session.session_type is 'instream'

Metatable session_groups

Defines a mapping from session group name to boolean, indicating whether the session belongs to the session group or not.

Example usage:

if session_groups.vod then print('vod') else print('not vod') end

or

if session_groups['vod'] then print('vod') else print('not vod') end

Global tables

In addition to the (non-iterable) metatables and (iterable) arguments above, the following global iterable tables are available from all Lua functions:

Table selection_input

See documentation for See documentation for request_translation_function. Values in the selection_input metatable will remain unchanged since a prior call to a request_translation_function.

3.1.1.5.6 - Routing Engine

How the routing engine works and how to configure it

The central component of ESB3024 Router is the routing engine. It is what analyses an incoming video request and determines which CDN, if any, to pass it on to based on a variety of factors such as geographic location, content type and current server load.

Like most of the router, the routing engine is configured through the /v2/configuration API, see Configuration for general configuration information. The basic structure looks something like this:

{
  // ...
  "cdns": [
    {
      "id": "cdn1",
      "http_port": 80,
      "https_port": 443,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      },
      "redirecting": false
    }
  ],
  "hosts": [
    {
      "id": "host1"
      "cdn_id": "cdn1",
      "host": "host1.example.com",
      "ipv6_address": "fc00:ed6e:0:201:0:aff:fe10:306b"
    },
    {
      "id": "host2"
      "cdn_id": "cdn1",
      "host": "host2.example.com",
    }
  ],
  // ...
  "routing": {
    "id": "routing_table",
    "member_order": "weighted",
    "members": [
      {
        "id": "node1",
        "host_id": "host1",
        "weight_function": "return 100"
      },
      {
        "id": "node2",
        "host_id": "host2",
        "weight_function": "return 100"
      }
    ],
    "weight_function": "return 1"
  },
  // ...
}

In the above example the routing engine configuration is contained in the "routing" field of the JSON structure. The "cdns" and "hosts" fields are included to provide a context and show where the "host_id" values come from.

Tree components

The "routing" part of the configuration is a tree of routing nodes. These nodes can be either of two types: A leaf node or a branch node. Leaf nodes contain references to CDN hosts while branch nodes contain a list of member nodes but do not reference any hosts itself.

All nodes, regardless of type, have a unique ID as well as a weight function. The ID is used to identify the node in e.g. rule evaluation metrics and the weight function is used to dynamically determine if a node should be evaluated for the incoming request.

Let us go through the two structures one by one and look at their fields and possible values.

Branch node

Branch nodes do not refer to any hosts by themselves, but contain member nodes that may be traversed in order to find a suitable host.

{
  "id": "branch_node_example",
  "members": [],
  "member_order": "weighted",
  "weight_function": "return 1"
}
  • "id": The unique identifier for a node. Its value cannot be used on any other node, not even a leaf node.
  • "weight_function": A Lua function body returning an integer value. Exactly how the return value is used depends on the parent node’s member_order field, but a higher value generally indicates higher likelihood of the node being traversed. The value of 0 or less means that this node should not be used.
  • "members": A list of child nodes that will be evaluated if this node is selected by the routing engine. How they are evaluated depends on the value of the member_order field.
  • "member_order: A string determining how this node is to be evaluated. Allowed values are "sequential", "sorted" and "weighted".

Member Order Evaluation

As mentioned above, there are three different member orders and they affect how children of a branch node are traversed.

"sequential" means that all children are evaluated in the order they are listed in the configuration. If a child’s weight function returns a positive value, it will be picked for traversal even if one of its siblings has a higher weight. In order to skip a child its weight function must return 0.

If a child is picked for traversal but none of the leaf nodes in its subtree return a positive weight the routing engine will move on to the next sibling and attempt to find a leaf node there instead. This will continue until a leaf node is found or the entire tree is exhausted. If no valid leaf is found an error will be sent to the client.

"sorted" will cause the route engine to compute the weight of each child node, using each child’s "weight_function" Lua code, sort them from highest to lowest and pick the first node.

If no leaf node within that child’s subtree is accepted, i.e. they all return 0 or less, then the next child will be traversed and so on until a suitable host is found or there are no more subtrees left to evaluate. If no host is found, an error message will be sent to the client.

"weighted" tells the routing engine to evaluate the weight functions for all children, and then pick one of them randomly with a probability equal to the child’s weight divided by the sum of the weights of all immediate children.

Just as with the other two variants, if no suitable leaf node is found within the child’s subtree one of its siblings is picked instead. The same random method is used to pick subsequent children until a leaf node is accepted or the entire tree is exhausted. An error message will be sent to the client if no host is found.

Leaf node

Leaf nodes contain a reference to a host object rather than more child nodes.

{
  "id": "leaf_node_example",
  "host_id": "cdn_host_id",
  "weight_function": "return 100"
}
  • "id": The unique identifier for a node. Its value cannot be used on any other node, not even a branch node.
  • "host_id": The ID of one of the hosts in the "hosts" list. Represents the host the client will be routed through if this leaf node is selected.
  • "weight_function": A Lua function body that returns the weight of this particular node. The return value is used by the parent node to determine which leaf node to select for the current request.

A Note on Weight Functions

While the primary and mandatory purpose of the weight function is to return a value to let the routing engine determine which leaf node is most suitable for a client request, it can do more things. It is, however, vital that a weight function always returns an integer value.

There is a global Lua context for the functions to use to set and read global states, third party software can be used to keep track of external states and values through the selection_input API. It is even possible to set up a dummy node that prints out debug information but always returns 0, in effect having nothing to do with the actual routing.

Due to the global nature of variables in Lua it is important to remember to declare any variables used for temporary calculations as local or risk cross-contamination between client requests. It is generally recommended to avoid using global variables at all in the router unless absolutely certain what the consequences may be.

A Practical Example

Imagine we have a system for a Swedish market, with capacity enough for most of the time, but with rented offload capacity in the third party CDN for peak hour traffic as well as for any clients connecting from outside of Sweden. The private CDN is separated in a host for live content and one for VOD, but the offload CDN has a single host capable of handling anything. The private CDN in this example will also report its remaining capacity in per cent to the selection_input variable capacity_percent and as long as at least 10 % is unused it should accept new requests.

The router configuration will have to set up a few hosts, classifiers for incoming requests and finally a routing tree which we will go through in detail further down:

{
  "cdns": [
    {
      "http_port": 80,
      "https_port": 443,
      "id": "offload",
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      },
      "redirecting": false
    },
    {
      "http_port": 80,
      "https_port": 443,
      "id": "cdn",
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      },
      "redirecting": false
    }
  ],
  "hosts": [
    {
      "cdn_id": "offload",
      "host": "offload.example",
      "ipv6_address": "fc00:ed6e:0:201:0:aff:fe10:306b",
      "id": "offload"
    },
    {
      "cdn_id": "cdn",
      "host": "vod.cdn.example",
      "id": "cdn_vod"
    },
    {
      "cdn_id": "cdn",
      "host": "live.cdn.example",
      "id": "cdn_live"
    }
  ],
  "session_groups": [
    {
      "id": 1,
      "name": "Not Sweden",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": true,
            "name": "Not Sweden",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "country": "Sweden"
            }
          }
        ]
      ]
    },
    {
      "id": 2,
      "name": "IsLive",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "Is live content",
            "rule": {
              "pattern": "*/live/*",
              "rule_type": "string_match_rule",
              "source": "session/content_url_path"
            }
          }
        ]
      ]
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "Offload if not Sweden",
        "host_id": "offload",
        "weight_function": "local retval = 0; if session_groups[\"Not Sweden\"] \
          then retval = 1; end; return retval"
      },
      {
        "id": "Private CDN",
        "member_order": "sorted",
        "members": [
          {
            "id": "live",
            "host_id": "cdn_live",
            "weight_function": "local retval = 0; if (selection_input.capacity_percent \
              or 0) > 10 and session_groups.IsLive then retval = 1; end; return retval"
          },
          {
            "id": "vod",
            "host_id": "cdn_vod",
            "weight_function": "local retval = 1; if (selection_input.capacity_percent \
              or 0) < 10 or session_groups.IsLive then retval = 0; end; return retval"
          }
        ],
        "weight_function": "return 1"
      },
      {
        "id": "Offload if no match",
        "host_id": "offload",
        "weight_function": "return 1"
      }
    ],
    "weight_function": "return 1"
  }
}

In order to understand this configuration, let us pretend some content is requested from a client:

  • Client IP: 94.127.35.102
  • Content path: "/live/news.m3u8"

The first thing that will happen is that the session group classifiers will analyse the request.

The IP is geolocated to Stockholm, Sweden. This means that the classifier named "Not Sweden" will be negative1, which in turn means that the session group named "Not Sweden" will also be negative.

The content path contains the string "/live/" which causes the classifier named "Is live content" to be positive and the corresponding session group "IsLive" will also become positive as a result.

With the classifiers done, it is time to traverse the routing tree.2

First the root node is evaluated. Its weight function returns a positive value, so its child nodes will be traversed.3 The member order is set to "sequential" so the routing engine goes through them one by one in the order they are written in the configuration and picks the first one to return a positive value.

"Offload if not Sweden" comes first, so its weight function is called. Since the session group "Not Sweden" is false, the weight function will return 0 and the engine moves on to the next sibling.

"Private CDN" has two children and the member order "sorted" meaning that they will both be evaluated, and the one with the highest weight will be picked. Assuming that the CDN capacity is sufficient, the child "live" will return 1 and "vod" will return 0, meaning that the host object with ID "cdn_live" will be selected and the client redirected to live.cdn.example/live/news.m3u8.

However, if the capacity is insufficient, neither child will return a positive value and the engine continues on to "Offload if no match" which always returns 1 and is therefore guaranteed to match and cause any unclaimed requests to end up at offload.example/live/news.m3u8.


  1. The classifier rule actually evaluates positively against IP:s located in Sweden, but since it is marked as inverted, the result is flipped and the whole thing ends up being negative instead. This is much simpler than trying to write rules that match against everything except Sweden. ↩︎

  2. Note that some of the weight functions are too long to fit on a single line. They have been split into multiple lines with a backslash indicating the break point. These backslashes and line breaks must be removed for the configuration to be valid and accepted by the router. ↩︎

  3. This is not strictly necessary. By default any node without an explicit weight function will have "return 100" instead. Explicit functions are used in this example for clarity. ↩︎

3.1.1.6 - Operations

Operators Guide

This guide describes how to perform day-to-day operations of the ACD Router and its associated services, collectively known as the Director.

Component Overview

To effectively operate the Director software, it is important to understand the composition of the various software components and how they are deployed.

Each Director instance functions as an independent system, comprising multiple containerized services. These containers are managed by a standard container runtime and are seamlessly integrated with the host’s operating system to enhance the overall operator experience.

For Red Hat Enterprise Linux 8 based operating systems, the Podman container runtime is used for container management. In the case of older Red Hat releases, Docker serves as the container runtime. Although both

runtimes

utilize the same OCI compliant container images and offer equivalent levels of abstraction, performance, and security, the key distinction lies in Podman’s ability to operate without an additional daemon service running on the host. Unlike Docker, Podman manages each container as a separate process, eliminating the reliance on a shared daemon and mitigating the risk of a single-point-of-failure scenario.

Although several distinct services make up the Director, the primary component is the router. The router is responsible for listening for incoming requests, processing the request, and redirecting the client to the appropriate host, or CDN to deliver the requested content.

Two additional containers are responsible for configuration management. Those are confd and confd-transformer. The former manages a local database of configuration metadata and provides a REST API for managing the configuration. The confd-transformer simply listens for configuration changes from confd and adapts that configuration to a format suitable for the router to ingest. For additional information about setting up and using confd see here..

The next two components, the edns-proxy and the convoy-bridge allow the router to communicate with an EDNS server for EDNS-based routing, and with synchronization with Convoy respectively. Additional information about the EDNS-Proxy is available here.. For the Convoy Bridge service see here..

The remaining containers are useful for metrics, monitoring, and alerting. These include prometheus and grafana for monitoring and analytics, fluentbit and alertmanager for monitoring and alarms, and grafana-loki for log aggregation.

3.1.1.6.1 - Services

Starting / Stopping / Monitoring Services

Each container shipped with the Director is fully-integrated with the systemd service on the host, enabling easy management using standard systemd commands. The logs for each container are also full-integrated with journald to simplify troubleshooting.

In order to integrate the Podman containers with systemd, a common prefix of acd- has been applied to each service name. For example the router container is managed by the service acd-router, and the confd container is managed by the service acd-confd. These same prefixed names apply while fetching logs via journald. This common prefix aids in grouping the related services as well as provides simpler filtering for tab-completion.

Starting / Stopping Services

Standard systemd commands should be used to start and stop the services.

  • systemctl start acd-router - Starts the router container.
  • systemctl stop acd-router - Stops the router container.
  • systemctl status acd-router - Displays the status of the router container.

Due to the limitation of needing the acd- prefix, it provides the ability to work with all ACD services in a group. For example:

  • systemctl status 'acd-*' - Display the status of all installed ACD components.
  • systemctl start 'acd-*' - Start all ACD components.

Logging

Each ACD component corresponds to a journal entry with the same unit name, with the acd- prefix. Standard journald commands can be used to view and manage the logging.

  • journalctl -u acd-router - Display the logs for the router container

Access Log

Access logs can be obtained from journald by using the following command:

journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1

This will output the router’s access logs in a standard format.

Troubleshooting

Some additional logging may be available in the filesystem, the paths of which can be determined by executing the ew-sysinfo command. See Diagnostics. for additional details.

3.1.1.6.2 - Docker

Special operating instructions for Red Hat Enterprise Linux 7

Support for Red Hat Enterprise Linux 7 and compatible Operating Systems is considered best-effort and the instructions included here are only maintained for archival purposes.

Since Red Hat Enterprise Linux 7 uses the Docker runtime, there are several key differences which are noted below.

Starting and Stopping Services

Since the containers are not integrated into systemd under Docker, standard Docker container management commands must be used to start and stop the services.

  • docker ps - Displays all running containers along with their relevant metadata.
  • docker stop router - Stops the router container.
  • docker start router - Starts the router container.

Obtaining container logs

The standard docker logs command should be used to view the logs for the various containers.

  • docker logs router - Display the complete log for the router container.
  • docker logs -f router - Display and tail the log for the router container.

Router Access Logs are not available under Docker.

3.1.1.7 - Convoy Bridge

Convoy Bridge Integration

The convoy-bridge is an optional integration service, pre-installed alongside the router which provides two-way communication between the router and a separate Convoy installation.

The convoy-bridge is designed to allow the Convoy account metadata to be available from within the router for such use-cases as inserting the account specific prefixes in the redirect URL and validating per-account internal security tokens. The service works by periodically polling the Convoy server for changes to the configuration, and when detected, the relevant configuration information is pushed to the router.

In addition, the convoy-bridge has the ability to integrate the router with the Convoy analytics service, such that client sessions started by the router are properly collected by Convoy, and are available in the dashboards.

Configuration

The convoy-bridge service is configured using confcli on the router host. All configuration for the convoy-bridge exists under the path integration.convoy.bridge.

{
  "logLevel": "info",
  "accounts": {
    "enabled": true,
    "dbUrl": "mysql://convoy:eith7jee@convoy:3306",
    "dbPollInterval": 60
  },
  "analytics": {
    "enabled": true,
    "brokers": ["broker1:9092", "broker2:9092"],
    "batchInterval": 10,
    "maxBatchSize": 500
  },
  "otherRouters": [
    {
      "url": "https://router2:5001",
      "apiKey": "key1",
      "validateCerts": true
    }
  ]
}

In the above configuration block, there are three main sections. The accounts section enables fetching account metadata from Convoy towards the router. The analytics section controls the integration between the router and the Convoy analytics service. The otherRouters section is used to synchronize additional router instances. The local router instance will always be implicitly included. Additional routers listed in this section will be handled by this instance of the convoy-bridge service.

Logging

For RHEL8 or later, the logs are available in the system journal and can be viewed using:

journalctl -u acd-convoy-bridge

For RHEL7, logs are available from within Docker and can be viewed with the command:

docker logs convoy-bridge

3.1.1.8 - Monitoring

Monitoring

3.1.1.8.1 - System troubleshooting

Using ew-sysinfo to monitor and troubleshoot ESB3024

ESB3024 contains the tool ew-sysinfo that gives an overview of how the system is doing. Simply use the command and the tool will output information about the system and the installed ESB3024 services.

The output format can be changed using the --format flag, possible values are human (default) and json, e.g.:

$ ew-sysinfo
system:
   os: ['5.4.17-2136.321.4.el8uek.x86_64', 'Oracle Linux Server 8.8']
   cpu_cores: 2
   cpu_load_average: [0.03, 0.03, 0.0]
   memory_usage: 478 MB
   memory_load_average: [0.03, 0.03, 0.0]
   boot_time: 2023-09-08T08:30:57Z
   uptime: 6 days, 3:43:44.640665
   processes: 122
   open_sockets:
      ipv4: 12
      ipv6: 18
      ip_total: 30
      tcp_over_ipv4: 9
      tcp_over_ipv6: 16
      tcp_total: 25
      udp_over_ipv4: 3
      udp_over_ipv6: 2
      udp_total: 5
      total: 145
system_disk (/):
   total: 33271 MB
   used: 7978 MB (24.00%)
   free: 25293 MB
journal_disk (/run/log/journal):
   total: 1954 MB
   used: 217 MB (11.10%)
   free: 1736 MB
vulnerabilities:
   meltdown: Mitigation: PTI
   spectre_v1: Mitigation: usercopy/swapgs barriers and __user pointer sanitization
   spectre_v2: Mitigation: Retpolines, STIBP: disabled, RSB filling, PBRSB-eIBRS: Not affected
processes:
   orc-re:
      pid: 177199
      status: sleeping
      cpu_usage_percent: 1.0%
      cpu_load_average: 131.11%
      memory_usage: 14 MB (0.38%)
      num_threads: 10
hints:
   get_raw_router_config: cat /opt/edgeware/acd/router/cache/config.json
   get_confd_config: cat /opt/edgeware/acd/confd/store/__active
   get_router_logs: journalctl -u acd-router
   get_edns_proxy_logs: journalctl -u acd-edns-proxy
   check_firewall_status: systemctl status firewalld
   check_firewall_config: iptables -nvL
# For --format=json, it's recommended to pipe the output to a JSON interpreter
# such as jq

$ ew-sysinfo --format=json | jq
{
  "system": {
    "os": [
      "5.4.17-2136.321.4.el8uek.x86_64",
      "Oracle Linux Server 8.8"
    ],
    "cpu_cores": 2,
    "cpu_load_average": [
      0.01,
      0.0,
      0.0
    ],
    "memory_usage": "479 MB",
    "memory_load_average": [
      0.01,
      0.0,
      0.0
    ],
    "boot_time": "2023-09-08 08:30:57",
    "uptime": "6 days, 5:12:24.617114",
    "processes": 123,
    "open_sockets": {
      "ipv4": 13,
      "ipv6": 18,
      "ip_total": 31,
      "tcp_over_ipv4": 10,
      "tcp_over_ipv6": 16,
      "tcp_total": 26,
      "udp_over_ipv4": 3,
      "udp_over_ipv6": 2,
      "udp_total": 5,
      "total": 146
    }
  },
  "system_disk (/)": {
    "total": "33271 MB",
    "used": "7977 MB (24.00%)",
    "free": "25293 MB"
  },
  "journal_disk (/run/log/journal)": {
    "total": "1954 MB",
    "used": "225 MB (11.50%)",
    "free": "1728 MB"
  },
  "vulnerabilities": {
    "meltdown": "Mitigation: PTI",
    "spectre_v1": "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
    "spectre_v2": "Mitigation: Retpolines, STIBP: disabled, RSB filling, PBRSB-eIBRS: Not affected"
  },
  "processes": {
    "orc-re": {
      "pid": 177199,
      "status": "sleeping",
      "cpu_usage_percent": "0.0%",
      "cpu_load_average": "137.63%",
      "memory_usage": "14 MB (0.38%)",
      "num_threads": 10
    }
  }
}

Note that your system might have different monitored processes and field names.

The field hints is different from the rest. It lists common commands that can be used to further monitor system performance, useful for quickly troubleshooting a faulty system.

3.1.1.8.2 - Scraping data with Prometheus

Prometheus is a third-party data scraper which is installed as a containerized service in the default installation of ESB3024 Router. It periodically reads metrics data from different services, such as acd-router, aggregates it and makes it available to other services that visualize the data. Those services include Grafana and Alertmanager.

The Prometheus configuration file can be found on the host at /opt/edgeware/acd/prometheus/prometheus.yaml.

Accessing Prometheus

Prometheus has a web interface that is listening for HTTP connections on port 9090. There is no authentication, so anyone who has access to the host that is running Prometheus can access the interface.

Starting / Stopping Prometheus

After the service is configured, it can be managed via systemd, under the service unit acd-prometheus.

systemctl start acd-prometheus

For EL7 systems running under Docker, the container must be started or stopped using the respective Docker start/stop commands. Note that the acd- prefix is not applicable under Docker.

docker start prometheus

Logging

The container logs are automatically published to the system journal, under the same unit descriptor, and can be viewed using journalctl

journalctl -u acd-prometheus

For EL7 systems running under Docker, the container logs can only be viewed using the docker logs command. Note that the acd- prefix is not applicable under Docker.

docker logs prometheus

3.1.1.8.3 - Visualizing data with Grafana

3.1.1.8.3.1 - Managing Grafana

Grafana displays graphs based on data from Prometheus. A default deployment of Grafana is running in a container alongside ESB3024 Router.

Grafana’s configuration and runtime files are stored under /opt/edgeware/acd/grafana. It comes with default dashboards that are documented at Grafana dashboards.

Accessing Grafana

Grafana’s web interface is listening for HTTP connections on port 3000. It has two default accounts, edgeware and admin.

The edgeware account can only view graphs, while the admin account can also edit graphs. The accounts with default passwords are shown in the table below.

AccountDefault password
edgewareedgeware
adminedgeware

Starting / Stopping Grafana

Grafana can be managed via systemd, under the service unit acd-grafana.

systemctl start acd-grafana

For EL7 systems running under Docker, the container must be started or stopped using the respective Docker start/stop commands. Note that the acd- prefix is not applicable under Docker.

docker start grafana

Logging

The container logs are automatically published to the system journal, under the same unit descriptor, and can be viewed using journalctl

journalctl -u acd-grafana

For EL7 systems running under Docker, the container logs can only be viewed using the docker logs command. Note that the acd- prefix is not applicable under Docker.

docker logs grafana

3.1.1.8.3.2 - Grafana Dashboards

Dashboards in default Grafana installation

Grafana will be populated with pre-configured graphs which present some metrics on a time scale. Below is a comprehensive list of those dashboards, along with short descriptions.

Router Monitoring dashboard

This dashboard is by default set as home directory - it’s what user will see after logging in.

Number Of Initial Routing Decisions

HTTP Status Codes

Total number of responses sent back to incoming requests, shown by their status codes. Metric: client-response-status

Incoming HTTP and HTTPS Requests

Total number of incoming requests that were deemed valid, divided into SSL and Unencrypted categories. Metric: num_valid_http_requests

Debugging Information dashboard

Number of Lua Exceptions

Number of exceptions encountered so far while evaluating Lua rules. Metric: lua_num_errors

Number of Lua Contexts

Number of active Lua interpreters, both running and idle. Metric: lua_num_evaluators

Time Spent In Lua

Number of microseconds the Lua interpreters were running. Metric: lua_time_spent

Router Latencies

Histogram-like graph showing how many responses were sent within the given latency interval. Metric: orc_latency_bucket

Internal debugging

A folder that contains dashboards intended for internal use.

ACD: Incoming Internet Connections dashboard

SSL Warnings

Rate of warnings logged during TLS connections Metric: num_ssl_warnings_total

SSL Errors

Rate of errors logged during TLS connections Metric: num_ssl_errors_total

Valid Internet HTTPS Requests

Rate of incoming requests that were deemed valid, HTTPS only. Metric: num_valid_http_requests

Invalid Internet HTTPS Requests

Rate of incoming requests that were deemed invalid, HTTPS only. Metric: num_invalid_http_requests

Valid Internet HTTP Requests

Rate of incoming requests that were deemed valid, HTTP only. Metric: num_valid_http_requests

Invalid Internet HTTP Requests

Rate of incoming requests that were deemed invalid, HTTP only. Metric: num_invalid_http_requests

Prometheus: ACD dashboard

Logged Warnings

Rate of logged warnings since the router has started, divided into CDN-related and CDN-unrelated. Metric: num_log_warnings_total

Logged Errors

Rate of logged errors since the router has started. Metric: num_log_errors_total

HTTP Requests

Rate of responses sent to incoming connections. Metric: orc_latency_count

Number Of Active Sessions

Number of sessions opened on router that are still active. Metric: num_sessions

Total Number Of Sessions

Total number of sessions opened on router. Metric: num_sessions

Session Type Counts (Non-Stacked)

Number of active sessions divided by type; see metric documentation linked below for up-to-date list of types. Metric: num_sessions

Prometheus/ACD: Subrunners

Client Connections

Number of currently open client connections per subrunner. Metric: subrunner_client_conns

Asynchronous Queues (Current)

Number of queued events per subrunner, roughly corresponding to load. Metric: subrunner_async_queue

Used <Send/receive> Data Blocks

Number of send or receive data blocks currently in use per subrunner, as decided by the “Send/receive” drop down box. Metric: subrunner_used_send_data_blocks and subrunner_used_receive_data_blocks

Asynchronous Queues (Max)

Maximum number of events waiting in queue. Metric: subrunner_max_async_queue

Total <Send/receive> Data Blocks

Number of send or receive data blocks allocated per subrunner, as decided by the “Send/receive” drop down box. Metric: subrunner_total_send_data_blocks and subrunner_total_receive_data_blocks

Low Queue (Current)

Number of low priority events queued per subrunner. Metric: subrunner_low_queue

Medium Queue (Current)

Number of medium priority events queued per subrunner. Metric: subrunner_medium_queue

High Queue (Current)

Number of high priority events queued per subrunner. Metric: subrunner_high_queue

Low Queue (Max)

Maximum number of events waiting in low priority queue. Metric: subrunner_max_low_queue

Medium Queue (Max)

Maximum number of events waiting in medium priority queue. Metric: subrunner_max_medium_queue

High Queue (Max)

Maximum number of events waiting in high priority queue. Metric: subrunner_max_high_queue

Wakeups

The number of times a subrunner has been waken up from sleep. Metric: subrunner_io_wakeups

Overloaded

The number of times the number of queued events for a subrunner exceeded its maximum. Metric: subrunner_times_worker_overloaded

Autopause

Number of sockets that have been automatically paused. This happens when the work manager is under heavy load. Metric: subrunner_io_autopause_sockets

3.1.1.8.4 - Alarms and Alerting

Configuring alarms and alerting

Alerts are generated by the third-party service Prometheus, which sends them to the Alertmanager service. A default containerized instance of Alertmanager is deployed alongside ESB3024 Router. Out of the box, Alertmanager ships with only a sample configuration file, and will require manual configuration prior to enabling the alerting functionality. Due to the many different possible configurations for how alerts are both detected and where they are pushed, the official Alertmanager documentation should be followed for how to configure the service.

The router ships with Alertmanager 0.25, the documentation for which can be found at prometheus.io. The Alertmanager configuration file can be found on the host at /opt/edgeware/acd/alertmanager/alertmanager.yml.

Accessing Alertmanager

Alertmanager has a web interface that is listening for HTTP connections on port 9093. There is no authentication, so anyone who has access to the host that is running Alertmanager can access the interface.

Starting / Stopping Alertmanager

After the service is configured, it can be managed via systemd, under the service unit acd-alertmanager.

systemctl start acd-alertmanager

For EL7 systems running under Docker, the container must be started or stopped using the respective Docker start/stop commands. Note that the acd- prefix is not applicable under Docker.

docker start alertmanager

Logging

The container logs are automatically published to the system journal, under the same unit descriptor, and can be viewed using journalctl

journalctl -u acd-alertmanager

For EL7 systems running under Docker, the container logs can only be viewed using the docker logs command. Note that the acd- prefix is not applicable under Docker.

docker logs alertmanager

3.1.1.8.5 - Monitoring multiple routers

By default an instance of Prometheus only monitors the ESB3024 Router that is installed on the same host as where Prometheus is installed. It is possible to make it monitor other router instances and visualize all instances on one Grafana instance.

Configuring of Prometheus

This is configured in the scraping configuration of Prometheus, which is found in the file /opt/edgeware/acd/prometheus/prometheus.yaml, which typically looks like this:

global:
  scrape_interval:     15s

rule_files:
  - recording-rules.yaml

# A scrape configuration for router metrics
scrape_configs:
  - job_name: 'router-scraper'
    scheme: https
    tls_config:
      insecure_skip_verify: true
    static_configs:
    - targets:
      - acd-router-1:5001
    metrics_path: /m1/v1/metrics
    honor_timestamps: true
  - job_name: 'edns-proxy-scraper'
    scheme: http
    static_configs:
    - targets:
      - acd-router-1:8888
    metrics_path: /metrics
    honor_timestamps: true

More routers can be added to the scrape configuration by simply adding more routers under targets in the scraper jobs.

For instance, to monitor acd-router-2 and acd-router-3 along acd-router-1, the configuration file needs to be modified like this:

global:
  scrape_interval:     15s

rule_files:
  - recording-rules.yaml

# A scrape configuration for router metrics
scrape_configs:
  - job_name: 'router-scraper'
    scheme: https
    tls_config:
      insecure_skip_verify: true
    static_configs:
    - targets:
      - acd-router-1:5001
      - acd-router-2:5001
      - acd-router-3:5001
    metrics_path: /m1/v1/metrics
    honor_timestamps: true
  - job_name: 'edns-proxy-scraper'
    scheme: http
    static_configs:
    - targets:
      - acd-router-1:8888
      - acd-router-2:8888
      - acd-router-3:8888
    metrics_path: /metrics
    honor_timestamps: true

After the file has been modified, Prometheus needs to be restarted by typing

systemctl restart acd-prometheus

It is possible to use the same configuration on multiple routers, so that all routers in a deployment can monitor each other.

Selecting router in Grafana

In the top left corner the Grafana dashboards have a drop-down menu labeled “ACD Router”, which allows to choose which router to monitor.

3.1.1.8.6 - Routing Rule Evaluation Metrics

Node Visit counters

ESB3024 Router counts the number of times a node and any of its children is selected in the routing table.

The visit counters can be retrieved with the following end points:

/v1/node_visits

  • Returns visit counters for each node as a flat list of host:counter pairs in JSON.

  • Example output:

    {
      "node1": "1",
      "node2": "1",
      "node3": "1",
      "top": "3"
    }
    

/v1/node_visits_graph

  • Returns a full graph of nodes with their respective visit counters in GraphML.

  • Example output:

    <?xml version="1.0"?>
    <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
    http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
      <key id="visits" for="node" attr.name="visits" attr.type="string" />
      <graph id="G" edgedefault="directed">
        <node id="routing_table">
          <data key="visits">5</data>
        </node>
        <node id="cdn1">
          <data key="visits">1</data>
        </node>
        <node id="node1">
          <data key="visits">1</data>
        </node>
        <node id="cdn2">
          <data key="visits">2</data>
        </node>
        <node id="node2">
          <data key="visits">2</data>
        </node>
        <node id="cdn3">
          <data key="visits">2</data>
        </node>
        <node id="node3">
          <data key="visits">2</data>
        </node>
        <edge id="e0" source="cdn1" target="node1" />
        <edge id="e1" source="routing_table" target="cdn1" />
        <edge id="e2" source="cdn2" target="node2" />
        <edge id="e3" source="routing_table" target="cdn2" />
        <edge id="e4" source="cdn3" target="node3" />
        <edge id="e5" source="routing_table" target="cdn3" />
      </graph>
    </graphml>
    
  • To receive the graph as JSON, specify Accept:application/json in the request headers.

  • Example output:

    {
      "edges": [
        {
          "source": "cdn1",
          "target": "node1"
        },
        {
          "source": "routing_table",
          "target": "cdn1"
        },
        {
          "source": "cdn2",
          "target": "node2"
        },
        {
          "source": "routing_table",
          "target": "cdn2"
        },
        {
          "source": "cdn3",
          "target": "node3"
        },
        {
          "source": "routing_table",
          "target": "cdn3"
        }
      ],
      "nodes": [
        {
          "id": "routing_table",
          "visits": "5"
        },
        {
          "id": "cdn1",
          "visits": "1"
        },
        {
          "id": "node1",
          "visits": "1"
        },
        {
          "id": "cdn2",
          "visits": "2"
        },
        {
          "id": "node2",
          "visits": "2"
        },
        {
          "id": "cdn3",
          "visits": "2"
        },
        {
          "id": "node3",
          "visits": "2"
        }
      ]
    }
    

Resetting Visit Counters

A node visit counter with an id not matching any node id of a newly applied routing table is destroyed.

Reset all counters to zero by momentarily applying a configuration with a placeholder routing root node, that has unique id and an empty members list, e.g:

"routing": {
  "id": "empty_routing_table",
  "members": []
}

… and immediately reapply the desired configuration.

3.1.1.8.7 - Metrics

Metrics endpoint

ESB3024 Router collects a large number of metrics that can give insight into it’s condition at runtime. Those metrics are available in Prometheustext-based exposition format at endpoint :5001/m1/v1/metrics.

Below is the description of these metrics along with their labels.

client_response_status

Number of responses sent back to incoming requests.

lua_num_errors

Number of errors encountered when evaluating Lua rules.

  • Type: counter

lua_num_evaluators

Number of Lua rules evaluators (active interpreters).

lua_time_spent

Time spent by running Lua evaluators, in microseconds.

  • Type: counter

num_configuration_changes

Number of times configuration has been changed since the router has started.

  • Type: counter

num_endpoint_requests

Number of requests redirected per CDN endpoint.

  • Type: counter
  • Labels:
    • endpoint - CDN endpoint address.
    • selector - whether the request was counted during initial or instream selection.

num_invalid_http_requests

Number of client requests that either use wrong method or wrong URL path. Also number of all requests that cannot be parsed as HTTP.

  • Type: counter
  • Labels:
    • source - name of internal filter function that classified request as invalid. Probably not of much use outside debugging.
    • type - whether the request was HTTP (Unencrypted) or HTTPS (SSL).

num_log_errors_total

Number of logged errors since the router has started.

  • Type: counter

num_log_warnings_total

Number of logged warnings since the router has started.

  • Type: counter

num_managed_redirects

Number of redirects to the router itself, which allows session management.

  • Type: counter

num_manifests

Number of cached manifests.

  • Type: gauge
  • Labels:
    • count - state of manifest in cache, can be either lru, evicted or total.

num_qoe_losses

Number of “lost” QoE decisions per CDN.

  • Type: counter
  • Labels:
    • cdn_id - ID of CDN that loose QoE battle.
    • cdn_name - name of CDN that loose QoE battle.
    • selector - whether the decision was taken during initial or instream selection.

num_qoe_wins

Number of “won” QoE decisions per CDN.

  • Type: counter
  • Labels:
    • cdn_id - ID of CDN that won QoE battle.
    • cdn_name - name of CDN that won QoE battle.
    • selector - whether the decision was taken during initial or instream selection.

num_rejected_requests

Deprecated, should always be at 0.

  • Type: counter
  • Labels:
    • selector - whether the request was counted during initial or instream selection.

num_requests

Total number of requests received by the router.

  • Type: counter
  • Labels:
    • selector - whether the request was counted during initial or instream selection.

num_sessions

Number of sessions opened on router.

  • Type: gauge
  • Labels:
    • state - either active or inactive.
    • type - one of: initial, instream, qoe_on, qoe_off, qoe_agent or sp_agent.

num_ssl_errors_total

Number of all errors logged during TLS connections, both incoming and outgoing.

  • Type: counter

num_ssl_warnings_total

Number of all warnings logged during TLS connections, both incoming and outgoing.

  • Type: counter
  • Labels:
    • category - which kind of TLS connection triggered the warning. Can be one of: cdn, content, generic, repeated_session or empty.

num_unhandled_requests

Number of requests for which no CDN could be found.

  • Type: counter
  • Labels:
    • selector - whether the request was counted during initial or instream selection.

num_unmanaged_redirects

Number of redirects to “outside” the router - usually to CDN.

  • Type: counter
  • Labels:
    • cdn_id - ID of CDN picked for redirection.
    • cdn_name - name of CDN picked for redirection.
    • selector - whether the redirect was result of initial or instream selection.

num_valid_http_requests

Number of received requests that were not deemed invalid, see num_invalid_http_requests.

  • Type: counter
  • Labels:
    • source - name of internal filter function that classified request as invalid. Probably not of much use outside debugging.
    • type - whether the request was HTTP (Unencrypted) or HTTPS (SSL).

orc_latency_bucket

Total number of responses sorted into “latency buckets” - labels denoting latency interval.

  • Type: counter
  • Labels:
    • le - latency bucket that given response falls into.
    • orc_status_code - HTTP status code of given response.

orc_latency_count

Total number of responses.

  • Type: counter
  • Labels:
    • tls - whether the response was sent via SSL/TLS connection or not.
    • orc_status_code - HTTP status code of given response.

ssl_certificate_days_remaining

Number of days until a SSL certificate expires.

  • Type: gauge
  • Labels:
    • domain - the common name of the domain that the certificate authenticates.
    • not_valid_after - the expiry time of the certificate.
    • not_valid_before - when the certificate starts being valid.
    • usable - if the certificate is usable to the router, see the ssl_certificate_usable_count metric for an explanation.

ssl_certificate_usable_count

Number of usable SSL certificates. A certificate is usable if it is valid and authenticates a domain name that points to the router.

  • Type: gauge

3.1.1.8.7.1 - Internal Metrics

Internal Metrics

A subrunner is an internal module of ESB3024 Router which handles routing requests. The subrunner metrics are technical and mainly of interest for Agile Content. These metrics will be briefly described here.

subrunner_async_queue

Number of queued events per subrunner, roughly corresponding to load.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_client_conns

Number of currently open client connections per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_high_queue

Number of high priority events queued per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_io_autopause_sockets

Number of sockets that have been automatically paused. This happens when the work manager is under heavy load.

  • Type: counter
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_io_send_data_fast_attempts

A fast data path was added that in many cases increases the performance of the router. This metric was added to verify that the fast data path is taken.

  • Type: counter
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_io_wakeups

The number of times a subrunner has been waken up from sleep.

  • Type: counter
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_low_queue

Number of low priority events queued per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_max_async_queue

Maximum number of events waiting in queue.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_max_high_queue

Maximum number of events waiting in high priority queue.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_max_low_queue

Maximum number of events waiting in low priority queue.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_max_medium_queue

Maximum number of events waiting in medium priority queue.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_medium_queue

Number of medium priority events queued per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_times_worker_overloaded

Number of times when queued events for given subrunner exceeded the tuning.overload_threshold value (defaults to 32).

  • Type: counter
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_total_receive_data_blocks

Number of receive data blocks allocated per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_total_send_data_blocks

Number of send data blocks allocated per subrunner.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_used_receive_data_blocks

Number of receive data blocks currently in use per subrunner. Same as subrunner_total_receive_data_blocks.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

subrunner_used_send_data_blocks

Number of send data blocks currently in use per subrunner. Same as subrunner_total_send_data_blocks.

  • Type: gauge
  • Labels:
    • subrunner_id - ID of given subrunner.

3.1.1.9 - Releases

ESB3024 Router releases

3.1.1.9.1 - Release esb3024-1.10.1

Build date

2024-04-18

Release status

Type: production

Breaking changes

If upgrading from a release prior to 1.10.0, the configuration needs to be manually updated after upgrading to 1.10.1. See Installing release 1.10.x for more information.

Change log

  • NEW: Change predictive load balancing functions to use megabits/s [ESB3024-932]
  • FIXED: Logic classifier statements can consume all memory [ESB3024-937]

Known Limitations

None

3.1.1.9.2 - Release esb3024-1.10.0

Build date

2024-04-02

Release status

Type: production

Breaking changes

The configuration needs to be manually updated after upgrading to 1.10.0. See Installing release 1.10.0 for more information.

Change log

  • NEW: Use metrics from streamers in routing decisions. Added standard library Lua support to use hardware metrics in routing decisions. Added host health checks in the configuration. [ESB3024-154]
  • NEW: Remove unused field “apiKey” from configuration [ESB3024-426]
  • NEW: Support integration with Convoy Analytics [ESB3024-694]
  • NEW: Support combining classifiers using AND/OR in session groups [ESB3024-776]
  • NEW: Enable access logging by default [ESB3024-816]
  • NEW: Improved Lua translation function error handling [ESB3024-874]
  • NEW: Updated predictive load balancing functions to support hardware metrics [ESB3024-887]
  • NEW: Remove apiKey from documentation [ESB3024-927]
  • FIXED: Condition with ‘or’ statement sometimes generate faulty Lua [ESB3024-863]

Known Limitations

None

3.1.1.9.3 - Release esb3024-1.8.0

Build date

2024-02-07

Release status

Type: production

Breaking changes

The configuration needs to be manually updated after upgrading to 1.8.0. See Installing release 1.8.0 for more information.

Change log

  • NEW: Remove ESB3026 Account Monitor from installer. [ESB3024-354]
  • NEW: Improve selection input endpoint flexibility and security. See API overview documentation for details. [ESB3024-423]
  • NEW: Support anonymous geoip rules [ESB3024-699]
  • NEW: Add ASN IDs list classifiers to confd [ESB3024-778]
  • NEW: Enable content popularity tracking by default. Added option to enable/disable in confd/confcli. [ESB3024-781]
  • NEW: Remove dependency on session from security token verification [ESB3024-809]
  • FIXED: A lot of JSON output on failed routing. HTTP response no longer contains internal routing information. [ESB3024-523]
  • FIXED: Returning Lua table from Lua debug endpoint can crash router. Selection Input values now support floating point values in a Lua context [ESB3024-691]
  • FIXED: Floating point selection inputs are truncated to ints when passed to Lua context [ESB3024-710]
  • FIXED: Race condition between RestApi and Session [ESB3024-753]
  • FIXED: confd/concli doesn’t support “forward_host_header” on hostGroups [ESB3024-761]
  • FIXED: Support Lua vector keys in reverse order [ESB3024-780]

Known Limitations

None

3.1.1.9.4 - Release esb3024-1.6.0

Build date

2023-12-20

Release status

Type: production

Breaking changes

The configuration needs to be manually updated after upgrading to 1.6.0. See configuration changes between 1.4.0 and 1.6.0 for more information.

Change log

  • NEW: Remove the lua_paths array from the config . Lua scripts are now added using a REST API on the /v1/lua/ endpoint. [ESB3024-204]
  • NEW: Separate “account-monitor” from installer [ESB3024-238]
  • NEW: Consistent hashing based routing . Added support for content distribution control for load balancing and cache partitioning [ESB3024-274]
  • NEW: Predictive load balancing . Account for in-transit traffic to prevent cache overload when there is a sudden burst of new sessions. [ESB3024-275]
  • NEW: Support Convoy security tokens [ESB3024-386]
  • NEW: Expose quality, host and session ID in the session object in Lua context [ESB3024-429]
  • NEW: Support upgrade of system python in installer [ESB3024-442]
  • NEW: Do not configure selinux and firewalld in installer [ESB3024-493]
  • NEW: Convoy Distribution/Account integration [ESB3024-503]
  • NEW: Make eDNS server port configurable . The router configuration hosts.proxy_address has been renamed to hosts.proxy_url and now accepts a port that is used when connecting to the proxy. The cdns.http_port and cdns.https_port configurations now configure the port that is used for connecting to the EDNS server, before they configured the port that was used for connecting to the proxy. [ESB3024-509]
  • NEW: Expand node table in Lua context . New fields are: node.id, node.visits, host.id, host.recent_selections [ESB3024-630]
  • FIXED: DNS lookup can fail . DNS lookup can fail when same content requested from both IPv4 and IPv6 clients [ESB3024-427]
  • FIXED: Failed DNS requests are not retried . Fixed bug where failed eDNS requests were not retried [ESB3024-504]
  • FIXED: Lua functions are not updated when uploaded [ESB3024-544]
  • FIXED: Undefined metatable fields evaluate to false rather than nil [ESB3024-642]
  • FIXED: Evaluator::evaluate() doesn’t support different types of its variadic arguments [ESB3024-687]
  • FIXED: Segfault when accessing REST api with empty path [ESB3024-752]
  • FIXED: Container UID/GID may change between versions [ESB3024-755]

3.1.1.9.5 - Release esb3024-1.4.0

Build date

2023-09-29

Release status

Type: production

Breaking changes

  • All configuration is now stored under /opt/edgeware/acd, see [ESB3024-425]. Any configuration that is to be kept needs to be manually migrated.
    Typically /opt/edgeware/etc/confd/store/store.json needs to be copied to /opt/edgeware/acd/confd/store/store.json, /opt/edgeware/var/lib/acd-router/cached-acd-router-config.json needs to be copied to /opt/edgeware/acd/router/cache/config.json and /opt/edgeware/var/lib/acd-router/cached-router-rest-api-key.json needs to be copied to /opt/edgeware/acd/router/cache/rest-api-key.json. Custom Lua functions need to be migrated from /opt/edgeware/acd/var/lib/custom_lua to /opt/edgeware/acd/router/lib/custom_lua. The Prometheus and Grafana configurations also need to be copied if they have been modified.

    The following changes were made to the confcli configuration [ESB3024-455].
  • The rule fields inside the routing rule items were renamed to condition to avoid confusion with the rules list. This applies to the blocks allow, deny, split and weighted.
  • The popularityThreshold in the contentPopularity routing rule was renamed to contentPopularityCutoff.

Change log

  • NEW: 1-Page Status Report . Added command ew-sysinfo that can be used on any machine with an ESB3024 installation. The command outputs various information about the system and installed services which can be used for monitoring and diagnostics. [ESB3024-391]
  • NEW: Update routing rule property names . Routing rule property names updated for consistency and clarity [ESB3024-455]
  • FIXED: Deleting confd API array element inside oneOf object fails [ESB3024-355]
  • FIXED: Container logging not captured by systemd until services are restarted [ESB3024-359]
  • FIXED: Alertmanager restricts the configuration to a single file [ESB3024-381]
  • FIXED: Split rules in routing configuration should terminate on error [ESB3024-420]
  • FIXED: Improve alert configuration in Prometheus [ESB3024-422]
  • FIXED: Inconsistent storage paths of service configuration and data [ESB3024-425]
  • FIXED: confd-transformer is not working in el7 [ESB3024-430]

3.1.1.9.6 - Release acd-router-1.2.3

Build date

2023-08-16

Release status

Type: production

Breaking changes

None

Change log

  • NEW: Add more classifiers . New classifiers are hostName, contentUrlPath, userAgent, contentUrlQueryParameters [ESB3024-298]
  • NEW: Add allow- and denylist rule blocks [ESB3024-380]
  • NEW: Add enhanced validation of scriptable field in routing rules [ESB3024-393]
  • NEW: Add services to the config tree [ESB3024-410]
  • NEW: Prohibit unknown configuration properties [ESB3024-416]
  • FIXED: Duplicate session group IDs are allowed [ESB3024-49]
  • FIXED: Invalid URL returned for IPv4 requests when using a DNS backend [ESB3024-374]
  • FIXED: Not possible to set log level in eDNS proxy [ESB3024-378]
  • FIXED: Instream selection fails when DASH manifest has template paths using “../” [ESB3024-384]

3.1.1.9.7 - Release acd-router-1.2.0

Build date

2023-06-27

Release status

Type: production

Breaking changes

None

Change log

  • NEW: Add meta fields to the configuration . The API now allows the meta data fields “created_at”, “source” and “source_checksum” that can be used for the API consumer to track who did what change when.
  • NEW: Control routing behavior based on backend response code . This gives control over when to return backend response codes to the end user and when to trigger a failover to another CDN or host.
  • NEW: Manage Lua scripts via API
  • NEW: Support popularity-based routing . Content can be ordered in multiple groups with descending popularity. Popularity can also be tracked per session group.
  • NEW: Improved support for IPv6 routing . It is now possible to select backend depending on the IP protocol version.
  • NEW: Add DNS backend support . This allows delegating routing decisions to an EDNS0 server.
  • NEW: Support HMAC with SHA256 in Lua scripts
  • NEW: Add alarm support . The alarms are handled by Prometheus and Alertmanager.
  • NEW: Support saving Grafana Dashboards
  • NEW: Add simplified configuration API and CLI tool . A new configuration API with an easier to use model has been added. The “confcli” tool present in many other Edgeware products is now supported.
  • NEW: Add authentication to the REST API
  • FIXED: Host headers not forwarded to Request Router when ‘redirecting: true’ is enabled
  • FIXED: IP range classifier 0.0.0.0/0 does not work in session groups

3.1.1.9.8 - Release acd-router-1.0.0

First production

Build date

2022-11-22

Release status

Type: First production release

Known Limitations

The setting “allowed_clients” should not be used since the functionality does not work as expected.

Change log

  • Flexible routing rule engine with support for Lua plugins. Support many use cases, including CDN Offload and CDN Selection.
  • Advanced client classification mechanisms for routing based on group memberships (device type, content type, etc).
  • Geobased routing including dedicated high-performing API for subnet matching, associating an incoming request with a region.
  • Integration API to feed the service with arbitrary variables to use for routing decisions. Can be used to get streaming bitrate in public CDNs, status from network probes, etc.
  • Flexible request/response translation manipulation on the client facing interface. Can be used for URL manipulation, encoding/decoding tokens or adapting the interface to e.g. the PowerDNS backend protocol.
  • Metrics API that can be monitored with standard monitoring software. Out-of-the-box integration with Prometheus and Grafana.
  • Robust deployment with each service instance running independently, and allowing the service to stay in operational state even when backends become temporarily unavailable.
  • RHEL 7/8 support.
  • Online documentation at https://docs.agilecontent.com/

3.1.1.10 - Glossary

ESB3024 Router definitions of commonly used terms
ACD
Agile CDN Director. See “Director”.
Confd
A backend service that hosts the service configuration. Comes with an API, a CLI and a GUI.
Classifier
A filter that associate a request with a tag that can be used to define session groups.
Director
The Agile Delivery OTT router and related services.
ESB
A software bundle that can be separately installed and upgraded, and is released as one entity with one change log. Each ESB is identified with a number. Over time, features and functions within an ESB can change.
Lua
A widely available scripting language that is often used to extend the capabilities of a piece of software.
Router
Unless otherwise specified, an HTTP router that manages an OTT session using HTTP redirect. There are also ways to use DNS instead of HTTP.
Selection Input API
Data posted to this API can be accessed by the routing rules and hence influence the routing decisions.
Subnet API
An API to define mappings between subnets and names (typically regions) for those subnets. Routing rules can then refer to the names rather than the subnets.
Session Group
A handle on a group of requests, defined via classifiers.

3.1.2 - ESB3032 ACD Aggregator

Aggregates CDN statistics

3.1.2.1 - Getting Started

Getting started with the Account Aggregator

The account aggregator is a service responsible for monitoring various input streams, compiling and aggregating statistics, and selectively reporting to one or more output streams. It acts primarily as a centralized collector of metrics which may have various aggregations applied before being published to one or more endpoints.

Modes of operation

There are two primary modes of operation, a live-monitoring mode, as well as a reporting mode. The live-monitoring mode measures the account records in real-time, filters, and aggregates the data to the various outputs in real-time. In this mode, only the most recent data will be considered, and any historical context upon startup may be skipped. In the reporting mode, the account record data will be consumed and processed in the order in which they were published to Kafka, and the service will guarantee that all records, still available within the Kafka topic will be processed and reported upon.

Activating the various modes of operation is performed by way of the set of input and output blocks within the configuration file. The file may contain one or more input blocks which specify where the data is sourced, e.g. account records from Kafka, and one or more output blocks which determine how and where the aggregated statistics are published.

While it is possible to specify multiple input and output blocks within a single configuration file, it is highly recommended to separate each pairing of input and output blocks into separate instances running on different nodes. This will yield the best performance and provide for better load balancing, since each instance will be responsible for a single mode of operation.

Real-time account monitoring

In the real-time account monitoring mode, account records, which are sent from each streaming server through the Kafka message broker, are processed by the account aggregator, and current real-time throughput metrics are updated in a Redis database. These metrics, which are constantly being updated, reflect the most current state of the CDN, and can be used by the Convoy Request Router to make real-time routing decisions.

PCX Reporting

In the PCX collector mode, account records are consumed in such a way that past throughput and session statistics can be aggregated to produce billing related reports. These reports are not considered real-time metrics, but represent usage statistics over fixed time intervals. This mode of operation requires a PCX API compatible reporting endpoint. See Appendix B for additional information regarding the PCX reporting format.

Installation

Prerequisites

The account aggregator is shipped as a compressed OCI formatted container image and as such, it requires a supported container runtime such as one of the following:

  • Docker
  • Podman
  • Kubernetes

Any runtime capable of running a Linux container should work the same. For simplicity, the following installation instructions assume that Docker is being used, and that Docker is already configured and running on the target system.

To test that Docker is setup and running, and that the current user has the required privileges to create a container, you may execute the following command.

$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

If you get a permission denied error, ensure that the current user is a member of the docker group or execute all Docker commands under sudo.

Loading the container image

The container image is delivered as a compressed OCI formatted image, which can be loaded directly via the docker load command. The following assumes that the image is in /tmp/esb3032-acd-aggregator-0.0.0.gz

docker load --input /tmp/esb3032-acd-aggregator-0.0.0.gz

You will now be able to verify that the image was loaded successfully by executing the following and looking for the image name in the output.

$ docker images | grep acd-aggregator

images.edgeware.tv/esb3032-acd-aggregator latest   4bbe28b444d3 1 day ago  2.08GB

Creating the configuration file

The configuration file may be located anywhere on the filesystem, however it is recommended to keep everything under the /opt/edgeware/acd/aggregator folder to be consistent with other products under the ACD product family. If that folder doesn’t already exist, you may create the folder with the following command.

mkdir -p /opt/edgeware/acd/aggregator

If using a different location, you will need to map the folder to the container while creating the Docker container. Additional information describing how to map the volume is available in the section “Creating and starting the container” below.

The configuration file for the account aggregator is divided into several sections, input, output and tuning. One or more input blocks may be specified to configure from where the data should be sourced. One or more output blocks may be configured which determine to where the resulting aggregated data is published. Finally the tuning block configures various global settings for how the account aggregator operates, such as the global log_level.

Configuring the input source

As of the current version of the account aggregator, there is only a single type of input source supported, and that is account_records. This input source connects to a Kafka message broker, and consumes account records.
Depending on which output types are configured, the Kafka consumer may either start by processing the oldest or most recent records first.

The following configuration block sample will be used as an example in the description below.

Note that the key input is surrounded by double-square-brackets. This is a syntax element to indicate that there may be multiple input sections in the configuration.

[[input]]
type = "account_records"
servers = [
    "kafka://192.0.2.1:9092",
    "kafka://192.0.2.2:9092",
]
group_name = "acd-aggregator"
kafka_max_poll_interval_ms = 30000
kafka_session_timeout_ms = 3000
log_level = "off"

The type property is used to determine the type of input, and the only valid value is account_records.

The servers list must contain at least 1 Kafka URL, prefixed with the URL scheme kafka://. If not specified, the default Kafka port of 9092 will be used. It is recommended but not required to specify all servers here, as the Kafka client library will obtain the full list of endpoints from the server on startup, however, the initial connection will be made to one or more of the provided URLs.

The group_name property identifies to which consumer group the aggregator should belong. Due to the type of data which account records represent, each instance of the aggregator connecting to the same Kafka message broker MUST have a unique group name. If two instances belong to the same group, the data will be partitioned among both instances, and the resulting aggregations may not be correct. If only a single instance of the account aggregator is used, this property is optional and defaults to “acd-aggregator”.

The kafka_* properties, for max_poll_interval and session_timeout are used to tune the connection parameters for the internal Kafka consumer. More details for these properties can be found in the documentation for the rdkafka library. See Kafka documentation for more details.

The log_level property configures the logging level for the Kafka library and supports the values “off”, “trace”, “debug”, “info”, “warn”, and “error”. By default, logging from this library is disabled. This should only be enabled for troubleshooting purposes, as it is extremely verbose, and any warnings or error messages will be repeated in the account aggregator’s log. The logging level for the Kafka library must be higher then the general logging level for the aggregator, as defined in the “tuning” section or the lower-level messages from the Kafka library will be skipped.

Configuring output

The account aggregator currently supports two types of output blocks, depending on the desired mode of operation. For reference purposes, both types will be described within this section, but it is recommended to only use a single type per instance of the account aggregator.

Note that the key output is surrounded by double-square-brackets. This is a syntax element to indicate that there may be multiple output sections in the configuration.

[[output]]
type = "account_monitor"
redis_servers = [
    "redis://192.0.2.7:6379/0",
    "redis://:password@192.0.2.8:6379/1",
]
stale_threshold_s = 12
throughput_correction_mbps = 0
minimum_check_interval_ms = 1000

[[output]]
type = "pcx_collector"
report_url = "https://192.0.2.5:8000/v1/collector"
client_id = "edgeware"
secret = "abc123"
report_timeout_ms = 2000
report_interval_s = 30
report_delay_s = 30
Real-time account monitor output

The first output block has the type account_monitor and represents the live account monitoring functionality, which publishes per-account bandwidth metrics to one or more Redis servers. When this type of output block is configured, the account records will be consumed starting with the most recent messages first, and offsets will not be committed. Stopping or restarting the service may cause account records to be skipped. This type of output is suitable for making real-time routing decisions, but should not be relied upon for critical billing or reporting metrics.

The redis_servers list consists of URLs to Redis instances which shall be updated with the current real-time bandwidth metrics. If the Redis instance requires authentication, the global instance password can be specified as part of the URL as in the second entry in the list. Since Redis does not support usernames, anything before the : in the credentials part of the URL will be ignored. At least 1 Redis URL must be provided.

The stale_threshold_s property determines the maximum timeout in seconds, after which, if no account records have been received for a given host, the host will be considered stale and removed.

The throughput_correction_mbps property can be used to add or subtract a fixed correction factor to the bandwidth reported in Redis. This is specified in megabits per second, and this may be either positive or negative. If the value is negative, and the calculated bandwidth is less than the correction factor, a minimum bandwidth of 0 will be reported.

The minimum_check_interval_ms property is used to throttle how frequently the statistics will be processed. By default, the account aggregator will not recalculate the statistics more than once per second. Setting this value too low will result in potentially higher CPU usage, while setting it too high may result in some account records being missed. The default of 1 second should be adequate for most situations.

PCX Collector output

The pcx_collector type configures the account aggregator as a reporting

agent for the PCX API. Whenever this configuration is present, the account record consumer will be configured to always start at the oldest records retained within the Kafka topic. It then processes the records one at a time, committing the Kafka offset each time a report is successfully received. This mode does not make any guarantees as to how recent the data is on which the reports are made, but does guarantee that every record will be counted in the aggregated report. Stopping or restarting the service will result in the account record consumer resuming processing from the last successful report. This type of reporting is suitable for billing purposes assuming that there are multiple replicated Kafka nodes, and that the service is not stopped for longer than the maximum retention period configured within Kafka. Stopping the service for longer than the retention period will result in messages being unavailable. Because this type of output requires that the Kafka consumer is processed in a specific order, and will not proceed with reading additional messages until all reports have been successfully received, it is not recommended to have both pcx_collector and the account_monitor type output blocks configured within the same instance.

The report_url property is a single HTTP endpoint URL where the PCX API can be reached. This property is required and may be either an HTTP or HTTPS URL. For HTTPS, the validity of the TLS certificate will be enforced, meaning that self-signed certificates will not be considered valid.

The client_id and secret fields are used to authenticate the client with the PCX API via token-based authentication. These fields are both required, however if not used by the specific PCX API instance, the empty string "" may be provided.

The report_timeout_ms field is an optional maximum timeout for the HTTP connection to the PCX API before the connection will fail. Failed reports will be retried indefinitely.

The report_interval_s property represents the interval bucket size for reporting metrics. The timing for this type of output is based solely on the embedded timestamp value of the account records, meaning that this property is not an absolute period on which the reports will be sent, but instead represents the duration between the start and ending timestamps of the report. Especially upon startup, reports may be sent much more frequently than this interval, but will always cover this duration of time.

The report_delay_s property is an optional offset used to account for both clock synchronization between servers as well as propagation delay of the account records through the message broker. The default delay is 30 seconds. This means that the ending timestamp of a given report will be no more recent than this many seconds in the past. It is important to include this delay, as any account records received with a timestamp that would be within period which has already been reported upon, will be dropped.

Tuning the account aggregator

The tuning configuration block represents the global properties for tuning how the account aggregator functions. Currently only one tuning property can be configured, and that is the log_level. The default log_level is “info”, which should be used in normal operation of the account aggregator, however, other possible values in order of verbosity include “trace”, “debug”, “info”, “warn”, “error”, and “off”.

Note that the tuning key is surrounded by single square-brackets. This is TOML syntax meaning that only one instance of tuning is allowed.

[tuning]
log_level = "info"

Example configurations

This section describes some example configuration files which can be used as a starting template depending on which mode of operation is desired.

Real-time account monitoring

This configuration will consume account records from a Kafka server running on 3 hosts, kafka-1, kafka-2, and kafka-3. The account records will be consumed starting with the most recent records. The resulting aggregations will be published to two Redis instances, running on redis-1 and redis-2. The reported bandwidth will have a 2Gb/s correction factor applied.

[[input]]
type = "account_records"
servers = [
    "kafka://kafka-1:9092",
    "kafka://kafka-2:9092",
    "kafka://kafka-3:9092"
]
group_name = "acd-aggregator-live"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"

[[output]]
type = "account_monitor"
redis_servers = [
    "redis://redis-1:6379/0",
    "redis://redis-2:6379/0",
]
# stale_threshold_s = 12
throughput_correction_mbps = 2000
# minimum_check_interval_ms = 1000

[tuning]
log_level = "info"

The keys prefixed by # are commented out, since the default values will be used. They are included in the example for completeness.

PCX collector

This configuration will consume account records starting from the earliest record, calculate aggregated statistics for every 30 seconds, offset with a delay of 30 seconds, and publish the results to https://pcx.example.com/v1/collector.

[[input]]
type = "account_records"
servers = [
    "kafka://kafka-1:9092",
    "kafka://kafka-2:9092",
    "kafka://kafka-3:9092"
]
group_name = "acd-aggregator-pcx"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"

[[output]]
type = "pcx_collector"
report_url = "https://pcx.example.com/v1/collector"
client_id = "edgeware"
secret = "abc123"
# report_timeout_ms = 2000
# report_interval_s = 30
# report_delay_s = 30

[tuning]
log_level = "info"

The keys prefixed by # are commented out, since the default values will be used. They are included in the example for completeness.

Combined PCX collector with real-time account monitoring

While this configuration is possible, it is not recommended, since the pcx_collector output type will force all records to be consumed starting at the earliest record. This will cause the live statistics to be delayed until ALL earlier records have been consumed, and reports have been successfully accepted by the PCX API. This combined role configuration can be used to minimize the number of servers or services running if the above limitations are acceptable.

Note: This is simply the combination of the above two output blocks in the same configuration file.

[[input]]
type = "account_records"
servers = [
    "kafka://kafka-1:9092",
    "kafka://kafka-2:9092",
    "kafka://kafka-3:9092"
]
group_name = "acd-aggregator-combined"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"

[[output]]
type = "account_monitor"
redis_servers = [
    "redis://redis-1:6379/0",
    "redis://redis-2:6379/0",
]
# stale_threshold_s = 12
throughput_correction_mbps = 2000
# minimum_check_interval_ms = 1000

[[output]]
type = "pcx_collector"
report_url = "https://pcx.example.com/v1/collector"
client_id = "edgeware"
secret = "abc123"
# report_timeout_ms = 2000
# report_interval_s = 30
# report_delay_s = 30

[tuning]
log_level = "info"

Upgrading

The upgrade procedure for the aggregator consists of simply stopping the existing container with docker stop acd-aggregator, removing the existing container with docker rm acd-aggregator, and following the steps in “Creating and starting the container” below with the upgraded Docker image.

To roll back to a previous version, simply perform the same steps with the previous image. It is recommended to keep at least one previous image around until such time that you are satisfied with the new version. After which, you may remove the previous image with docker rmi images.edgeware.tv/esb3032-acd-aggregator:1.2.3 where “1.2.3” represents the previous version number.

Creating and starting the container

Now that the configuration file has been created, and the image has been loaded, we will need to create and start the container instance. The following docker run command will create a new container called “acd-aggregator”, start the process, and automatically resume the container once the Docker daemon is loaded at startup.

docker run \
  --name "acd-aggregator" \
  --detach \
  --restart=always \
  -v <PATH_TO_CONFIG_FOLDER>:/opt/edgeware/acd/aggregator:ro \
  <IMAGE NAME>:<VERSION> \
  --config /opt/edgeware/acd/aggregator/aggregator.toml

As an example using version 1.4.0:

docker run \
  --name "acd-aggregator" \
  --detach \
  --restart=always \
  -v /opt/edgeware/acd/aggregator:/opt/edgeware/acd/aggregator:ro \
  images.edgeware.tv/esb3032-acd-aggregator:1.4.0 \
  --config /opt/edgeware/acd/aggregator/aggregator.toml

Note: The image tag in the example is “1.4.0”, you will need to replace that tag with the image tag loaded from the compressed OCI formatted image file, which can be obtained by running docker images and searching for the account aggregator image as described in the step “Loading the container image” above.

If the configuration file saved in the previous step was at a different location from /opt/edgeware/acd/aggregator/aggregator.toml you will need to change both the -v option and the --config option in the above command to represent that location. The -v option mounts the containing folder from the host system on the left to the corresponding path inside the container on the right, and the :ro tells Docker that the volume is mounted read-only. The --config should be the absolute path to the configuration file from INSIDE the container. For example, if you saved the configuration file as /host/path/config.toml on the host, and you need to map that to /container/path/config.toml within the container, the lines should be -v /host/path:/container/path:ro and --config /container/path/config.toml respectively.

The --restart=always line tells Docker to automatically restart the container when the Docker runtime is loaded, and is the equivalent in systemd to “enabling” the service.

Starting and Stopping the container

To view the status of the running container, use the docker ps command. This will give a line of output for the acd-aggregator container if it is currently running. Appending the -a flag, will list the aggregator container if is not running as well.

Execute the following:

docker ps -a

You should see a line for the container with the container name “acd-aggregator” along with the current state of the container. If all is OK, you should see the container process running at this point, but it may show as “exited” if there was a problem.

To start and stop the container the docker start acd-aggregator and docker stop acd-aggregator commands can be used.

Viewing the logs

By default, Docker will maintain the logs of the individual containers within its own internal logging subsystem, which requires the user to use the command

docker logs

to view them. It is possible however to configure the Docker daemon to send logs to the system journal, however configuring that is beyond the scope of this document. Additional details describing how to do that are described here

[https://docs.docker.com/config/containers/logging/journald/].

To view the complete log for the aggregator the following command can be used.

docker logs acd-aggregator

Supplying the -f flag, can be used to “follow” the log until either the process terminates or CTRL+C is pressed.

docker logs -f acd-aggregator

Appendix A: Real-time account monitoring

Redis key value pairs

Each account will have a single key-value stored in Redis with the current throughput with any correction factor applied, which will be updated in real-time every time all hosts for the given account have received a new account record. This should be approximately every 10 seconds, but may vary slightly due to processing time.

The keys are structured in the following format:

bandwidth:<account>:value

and the value is reported in bits-per-second.

For example for accounts foo, bar and baz we may see the following:

bandwidth:foo:value = 123456789
bandwidth:bar:value = 234567890
bandwidth:baz:value = 102400

These values represent the most current throughput for each account, and will be updated periodically. A TTL of 48 hours is added to the keys, such that they will be pruned automatically after 48 hours since the last update. This is to prevent stale keys from remaining in Redis indefinitely. This TTL is not configurable by the end user.

Appendix B: PCX collector reporting

PCX reporting format

The following is an example of the report sent to the PCX HTTP endpoint.

{
    timestamp_begin: 1674165540,
    timestamp_end: 1674165570,
    writer_id: "writer-1",
    traffic: [
        Traffic {
            account_id: "unknown",
            num_ongoing_sessions: 0,
            bytes_transmitted: 0,
            edges: [
                Edge {
                    server: "orbit-1632",
                    num_ongoing_sessions: 0,
                    bytes_transmitted: 0,
                },
            ],
        },
        Traffic {
            account_id: "default",
            num_ongoing_sessions: 747,
            bytes_transmitted: 75326,
            edges: [
                Edge {
                    server: "orbit-1632",
                    num_ongoing_sessions: 747,
                    bytes_transmitted: 75326,
                },
            ],
        },
    ],
}

The report can be broken down into 3 parts. The outer root section includes the starting and stopping timestamps, as well as a writer_id field which is currently unused. For each account a Traffic section contains the aggregated statistics for that account, as well as a detailed breakdown of each Edge. An Edge is the portion of traffic for the account streamed by each server. Within an Edge the num_ongoing_sessions represents the peak ongoing sessions during the reporting interval, while the bytes_transmitted represents the total egress bandwidth in bytes over the entire period. For each outer Traffic section, the num_ongoing_sessions and bytes_transmitted represent the sum of the corresponding entries in all Edges.

Data protection and consistency

The ACD aggregator works by consuming messages from Kafka. Once a report has successfully been submitted, as determined by a 200 OK HTTP status from the reporting endpoint, the position in the Kafka topic will be committed. This means that if the aggregator process stops and is restarted, reporting will resume from the last successful report, and no data will be lost. There is a limitation to this, however, and that has to do with the data retention time of the messages in Kafka and the TTL value specified in the aggregator configuration. Both default to the same value of 24 hours. This means that if the aggregator process is stopped for more than 24 hours, data loss will result since the source account records will have expired from Kafka before they can be reported on by the aggregator.

Upon startup of the aggregator, all records stored in Kafka will be reported on in the order they are read, starting from either the last successful report or the oldest record currently in Kafka. Reports will be sent each time the timestamp in the current record read from Kafka exceeds the reporting interval meaning a large burst of reports will be sent at startup to cover each interval. Once the aggregator has caught up with the backlog of account records, it will send a single report roughly every 30 seconds (configurable).

It is not recommended to have more than a single account aggregator instance reading from Kafka at a time, as this will result in partial reports being sent to the HTTP endpoint which will require the endpoint to reconstruct the data upon receipt. All redundancy in the account aggregator is handled by the redundancy within Kafka itself. With this in mind, it is important to ensure that there are multiple Kafka instances running and that the aggregator is configured to read from all of them.

3.1.2.2 - Releases

ESB3032 ACD Aggregator releases

3.1.2.2.1 - Release esb3032-0.2.0

Build date

2022-12-21

Release status

Type: devdrop

Change log

  • NEW: Use config file instead of command line switches
  • NEW: Reports are now aligned with wall-clock time
  • NEW: Reporting time no longer contains gaps in coverage
  • FIX: Per-account number of sessions only shows largest host

3.1.2.2.2 - Release esb3032-1.0.0

First official release

Build date

2023-02-14

Release status

Type: production

Change log

  • NEW: Create user documentation for ACD Aggregator
  • NEW: Simplify configuration . Changed from YAML to TOML format.
  • NEW: Handle account records arriving late
  • FIXED: Aggregator hangs if committing to Kafka delays more than 5 minutes

3.1.2.2.3 - Release esb3032-1.2.1

Production release

Build date

2023-04-24

Release status

Type: production

Breaking changes

No breaking changes

Change log

  • NEW: Port Account Monitor functionality for Convoy Request Router
  • NEW: Aggregator Performance Improvements
  • FIXED: Reports lost when restarting acd-aggregator

3.1.2.2.4 - Release esb3032-1.4.0

Build date

2023-09-28

Release status

Type: production

Breaking changes

None

Change log

  • NEW: Extend aggregator with additional metrics. Per streamer bandwidth and total bandwidth are now updated in Redis. [ESB3032-98]
  • FIXED: Not all Redis instances are updated after a failure [ESB3032-99]
  • FIXED: Kafka consumer restarts on Partition EOF [ESB3032-100]

3.1.3 - ACD Cache

Information about the ACD Cache Orbit version is available in EDGS-103 Orbit TV Server User Guide1 and information about the ACD Cache SW Streamer version is available in EDGS-171 SW Streamer User Guide1.


  1. If you don’t have an Edgeware Support account please contact us here↩︎ ↩︎

3.1.4 - ESB3013 BGP Sniffer

Information about the ACD BGP Sniffer is available in EDGS-214 ESB3013 User Guide1.


  1. If you don’t have an Edgeware Support account please contact us here↩︎

3.1.5 - Edgeware CDN Management System

Information about the classic Edgeware CDN Management System (aka Convoy) is available in EDGS-069 Convoy Management Software User Guide1.


  1. If you don’t have an Edgeware Support account please contact us here↩︎

3.1.6 - ESB3008 Edgeware CDN Request Router

Information about the convoy based Edgeware CDN Request Router is available in EDGS-197 ESB3008 HTTP Request Router - User Guide1.


  1. If you don’t have an Edgeware Support account please contact us here↩︎

3.2 - Introduction

Introduction to ACD - Agile Content Delivery.

ACD is a software suite for CDNs (Content Delivery Networks). The services built around the ACD software come into play when a user starts to view video content on a video streaming portal. The focus is on the server side of the delivery. The portal and players or set-to-boxes are not part of ACD, although they are part of Agile Contents product portfolio as a whole. Likewise, video stream repackaging and DRM are not part of ACD (see ACP).

The ACD software can be used to build a complete private CDN and/or to select between CDNs. A typical deployment is a nation-wide TV streaming service operated by a telecom operator or a broadcaster.

At the core of the system sits ESB3024 Router which will process an incoming client request and make an optimized decision from where to serve the user. The router will classify each playback request according to a variety of configured parameters such as device type, geographic region or content class. Based on the classification together with the current state of the network, its streaming capacity and public offload CDNs status, the best streaming location is determined. If desired, business rules for when to use public CDNs can be applied.

The ACD software suite includes the ACD Cache that is installed on servers placed in data centers that will guarantee an efficient and robust distribution of the content. Depending on the core network architecture, a centralized or decentralized approach is best. Agile Content can help find a good system solution.

Behind the client facing interfaces, there are backend services to monitor and measure the system. This information can be used to troubleshoot network problems, analyze viewing patterns or to plan upgrades of capacity.

Returning to the router, it is built around a very flexible routing rule evaluation engine that can route between and within CDNs. The rule evaluation engine weighs together multiple sources of information to optimize system behavior. Apart from the request classification of device type, content class etc, there are also several integration APIs that can be used to extend the product and solve problems that are particular to a specific customer. One of those integration APIs is the Selection Input API which can take any external information such as streaming bitrate of public CDNs, load balancing settings from a GUI slide bar or status from network probes and include it in the routing decision rules. Another is the Subnet API that can efficiently handle thousands of subnets and map each one to a high-level group membership (typically a region) and route based on that. There is also a metrics API to monitor the service. It integrates out-of-the-box with Prometheus and Grafana.

All APIs are documented under the API overview.

In addition to the flexibility provided by the APIs, there is also a possibility to extend functionality via plugins (using Lua). This can be used to support the decoding and encoding of security tokens (digital signatures of the URLs) or advanced routing rules that are not available out-of-the-box.

A modern TV CDN is considered as critical infrastructure and has very high requirements on uptime and robustness. This is in obtained via multiple independent and stand-alone instances of each service (although particular use cases might require sharing data via a redundant database). The ACD software services run on RHEL8 Linux.

Note: Not all products or components that are part of ACD are documented here. Please contact our Sales for a complete overview.

3.3 - Solutions

ACD Reference Solutions. Blueprints for different families of use cases.

3.3.1 - Cache hardware metrics: monitoring and routing

How to set up monitoring and make routing decisions based on cache hardware metrics

Observability and monitoring is important in a CDN. To facilitate this, we use the open source application Telegraf for two key roles: as a metrics agent and as a metrics aggregator. Telegraf performs both these roles depending on its configuration.

The image below demonstrates an example architecture when using multiple caches and instances of ESB3024 Router.

Architecture

Metrics agent

All deployments of ESB2001 Orbit TV Server (from version 3.6.0) and ESB3004 SW Streamer (from version 1.36.0) come bundled with an instance of Telegraf running as a metrics agent, collecting information on hardware metrics such as usage of CPU, memory and network interfaces. If you are using other caches in your CDN, Telegraf can be manually installed and configured.

Telegraf is configured via a configuration daemon, telegraf-configd. On the Orbit TV Server is starts automatically, but on the SW Streamer it needs to be started manually by typing this:

systemctl start telegraf-configd

To make it always start during boot, type

systemctl enable telegraf-configd

Once the configuration daemon is running, Telegraf can be configured using confcli:

$ confcli integration.acd.telegraf
{
  "telegraf": {
    "enable": true,
    "exportUrls": [],
    "hostname": ""
  }
}

To enable or disable the Telegraf instance, type

$ confcli integration.acd.telegraf.enable true
integration.acd.telegraf.enable = True

$ confcli integration.acd.telegraf.enable false
integration.acd.telegraf.enable = false

The Telegraf agents need to export their metrics to an aggregator to be useful. The field integration.acd.telegraf.exportUrls is a list of Telegraf aggregator instances to which the metrics will be exported. It is recommended to use at least two Telegraf aggregator instances for redundancy.

As an example, type this to configure a cache to export metrics to http://aggregator-host-1:8086 and http://aggregator-host-2:8086:

$ confcli integration.acd.telegraf.exportUrls -w
Running wizard for resource 'exportUrls'
<A list of aggregator URLs to export metrics to (default: [])>

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

exportUrls <A list of aggregator URLs to export metrics to (default: [])>: [
  exportUrl (default: ): http://aggregator-host-1:8086
  Add another 'exportUrl' element to array 'exportUrls'? [y/N]: y
  exportUrl (default: ): http://aggregator-host-2:8086
  Add another 'exportUrl' element to array 'exportUrls'? [y/N]: n
]
Generated config:
{
  "exportUrls": [
    "http://aggregator-host-1:8086",
    "http://aggregator-host-2:8086"
  ]
}
Merge and apply the config? [y/n]: y

The Telegraf agent tags all metrics it collects with the hostname of the machine it is running on. To change this hostname, the field integration.acd.telegraf.hostname can be modifed:

$ confcli integration.acd.telegraf.hostname 'new-hostname'
integration.acd.telegraf.hostname = 'new-hostname'

Metrics aggregator

Telegraf is not installed together with the router since it is dependent on your system. Either follow these steps or ask an Agile Content integrator to set it up for your system. To set up Telegraf as an aggregator on your desired hosts, two steps need to be performed.

  1. Install Telegraf according to official instructions.
  2. Configure Telegraf to act as an aggregator by adding the following configuration file: /etc/telegraf/telegraf.conf

Due to a limitation of the [[outputs.http]] plugin, multiple output URLs cannot be defined as a list, the plugin only accepts a single URL. This means that the whole [[outputs.http]] and [outputs.http.headers] needs to be repeated for each router host.

Each router section needs to be modified in two places:

  1. Below [[outputs.http]], the url directive has to be made direct to the router’s address.
  2. Below [outputs.http.headers], X-API-Key has to contain the router’s REST API key. The key is stored in /opt/edgeware/acd/router/cache/rest-api-key.json on the router server.

After the configuration file is complete, type systemctl reload telegraf to make Telegraf reload the new configuration.

When the aggregator is succesfully started and configured, the metrics JSON packet is sent to the selection input API with the following structure:

{
  "cache-1": {
    "hardware_metrics": {
      "/": {
        "free": 18113810432,
        "total": 34887954432,
        "used": 16774144000,
        "used_percent": 48.08004445400899
      },
      "cpu_load1": 0.70,
      "cpu_load5": 0.53,
      "cpu_load15": 0.40,
      "mem_available": 3129425920,
      "mem_available_percent": 76.34786936062332,
      "mem_total": 4098904064,
      "mem_used": 519901184,
      "n_cpus": 2
    },
    "per_interface_metrics": {
      "eth0": {
        "bytes_recv": 57585596566,
        "bytes_recv_rate": 939.4, // bytes per second
        "bytes_sent": 10127106702,
        "bytes_sent_rate": 637.9, // bytes per second
        "drop_in": 1800079,
        "drop_in_rate": 0,
        "drop_out": 0,
        "drop_out_rate": 0,
        "err_in": 0,
        "err_in_rate": 0,
        "err_out": 0,
        "err_out_rate": 0,
        "interface_up": true,
        "link": 1,
        "megabits_recv": 460684,
        "megabits_recv_rate": 0.0075152, // megabits per second
        "megabits_sent": 81016,
        "megabits_sent_rate": 0.0051032, // megabits per second
        "speed": 100
      }
    },
    "timestamp": 1709296800
  }
}

Monitoring

All router installations come bundled with a Prometheus instance that can be configured to scrape the aggregator instances, allowing alarms and visualization of all caches’ metrics.

On a router host, modify the configuration file /opt/edgeware/acd/prometheus/prometheus.yaml to include a scrape job for the aggregators in your system:

global:
  scrape_interval: 15s

rule_files:
  - recording-rules.yaml

scrape_configs:
  - job_name: 'router-scraper'
    scheme: https
    tls_config:
      insecure_skip_verify: true
    static_configs:
    - targets:
      - 10.16.48.106:5001
    metrics_path: /m1/v1/metrics
    honor_timestamps: true
  - job_name: 'edns-proxy-scraper'
    scheme: http
    static_configs:
    - targets:
      - 10.16.48.106:8888
    metrics_path: /metrics
    honor_timestamps: true
  - job_name: 'metric-aggregators'
    scheme: http
    static_configs:
    - targets:
      - http://aggregator-host-1:12001
      - http://aggregator-host-2:12001
    metrics_path: /metrics
    honor_timestamps: true

Once the new configuration file is set, restart the Prometheus instance with systemctl restart acd-prometheus. When the Prometheus instance starts scraping the aggregators, all caches’ metrics will be available for visualization in Grafana and alarms in AlertManager.

Using hardware metrics in routing

When the hardware metrics have been succesfully injected into the selection input API, the data is ready to be used for routing decisions. In addition to creating routing conditions, hardware metrics are particularly suited to host health checks.

Host health checks

When the hardware metrics have been succesfully injected into the selection input API, the data is ready to make routing decisions with. In addition to creating routing conditions, hardware metrics are particularly suited to host health checks.

Host health checks

Host health checks are Lua functions that determine whether or not a host is ready to take on more clients. To configure host health checks, see configuring CDNs and hosts. See Health Check Functions for documentation on how to use the built in health functions. Note that these health check functions can also be used for making routing conditions in the routing tree.

Routing based on cache metrics

Instead of using health check functions to incorporate hardware metrics into the routing decisions, regular routing conditions can be used.

As an example, using the health check function cpu_load_ok() in routing can be configured as follows:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): dont_overload_cache
      type (default: firstMatch): 
      targets : [
        target : {
          onMatch (default: ): default_host
          condition (default: always()): cpu_load_ok()
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): offload_host
          condition (default: always()): 
        }
        Add another 'target' element to array 'targets'? [y/N]: n
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
  "rules": [
    {
      "name": "dont-overload-cache",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "default_host",
          "condition": "cpu_load_ok()"
        },
        {
          "onMatch": "offload_host",
          "condition": "always()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "routing": {
    "id": "dont_overload_cache",
    "member_order": "sequential",
    "members": [
      {
        "id": "default-node",
        "host_id": "default-host",
        "weight_function": "return cpu_load_ok()"
      }
      {
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

3.3.2 - Private CDN Offload Routing with DNS

Use CoreDNS and ESB3024 Router to offload traffic from a private CDN

This shows a setup to do DNS based routing and 3rd party CDN offload from a private main CDN. The following components are used in the setup:

  • A private Edgeware CDN with Convoy (ESB3006), Request Router (ESB3008) and SW Streamers (ESB3004)
  • ESB3024 Router to offload traffic to an external CDN
  • CoreDNS to support DNS based routing using ESB3024

The following figure shows an overview of the different components and how they interact.

Solution Overview

A client retrieves a DNS name from it’s content portal. The DNS name is then resolved by CoreDNS that asks the router for a suitable host. The router either returns a host from ESB3008 Request Router or a configured offload host.

The following sequence diagram illustrates the flow.

DNS Resolution Sequence Diagram

Follow the links below to configure different use cases of this setup.

3.3.3 - Monitor ACD with Prometheus, Grafana and Alert Manager

Use Prometheus, Grafana and Alert Manager to monitor ACD

ACD can be monitored with standard monitoring solutions. This allows you to adapt the monitoring to your needs. The following shows a setup with the following components

  • Prometheus as metrics database
  • Grafana to create Dashboards
  • Alert Manager to create alarms from Prometheus alerts

Overview

Prometheus and Grafana can also be installed with ESB3024 Router installer in which case Grafana is also pre-populated with standard routing dashboards as well as the router troubleshooting Dashboards.

3.4 - Use Cases

Configuration building blocks for constructing full solutions.

3.4.1 - Route on GeoIP/ASN

How to write ESB3024 Router configurations for GeoIP and ASN-based routing using classifiers and session groups.

This page describes how to write configuration for GeoIP and ASN-based routing. For configuration in general, see Configuration.

For more details on session groups and classifiers, see Session Groups and Classification.

ASN

Routing on ASN is done through a combination of session group classifiers and Lua script weight functions. We need to create ASN classifier(s) and then associate them with a session group:

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 3
  Adding a 'geoip' element
    classifier : {
      name (default: ): allowed_asn_classifier
      type (default: geoip): ⏎
      inverted (default: False): ⏎
      continent (default: ): ⏎
      country (default: ): ⏎
      cities : [
        city (default: ): ⏎
        Add another 'city' element to array 'cities'? [y/N]: ⏎
      ]
      asn (default: ): Agile*ISP
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "allowed_asn_classifier",
      "type": "geoip",
      "inverted": false,
      "continent": "",
      "country": "",
      "cities": [],
      "asn": "Agile*ISP"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): allowed_asn
    classifiers : [
      classifier (default: ): allowed_asn_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "allowed_asn",
      "classifiers": [
        "allowed_asn_classifier"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_asn",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_asn_classifier",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "asn": "Agile*ISP"
            }
          }
        ]
      ]
    }
  ]
}

The asn value is a string, matching an ISP name or similar. It supports wildcard matching using asterisks and is case insensitive.

Note that each ASN classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different ASNs. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.

Simple Example

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): asn_split_node
      type (default: split): ⏎
      rule (default: ): return in_session_group("allowed_asn")
      onMatch (default: ): allowed-asn-host
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "asn_split_node",
      "type": "split",
      "condition": "in_session_group('allowed_asn')",
      "onMatch": "allowed-asn-host",
      "onMiss": "offload-host"
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_asn",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_asn_classifier_agile",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "asn": "Agile*ISP"
            }
          }
        ],
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_asn_classifier_edgeware",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "asn": "Edgeware *"
            }
          }
        ]
      ]
    }
  ],
  "cdns": [
    {
      "id": "basic-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "default-host",
      "cdn_id": "basic-cdn",
      "address_family": "ipv4",
      "host": "cdn-host.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "address_family": "ipv4",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "default-node",
        "host-id": "default-host",
        "weight_function": "return in_session_group('allowed_asn')"
      },
      {
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

Geographical Location

Routing on geographical location is done in a similar fashion. Once again, we create location classifier(s) and associate them with a session group:

Geographical locations are provided by a MaxMind database.

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 3
  Adding a 'geoip' element
    classifier : {
      name (default: ): allowed_location
      type (default: geoip): ⏎
      inverted (default: False): ⏎
      continent (default: ): ⏎
      country (default: ): ⏎
      cities : [
        city (default: ): stockholm
        Add another 'city' element to array 'cities'? [y/N]: ⏎
      ]
      asn (default: ): ⏎
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "allowed_location",
      "type": "geoip",
      "inverted": false,
      "continent": "",
      "country": "",
      "cities": [
        "stockholm"
      ],
      "asn": ""
    }
  ]
}
Merge and apply the config? [y/n]: y
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_location",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_location_classifier",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "continent": "",
              "country": "",
              "region": "",
              "cities": ["stockholm"]
            }
          }
        ]
      ]
    }
  ]

At least one of the optional fields continent, country, region and cities are required. The classifier matches a request when all specified fields do (for the cities list, one matching member is sufficient). All values support wildcard matching using asterisks and are case insensitive.

Note that each location classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different locations. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.

Simple Example

confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): geographic_location_split_node
      type (default: split): ⏎
      rule (default: ): return in_session_group("allowed_location")
      onMatch (default: ): allowed-location-host
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "geographic_location_split_node",
      "type": "split",
      "condition": "in_session_group('allowed_location')",
      "onMatch": "allowed-location-host",
      "onMiss": "offload-host"
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_location",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_location_classifier_sweden",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "country": "Sweden"
            }
          }
        ],
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_location_classifier_oslo",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "country": "Norway",
              "cities": ["Oslo"]
            }
          }
        ]
      ]
    }
  ],
  "cdns": [
    {
      "id": "basic-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "default-host",
      "cdn_id": "basic-cdn",
      "address_family": "ipv4",
      "host": "cdn-host.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "address_family": "ipv4",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "default-node",
        "host_id": "default-host",
        "weight_function": "return in_session_group('allowed_location')"
      }
      {
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

3.4.2 - Route on Subnet

How to write ESB3024 Router configurations for client routing based on subnets, either by using session groups or by using the subnets API

This page describes how to write configuration for subnet-based routing. For configuration in general, see Configuration.

For details on the subnets API, see Subnets API.

Subnet-based routing can be done either by using session groups and classifiers or by using the subnets API, allowing large amounts of named subnets.

Session Group Classifiers

Routing on subnets can be done through a combination of session group classifiers and Lua script weight functions. Configuring session groups and classifiers based on subnets and using them in routing may look like:

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 5
  Adding a 'ipranges' element
    classifier : {
      name (default: ): ip_ranges_classifier
      type (default: ipranges): ⏎
      inverted (default: False): ⏎
      ipranges : [
        iprange (default: ): 10.0.0.0/8
        Add another 'iprange' element to array 'ipranges'? [y/N]: y
        iprange (default: ): 192.168.0.0/16
        Add another 'iprange' element to array 'ipranges'? [y/N]: y
        iprange (default: ): 2001:0db8:85a3::/128
        Add another 'iprange' element to array 'ipranges'? [y/N]: ⏎
      ]
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "ip_ranges_classifier",
      "type": "ipranges",
      "inverted": false,
      "ipranges": [
        "10.0.0.0/8",
        "192.168.0.0/16",
        "2001:0db8:85a3::/128"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): allowed_subnets
    classifiers : [
      classifier (default: ): ip_ranges_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "allowed_subnets",
      "classifiers": [
        "ip_ranges_classifier"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_subnets",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_subnet_classifier",
            "rule": {
              "rule_type": "ip_ranges_rule",
              "source": "session/client_ip",
              "ip_ranges": ["10.0.0.0/8", "192.168.0.0/16", "2001:0db8:85a3::/128"]
            }
          }
        ]
      ]
    }
  ]
}

The field ip_ranges is a list of CIDR-notation strings, supporting both IPv4 and IPv6 format. Incoming requests have their IP tested against the listed ranges. The classifier evaluates as true if any of the ranges in the classifier’s list matches the IP address of the request.

These session groups can then be used in routing as follows:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): subnet_split_node
      type (default: split): ⏎
      rule (default: ): return in_session_group('allowed_subnets')
      onMatch (default: ): allowed-host
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "subnet_split_node",
      "type": "split",
      "condition": "in_session_group('allowed_subnets')",
      "onMatch": "allowed-host",
      "onMiss": "offload-host"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint subnet_split_node
services.routing.entrypoint = 'subnet_split_node'
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "cdns": [
    {
      "id": "allowed-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "allowed-host",
      "cdn_id": "allowed-cdn",
      "host": "allowed-host.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "allowed-node",
        "host_id": "allowed-host",
        "weight_function": "return in_session_group('allowed_subnets')"
      },
      {
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  },
  "session_groups": [
    {
      "id": 1,
      "name": "allowed_subnets",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "allowed_subnet_classifier",
            "rule": {
              "rule_type": "ip_ranges_rule",
              "source": "session/client_ip",
              "ip_ranges": ["10.0.0.0/8", "192.168.0.0/16", "2001:0db8:85a3::/128"]
            }
          }
        ]
      ]
    }
  ]
}

Named Subnets

Named subnets are injected into the router in the form of JSON payloads to the Subnets API. Once the subnet data has been fed to the router, Lua functions can access the subnet name associated with an incoming request and use the result when it performs routing.

Note that confcli cannot be used to inject named subnets into the router.

Assume we have injected the following subnet configuration into the router:

{
  "10.0.0.0/8": "test_net_4",
  "192.168.0.0/16": "test_net_4",
  "2001:0db8:85a3::/128": "test_net_6"
}

A router configuration using this subnet configuration can then be constructed as:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: split
  Adding a 'split' element
    rule : {
      name (default: ): subnet_split_node
      type (default: split): ⏎
      rule (default: ): return in_subnet("test_net_4")
      onMatch (default: ): allowed-host-4
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "subnet_split_node",
      "type": "split",
      "condition": "in_subnet('test_net_4')",
      "onMatch": "allowed-host-4",
      "onMiss": "offload-host"
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint subnet_split_node
services.routing.entrypoint = 'subnet_split_node'
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "cdns": [
    {
      "id": "allowed-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "allowed-host-4",
      "cdn_id": "allowed-cdn",
      "address_family": "ipv4",
      "host": "allowed-host4.example"
    },
    {
      "id": "allowed-host-6",
      "cdn_id": "allowed-cdn",
      "address_family": "ipv6",
      "host": "allowed-host6.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "address_family": "ipv4",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "allowed-node-4",
        "host_id": "allowed-host-4",
        "weight_function": "return in_subnet('test_net_4')"
      },
      {
        "id": "allowed-node-6",
        "host_id": "allowed-host-6",
        "weight_function": "return in_subnet('test_net_6')"
      },
      {
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

Note the absence of session groups in this configuration, instead relying solely on the named subnet API to making routing decisions based on subnets.

3.4.3 - Route on Content Type

How to write ESB3024 Router configurations for content-based routing

This page describes how to write configuration for content-based routing. For configuration in general, see Configuration.

Two ways to route on content type will be demonstrated: content path based and hostname based using session groups and classifiers. For more details on session groups and classifiers, see Session Groups and Classification.

Content Path

Routing on content path is done through a combination of session group classifiers and Lua script weight functions. Two suitable classifiers for content path matching are string_match_rule and regex_rule.

The pattern is a string matching the path segment of a request URL, including the file name. When selecting the string_match_rule type, use asterisks for wildcard matching. When selecting the regex_rule follow the C++11 std::regex ECMAScript syntax to make valid patterns. Make sure to write patterns that match the entire path segment, not just part of it.

Note that each content classifier normally has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different content paths. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.

Simple Example

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 1
  Adding a 'contentUrlPath' element
    classifier : {
      name (default: ): live_content_classifier
      type (default: contentUrlPath): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *live_tv*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: y
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 1
  Adding a 'contentUrlPath' element
    classifier : {
      name (default: ): news_content_classifier
      type (default: contentUrlPath): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): regex
      pattern (default: ): /([^/]+/)?news_reports_\\d+/.*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: y
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 1
  Adding a 'contentUrlPath' element
    classifier : {
      name (default: ): hls_content_classifier
      type (default: contentUrlPath): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *.m3u8
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
  "classifiers": [
    {
      "name": "live_content_classifier",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*live_tv*"
    },
    {
      "name": "news_content_classifier",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "regex",
      "pattern": "/([^/]+/)?news_reports_\\\\d+/.*"
    },
    {
      "name": "hls_content_classifier",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*.m3u8"
    }
  ]
}
Merge and apply the config? [y/n]: y

confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): live_content
    classifiers : [
      classifier (default: ): live_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
  sessionGroup : {
    name (default: ): news_content
    classifiers : [
      classifier (default: ): news_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
  sessionGroup : {
    name (default: ): hls_content
    classifiers : [
      classifier (default: ): hls_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "live_content",
      "classifiers": [
        "live_content_classifier"
      ]
    },
    {
      "name": "news_content",
      "classifiers": [
        "news_content_classifier"
      ]
    },
    {
      "name": "hls_content",
      "classifiers": [
        "hls_content_classifier"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "session_groups": [
    {
      "id": 1,
      "name": "live_content",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "live_content_classifier",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/content_url_path",
              "pattern": "*live_tv*"
            }
          }
        ]
      ],
      [
        [
          {
            "id": 2,
            "inverted": false,
            "name": "news_content_classifier",
            "rule": {
              "rule_type": "regex_rule",
              "source": "session/content_url_path",
              "pattern": "/([^/]+/)?news_reports_\\d+/.*"
            }
          }
        ]
      ]
    },
    {
      "id": 2,
      "name": "hls_content",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "hls_content_classifier",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/content_url_path",
              "pattern": "*.m3u8"
            }
          }
        ]
      ]
    }
  ],
  "cdns": [
    {
      "id": "live-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "vod-hls-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "vod-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "live-host",
      "cdn_id": "live-cdn",
      "address_family": "ipv4",
      "host": "live-host.example"
    },
    {
      "id": "vod-hls-host",
      "cdn_id": "vod-hls-cdn",
      "address_family": "ipv4",
      "host": "vod-hls-host.example"
    },
    {
      "id": "vod-host",
      "cdn_id": "vod-cdn",
      "address_family": "ipv4",
      "host": "vod-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "live-node",
        "host_id": "live-host",
        "weight_function": "return session_groups.live_content and 1 or 0"
      },
      {
        "id": "vod-hls-node",
        "host_id": "vod-hls-host",
        "weight_function": "return session_groups.hls_content and 1 or 0"
      },
      {
        "id": "vod-node",
        "host_id": "vod-host",
        "weight_function": "return 1"
      }
    ]
  }
}

Hostname

In cases where there are separate domain or subdomain names for different content types, it’s simple to make classifiers that filter on those names.

The pattern is a string matching the hostname segment of a request URL, including the file name. When selecting the string_match_rule type, use asterisks for wildcard matching. When selecting the regex_rule follow the C++11 std::regex ECMAScript syntax to make valid patterns. Make sure to write patterns that match the entire hostname segment, not just part of it.

Note that each hostname classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different hostnames. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.

Simple example

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 4
  Adding a 'hostName' element
    classifier : {
      name (default: ): live_content_classifier
      type (default: hostName): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): live.example.com
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: y
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 4
  Adding a 'hostName' element
    classifier : {
      name (default: ): news_content_classifier
      type (default: hostName): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): regex
      pattern (default: ): /([^\\.]+/)\\.news_reports_\\d+/\\.example\\.com
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "live_content_classifier",
      "type": "hostName",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "live.example.com"
    },
    {
      "name": "news_content_classifier",
      "type": "hostName",
      "inverted": false,
      "patternType": "regex",
      "pattern": "/([^\\\\.]+/)\\\\.news_reports_\\\\d+/\\\\.example\\\\.com"
    }
  ]
}
Merge and apply the config? [y/n]: y

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): live_content
    classifiers : [
      classifier (default: ): live_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
  sessionGroup : {
    name (default: ): news_content
    classifiers : [
      classifier (default: ): news_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
  sessionGroup : {
    name (default: ): hls_content
    classifiers : [
      classifier (default: ): hls_content_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "live_content",
      "classifiers": [
        "live_content_classifier"
      ]
    },
    {
      "name": "news_content",
      "classifiers": [
        "news_content_classifier"
      ]
    },
    {
      "name": "hls_content",
      "classifiers": [
        "hls_content_classifier"
      ]
    }
  ]
}
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "session_groups": [
    {
      "id": 1,
      "name": "live_content",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": false,
            "name": "live_content_classifier",
            "rule": {
              "rule_type": "string_match_rule",
              "source": "session/hostname",
              "pattern": "live.example.com"
            }
          }
        ],
        [
          {
            "id": 2,
            "inverted": false,
            "name": "news_content_classifier",
            "rule": {
              "rule_type": "regex_rule",
              "source": "session/hostname",
              "pattern": "/([^\\.]+/)\\.news_reports_\\d+/\\.example\\.com"
            }
          }
        ]
      ]
    }
  ],
  "cdns": [
    {
      "id": "live-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "vod-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "live-host",
      "cdn_id": "live-cdn",
      "address_family": "ipv4",
      "host": "live-host.example"
    },
    {
      "id": "vod-host",
      "cdn_id": "vod-cdn",
      "address_family": "ipv4",
      "host": "vod-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    "member_order": "sequential",
    "members": [
      {
        "id": "live-node",
        "host_id": "live-host", 
        "weight_function": "return session_groups.live_content and 1 or 0"
      },
      {
        "id": "vod-node",
        "host_id": "vod-host",  
        "weight_function": "return 1"
      }
    ]
  }
}

Using the session groups in confcli

The constructed session groups can be used in routing by creating a rule that references them:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): classifier_routing_rule
      type (default: firstMatch): ⏎
      targets : [
        target : {
          onMatch (default: ): live-host
          rule (default: ): in_all_session_groups('live_content', 'news_content')
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): vod-hls-host
          rule (default: ): in_session_group('hls_content')
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): offload-host
          rule (default: ): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "classifier_routing_rule",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "live-host",
          "condition": "in_all_session_groups('live_content', 'news_content')"
        },
        {
          "onMatch": "vod-hls-host",
          "condition": "in_session_group('hls_content')"
        },
        {
          "onMatch": "offload-host",
          "condition": "always()"
        }
      ],
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint classifier_routing_rule
services.routing.entrypoint = classifier_routing_rule

3.4.4 - Route on Content Popularity

How to write ESB3024 Router configurations for content popularity based routing

This page describes how to write configuration for content popularity routing. For configuration in general, see Configuration.

For more details on content popularity tuning and routing, see

Content Popularity.

Content Popularity

The router tracks content popularity which can be utilized for routing. Using the configuration tool confcli, creating a content popularity based routing configuration for hierarchical and multi-edge scenarios will be demonstrated.

Hierarchical

Consider a CDN setup with edge streamers that has cached popular content and a central streamer where all content is available. You can decide where to route clients based on the requested content’s popularity.

Assuming that appropriate streamer hosts have already been configured, configuration will look like:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: contentPopularity
  Adding a 'contentPopularity' element
    rule : {
      name (default: ): contentPopularityHierarchy
      type (default: contentPopularity): ⏎
      popularityThreshold (default: 10): 2000
      onPopular (default: ): edgeStreamer
      onUnpopular (default: ): centralStreamer
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "contentPopularityHierarchy",
      "type": "contentPopularity",
      "popularityThreshold": 2000.0,
      "onPopular": "edgeStreamer",
      "onUnpopular": "offloadStreamer"
    }
  ]
}
Merge and apply the config? [y/n]: y

where name is the name of the rule, isPopular is the rule to route to if the content is popular, otherwise the rule isUnpopular is routed to. Lastly, popularityThreshold is the threshold for which content is considered popular. Configuring popularityThreshold = 2001 means that the top 2000 most popular assets will be routed to edgeStreamer.

The rule contentPopularityHierarchy can then be used to construct your routing tree.

Multi-edge

Consider a CDN setup with three edge streamers, edge1, edge2 and edge3, configured to cache very popular content, mildly popular content and unpopular content respectively. Assuming that appropriate streamer hosts have already been configured, the following configuration can be used for correctly routing a request in this scenario:

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: contentPopularity
  Adding a 'contentPopularity' element
    rule : {
      name (default: ): mildlyAndUnpopular
      type (default: contentPopularity): ⏎
      popularityThreshold (default: 10): 2001
      onPopular (default: ): edge2
      onUnpopular (default: ): edge3
    }
  Add another 'rule' element to array 'rules'? [y/N]: y
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: contentPopularity
  Adding a 'contentPopularity' element
    rule : {
      name (default: ): multiLevelPopularity
      type (default: contentPopularity): ⏎
      popularityThreshold (default: 10): 101
      onPopular (default: ): edge1
      onUnpopular (default: ): mildyAndUnpopular
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "mildlyAndUnpopular",
      "type": "contentPopularity",
      "popularityThreshold": 2001.0,
      "onPopular": "edge2",
      "onUnpopular": "edge3"
    },
    {
      "name": "multiLevelPopularity",
      "type": "contentPopularity",
      "popularityThreshold": 101.0,
      "onPopular": "edge1",
      "onUnpopular": "mildyAndUnpopular"
    }
  ]
}
Merge and apply the config? [y/n]: y

By configuring a rule to route to multiLevelPopularity, this configuration will route requests for the top 100 most popular content to edge1, popularity ranking 101-2000 to edge2 and popularity ranking > 2000 to edge3. Since the contentPopularity rule offers a binary routing choice of either isPopular or isUnpopular, multiple contentPopularity rules can be utilized to construct multi-leveled content popularity based routing configurations.

Application

To use any of these two configurations in your installation, you’ll need to configure either a rule or the entrypoint to route to either multiLevelPopularity or contentPopularityHierarchy.

3.4.5 - Route on Selection Input

How to write ESB3024 Router configurations to route on selection input, using CDN bandwidth and number of ongoing sessions as example.

This page describes how to write configuration for routing on bandwidth usage or number of ongoing sessions in Edgeware CDN:s by using the selection input API. For configuration in general, see Configuration.

For more details on the selection input API, see Selection Input.

Selection Input

The selection input API allows you to inject custom data, that can be used during routing, into the router. For this use case, we will use CDN bandwidth and the number of ongoing sessions to demonstrate the capabilities of the selection input API.

Imagine that we have a monitor constantly polling the bandwidth and ongoing sessions of hosts in a CDN. These values are injected into the selection input API as JSON packets:

{
  "edge-host-available-bps": 1000000000,
  "edge-host-ongoing-sessions": 300
}

These keys will end up in the router Lua context as “selection inputs”, arbitrary values or JSON objects that can be used to calculate routing weights.

The selection input variable edge-host-available-bps will be available through either selection_input.edge-host-available-bps or si('edge-host-available-bps'). The function si(si_var) fetches the selection input value if it exists, otherwise it returns 0. However, when comparing selection input variables with numbers, there are a number of built-in Lua functions that will simplify things, such as gt() and lt(). For a complete list and more details on these functions, see Built-in Functions.

Simple Example

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): selection-input-routing
      type (default: firstMatch): ⏎
      targets : [
        target : {
          onMatch (default: ): edge-host
          rule (default: ): lt('edge_host_ongoing_sessions', 1000)
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): edge-host
          rule (default: ): gt('edge_host_available_bps', 5000000)
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): offload-host
          rule (default: ): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "selection-input-routing",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "edge-host",
          "condition": "lt('edge_host_ongoing_sessions', 1000)"
        },
        {
          "onMatch": "edge-host",
          "condition": "gt('edge_host_available_bps', 5000000)"
        },
        {
          "onMatch": "offload-host",
          "condition": "always()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint selection-input-routing
services.routing.entrypoint = 'selection-input-routing'
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "cdns": [
    {
      "id": "edge-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "edge-host",
      "cdn_id": "edge-cdn",
      "host": "edge-host.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing-table",
    "member_order": "sequential",
    "members": [
      {
        "id": "edge-host-sessions-available",
        "host_id": "edge-host",
        "weight_function": "return (lt('edge_host_ongoing_sessions', 1000) ~= 0) and 1 or 0"
      },
      {
        "id": "edge-host-bandwith-available",
        "host_id": "edge-host",
        "weight_function": "return (gt('edge_host_available_bps', 5000000) ~= 0) and 1 or 0"
      },
      {
        "id": "offload",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

3.4.6 - Adapt to multi-CDN

How to write ESB3024 Router configuration to handle multi-CDN setups with tokens.

This page describes how to write configuration for setups that require the URL sent back to the client to be rewritten based on routing results, for example by adding a token to the path or as a query string parameter. For configuration in general, see Configuration.

In order to change the redirect location URL, we need to add a response translation function to the confd configuration. By default, all translation functions are empty:

$ confcli services.routing.translationFunctions
{
    "translationFunctions": {
        "request": "",
        "response": ""
    }
}

For full documentation of the response translation function, please see Lua Hooks.

Simple example

Translation functions tend to become large, which makes it hard to write them inside a single string. Instead, the function can be written in a separate .lua script file that is uploaded to the router and referenced from the confd configuration.

The following example will take this approach, adding a script called "rewrite.lua" to the configured custom Lua folder /tmp/custom_lua on the router. For more information see the Configuration JSON Overview.

Lua script

The following script assumes the existence of the function parse_url that returns an object with URL segments that can be altered and then combined into a URL string using the tostring(obj) function again.

Beware that the router does not validate the URL in the Location header, it is up to the Lua script writer to ensure that only URLs are returned.

function response_rewrite(Headers)
   -- The live server has the token as part of the path, added first before the
   -- path from the request.
   local location = parse_url(response_headers.location)

   if location.host == "live-host.example" then
      location.path = "/live-prefix" .. location.path
      return HTTPResponse(
         {
            Headers = {
               {"location", tostring(location)}
            }
         }
      )
   end

   -- The VOD server expects the token as a query string rather than as part
   -- of the path segment.
   -- Since VOD can be used for offload, check that session_groups.is_vod
   -- is set as well.
   if location.host == "vod-host.example" and session_groups.is_vod then
      location.query["token"] = md5sum(secret_key .. request.path)
      return HTTPResponse(
         {
            Headers = {
               {"location", tostring(location)}
            }
         }
      )
   end

   -- If the request was neither in the is_live session group, nor contained
   -- the path element "vod", we return a nil object to indicate that we don't
   -- want to change anything in the response.
   return nil
end

Configuration

To configure a response translation function using with the custom Lua function response_rewrite() using confcli, run the command:

$ confcli services.routing.translationFunctions.response 'return response_rewrite()'
services.routing.translationFunctions.response = 'return response_rewrite()'

An example confd configuration utilizing this translation function based on session groups would look like this:

$ confcli services.routing
{
  "translationFunctions": {
    "request": "",
    "response": "return response_rewrite()"
  },
  "sessionGroups": [
    {
      "name": "is_live",
      "classifiers": [
          "is_live_classifier"
      ]
    },
    {
      "name": "is_vod",
      "classifiers": [
          "is_vod_classifier"
      ]
    }
  ],
  "classifiers": [
    {
      "name": "is_live_classifier",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*/live/*"
    },
    {
      "name": "is_vod_classifier",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*/vod/*"
    }
  ],
  "hostGroups": [
    {
      "name": "live-cdn",
      "type": "host",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
          {
              "name": "live-host",
              "hostname": "live-host.example",
              "ipv6_address": ""
          }
      ]
    },
    {
      "name": "vod-cdn",
      "type": "host",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
          {
              "name": "vod-host",
              "hostname": "vod-host.example",
              "ipv6_address": ""
          }
      ]
    }
  ],
  "rules": [
    {
      "name": "multiCdnExample",
      "type": "firstMatch",
      "targets": [
        {
          "condition": "in_session_group('is_live')",
          "onMatch": "live-host"
        },
        {
          "condition": "in_session_group('is_vod')",
          "onMatch": "vod-host"
        },
        // Use the vod-host as offload for any content, but don't set any
        // token for requests not classified as vod.
        {
          "condition": "always()",
          "onMatch": "vod-host"
        }
      ]
    }
  ],
  "entrypoint": "multiCdnExample",
  "applyConfig": true
}

3.4.7 - How to use ACD router for EDNS routing

How to write ACD Route configurations for EDNS routing

This page describes how to write configuration for EDNS routing. For configuration in general, see Configuration.

EDNS routing

In your CDN architecture, you might utilize EDNS routing to redirect clients. Whether it’s your own CDN or a third party CDN, the ESB3024 Router supports creating EDNS requests and sending them to any DNS server.

Configuration

To configure EDNS routing, you first need to create a DNS type host. Using confcli:

[user@acd-router ~]# confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 1
  Adding a 'dns' element
    hostGroup : {
      name (default: ): edns-cdn
      type (default: dns): ⏎
      hosts : [
        host : {
          name (default: ): edns-host
          hostname (default: ): ednshost.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "edns-cdn",
      "type": "dns",
      "hosts": [
        {
          "name": "edns-host",
          "hostname": "ednshost.com",
          "ipv6_address": ""
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Note that the hostname is the name of the DNS server that will receive the EDNS request. You can now use the DNS host when creating the routing tree, e.g. in a random type rule:

[user@router ~]# confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: random
  Adding a 'random' element
    rule : {
      name (default: ): random-rule
      type (default: random): ⏎
      targets : [
        target (default: ): edns-host
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "random-rule",
      "type": "random",
      "targets": [
        "edns-host"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
[user@router ~]# confcli services.routing.entrypoint random-rule
services.routing.entrypoint = 'random-rule'

Or simply use it as the entrypoint:

confcli services.routing.entrypoint edns-host

3.4.8 - How to use ESB3024 Router with Edgeware CDN Request Router

How to use ESB3024 Router with ESB3008 Request Router

This page describes how to write configuration for using ESB3024 Router in conjunction with ESB3008 Request Router. It can request a host from an ESB3008 Request Router and forward the response to the client, perform load balancing between several Request Routers and handle fallback to an external CDN in case no Request Routers are able to service the request.

Simple Example

# The tuning parameter `target.requestAttempts` controls the number of attempts
# made to find a host. In this example we want to fallback to the external CDN
# in case both Request Routers are down, so we set it to at least 3.

$ confcli services.routing.tuning.target.requestAttempts 3
services.routing.tuning.target.requestAttempts = 3

# Create a classifier to filter incoming requests from Sweden.

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: geoip
  Adding a 'geoip' element
    classifier : {
      name (default: ): sweden_classifier
      type (default: geoip): ⏎
      inverted (default: False): ⏎
      continent (default: ): ⏎
      country (default: ): sweden
      cities : [
        city (default: ): ⏎
        Add another 'city' element to array 'cities'? [y/N]: ⏎
      ]
      asn (default: ): ⏎
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "sweden_classifier",
      "type": "geoip",
      "inverted": false,
      "continent": "",
      "country": "sweden",
      "cities": [
        ""
      ],
      "asn": ""
    }
  ]
}
Merge and apply the config? [y/n]: y

# Create a session group for the non-Swedish requests, to use in routing rules

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): sweden
    classifiers : [
      classifier (default: ): sweden_classifier
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "sweden",
      "classifiers": [
        "sweden_classifier"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

# The internal CDN uses Edgeware Request Routers that return a redirect
# location.  The router takes the content from the client request,
# and makes its own request to the Request Router using that same
# content.  The returned location is then forwarded to the client.
#
# In case the Request Router responds with an error code, or times out,
# the router will continue traversing the routing tree until a
# successful route is found or the entire tree has been evaluated.

$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 3
  Adding a 'redirecting' element
    hostGroup : {
      name (default: ): internal-cdn
      type (default: redirecting): ⏎
      httpPort (default: 80): ⏎
      httpsPort (default: 443): ⏎
      hosts : [
        host : {
          name (default: ): internal-host-1
          hostname (default: ): internal-host-1.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: y
        host : {
          name (default: ): internal-host-2
          hostname (default: ): internal-host-2.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "internal-cdn",
      "type": "redirecting",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "internal-host-1",
          "hostname": "internal-host-1.example.com",
          "ipv6_address": ""
        },
        {
          "name": "internal-host-2",
          "hostname": "internal-host-2.example.com",
          "ipv6_address": ""
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

# The offload CDN is non-redirecting, meaning that router does not
# make any request to its associated hosts to ask for a redirect location
# to forward to the clients, instead it simply returns a location using
# one of the CDN's hosts substituted for the router's host in the
# client request possibly with some kind of respsonse translation to add
# e.g. tokens or path prefixes.

$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

hostGroups : [
  hostGroup can be one of
    1: dns
    2: host
    3: redirecting
  Choose element index or name: 2
  Adding a 'host' element
    hostGroup : {
      name (default: ): offload-cdn
      type (default: host): ⏎
      httpPort (default: 80): ⏎
      httpsPort (default: 443): ⏎
      hosts : [
        host : {
          name (default: ): offload-host
          hostname (default: ): offload-host.example.com
          ipv6_address (default: ): ⏎
        }
        Add another 'host' element to array 'hosts'? [y/N]: ⏎
      ]
    }
  Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
  "hostGroups": [
    {
      "name": "offload-cdn",
      "type": "host",
      "httpPort": 80,
      "httpsPort": 443,
      "hosts": [
        {
          "name": "offload-host",
          "hostname": "offload-host.example.com",
          "ipv6_address": ""
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

# Begin with adding a load balancing route rule between the two internal
# hosts. Let's make internal-host-2 have twice the capacity of
# internal-host-1 by using a weighted rule.

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: weighted
  Adding a 'weighted' element
    rule : {
      name (default: ): balancer
      type (default: weighted): ⏎
      targets : [
        target : {
          target (default: ): internal-host-1
          weight (default: 100): 1,
          rule (default: always()): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          target (default: ): internal-host-2
          weight (default: 100): 2,
          rule (default: always()): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "balancer",
      "type": "weighted",
      "targets": [
        {
          "target": "internal-host-1",
          "weight": "1",
          "rule:": "always()"
        },
        {
          "target": "internal-host-2",
          "weight": "2",
          "rule:": "always()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

# Make an offload rule to route any traffic not in Sweden to the
# offload CDN.

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): offload
      type (default: firstMatch): ⏎
      targets : [
        target : {
          onMatch (default: ): offload-host
          rule (default: ): not in_session_group('sweden')
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): balancer
          rule (default: ): in_session_group('sweden')
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "offload",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "offload-host",
          "condition": "not in_session_group('sweden')"
        },
        {
          "onMatch": "balancer",
          "condition": "in_session_group('sweden')"
        }
      ],
      "onMiss": "offload-host"
    }
  ]
}
Merge and apply the config? [y/n]: y
{
  "tuning": {
    // "target_request_attempts" controls the number of attempts to find a host.
    // In this example we want to fallback to the external CDN in case both
    // Request Routers are down, so we set it to 3.
    "target_request_attempts": 3
  },
  "session_groups": [
    {
      "id": 1,
      "name": "not_sweden",
      "classifiers": [
        [
          {
            "id": 1,
            "inverted": true,
            "name": "not_sweden_classifier",
            "rule": {
              "rule_type": "geoip_rule",
              "source": "session/client_ip",
              "country": "Sweden"
            }
          }
        ]
      ]
    }
  ],
  "cdns": [
    {
      "id": "internal-cdn",
      "http_port": 80,
      "https_port": 443,
      // The internal CDN uses Edgeware Request Routers that return a redirect
      // location.  The router takes the content from the client request,
      // and makes its own request to the Request Router using that same
      // content.  The returned location is then forwarded to the client.
      //
      // In case the Request Router responds with an error code, or times out,
      // the router will continue traversing the routing tree until a
      // successful route is found or the entire tree has been evaluated.
      "redirecting": true,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      // The offload CDN is non-redirecting, meaning that router does not
      // make any request to its associated hosts to ask for a redirect location
      // to forward to the clients, instead it simply returns a location using
      // one of the CDN's hosts substituted for the router's host in the
      // client request possibly with some kind of respsonse translation to add
      // e.g. tokens or path prefixes.
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "internal-host-1",
      "cdn_id": "internal-cdn",
      "address_family": "ipv4",
      "host": "internal-host-1.example"
    },
    {
      "id": "internal-host-2",
      "cdn_id": "internal-cdn",
      "address_family": "ipv4",
      "host": "internal-host-2.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "address_family": "ipv4",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing_table",
    // "sequential" - Go through the rules at this level one by one, and pick
    // the first that returns a positive weight.
    "member_order": "sequential",
    "members": [
      {
        "id": "reject-node",
        "host_id": "offload-host",
        // Send filtered-out clients to an offload host.
        "weight_function": "return session_groups.not_sweden and 1 or 0"
      },
      {
        "id": "internal_routing",
        // Return 1 to make sure this tree is evaluated at all.
        "weight_function": "return 1"
        // "weighted" - Evaluate all the rules at this level, and pick one of
        // them randomly based on their respective weights.
        //
        // In this example host 1 has half the capacity of host 2, so we just
        // randomly route twice as many clients to host 2.
        "member_order": "weighted",
        "members": [
          {
            "id": "internal-node-1",
            "host_id": "internal-host-1",
            // Half the weight of the other host -> half as likely to be picked.
            "weight_function": "return 1"
          },
          {
            "id": "internal-node-2",
            "host_id": "internal-host-2",
            // Twice the weight of the other -> twice as likely to be picked.
            "weight_function": "return 2"
          }
        ]
      },
      {
        // Add a non-redirecting offload host as the last target in case all the
        // internal redirecting hosts are unavailable or respond with some kind
        // of error code.
        "id": "offload-node",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}

3.4.9 - How to use ESB3024 Router with CoreDNS

How to use ESB3024 Router with CoreDNS

CoreDNS can be configured to work as a DNS server in front of ESB3024 Router. In this mode of operation the client DNS request is terminated by CoreDNS which requests an optimal streaming location from the router.

Contact Edgeware for detailed information on how to set this up, if you don’t already have an Edgeware Support account please contact us here.

3.4.10 - How to use the Director as a replacement for Edgeware CDN Request Router

How to use the Director as a replacement for ESB3008 Request Router

This guide outlines how to replicate Convoy’s ESB3008 HTTP Request Router using the Director. This is accomplished using the Convoy Bridge, which is an integration service designed to allow the router and an existing Convoy installation to work together seamlessly.

Following the steps outlined below enables the replacement of existing ESB3008 HTTP Request Router instances with the Director. As of the current documentation, the Director is not a direct substitute for the ESB3008 HTTP Request Router. However, most of the functionality is available, and in the majority of cases, the Director can be used without any loss of functionality.

The purpose of this guide is to detail the process of transitioning from an existing Convoy installation, which includes one or more instances of ESB3008 HTTP Request Router, to a configuration utilizing the Director. This transition allows the existing Convoy installation to continue its role in CDN provisioning, content management, and analytics. Simultaneously, the router assumes responsibility for managing HTTP(S) redirects directly from clients to selected streamers.

One functional difference between ESB3008 HTTP Request Router and the Director is in communication with the streamer to determine specific interface assignments. ESB3008 uses a proprietary protocol to communicate with the streamer to help determine the best interface for the client. For the Director, in order to work with both streamers and third-party CDNs, the use of the proprietary protocol is not supported, and the router’s rule engine must be used to accomplish the same result. It is for this reason that it is recommended to configure each streaming interface as a distinct host entry in the router’s configuration. This allows the router to address each interface separately.

Prerequisites

This guide assumes both an existing Convoy installation and a partiality configured instance of the Director. The router should have all the necessary routing configuration in place for hostGroups, sessionGroups and routing rules to direct traffic to the streaming interfaces of the streamers. It is also assumed that the proper firewall rules are allowing the required traffic between the router, the Convoy Bridge integration and the Convoy management nodes.

The minimum compatible version of Convoy which can be used with the analytics synchronization feature is Convoy 3.0.0. Previous versions may be used only if Convoy is not being used for analytics.

Firewall Configuration

Proper firewall configuration is required to allow both the router and Convoy to communicate through bidirectional connections established from the Convoy Bridge integration. The Convoy Bridge does not need to be enabled for each router instance, one instance of the Convoy Bridge can synchronize multiple instances of the router simultaneously. Only the router nodes with the Convoy Bridge enabled will need access through the firewall to establish outgoing connections to the Convoy management nodes, or whichever nodes are running MariaDB and Kafka. Additionally, if multiple router instances are to be synchronized by a single Convoy Bridge instance, the firewall must allow the Convoy Bridge to establish connections to each router instance on port 5001.

The following table outlines the necessary connections to be allowed through the firewall.

SourceDestinationPortDescription
Convoy BridgeConvoy Management3306/TCPAccount Configuration
Convoy BridgeConvoy Management9092/TCPAnalytics Data
Convoy BridgeThe router5001/TCPRest API

Response Translation Functions

In order to have the router generate a redirect URL which is compatible with the format generated by the ESB3008 HTTP Request Router, a response translation function must be used to modify the redirect URL before it is returned to the client. A predfined function convoy_compatibility_response is available in the standard library to be used for this purpose. This function appends both the session-id and storage-prefix based on the account and distribution information in Convoy.

On the Director, set the response translation function as follows:

> confcli services.routing.translationFunctions.response "return convoy_compatibility_response(Headers, '')"

This function depends on the account synchronization feature of the Convoy bridge to determine the correct storage prefix based on the incoming Host header value. It works by using the Host header to lookup the storage prefix from the account configuration, and then modifying the redirect URL to prepend /session/<session-id>/<prefix>. The streamer can then use this information for both origin selection and session tracking.

Enabling the Convoy Bridge

Before using the Convoy Bridge integration, a valid configuration must first be applied. All configuration for the Convoy Bridge is available in confd under the key integration.convoy.bridge. The configuration is divided into three main sections: The account synchronization feature, the convoy analytics integration, and a list of additional router instances to synchronize.

By default, the Convoy Bridge will include the current local router instance in the synchronization process. The connection details are hard-wired into the container at startup, and do not need to be specified in the configuration. Because one Convoy Bridge can serve multiple instances of the router, it is not necessary to configure the Convoy Bridge on each node separately. However, if multiple Convoy Bridge instances are used, it is recommended to configure them so that one router is served by multiple instances of the Convoy Bridge. This provides high-availability in a production environment.

As an example, if there are 4 router instances, A, B, C, and D, and 4 Convoy Bridge instances, configuring them such that Bridge 1 synchronizes A & B, 2, synchronizes B & C, 3, synchronizes C & D and 4 synchronizes D & A will provide fault tolerance in the event that one bridge is unavailable.

The account synchronization feature of the Convoy Bridge watches the MariaDB database on the Convoy management node for changes to the account and distribution configuration, and if the configuration differs from what is currently known to the router the configuration will be updated. This feature is required by both the router for use with the convoy_compatibility_response response translation function, and within the Convoy Bridge integration for setting the correct account, storage, and distribution fields with the analytics integration feature.

The analytics integration feature monitors monitors the router’s Event API for newly established sessions, and produces session-record messages over the Kafka message broker for use by Convoy. This feature requires that Convoy is both licensed and configured for use with the analytics feature. The integration works by establishing a persistent connection to each router, and listening for new session events. Due to the protocol in use by the Event API to send the events, only one instance of the Convoy Bridge will have the ability to receive each event, and only that instance will produce the session-record to the Kafka message brokers.

Synchrnoizing multiple routers with the same instance of the Convoy Bridge is performed by configuring the otherRouters section of the Convoy Bridge configuration. In addition to the local router, each otherRouter entry will have the same account and distribution information updated simultaneously, and will be used as an event source for the analytics integration. The otherRouters entries require the URL to the router’s Rest API, an optional API key, and a flag to indicate if SSL certificate validation should be enforced.

Enable the account synchronization feature by running the following command:

> confcli integration.convoy.bridge.accounts -w
Running wizard for resource 'accounts'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

accounts : {
  enabled (default: False): true
  dbUrl (default: mysql://user:pass@localhost:3306): mysql://convoy:password@convoy-mgmt1:3306
  cmsUrl (default: http://localhost:5555): http://convoy-mgmt1:5555
  pollInterval (default: 60):
}
Generated config:
{
  "accounts": {
    "enabled": true,
    "dbUrl": "mysql://convoy:password@convoy-mgmt1:3306",
    "cmsUrl": "http://convoy-mgmt1:5555",
    "pollInterval": 60
  }
}
Merge and apply the config? [y/n]:

This will result in the Convoy Bridge continuously polling the Convoy instance running on convoy-mgmt1 every 60 seconds for changes to the account configuration. Only when the account configuration differs from the current configuration on the router will it be updated with the change.

The pollInterval parameter can be used to control how frequently the Convoy Bridge will attempt to poll the database for changes. Setting this value too high will result in a longer delay between changes being made in Convoy and the changes being reflected in the router. Setting this value too low will result in unnecessary load on the Convoy database. The default value of 60 seconds should be sufficient for most use cases.

To enable the analytics integration feature, run the following command:

> confcli integration.convoy.bridge.analytics -w
Running wizard for resource 'analytics'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

analytics : {
  enabled (default: False): true
  brokers : [
    broker (default: ): convoy-mgmt1:9092
    Add another 'broker' element to array 'brokers'? [y/N]: y
    broker (default: ): convoy-mgmt2:9092
    Add another 'broker' element to array 'brokers'? [y/N]: y
    broker (default: ): convoy-mgmt3:9092
    Add another 'broker' element to array 'brokers'? [y/N]: n
  ]
  batchInterval (default: 10):
  maxBatchSize (default: 500):
}
Generated config:
{
  "analytics": {
    "enabled": true,
    "brokers": [
      "convoy-mgmt1:9092",
      "convoy-mgmt2:9092",
      "convoy-mgmt3:9092"
    ],
    "batchInterval": 10,
    "maxBatchSize": 500
  }
}
Merge and apply the config? [y/n]:

This will enable the analytics integration, which will produce session-record messages to the configured Kafka brokers. The brokers configuration list is used to bootstrap the initial set of brokers which will be contacted by the Convoy Bridge to then obtain the current set of active brokers. It is not necessary to include all brokers here, as the initial connection will automatically negotiate the correct broker list.

The batchInterval parameter must be set to a value much less than 60 seconds, since the streamer will send session-sample messages to Kafka every 60 seconds, and if the corresponding session-record message is not received within that time, the sample will be dropped, resulting in potentially inaccurate bandwidth statistics.

> confcli integration.convoy.bridge.otherRouters -w
Running wizard for resource 'otherRouters'
<Other routers which will be kept in sync (default: [])>

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

otherRouters <Other routers which will be kept in sync (default: [])>: [
  otherRouter : {
    url (default: ): https://router-2:5001
    apiKey (default: ): 1234
    validateCerts (default: True): false
  }
  Add another 'otherRouter' element to array 'otherRouters'? [y/N]: y
  otherRouter : {
    url (default: ): https://router-3:5001
    apiKey (default: ):
    validateCerts (default: True):
  }
  Add another 'otherRouter' element to array 'otherRouters'? [y/N]: n
]
Generated config:
{
  "otherRouters": [
    {
      "url": "https://router-2:5001",
      "apiKey": "1234",
      "validateCerts": false
    },
    {
      "url": "https://router-3:5001",
      "apiKey": "",
      "validateCerts": true
    }
  ]
}
Merge and apply the config? [y/n]:

3.4.11 - Use In-Stream Sessions

How to configure ACD Router to use In-Stream sessions

In-Stream sessions is a routing mode where the router keeps control of the session for the full session lifetime instead of only routing the session to the preferred CDN (or cache node) once. Technically it works by letting the client return to the router for manifest and segments and redirect each segment to the preferred CDN. This enables changing CDN in the middle of a session.

Configure In-Stream Sessions

The following configuration enables In-Stream routing

{
  "managed_sessions": {
    "fraction": 1.0,
    "max_active": 1000000,
    "session_types": [
      {
        "enabled": true,
        "max_active": 1000000,
        "session_group_ids": [],
        "type": "instream"
      }
    ]
  }
}

The fraction of In-Stream sessions and the maximum number of active In-Stream sessions can be controlled. It is also possible to specify that In-Stream sessions should only be used for certain session groups, for example only for specific contents. See here for a description of the available configuration options.

The following example illustrate the request flow for in-stream session

$ curl  -i http://test-acd-router/content/playlist.m3u8
HTTP/1.1 302 Found
Access-Control-Allow-Origin: *
Content-Length: 0
Location: http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/playlist.m3u8
X-Service-Identity:

$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/playlist.m3u8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Length,Content-Range
Connection: keep-alive
Content-Length: 306
Content-Type: application/vnd.apple.mpegurl
Date: Fri, 31 Mar 2023 10:18:42 GMT
ETag: "5d711f08-132"
Last-Modified: Thu, 05 Sep 2019 14:43:20 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Service-Identity:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=320x180
abr_500k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360
abr_1000k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1700000,RESOLUTION=1280x720
abr_1700k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3300000,RESOLUTION=1280x720
abr_3300k.m3u8

$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/abr_500k.m3u8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Length,Content-Range
Connection: keep-alive
Content-Length: 276
Content-Type: application/vnd.apple.mpegurl
Date: Fri, 31 Mar 2023 12:02:04 GMT
ETag: "6426cbbc-114"
Last-Modified: Fri, 31 Mar 2023 12:02:04 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Service-Identity:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:1
#EXT-X-MEDIA-SEQUENCE:112583846
#EXTINF:0.834444,
abr_500k112583846.ts
#EXTINF:0.834444,
abr_500k112583847.ts
#EXTINF:0.834444,
abr_500k112583848.ts
#EXTINF:0.834444,
abr_500k112583849.ts
#EXTINF:0.834444,
abr_500k112583850.ts

$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/abr_500k112583846.ts
HTTP/1.1 302 Found
Access-Control-Allow-Origin: *
Content-Length: 0
Location: http://testcdn.tv/abr_500k112583846.ts
X-Service-Identity:

A Note on Confcli

In-stream selection sessions can’t be configured in confcli at the moment, but it is possible to configure such sessions while configuring routing etc using confcli.

Begin with configuring routing, classification and session groups in confcli, for example based on content types.

# Create a classifier for live sessions

$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

classifiers : [
  classifier can be one of
    1: contentUrlPath
    2: contentUrlQueryParameters
    3: geoip
    4: hostName
    5: ipranges
    6: regexMatcher
    7: stringMatcher
    8: subnet
    9: userAgent
  Choose element index or name: 1
  Adding a 'contentUrlPath' element
    classifier : {
      name (default: ): live
      type (default: contentUrlPath): ⏎
      inverted (default: False): ⏎
      patternType (default: stringMatch): ⏎
      pattern (default: ): *live*
    }
  Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
  "classifiers": [
    {
      "name": "live",
      "type": "contentUrlPath",
      "inverted": false,
      "patternType": "stringMatch",
      "pattern": "*live*"
    }
  ]
}
Merge and apply the config? [y/n]: y

# Create a session group using the classifier

$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

sessionGroups : [
  sessionGroup : {
    name (default: ): live
    classifiers : [
      classifier (default: ): live
      Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
    ]
  }
  Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
  "sessionGroups": [
    {
      "name": "live",
      "classifiers": [
        "live"
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y

Then look at the raw configuration to determine what session ID numbers to use for in-stream routing:

// curl -k https://localhost:5001/v2/configuration | jq .session_groups
[
  {
    "classifiers": [
      [
        {
          "id": 0,
          "inverted": false,
          "name": "classifier_live",
          "rule": {
            "pattern": "*live*",
            "rule_type": "string_match_rule",
            "source": "session/content_url_path"
          }
        }
      ]
    ],
    "id": 0,
    "name": "live"
  }
]

The output shows that the session group with the name "live" has the session group ID number 0, meaning that the configuration required to enable in-stream selection sessions for 100 % of live content sessions would look like

{
  "managed_sessions": {
    "fraction": 1.0,
    "max_active": 1000000,
    "session_types": [
      {
        "enabled": true,
        "max_active": 1000000,
        "session_group_ids": [0], // Session group ID from config here
        "type": "instream"
      }
    ]
  }
}

This configuration can be sent on its own to the configuration API using a PUT request without interfering with any of the configuration done using confcli.

Monitoring

If Grafana is installed together with the ESB-3024 installer, the number of started In-Stream sessions as well as currently active In-Stream sessions can be seen in a Dashboard.

Notes on Performance

Be aware that In-Stream sessions puts additional load on the request router since all clients continuously comes back to the router to fetch new manifests and to get segment redirects. The necessary router capacity therefore scaled both with number of started sessions and the average session length.

3.5 - Ready for Production?

Prepare for production

3.5.1 - Setup for Redundancy

Configuring Redundancy

The Agile Director is designed to support the coexistence of multiple independent instances, facilitating either high-availability and/or horizontal scaling based on specific use cases and requirements. Each instance of the Director operates as a complete isolated entity, offering multiple solutions for redundancy. The choice between these solutions depends on the particular use case and requirements of the deployment.

A few select use-cases and example deployments are described in the sections that follow. Note however that this list is not exhaustive, and other approaches not listed here may be more applicable to a specific use-case.

Third-party load balancer

In this first scenario, multiple instances of the router are positioned behind an off-the-shelf load balancer. This could range from a simple

Nginx

proxy to a more sophisticated commercial load balancer, depending on the user’s specific needs and requirements.

DNS Round Robin

A straightforward alternative to deploying multiple instances of the router behind a load balancer is to employ round-robin DNS. In this approach, each router instance is associated with a distinct A record in DNS, all sharing the same domain name. Clients querying this DNS server receive multiple entries in response. Typically, clients utilize a round-robin algorithm to resolve the IP address of the router, although some clients might randomly select an address from the available servers.

While this method effectively distributes the load across multiple instances, it has a few drawbacks. First, clients are not guaranteed to use any specific algorithm for selecting the IP address. Second, due to DNS caching in the network and on the client’s device, modifications to the DNS record (e.g., taking a node out of service or adding additional nodes) will experience higher latency compared to some other techniques. Third, there is a dependency on the client being able to recognize this DNS server as authoritative. And fourth, this approach does not provide any means of high-availability. If a node is offline, requests to that node will fail.

VRRP

If horizontal scaling is not required, employing a shared Virtual IP Address through the VRRP protocol may suffice. This can be easily configured on one or more instances of the router by installing and setting up keepalived. While the specific details of keepalived are beyond the scope of this document, it can establish a Primary/Backup node configuration, where heartbeat packets and server priority determine each node’s role. Using VRRP, a Virtual IP address always points to the current primary node, and in the event of a primary node failure, the remaining nodes elect a new primary node based on the predetermined priority.

This solution has some drawbacks compared to others; the VIP may only be assigned to a single node at a time, rendering horizontal scaling impossible using this solution alone. Another drawback is that if the primary node fails, there will be a brief period, usually around one second, before the failure is detected and the VIP is reassigned.

This solution can be more effectively utilized as part of a larger combined solution in which several groups of nodes are employed. In each group, there is a Primary and Backup, and selection between the groups is handled via one of the other scaling solutions.

An Example Combined Approach Scenario

The following represents an example scenario where eight independent router nodes are utilized employing all three of the above approaches.

The scenario consists of four pairs of nodes, with each pair using VRRP to designate one node as Master and one as a Backup. In front of two pairs of pairs would sit two load balancers, each configured with the VIP address of each pair below. The two load balancers would then be placed into Round Robin DNS with the same FQDN.

Incoming requests would resolve the DNS record, yielding two servers. They would then send requests to each in turn. The load balancer at the end of those IP addresses would then select among the two VIP addresses below, and the request would be routed to the current Primary node in the group.

In this scenario, if any one of the primary nodes becomes offline, the VRRP protocol will move the VIP to the backup node. While that process is ongoing, the load balancer will detect that the VIP is unreachable, routing all traffic in the meantime to the VIP of the second pair. The DNS round-robin would be used to evenly distribute the traffic between the two load balancers.

3.5.2 - HTTPS Certificates

Installation and verification of SSL certificates

Configuration of ESB3024 Router is done through a REST API over HTTPS. While the router installer generates a self-signed certificate in order to enable the interface at all, this is not considered safe and secure so a properly generated certificate should be used instead.

For SSL to work, the router needs to have both an x509 certificate and a key in ASCII armored PEM format:

-----BEGIN PRIVATE KEY-----
[...]
-----END PRIVATE KEY-----

-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----

The files can be either separate .crt and .key files or a combined .pem file.

Simply copy the file(s) generated by your CA service, into the /opt/edgeware/acd/ssl folder on the host machine and they will automatically be used by the router. The filenames must match the associated hostname, and there’s currently no support for wildcard matching or multiple domains per certificate. Several key/crt pairs can be placed in the folder in order to support more than one domain name.