<commit_before>SRT Live Transmit
---------

The *srt-live-transmit* tool is a universal data transport tool, which's
intention is to transport data between SRT and other medium.
At the same time it is just a sample application to show some of 
the powerful features of SRT. We encourage you to use SRT library
itself integrated into your products.

The *srt-live-transmit* can be both used as a universal SRT-to-something-else
flipper, as well as a testing tool for SRT.

The general usage is the following:

    srt-live-transmit <input-uri> <output-uri> [options]

The following medium types are handled by *srt-live-transmit*:

- SRT - use SRT for reading or writing, in listener, caller or rendezvous mode, with possibly additional parameters
- UDP - read or write the given UDP address (also multicast)
- Local file - read or store the stream into the file
- Process's pipeline - use the process's *stdin* and *stdout* standard streams

Any medium can be used with any direction, although some of them may
have special direction-dependent cases.

Mind that the URI has a standard syntax:

    scheme://HOST:PORT/PATH?PARAM1=VALUE&PARAM2=VALUE

If you specify only the path (no **://** specified), then the scheme
defaults to **file**. The path can be also specified as relative this
way. Note also that empty host (`scheme://:PORT`) defaults to 0.0.0.0,
and an empty port (when there's no `:PORT` part) defaults to port number 0.

Special options for particular medium may be specified in **PARAM...**
items. All options are medium-specific, although there may happen some
options common for multiple media types.

Note also that the *host* part is always tried to be resolved as a name,
if its form is not directly the IPv4 address.

Example for smoke testing
-------------------------

First we need to start up the SRT live transmit app, listening for unicast UDP TS input on port 1234 and making SRT available on port 4201. Note, these are randomly chosen ports. We also open the app in verbose mode for debugging

    srt-live-transmit udp://:1234 srt://:4201 -v

Now we need to generate a UDP stream. ffmpeg can be used to generate bars and tone as follows, doing a simple unicast push to our listening srt-live-tansmit app:

    ffmpeg -f lavfi -re -i smptebars=duration=300:size=1280x720:rate=30 -f lavfi -re -i sine=frequency=1000:duration=60:sample_rate=44100 -pix_fmt yuv420p -c:v libx264 -b:v 1000k -g 30 -keyint_min 120 -profile:v baseline -preset veryfast -f mpegts "udp://127.0.0.1:1234?pkt_size=1316"

You should see the stream connect in srt-live-transmit.

Now you can test in VLC (make sure you're using the latest version!) - just go to file -> open network stream and enter

    srt://127.0.0.1:4201

and you should see bars and tone right away.

If you're having trouble, make sure this works, then add complexity one step at a time (multicast, push vs listen, etc)


Medium: FILE (including standard process pipes)
-----------------------------------------------

**NB!** File mode, except `file://con` is supported in *srt-file-transmit* tool!

The general syntax is: `file:///global/path/to/the/file`. No
parameters in the URL are extracted. There's one (non-standard!)
special case, though:

    file://con

That is, **con** is used as a *HOST* part of the URI. If you use this
URI for \<input-uri\>, then the data will be read from the standard
input. If \<output-uri\>, the data will be send to the standard output.
Be careful with options being specified together with having standard
output as output URI - some of them are not allowed as the extra output
controlled by options might interfere with the data output.

Medium: UDP
-----------

UDP can only be used in listening mode for reading, and in calling mode
for writing. Therefore, when UDP is your \<input-uri\>, you usually
specify the local port, e.g.:

    udp://:5555

UDP handles two parameters: **iptos** and **ttl**.
**iptos** will set the value of Type-Of-Service (TOS) field for outgoing packets via IP_TOS socket option.
**ttl** parameter will set time-to-live value for outgoing packets via IP_TTL or IP_MULTICAST_TTL socket options.
See IP protocol documentation for details.

For a single host IP address (unicast):
* **reading**: The *host* part or **adapter** parameter can specify the adapter. The *port* part is mandatory.
* **writing**: Both *host* and *port* are mandatory. The **adapter** parameter is of no use.

If you use multicast IP address:
* For reading, need extra `@` character before the *host* part so that the application subscribes to the multicast group before reading
* The *host* part designates the multicast group (also as a resolvable name)
* The *port* designates the port in the multicast group
* The **adapter** parameter can be used to specify the adapter through which the given multicast group can be reached

Medium: SRT
-----------

Most important about SRT is that it can be either input or output and in
both these cases it can work in listener, caller and rendezvous mode. SRT
also handles several parameters special way, in addition to standard SRT
options that can be set through the parameters:

    srt://HOST:PORT?PARAM1=VALUE&PARAM2=VALUE...

SRT can be connected using one of three connection modes:

- **caller**: the "agent" (this application) sends the connection request to the peer, which must be **listener**, and this way it initiates the connection.
- **listener**: the "agent" waits for being contacted by any peer **caller** (note that a listener can accept multiple callers, but *srt-live-transmit* does not use this possibility - after the first connected one, it no longer accepts new connections).
- **rendezvous**: A one-to-one only connection where both parties are equivalent and both connect to one another simultaneously. Whoever happened to start first (or succeeded to punch through the firewall) is meant to have initiated the connection.

This mode can be specified explicitly using the **mode** parameter. When it's not specified, then it is "deduced" the following way:

- `srt://:1234` - the *port* is specified (1234), but *host* is empty. This assumes **listener** mode.
- `srt://remote.host.com:1234` - both *host* ***and*** *port* are specified. This assumes **caller** mode.

The **rendezvous** mode is not deduced and it has to be specified
explicitly. Note also special cases of the **host** and **port** parts
specified in the URI:

- **CALLER**: the *host* and *port* parts are mandatory and specify the remote host and port to be contacted.
    -   The **port** parameter can be used to enforce the local outgoing port (**not to be confused** with remote port!).
    -   The **adapter** parameter is not used.
- **LISTENER**: the *port* part is mandatory and it specifies the local listening port.
    -   The **adapter** parameter can be used to specify the adapter.
    -   The *host* part, if specified, can be also used to set the adapter - although in this case **mode=listener** must be set explicitly.
    -   The **port** parameter is not used.
- **RENDEZVOUS**: the *host* and *port* parts are mandatory.
    -   The *host* part specifies the remote host to contact.
    -   The *port* part specifies **both local and remote port**. Note that the local port is this way both listening port and outgoing port.
    -   The **adapter** parameter can be used to specify the adapter.
    -   The **port** parameter is not used.

Some parameters handled for SRT medium are specific, all others are socket options. The following parameters are handled special way by *srt-live-transmit*:

- **mode**: enforce caller, listener or rendezvous mode<commit_msg>Improve examples (#890)<commit_after>SRT Live Transmit
---------

The *srt-live-transmit* tool is a universal data transport tool, which's
intention is to transport data between SRT and other medium.
At the same time it is just a sample application to show some of 
the powerful features of SRT. We encourage you to use SRT library
itself integrated into your products.

The *srt-live-transmit* can be both used as a universal SRT-to-something-else
flipper, as well as a testing tool for SRT.

The general usage is the following:

    srt-live-transmit <input-uri> <output-uri> [options]

The following medium types are handled by *srt-live-transmit*:

- SRT - use SRT for reading or writing, in listener, caller or rendezvous mode, with possibly additional parameters
- UDP - read or write the given UDP address (also multicast)
- Local file - read or store the stream into the file
- Process's pipeline - use the process's *stdin* and *stdout* standard streams

Any medium can be used with any direction, although some of them may
have special direction-dependent cases.

Mind that the URI has a standard syntax:

    scheme://HOST:PORT/PATH?PARAM1=VALUE&PARAM2=VALUE

If you specify only the path (no **://** specified), then the scheme
defaults to **file**. The path can be also specified as relative this
way. Note also that empty host (`scheme://:PORT`) defaults to 0.0.0.0,
and an empty port (when there's no `:PORT` part) defaults to port number 0.

Special options for particular medium may be specified in **PARAM...**
items. All options are medium-specific, although there may happen some
options common for multiple media types.

Note also that the *host* part is always tried to be resolved as a name,
if its form is not directly the IPv4 address.

Example for smoke testing
-------------------------

First we need to start up the SRT live transmit app, listening for unicast UDP TS input on port 1234 and making SRT available on port 4201. Note, these are randomly chosen ports. We also open the app in verbose mode for debugging

    srt-live-transmit udp://:1234 srt://:4201 -v

Now we need to generate a UDP stream. ffmpeg can be used to generate bars and tone as follows, doing a simple unicast push to our listening srt-live-tansmit app:

    ffmpeg -f lavfi -re -i smptebars=duration=300:size=1280x720:rate=30 -f lavfi -re -i sine=frequency=1000:duration=60:sample_rate=44100 -pix_fmt yuv420p -c:v libx264 -b:v 1000k -g 30 -keyint_min 120 -profile:v baseline -preset veryfast -f mpegts "udp://127.0.0.1:1234?pkt_size=1316"

You should see the stream connect in srt-live-transmit.

Now you can test in VLC (make sure you're using the latest version!) - just go to file -> open network stream and enter

    srt://127.0.0.1:4201

and you should see bars and tone right away.

If you're having trouble, make sure this works, then add complexity one step at a time (multicast, push vs listen, etc)


Medium: FILE (including standard process pipes)
-----------------------------------------------

**NB!** File mode, except `file://con` is supported in *srt-file-transmit* tool!

The general syntax is: `file:///global/path/to/the/file`. No
parameters in the URL are extracted. There's one (non-standard!)
special case, though:

    file://con

That is, **con** is used as a *HOST* part of the URI. If you use this
URI for \<input-uri\>, then the data will be read from the standard
input. If \<output-uri\>, the data will be send to the standard output.
Be careful with options being specified together with having standard
output as output URI - some of them are not allowed as the extra output
controlled by options might interfere with the data output.

Medium: UDP
-----------

UDP can only be used in listening mode for reading, and in calling mode
for writing. Therefore, when UDP is your \<input-uri\>, you usually
specify the local port, e.g.:

    udp://:5555

UDP handles two parameters: **iptos** and **ttl**.
**iptos** will set the value of Type-Of-Service (TOS) field for outgoing packets via IP_TOS socket option.
**ttl** parameter will set time-to-live value for outgoing packets via IP_TTL or IP_MULTICAST_TTL socket options.
See IP protocol documentation for details.

For a single host IP address (unicast):
* **reading**: The *host* part or **adapter** parameter can specify the adapter. The *port* part is mandatory.
* **writing**: Both *host* and *port* are mandatory. The **adapter** parameter is of no use.

If you use multicast IP address:
* For reading, need extra `@` character before the *host* part so that the application subscribes to the multicast group before reading
* The *host* part designates the multicast group (also as a resolvable name)
* The *port* designates the port in the multicast group
* The **adapter** parameter can be used to specify the adapter through which the given multicast group can be reached

Medium: SRT
-----------

Most important about SRT is that it can be either input or output and in
both these cases it can work in listener, caller and rendezvous mode. SRT
also handles several parameters special way, in addition to standard SRT
options that can be set through the parameters:

    srt://HOST:PORT?PARAM1=VALUE&PARAM2=VALUE...

SRT can be connected using one of three connection modes:

- **caller**: the "agent" (this application) sends the connection request to the peer, which must be **listener**, and this way it initiates the connection.
- **listener**: the "agent" waits for being contacted by any peer **caller** (note that a listener can accept multiple callers, but *srt-live-transmit* does not use this possibility - after the first connected one, it no longer accepts new connections).
- **rendezvous**: A one-to-one only connection where both parties are equivalent and both connect to one another simultaneously. Whoever happened to start first (or succeeded to punch through the firewall) is meant to have initiated the connection.

This mode can be specified explicitly using the **mode** parameter. When it's not specified, then it is "deduced" the following way:

- `srt://:1234` - the *port* is specified (1234), but *host* is empty. This assumes **listener** mode.
- `srt://remote.host.com:1234` - both *host* ***and*** *port* are specified. This assumes **caller** mode.

When the `mode` parameter is specified explicitly, then the interpretation of the `host` part is the following:

* For caller, it's always the destination host address. If this is empty, it is resolved to `0.0.0.0`, which usually should mean connecting to the local host
* For listener, it defines the IP address of the local device on which the socket should listen, e.g.:

```
srt://10.10.10.100:5001?mode=listener
```
An alternative method to specify this IP address is the `adapter` parameter:
```
srt://:5001?adapter=10.10.10.100
```

The **rendezvous** mode is not deduced and it has to be specified
explicitly. Note also special cases of the **host** and **port** parts
specified in the URI:

- **CALLER**: the *host* and *port* parts are mandatory and specify the remote host and port to be contacted.
    -   The **port** parameter can be used to enforce the local outgoing port (**not to be confused** with remote port!).
    -   The **adapter** parameter is not used.
- **LISTENER**: the *port* part is mandatory and it specifies the local listening port.
    -   The **adapter** parameter can be used to specify the adapter.
    -   The *host* part, if specified, can be also used to set the adapter - although in this case **mode=listener** must be set explicitly.
    -   The **port** parameter is not used.
- **RENDEZVOUS**: the *host* and *port* parts are mandatory.
    -   The *host* part specifies the remote host to contact.
    -   The *port* part specifies **both local and remote port**. Note that the local port is this way both listening port and outgoing port.
    -   The **adapter** parameter can be used to specify the adapter.
    -   The **port** parameter is not used.

Some parameters handled for SRT medium are specific, all others are socket options. The following parameters are handled special way by *srt-live-transmit*:

- **mode**: enforce caller, listener or rendezvous mode
{'fraction_non_alphanumeric': 0.09541550896691084, 'fraction_numerical': 0.015218489517554938, 'mean_word_length': 3.7802595834591006, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 9, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1601017', 'n_tokens_mistral': 4576, 'n_tokens_neox': 4294, 'n_words': 2326}