Reference¶
Warning
There is no compatibility promise until 1.0.0 is released. Small breaking changes are possible.
See also
Alphabetical index is available here.
roc_context¶
#include <roc/context.h>
-
typedef struct roc_context roc_context¶
Shared context.
Context contains memory pools and network worker threads, shared among objects attached to the context. It is allowed both to create a separate context for every object, or to create a single context shared between multiple objects.
Life cycle
A context is created using roc_context_open() and destroyed using roc_context_close(). Objects can be attached and detached to an opened context at any moment from any thread. However, the user should ensure that the context is not closed until there are no objects attached to the context.
Thread safety
Can be used concurrently
See also
-
int roc_context_open(const roc_context_config *config, roc_context **result)¶
Open a new context.
Allocates and initializes a new context. May start some background threads. Overrides the provided
result
pointer with the newly created context.Parameters
config
should point to an initialized configresult
should point to an unitialized roc_context pointer
Returns
returns zero if the context was successfully created
returns a negative value if the arguments are invalid
returns a negative value if there are not enough resources
Ownership
passes the ownership of
result
to the user; the user is responsible to call roc_context_close() to free it
-
int roc_context_close(roc_context *context)¶
Close the context.
Stops any started background threads, deinitializes and deallocates the context. The user should ensure that nobody uses the context during and after this call.
If this function fails, the context is kept opened.
Parameters
context
should point to an opened context
Returns
returns zero if the context was successfully closed
returns a negative value if the arguments are invalid
returns a negative value if there are objects attached to the context
Ownership
ends the user ownership of
context
; it can’t be used anymore after the function returns
roc_sender¶
#include <roc/sender.h>
-
typedef struct roc_sender roc_sender¶
Sender peer.
Sender gets an audio stream from the user, encodes it into network packets, and transmits them to a remote receiver.
Context
Sender is automatically attached to a context when opened and detached from it when closed. The user should not close the context until the sender is closed.
Sender work consists of two parts: stream encoding and packet transmission. The encoding part is performed in the sender itself, and the transmission part is performed in the context network worker threads.
Life cycle
A sender is created using roc_sender_open().
Optionally, the sender parameters may be fine-tuned using
roc_sender_set_*()
functions.The sender either binds local endpoints using roc_sender_bind(), allowing receivers connecting to them, or itself connects to remote receiver endpoints using roc_sender_connect(). What approach to use is up to the user.
The audio stream is iteratively written to the sender using roc_sender_write(). The sender encodes the stream into packets and send to connected receiver(s).
The sender is destroyed using roc_sender_close().
Slots, interfaces, and endpoints
Sender has one or multiple slots, which may be independently bound or connected. Slots may be used to connect sender to multiple receivers. Slots are numbered from zero and are created automatically. In simple cases just use
ROC_SLOT_DEFAULT
.Each slot has its own set of interfaces, one per each type defined in roc_interface. The interface defines the type of the communication with the remote peer and the set of the protocols supported by it.
Supported actions with the interface:
Call roc_sender_bind() to bind the interface to a local roc_endpoint. In this case the sender accepts connections from receivers and sends media stream to all connected receivers.
Call roc_sender_connect() to connect the interface to a remote roc_endpoint. In this case the sender initiates connection to the receiver and starts sending media stream to it.
Supported interface configurations:
Connect
ROC_INTERFACE_CONSOLIDATED
to a remote endpoint (e.g. be an RTSP client).Bind
ROC_INTERFACE_CONSOLIDATED
to a local endpoint (e.g. be an RTSP server).Connect
ROC_INTERFACE_AUDIO_SOURCE
,ROC_INTERFACE_AUDIO_REPAIR
(optionally, for FEC), andROC_INTERFACE_AUDIO_CONTROL
(optionally, for control messages) to remote endpoints (e.g. be an RTP/FECFRAME/RTCP sender).
FEC scheme
If
ROC_INTERFACE_CONSOLIDATED
is used, it automatically creates all necessary transport interfaces and the user should not bother about them.Otherwise, the user should manually configure
ROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
interfaces:If FEC is disabled (ROC_FEC_ENCODING_DISABLE), only
ROC_INTERFACE_AUDIO_SOURCE
should be configured. It will be used to transmit audio packets.If FEC is enabled, both
ROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
interfaces should be configured. The second interface will be used to transmit redundant repair data.
The protocols for the two interfaces should correspond to each other and to the FEC scheme. For example, if
ROC_FEC_RS8M
is used, the protocols should beROC_PROTO_RTP_RS8M_SOURCE
andROC_PROTO_RS8M_REPAIR
.Sample rate
If the sample rate of the user frames and the sample rate of the network packets are different, the sender employs resampler to convert one rate to another.
Resampling is a quite time-consuming operation. The user can choose between completely disabling resampling (and so use the same rate for frames and packets) or several resampler profiles providing different compromises between CPU consumption and quality.
Clock source
Sender should encode samples at a constant rate that is configured when the sender is created. There are two ways to accomplish this:
If the user enabled internal clock (
ROC_CLOCK_INTERNAL
), the sender employs a CPU timer to block writes until it’s time to encode the next bunch of samples according to the configured sample rate.This mode is useful when the user gets samples from a non-realtime source, e.g. from an audio file.
If the user enabled external clock (
ROC_CLOCK_EXTERNAL
), the samples written to the sender are encoded and sent immediately, and hence the user is responsible to call write operation according to the sample rate.This mode is useful when the user gets samples from a realtime source with its own clock, e.g. from an audio device. Internal clock should not be used in this case because the audio device and the CPU might have slightly different clocks, and the difference will eventually lead to an underrun or an overrun.
Thread safety
Can be used concurrently.
-
int roc_sender_open(roc_context *context, const roc_sender_config *config, roc_sender **result)¶
Open a new sender.
Allocates and initializes a new sender, and attaches it to the context.
Parameters
context
should point to an opened contextconfig
should point to an initialized configresult
should point to an unitialized roc_sender pointer
Returns
returns zero if the sender was successfully created
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
config
; it may be safely deallocated after the function returnspasses the ownership of
result
to the user; the user is responsible to call roc_sender_close() to free it
-
int roc_sender_set_outgoing_address(roc_sender *sender, roc_slot slot, roc_interface iface, const char *ip)¶
Set sender interface outgoing address.
Optional. Should be used only when connecting an interface to a remote endpoint.
If set, explicitly defines the IP address of the OS network interface from which to send the outgoing packets. If not set, the outgoing interface is selected automatically by the OS, depending on the remote endpoint address.
It is allowed to set outgoing address to
0.0.0.0
(for IPv4) or to::
(for IPv6), to achieve the same behavior as if it wasn’t set, i.e. to let the OS to select the outgoing interface automatically.By default, the outgoing address is not set.
Each slot’s interface can have only one outgoing address. The function should be called before calling roc_sender_connect() for this slot and interface. It should not be called when calling roc_sender_bind() for the interface.
Automatically initializes slot with given index if it’s used first time.
Parameters
sender
should point to an opened senderslot
specifies the sender slotiface
specifies the sender interfaceip
should be IPv4 or IPv6 address
Returns
returns zero if the outgoing interface was successfully set
returns a negative value if the arguments are invalid
returns a negative value if an error occurred
Ownership
doesn’t take or share the ownership of
ip
; it may be safely deallocated after the function returns
-
int roc_sender_set_reuseaddr(roc_sender *sender, roc_slot slot, roc_interface iface, int enabled)¶
Set sender interface address reuse option.
Optional.
When set to true, SO_REUSEADDR is enabled for interface socket, regardless of socket type, unless binding to ephemeral port (port explicitly set to zero).
When set to false, SO_REUSEADDR is enabled only for multicast sockets, unless binding to ephemeral port (port explicitly set to zero).
By default set to false.
For TCP-based protocols, SO_REUSEADDR allows immediate reuse of recently closed socket in TIME_WAIT state, which may be useful you want to be able to restart server quickly.
For UDP-based protocols, SO_REUSEADDR allows multiple processes to bind to the same address, which may be useful if you’re using socket activation mechanism.
Automatically initializes slot with given index if it’s used first time.
Parameters
sender
should point to an opened senderslot
specifies the sender slotiface
specifies the sender interfaceenabled
should be 0 or 1
Returns
returns zero if the multicast group was successfully set
returns a negative value if the arguments are invalid
returns a negative value if an error occurred
-
int roc_sender_connect(roc_sender *sender, roc_slot slot, roc_interface iface, const roc_endpoint *endpoint)¶
Connect the sender interface to a remote receiver endpoint.
Checks that the endpoint is valid and supported by the interface, allocates a new outgoing port, and connects it to the remote endpoint.
Each slot’s interface can be bound or connected only once. May be called multiple times for different slots or interfaces.
Automatically initializes slot with given index if it’s used first time.
Parameters
sender
should point to an opened senderslot
specifies the sender slotiface
specifies the sender interfaceendpoint
specifies the receiver endpoint
Returns
returns zero if the sender was successfully connected
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
endpoint
; it may be safely deallocated after the function returns
-
int roc_sender_write(roc_sender *sender, const roc_frame *frame)¶
Encode samples to packets and transmit them to the receiver.
Encodes samples to packets and enqueues them for transmission by the network worker thread of the context.
If
ROC_CLOCK_INTERNAL
is used, the function blocks until it’s time to transmit the samples according to the configured sample rate. The function returns after encoding and enqueuing the packets, without waiting when the packets are actually transmitted.Until the sender is connected to at least one receiver, the stream is just dropped. If the sender is connected to multiple receivers, the stream is duplicated to each of them.
Parameters
sender
should point to an opened, bound, and connected senderframe
should point to a valid frame with an array of samples to send
Returns
returns zero if all samples were successfully encoded and enqueued
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
frame
; it may be safely deallocated after the function returns
-
int roc_sender_close(roc_sender *sender)¶
Close the sender.
Deinitializes and deallocates the sender, and detaches it from the context. The user should ensure that nobody uses the sender during and after this call. If this function fails, the sender is kept opened and attached to the context.
Parameters
sender
should point to an opened sender
Returns
returns zero if the sender was successfully closed
returns a negative value if the arguments are invalid
Ownership
ends the user ownership of
sender
; it can’t be used anymore after the function returns
roc_receiver¶
#include <roc/receiver.h>
-
typedef struct roc_receiver roc_receiver¶
Receiver peer.
Receiver gets the network packets from multiple senders, decodes audio streams from them, mixes multiple streams into a single stream, and returns it to the user.
Context
Receiver is automatically attached to a context when opened and detached from it when closed. The user should not close the context until the receiver is closed.
Receiver work consists of two parts: packet reception and stream decoding. The decoding part is performed in the receiver itself, and the reception part is performed in the context network worker threads.
Life cycle
A receiver is created using roc_receiver_open().
Optionally, the receiver parameters may be fine-tuned using
roc_receiver_set_*()
functions.The receiver either binds local endpoints using roc_receiver_bind(), allowing senders connecting to them, or itself connects to remote sender endpoints using roc_receiver_connect(). What approach to use is up to the user.
The audio stream is iteratively read from the receiver using roc_receiver_read(). Receiver returns the mixed stream from all connected senders.
The receiver is destroyed using roc_receiver_close().
Slots, interfaces, and endpoints
Receiver has one or multiple slots, which may be independently bound or connected. Slots may be used to bind receiver to multiple addresses. Slots are numbered from zero and are created automatically. In simple cases just use
ROC_SLOT_DEFAULT
.Each slot has its own set of interfaces, one per each type defined in roc_interface. The interface defines the type of the communication with the remote peer and the set of the protocols supported by it.
Supported actions with the interface:
Call roc_receiver_bind() to bind the interface to a local roc_endpoint. In this case the receiver accepts connections from senders mixes their streams into the single output stream.
Call roc_receiver_connect() to connect the interface to a remote roc_endpoint. In this case the receiver initiates connection to the sender and requests it to start sending media stream to the receiver.
Supported interface configurations:
Bind
ROC_INTERFACE_CONSOLIDATED
to a local endpoint (e.g. be an RTSP server).Connect
ROC_INTERFACE_CONSOLIDATED
to a remote endpoint (e.g. be an RTSP client).Bind
ROC_INTERFACE_AUDIO_SOURCE
,ROC_INTERFACE_AUDIO_REPAIR
(optionally, for FEC), andROC_INTERFACE_AUDIO_CONTROL
(optionally, for control messages) to local endpoints (e.g. be an RTP/FECFRAME/RTCP receiver).
FEC scheme
If
ROC_INTERFACE_CONSOLIDATED
is used, it automatically creates all necessary transport interfaces and the user should not bother about them.Otherwise, the user should manually configure
ROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
interfaces:If FEC is disabled (ROC_FEC_ENCODING_DISABLE), only
ROC_INTERFACE_AUDIO_SOURCE
should be configured. It will be used to transmit audio packets.If FEC is enabled, both
ROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
interfaces should be configured. The second interface will be used to transmit redundant repair data.
The protocols for the two interfaces should correspond to each other and to the FEC scheme. For example, if
ROC_FEC_RS8M
is used, the protocols should beROC_PROTO_RTP_RS8M_SOURCE
andROC_PROTO_RS8M_REPAIR
.Sessions
Receiver creates a session object for every sender connected to it. Sessions can appear and disappear at any time. Multiple sessions can be active at the same time.
A session is identified by the sender address. A session may contain multiple packet streams sent to different receiver ports. If the sender employs FEC, the session will contain source and repair packet streams. Otherwise, the session will contain a single source packet stream.
A session is created automatically on the reception of the first packet from a new address and destroyed when there are no packets during a timeout. A session is also destroyed on other events like a large latency underrun or overrun or broken playback, but if the sender continues to send packets, it will be created again shortly.
Mixing
Receiver mixes audio streams from all currently active sessions into a single output stream.
The output stream continues no matter how much active sessions there are at the moment. In particular, if there are no sessions, the receiver produces a stream with all zeros.
Sessions can be added and removed from the output stream at any time, probably in the middle of a frame.
Sample rate
Every session may have a different sample rate. And even if nominally all of them are of the same rate, device frequencies usually differ by a few tens of Hertz.
Receiver compensates these differences by adjusting the rate of every session stream to the rate of the receiver output stream using a per-session resampler. The frequencies factor between the sender and the receiver clocks is calculated dynamically for every session based on the session incoming packet queue size.
Resampling is a quite time-consuming operation. The user can choose between completely disabling resampling (at the cost of occasional underruns or overruns) or several resampler profiles providing different compromises between CPU consumption and quality.
Clock source
Receiver should decode samples at a constant rate that is configured when the receiver is created. There are two ways to accomplish this:
If the user enabled internal clock (
ROC_CLOCK_INTERNAL
), the receiver employs a CPU timer to block reads until it’s time to decode the next bunch of samples according to the configured sample rate.This mode is useful when the user passes samples to a non-realtime destination, e.g. to an audio file.
If the user enabled external clock (
ROC_CLOCK_EXTERNAL
), the samples read from the receiver are decoded immediately and hence the user is responsible to call read operation according to the sample rate.This mode is useful when the user passes samples to a realtime destination with its own clock, e.g. to an audio device. Internal clock should not be used in this case because the audio device and the CPU might have slightly different clocks, and the difference will eventually lead to an underrun or an overrun.
Thread safety
Can be used concurrently.
-
int roc_receiver_open(roc_context *context, const roc_receiver_config *config, roc_receiver **result)¶
Open a new receiver.
Allocates and initializes a new receiver, and attaches it to the context.
Parameters
context
should point to an opened contextconfig
should point to an initialized configresult
should point to an unitialized roc_receiver pointer
Returns
returns zero if the receiver was successfully created
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
config
; it may be safely deallocated after the function returnspasses the ownership of
result
to the user; the user is responsible to call roc_receiver_close() to free it
-
int roc_receiver_set_multicast_group(roc_receiver *receiver, roc_slot slot, roc_interface iface, const char *ip)¶
Set receiver interface multicast group.
Optional.
Multicast group should be set only when binding receiver interface to an endpoint with multicast IP address. If present, it defines an IP address of the OS network interface on which to join the multicast group. If not present, no multicast group is joined.
It’s possible to receive multicast traffic from only those OS network interfaces, on which the process has joined the multicast group. When using multicast, the user should either call this function, or join multicast group manually using OS-specific API.
It is allowed to set multicast group to
0.0.0.0
(for IPv4) or to::
(for IPv6), to be able to receive multicast traffic from all available interfaces. However, this may not be desirable for security reasons.Each slot’s interface can have only one multicast group. The function should be called before calling roc_receiver_bind() for the interface. It should not be called when calling roc_receiver_connect() for the interface.
Automatically initializes slot with given index if it’s used first time.
Parameters
receiver
should point to an opened receiverslot
specifies the receiver slotiface
specifies the receiver interfaceip
should be IPv4 or IPv6 address
Returns
returns zero if the multicast group was successfully set
returns a negative value if the arguments are invalid
returns a negative value if an error occurred
Ownership
doesn’t take or share the ownership of
ip
; it may be safely deallocated after the function returns
-
int roc_receiver_set_reuseaddr(roc_receiver *receiver, roc_slot slot, roc_interface iface, int enabled)¶
Set receiver interface address reuse option.
Optional.
When set to true, SO_REUSEADDR is enabled for interface socket, regardless of socket type, unless binding to ephemeral port (port explicitly set to zero).
When set to false, SO_REUSEADDR is enabled only for multicast sockets, unless binding to ephemeral port (port explicitly set to zero).
By default set to false.
For TCP-based protocols, SO_REUSEADDR allows immediate reuse of recently closed socket in TIME_WAIT state, which may be useful you want to be able to restart server quickly.
For UDP-based protocols, SO_REUSEADDR allows multiple processes to bind to the same address, which may be useful if you’re using socket activation mechanism.
Automatically initializes slot with given index if it’s used first time.
Parameters
receiver
should point to an opened receiverslot
specifies the receiver slotiface
specifies the receiver interfaceenabled
should be 0 or 1
Returns
returns zero if the multicast group was successfully set
returns a negative value if the arguments are invalid
returns a negative value if an error occurred
-
int roc_receiver_bind(roc_receiver *receiver, roc_slot slot, roc_interface iface, roc_endpoint *endpoint)¶
Bind the receiver interface to a local endpoint.
Checks that the endpoint is valid and supported by the interface, allocates a new ingoing port, and binds it to the local endpoint.
Each slot’s interface can be bound or connected only once. May be called multiple times for different slots or interfaces.
Automatically initializes slot with given index if it’s used first time.
If
endpoint
has explicitly set zero port, the receiver is bound to a randomly chosen ephemeral port. If the function succeeds, the actual port to which the receiver was bound is written back toendpoint
.Parameters
receiver
should point to an opened receiverslot
specifies the receiver slotiface
specifies the receiver interfaceendpoint
specifies the receiver endpoint
Returns
returns zero if the receiver was successfully bound to a port
returns a negative value if the arguments are invalid
returns a negative value if the address can’t be bound
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
endpoint
; it may be safely deallocated after the function returns
-
int roc_receiver_read(roc_receiver *receiver, roc_frame *frame)¶
Read samples from the receiver.
Reads network packets received on bound ports, routes packets to sessions, repairs lost packets, decodes samples, resamples and mixes them, and finally stores samples into the provided frame.
If
ROC_CLOCK_INTERNAL
is used, the function blocks until it’s time to decode the samples according to the configured sample rate.Until the receiver is connected to at least one sender, it produces silence. If the receiver is connected to multiple senders, it mixes their streams into one.
Parameters
receiver
should point to an opened receiverframe
should point to an initialized frame which will be filled with samples; the number of samples is defined by the frame size
Returns
returns zero if all samples were successfully decoded
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
Ownership
doesn’t take or share the ownership of
frame
; it may be safely deallocated after the function returns
-
int roc_receiver_close(roc_receiver *receiver)¶
Close the receiver.
Deinitializes and deallocates the receiver, and detaches it from the context. The user should ensure that nobody uses the receiver during and after this call. If this function fails, the receiver is kept opened and attached to the context.
Parameters
receiver
should point to an opened receiver
Returns
returns zero if the receiver was successfully closed
returns a negative value if the arguments are invalid
Ownership
ends the user ownership of
receiver
; it can’t be used anymore after the function returns
roc_frame¶
#include <roc/frame.h>
-
struct roc_frame¶
Audio frame.
Represents a multichannel sequence of audio samples. The user is responsible for allocating and deallocating the frame and the data it is pointing to.
Thread safety
Should not be used concurrently.
roc_endpoint¶
#include <roc/endpoint.h>
-
typedef struct roc_endpoint roc_endpoint¶
Network endpoint.
Endpoint is a network entry point of a peer. The definition includes the protocol being used, network host and port, and, for some protocols, a resource. All these parts together are unambiguously represented by a URI. The user may set or get the entire URI or its individual parts.
Endpoint URI
Endpoint URI syntax is a subset of the syntax defined in RFC 3986:
Examples:protocol://host[:port][/path][?query]
rtsp://localhost:123/path?query
rtp+rs8m://localhost:123
rtp://127.0.0.1:123
rtp://[::1]:123
The following protocols (schemes) are supported:
rtp://
(ROC_PROTO_RTP)rtp+rs8m://
(ROC_PROTO_RTP_RS8M_SOURCE)rs8m://
(ROC_PROTO_RS8M_REPAIR)rtp+ldpc://
(ROC_PROTO_RTP_LDPC_SOURCE)ldpc://
(ROC_PROTO_LDPC_REPAIR)
The host field should be either FQDN (domain name), or IPv4 address, or IPv6 address in square brackets.
The port field can be omitted if the protocol defines standard port. Otherwise, the port can not be omitted. For example, RTSP defines standard port, but RTP doesn’t.
The path and query fields are allowed only for protocols that support them. For example, they’re supported by RTSP, but not by RTP.
Field invalidation
If some field is attempted to be set to an invalid value (for example, an invalid port number), this specific field is marked as invalid until it is successfully set to some valid value.
Sender and receiver refuse to bind or connect an endpoint which has invalid fields or doesn’t have some mandatory fields. Hence, it is safe to ignore errors returned by endpoint setters and check only for errors returned by bind and connect operations.
Thread safety
Should not be used concurrently.
-
int roc_endpoint_allocate(roc_endpoint **result)¶
Allocate and initialize endpoint.
All components of the newly created endpoint are empty.
Parameters
result
should point to an unitialized roc_endpoint pointer
Returns
returns zero if endpoint was successfully allocated and initialized
returns a negative value on invalid arguments
returns a negative value on allocation failure
Ownership
passes the ownership of
result
to the user; the user is responsible to call roc_endpoint_deallocate() to free it
-
int roc_endpoint_set_uri(roc_endpoint *endpoint, const char *uri)¶
Set endpoint URI.
Parses and sets endpoint URI. Overrides or clears each URI component.
On failure, invalidates endpoint URI. The endpoint becomes invalid until its URI or every individual component is successfully set.
Parameters
endpoint
should point to initialized endpointuri
should be a valid endpoint URI
Returns
returns zero if URI was successfully parsed and set
returns a negative value on invalid arguments
returns a negative value on allocation failure
Ownership
doesn’t take or share the ownership of
uri
; it may be safely deallocated after the function returns
-
int roc_endpoint_set_protocol(roc_endpoint *endpoint, roc_protocol proto)¶
Set endpoint protocol (scheme).
On failure, invalidates endpoint protocol. The endpoint becomes invalid until its protocol is successfully set.
Parameters
endpoint
should point to initialized endpointproto
defines new protocol
Returns
returns zero if protocol was successfully set
returns a negative value on invalid arguments
returns a negative value if protocol is incompatible with other URI parameters
-
int roc_endpoint_set_host(roc_endpoint *endpoint, const char *host)¶
Set endpoint host.
On failure, invalidates endpoint host. The endpoint becomes invalid until its host is successfully set.
Parameters
endpoint
should point to initialized endpointhost
specifies FQDN, IPv4 address, or IPv6 address
Returns
returns zero if host was successfully set
returns a negative value on invalid arguments
returns a negative value on allocation failure
Ownership
doesn’t take or share the ownership of
host
; it may be safely deallocated after the function returns
-
int roc_endpoint_set_port(roc_endpoint *endpoint, int port)¶
Set endpoint port.
When binding an endpoint, the port may be set to zero to select a random port. The selected port will be then written back to the endpoint. When connecting an endpoint, the port should be positive.
If port is not set, the standard port for endpoint protocol is used. This is allowed only if the protocol defines its standard port.
If port is already set, it can be unset by setting to special value “-1”.
On failure, invalidates endpoint port. The endpoint becomes invalid until its port is successfully set.
Parameters
endpoint
should point to initialized endpointport
specifies UDP or TCP port in range [0; 65535]
Returns
returns zero if port was successfully set
returns a negative value on invalid arguments
-
int roc_endpoint_set_resource(roc_endpoint *endpoint, const char *encoded_resource)¶
Set endpoint resource (path and query).
Path and query are both optional. Any of them may be omitted. If path is present, it should be absolute.
The given resource should be percent-encoded by user if it contains special characters. It may be inserted into the URI as is.
If resource is already set, it can be unset by setting to NULL or “”.
On failure, invalidates endpoint resource. The endpoint becomes invalid until its resource is successfully set.
Parameters
endpoint
should point to initialized endpointencoded_resource
specifies percent-encoded path and query
Returns
returns zero if resource was successfully set
returns a negative value on invalid arguments
returns a negative value on allocation failure
Ownership
doesn’t take or share the ownership of
encoded_resource
; it may be safely deallocated after the function returns
-
int roc_endpoint_get_uri(const roc_endpoint *endpoint, char *buf, size_t *bufsz)¶
Get endpoint URI.
Formats endpoint URI to user-provided buffer.
If the function succeeds, the output string is zero-terminated. No matter whether the function succeeds or fails,
bufsz
is updated with the actual output string length, including terminating zero byte.buf
may be NULL; in this case nothing is written, butbufsz
is still updated. This can be used to determine the proper buffer size in before.Parameters
endpoint
should point to initialized endpointbuf
should point to a buffer ofbufsz
bytesbufsz
defines the buffer size
Returns
returns zero if URI was successfully formatted
returns a negative value on invalid arguments
returns a negative value if endpoint URI is not set
returns a negative value if buffer is too small
-
int roc_endpoint_get_protocol(const roc_endpoint *endpoint, roc_protocol *proto)¶
Get endpoint protocol (scheme).
Parameters
endpoint
should point to initialized endpointproto
should point to a variable where to write the protocol
Returns
returns zero if protocol was successfully written
returns a negative value if endpoint protocol is not set
returns a negative value on invalid arguments
-
int roc_endpoint_get_host(const roc_endpoint *endpoint, char *buf, size_t *bufsz)¶
Get endpoint host.
Formats endpoint URI host to user-provided buffer.
If the function succeeds, the output string is zero-terminated. No matter whether the function succeeds or fails,
bufsz
is updated with the actual output string length, including terminating zero byte.buf
may be NULL; in this case nothing is written, butbufsz
is still updated. This can be used to determine the proper buffer size in before.Parameters
endpoint
should point to initialized endpointbuf
should point to a buffer ofbufsz
bytesbufsz
defines the buffer size
Returns
returns zero if host was successfully formatted
returns a negative value if endpoint host is not set
returns a negative value on invalid arguments
returns a negative value if buffer is too small
-
int roc_endpoint_get_port(const roc_endpoint *endpoint, int *port)¶
Get endpoint port.
Parameters
endpoint
should point to initialized endpointport
should point to a variable where to write the port
Returns
returns zero if port was successfully written
returns a negative value if endpoint port is not set
returns a negative value on invalid arguments
-
int roc_endpoint_get_resource(const roc_endpoint *endpoint, char *buf, size_t *bufsz)¶
Get endpoint resource (path and query).
Formats endpoint URI resource to user-provided buffer. The written resource is percent-encoded.
If the function succeeds, the output string is zero-terminated. No matter whether the function succeeds or fails,
bufsz
is updated with the actual output string length, including terminating zero byte.buf
may be NULL; in this case nothing is written, butbufsz
is still updated. This can be used to determine the proper buffer size in before.Parameters
endpoint
should point to initialized endpointbuf
should point to a buffer ofbufsz
bytesbufsz
defines the buffer size
Returns
returns zero if resource was successfully formatted
returns a negative value if neither of endpoint path and query is set
returns a negative value on invalid arguments
returns a negative value if buffer is too small
-
int roc_endpoint_deallocate(roc_endpoint *endpoint)¶
Deinitialize and deallocate endpoint.
Parameters
endpoint
should point to initialized endpoint
Returns
returns zero if endpoint was successfully deallocated
returns a negative value on invalid arguments
Ownership
ends the user ownership of
endpoint
; it can’t be used anymore after the function returns
roc_config¶
#include <roc/config.h>
-
typedef unsigned int roc_slot¶
Network slot.
A peer (sender or receiver) may have multiple slots, which may be independently bound or connected. You can use multiple slots on sender to connect it to multiple receiver addresses, and you can use multiple slots on receiver to bind it to multiple receiver address.
Slots are numbered from zero and are created implicitly. Just specify slot index when binding or connecting endpoint, and slot will be automatically created if it was not created yet.
In simple cases, just use
ROC_SLOT_DEFAULT
.Inside each slot, there can be up to one endpoint for each interface type. See roc_interface for details.
-
enum roc_interface¶
Network interface.
Interface is a way to access the peer (sender or receiver) via network.
Each peer slot has multiple interfaces, one of each type. The user interconnects peers by binding one of the first peer’s interfaces to an URI and then connecting the corresponding second peer’s interface to that URI.
A URI is represented by roc_endpoint object.
The interface defines the type of the communication with the remote peer and the set of protocols (URI schemes) that can be used with this particular interface.
ROC_INTERFACE_CONSOLIDATED
is an interface for high-level protocols which automatically manage all necessary communication: transport streams, control messages, parameter negotiation, etc. When a consolidated connection is established, peers may automatically setup lower-level interfaces likeROC_INTERFACE_AUDIO_SOURCE
,ROC_INTERFACE_AUDIO_REPAIR
, andROC_INTERFACE_AUDIO_CONTROL
.ROC_INTERFACE_CONSOLIDATED
is mutually exclusive with lower-level interfaces. In most cases, the user needs onlyROC_INTERFACE_CONSOLIDATED
. However, the lower-level interfaces may be useful if an external signaling mechanism is used or for compatibility with third-party software.ROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
are lower-level unidirectional transport-only interfaces. The first is used to transmit audio stream, and the second is used to transmit redundant repair stream, if FEC is enabled.ROC_INTERFACE_AUDIO_CONTROL
is a lower-level interface for control streams. If you useROC_INTERFACE_AUDIO_SOURCE
andROC_INTERFACE_AUDIO_REPAIR
, you usually also need to useROC_INTERFACE_AUDIO_CONTROL
to enable carrying additional non-transport information.Values:
-
enumerator ROC_INTERFACE_CONSOLIDATED¶
Interface that consolidates all types of streams (source, repair, control).
Allowed operations:
bind (sender, receiver)
connect (sender, receiver)
Allowed protocols:
-
enumerator ROC_INTERFACE_AUDIO_SOURCE¶
Interface for audio stream source data.
Allowed operations:
bind (receiver)
connect (sender)
Allowed protocols:
-
enumerator ROC_INTERFACE_AUDIO_REPAIR¶
Interface for audio stream repair data.
Allowed operations:
bind (receiver)
connect (sender)
Allowed protocols:
-
enumerator ROC_INTERFACE_AUDIO_CONTROL¶
Interface for audio control messages.
Allowed operations:
bind (sender, receiver)
connect (sender, receiver)
Allowed protocols:
-
enumerator ROC_INTERFACE_CONSOLIDATED¶
-
enum roc_protocol¶
Network protocol.
Defines URI scheme of roc_endpoint.
Values:
-
enumerator ROC_PROTO_RTSP¶
RTSP 1.0 (RFC 2326) or RTSP 2.0 (RFC 7826).
Interfaces:
Transports:
for signaling: TCP
for media: RTP and RTCP over UDP or TCP
-
enumerator ROC_PROTO_RTP¶
RTP over UDP (RFC 3550).
Interfaces:
Transports:
UDP
Audio encodings:
FEC encodings:
none
-
enumerator ROC_PROTO_RTP_RS8M_SOURCE¶
RTP source packet (RFC 3550) + FECFRAME Reed-Solomon footer (RFC 6865) with m=8.
Interfaces:
Transports:
UDP
Audio encodings:
similar to ROC_PROTO_RTP
FEC encodings:
-
enumerator ROC_PROTO_RS8M_REPAIR¶
FEC repair packet + FECFRAME Reed-Solomon header (RFC 6865) with m=8.
Interfaces:
Transports:
UDP
FEC encodings:
-
enumerator ROC_PROTO_RTP_LDPC_SOURCE¶
RTP source packet (RFC 3550) + FECFRAME LDPC-Staircase footer (RFC 6816).
Interfaces:
Transports:
UDP
Audio encodings:
similar to ROC_PROTO_RTP
FEC encodings:
-
enumerator ROC_PROTO_LDPC_REPAIR¶
FEC repair packet + FECFRAME LDPC-Staircase header (RFC 6816).
Interfaces:
Transports:
UDP
FEC encodings:
-
enumerator ROC_PROTO_RTCP¶
RTCP over UDP (RFC 3550).
Interfaces:
Transports:
UDP
-
enumerator ROC_PROTO_RTSP¶
-
enum roc_packet_encoding¶
Packet encoding.
Values:
-
enumerator ROC_PACKET_ENCODING_AVP_L16¶
PCM signed 16-bit.
“L16” encoding from RTP A/V Profile (RFC 3551). Uncompressed samples coded as interleaved 16-bit signed big-endian integers in two’s complement notation.
-
enumerator ROC_PACKET_ENCODING_AVP_L16¶
-
enum roc_fec_encoding¶
Forward Error Correction encoding.
Values:
-
enumerator ROC_FEC_ENCODING_DISABLE¶
No FEC encoding.
Compatible with ROC_PROTO_RTP protocol.
-
enumerator ROC_FEC_ENCODING_DEFAULT¶
Default FEC encoding.
Current default is ROC_FEC_ENCODING_RS8M.
-
enumerator ROC_FEC_ENCODING_RS8M¶
Reed-Solomon FEC encoding (RFC 6865) with m=8.
Good for small block sizes (below 256 packets). Compatible with ROC_PROTO_RTP_RS8M_SOURCE and ROC_PROTO_RS8M_REPAIR protocols for source and repair endpoints.
-
enumerator ROC_FEC_ENCODING_LDPC_STAIRCASE¶
LDPC-Staircase FEC encoding (RFC 6816).
Good for large block sizes (above 1024 packets). Compatible with ROC_PROTO_RTP_LDPC_SOURCE and ROC_PROTO_LDPC_REPAIR protocols for source and repair endpoints.
-
enumerator ROC_FEC_ENCODING_DISABLE¶
-
enum roc_channel_set¶
Channel set.
Values:
-
enumerator ROC_CHANNEL_SET_STEREO¶
Stereo.
Two channels: left and right.
-
enumerator ROC_CHANNEL_SET_STEREO¶
-
enum roc_frame_encoding¶
Frame encoding.
Values:
-
enumerator ROC_FRAME_ENCODING_PCM_FLOAT¶
PCM floats.
Uncompressed samples coded as floats in range [-1; 1]. Channels are interleaved, e.g. two channels are encoded as “L R L R …”.
-
enumerator ROC_FRAME_ENCODING_PCM_FLOAT¶
-
enum roc_clock_source¶
Clock source for sender or receiver.
Values:
-
enumerator ROC_CLOCK_EXTERNAL¶
Sender or receiver is clocked by external user-defined clock.
Write and read operations are non-blocking. The user is responsible to call them in time, according to the external clock.
-
enumerator ROC_CLOCK_INTERNAL¶
Sender or receiver is clocked by an internal clock.
Write and read operations are blocking. They automatically wait until it’s time to process the next bunch of samples according to the configured sample rate.
-
enumerator ROC_CLOCK_EXTERNAL¶
-
enum roc_resampler_backend¶
Resampler backend.
Affects speed and quality. Some backends may be disabled at build time.
Values:
-
enumerator ROC_RESAMPLER_BACKEND_DEFAULT¶
Default backend.
Depends on what was enabled at build time.
-
enumerator ROC_RESAMPLER_BACKEND_BUILTIN¶
Slow built-in resampler.
Always available.
-
enumerator ROC_RESAMPLER_BACKEND_SPEEX¶
Fast good-quality resampler from SpeexDSP.
May be disabled at build time.
-
enumerator ROC_RESAMPLER_BACKEND_DEFAULT¶
-
enum roc_resampler_profile¶
Resampler profile.
Affects speed and quality. Each resampler backend treats profile in its own way.
Values:
-
enumerator ROC_RESAMPLER_PROFILE_DISABLE¶
Do not perform resampling.
Clock drift compensation will be disabled in this case. If in doubt, do not disable resampling.
-
enumerator ROC_RESAMPLER_PROFILE_DEFAULT¶
Default profile.
Current default is
ROC_RESAMPLER_PROFILE_MEDIUM
.
-
enumerator ROC_RESAMPLER_PROFILE_HIGH¶
High quality, low speed.
-
enumerator ROC_RESAMPLER_PROFILE_MEDIUM¶
Medium quality, medium speed.
-
enumerator ROC_RESAMPLER_PROFILE_LOW¶
Low quality, high speed.
-
enumerator ROC_RESAMPLER_PROFILE_DISABLE¶
-
struct roc_context_config¶
Context configuration.
It is safe to memset() this struct with zeros to get a default config. It is also safe to memcpy() this struct to get a copy of config.
See also
Public Members
-
unsigned int max_packet_size¶
Maximum size in bytes of a network packet.
Defines the amount of bytes allocated per network packet. Sender and receiver won’t handle packets larger than this. If zero, default value is used.
-
unsigned int max_frame_size¶
Maximum size in bytes of an audio frame.
Defines the amount of bytes allocated per intermediate internal frame in the pipeline. Does not limit the size of the frames provided by user. If zero, default value is used.
-
unsigned int max_packet_size¶
-
struct roc_sender_config¶
Sender configuration.
It is safe to memset() this struct with zeros to get a default config. It is also safe to memcpy() this struct to get a copy of config.
See also
Public Members
-
unsigned int frame_sample_rate¶
The rate of the samples in the frames passed to sender.
Number of samples per channel per second. If
frame_sample_rate
andpacket_sample_rate
are different, resampler should be enabled. Should be set.
-
roc_channel_set frame_channels¶
The channel set in the frames passed to sender.
Should be set.
-
roc_frame_encoding frame_encoding¶
The sample encoding in the frames passed to sender.
Should be set.
-
unsigned int packet_sample_rate¶
The rate of the samples in the packets generated by sender.
Number of samples per channel per second. If zero, default value is used.
-
roc_channel_set packet_channels¶
The channel set in the packets generated by sender.
If zero, default value is used.
-
roc_packet_encoding packet_encoding¶
The sample encoding in the packets generated by sender.
If zero, default value is used.
-
unsigned long long packet_length¶
The length of the packets produced by sender, in nanoseconds.
Number of nanoseconds encoded per packet. The samples written to the sender are buffered until the full packet is accumulated or the sender is flushed or closed. Larger number reduces packet overhead but also increases latency. If zero, default value is used.
-
unsigned int packet_interleaving¶
Enable packet interleaving.
If non-zero, the sender shuffles packets before sending them. This may increase robustness but also increases latency.
-
roc_clock_source clock_source¶
Clock source to use.
Defines whether write operation will be blocking or non-blocking. If zero, default value is used.
-
roc_resampler_backend resampler_backend¶
Resampler backend to use.
-
roc_resampler_profile resampler_profile¶
Resampler profile to use.
If non-zero, the sender employs resampler if the frame sample rate differs from the packet sample rate.
-
roc_fec_encoding fec_encoding¶
FEC encoding to use.
If non-zero, the sender employs a FEC encoding to generate redundant packets which may be used on receiver to restore lost packets. This requires both sender and receiver to use two separate source and repair endpoints.
-
unsigned int fec_block_source_packets¶
Number of source packets per FEC block.
Used if some FEC encoding is selected. Larger number increases robustness but also increases latency. If zero, default value is used.
-
unsigned int fec_block_repair_packets¶
Number of repair packets per FEC block.
Used if some FEC encoding is selected. Larger number increases robustness but also increases traffic. If zero, default value is used.
-
unsigned int frame_sample_rate¶
-
struct roc_receiver_config¶
Receiver configuration.
It is safe to memset() this struct with zeros to get a default config. It is also safe to memcpy() this struct to get a copy of config.
See also
Public Members
-
unsigned int frame_sample_rate¶
The rate of the samples in the frames returned to the user.
Number of samples per channel per second. Should be set.
-
roc_channel_set frame_channels¶
The channel set in the frames returned to the user.
Should be set.
-
roc_frame_encoding frame_encoding¶
The sample encoding in the frames returned to the user.
Should be set.
-
roc_clock_source clock_source¶
Clock source to use.
Defines whether read operation will be blocking or non-blocking. If zero, default value is used.
-
roc_resampler_backend resampler_backend¶
Resampler backend to use.
-
roc_resampler_profile resampler_profile¶
Resampler profile to use.
If non-zero, the receiver employs resampler for two purposes:
adjust the sender clock to the receiver clock, which may differ a bit
convert the packet sample rate to the frame sample rate if they are different
-
unsigned long long target_latency¶
Target latency, in nanoseconds.
The session will not start playing until it accumulates the requested latency. Then, if resampler is enabled, the session will adjust its clock to keep actual latency as close as possible to the target latency. If zero, default value is used.
-
unsigned long long max_latency_overrun¶
Maximum delta between current and target latency, in nanoseconds.
If current latency becomes larger than the target latency plus this value, the session is terminated. If zero, default value is used.
-
unsigned long long max_latency_underrun¶
Maximum delta between target and current latency, in nanoseconds.
If current latency becomes smaller than the target latency minus this value, the session is terminated. May be larger than the target latency because current latency may be negative, which means that the playback run ahead of the last packet received from network. If zero, default value is used.
-
long long no_playback_timeout¶
Timeout for the lack of playback, in nanoseconds.
If there is no playback during this period, the session is terminated. This mechanism allows to detect dead, hanging, or broken clients generating invalid packets. If zero, default value is used. If negative, the timeout is disabled.
-
long long broken_playback_timeout¶
Timeout for broken playback, in nanoseconds.
If there the playback is considered broken during this period, the session is terminated. The playback is broken if there is a breakage detected at every
breakage_detection_window
duringbroken_playback_timeout
. This mechanism allows to detect vicious circles like when all client packets are a bit late and receiver constantly drops them producing unpleasant noise. If zero, default value is used. If negative, the timeout is disabled.
-
unsigned long long breakage_detection_window¶
Breakage detection window, in nanoseconds.
If zero, default value is used.
See also
-
unsigned int frame_sample_rate¶
roc_log¶
#include <roc/log.h>
-
enum roc_log_level¶
Log level.
See also
Values:
-
enumerator ROC_LOG_NONE¶
No messages.
Setting this level disables logging completely.
-
enumerator ROC_LOG_ERROR¶
Error messages.
Setting this level enables logging only when something goes wrong, e.g. a user operation can’t be completed, or there is not enough memory for a new session.
-
enumerator ROC_LOG_INFO¶
Informational messages.
Setting this level enables logging of important high-level events, like binding a new port or creating a new session.
-
enumerator ROC_LOG_DEBUG¶
Debug messages.
Setting this level enables logging of debug messages. Doesn’t affect performance.
-
enumerator ROC_LOG_TRACE¶
Debug messages (extra verbosity).
Setting this level enables verbose tracing. May cause significant slow down.
-
enumerator ROC_LOG_NONE¶
-
struct roc_log_message¶
Log message.
See also
Public Members
-
roc_log_level level¶
Message log level.
-
const char *module¶
Name of the module that originated the message.
Pointer can be used only until roc_log_handler() returns.
-
const char *file¶
Name of the source code file.
May be NULL. Pointer can be used only until roc_log_handler() returns.
-
int line¶
Line number in the source code file.
-
unsigned long long time¶
Message timestamp, nanoseconds since Unix epoch.
-
unsigned long long pid¶
Platform-specific process ID.
-
unsigned long long tid¶
Platform-specific thread ID.
-
const char *text¶
Message text.
Pointer can be used only until roc_log_handler() returns.
-
roc_log_level level¶
-
typedef void (*roc_log_handler)(const roc_log_message *message, void *argument)¶
Log handler.
Parameters
message
define message to be loggedargument
is the argument passed to roc_log_set_handler
See also
-
void roc_log_set_level(roc_log_level level)¶
Set maximum log level.
Messages with log levels higher than
level
will be dropped. By default the log level is set to ROC_LOG_ERROR.Thread safety
Can be used concurrently.
-
void roc_log_set_handler(roc_log_handler handler, void *argument)¶
Set log handler.
If
handler
is not NULL, messages are passed to the handler. Otherwise, messages are printed to stderr. By default the log handler is set to NULL.argument
will be passed to the handler each time it is invoked.It’s guaranteed that the previously set handler, if any, will not be used after this function returns.
Thread safety
Can be used concurrently. Handler calls are serialized, so the handler itself doesn’t need to be thread-safe.
roc_version¶
#include <roc/version.h>
-
ROC_VERSION_MAJOR¶
Major version component.
-
ROC_VERSION_MINOR¶
Minor version component.
-
ROC_VERSION_PATCH¶
Patch version component.
-
struct roc_version¶
Version components.
-
void roc_version_get(roc_version *version)¶
Retrieve version numbers.
This function can be used to retrieve actual run-time version of the library. It may be different from the compile-time version when using shared library.