[![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) 

![Sh4lt logo](doc/logo/Sh4lt-logo-small.png)

Sh4lt is a library to share streams of framed data between applications. It supports any type of data stream, such as multichannel audio, video frames, 3D models, application messages, and various other types of data. The communication paradigm is 1 to many, i.e., one *writer* is making available data frames to several *followers*, which make Sh4lt very efficient and flexible during data communication among software.

Currently, Sh4lt API is available for C/C++ and Python.

In addition to the library, this repo provides tools to transmit and monitor from the command line : `shlinew` and `shfollow`. An example with text data is provided in [Command line example](#command-line-example).


## Implementation details

* Sh4lt is server-less and uses a pair of names (*group* and *label*) in order to establish communication among the *writer* and its *followers*.
* Sh4lt is very fast and allows processes to access data streams without the need for extra copies.
* *Followers* and *writers* can hot connect and disconnect.
* Timecode: a consistent system time and playhead time are available for each Sh4lt 
* Inline metadata: *writers* can add metadata attached to sh4lt writes 
* Sh4lt transmission supports buffer resizing during communication. 
* Each Sh4lt type description is made from a structured string using JSON.  

# Installation

## Ubuntu

Note that three packages are provided: the `lib` version is for standard use, the `dev` for development and the `dbg` for debugging. If installed, the `dev` package replaces the `lib` package, like the documentation and extra tools related to Sh4lt development.   

Debian packages can be downloaded from [here](https://gitlab.com/sh4lt/sh4lt/-/releases). Once downloaded, it can be installed from the Ubuntu package manager or with the following command:

```
sudo dpkg -i <path to the package file>
```

If dpkg complains about dependencies errors, then you can run `sudo apt install -f` and then run `sudo dpkg -i <path to the package file>` again.

## Python installation with pip (Linux)

From a terminal, the following command install the python module for the last sh4lt release, along with some command line utils:
```
pip install git+https://gitlab.com/sh4lt/sh4lt.git
```

For a specific branch, for instance "develop":
```
pip install git+https://gitlab.com/sh4lt/sh4lt.git@develop
```

For a specific version, for instance "0.1.4":
```
pip install git+https://gitlab.com/sh4lt/sh4lt.git@0.1.4
```

## Installation from source

You can [install Sh4lt from source](doc/install-from-sources.md)

# Command line example

The example will illustrate a communication with Sh4lt, from a *writer* to two *follower*. One follower will be used for monitoring the transmission, while the other will format and write the transmitted data to a file.

### Writer

In a terminal, run a writer as follow:
```
while true; do echo Hello World $(date) ; sleep 1; done | shlinew hello
```

This will write "Hello World <date and time>" to the Sh4lt identified by the label "hello". Actually, `shlinew` reads its standard input and writes each line to a Sh4lt.

The following command sequence will let you check your Sh4lt installation. It describes how to i) generate a video test signal into a Sh4lt, ii) monitor it, and iii) read the video Sh4lt for display.

### Monitor the transmission

The `shflow` utility is installed along with the Sh4lt library. It prints the Sh4lt metadata once connected with the Sh4lt writer and then a line of information for each buffer pushed by the Sh4lt writer. Keep the video Sh4lt running, and then from a new terminal type:
```
# monitor a Sh4lt type and frame sizes
$ shflow -f c hello
/tmp/sh4lt-nico/8208575949763498332
connected: type {
	"group" : "Default",
	"label" : "hello",
	"media" : "text/x-raw"
}
265  size: 39  data: Hello World Wed Feb 7 16:02:38 EST 2024
266  size: 39  data: Hello World Wed Feb 7 16:02:39 EST 2024
267  size: 39  data: Hello World Wed Feb 7 16:02:40 EST 2024
268  size: 39  data: Hello World Wed Feb 7 16:02:41 EST 2024
269  size: 39  data: Hello World Wed Feb 7 16:02:42 EST 2024
270  size: 39  data: Hello World Wed Feb 7 16:02:43 EST 2024
etc
```
Here, the `-f c` option forces `shflow` to print data as a sequence of "char".

### Write the data to a file

In a new terminal, while the writing and monitoring are still running:
```
shflow -f c -n hello > data.txt
```
Actually, the command is almost the same as the one used for monitoring, but the `-n` option removes frame number, frame size, and timing information.

# Use Sh4lt in your code

In previous section, GStreamer is used in order to illustrate a transmission, but you can also include Sh4lt in you project with specific languages, using native Sh4lt API. Here follows some examples in various languages:

* [C++](tests/check-writer-follower.cpp)
* [C](tests/check-c-wrapper.cpp)
* [Python3](wrappers/python/tests/check-writer-follower.py)

Note that in order to develop with Sh4lt C or C++ API, you may want to install development files:
```
sudo apt install libsh4lt-dev
```

Then C and C++ using Sh4lt can be compiled with help from pkgconfig, as follows:
```bash
# C code:
gcc -o check-c-wrapper $(pkg-config --cflags sh4lt-0.0) ./check-c-wrapper.cpp $(pkg-config --libs sh4lt-0.0)

# C++ code
g++ -o check-writer-follower $(pkg-config --cflags sh4lt-0.0) ./check-writer-follower.cpp $(pkg-config --libs sh4lt-0.0)
```

### Use of Sh4lt static library

Sh4lt adds the pkg-config variable `static_lib_path` that provides the path to the Sh4lt static library. It can be used as follows, here runing from the `tests` directory of the Sh4lt sources. 
```
g++ -o check-shm-resize $(pkg-config --cflags sh4lt-0.0) check-shm-resize.cpp $(pkg-config --variable=static_lib_path sh4lt-0.0)
``` 

# Issues and contributions
To contribute to Sh4lt, please first [open an issue](https://gitlab.com/sh4lt/sh4lt/-/issues). If appropriate, please select the appropriate issue template among "bug report", "feature request" or "request for comments". For more details, see the [contribution guide](CONTRIBUTING.md)

# TODO

* [ ] Windows port - use Windows IPC for a windows build
* [ ] OSX port - Should work, but need to be included into the CI
* [ ] Port C++ metadata API to C and Python APIs
* [x] Writer discovery - Add Select Sh4lt to receive from a list of 
* [x] Sh4lt-NDI - a bridge between Sh4lt and NDI
* [x] GStreamer - elements for *writer* and *follower* 

# About us

Sh4lt is maintained by [Nicolas Bouillot](https://nicolasbouillot.net) from the [Lab148 coop](https://lab148.xyz/en/).

See a list of Sh4lt authors [here](AUTHORS.md).

## History
This project is fork of the [Shmdata](https://gitlab.com/nicobou/shmdata) project. For its first release, Sh4lt added timecode, improved data description API and Sh4lt selection through "group" and "label" instead of raw socket file path.


