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_register_encoding(roc_context *context, int encoding_id, const roc_media_encoding *encoding)¶
Register custom encoding.
Registers
encoding
with givenencoding_id
. Registered encodings complement built-in encodings defined by roc_packet_encoding enum. Whenever you need to specify packet encoding, you can use both built-in and registered encodings.On sender, you should register custom encoding and set to
packet_encoding
field ofroc_sender_config
, if you need to force specific encoding of packets, but built-in set of encodings is not enough.On receiver, you should register custom encoding with same id and specification, if you did so on sender, and you’re not using any signaling protocol (like RTSP) that is capable of automatic exchange of encoding information.
In case of RTP, encoding id is mapped directly to payload type field (PT).
Parameters
context
should point to an opened contextencoding_id
should be encoding identifier in range [1; 127]encoding
should point to valid encoding specification
Returns
returns zero if encoding was successfully registered
returns a negative value if the arguments are invalid
returns a negative value if encoding with given identifier already exists
Ownership
doesn’t take or share the ownership of
encoding
; copies its contents to internal encodings table
-
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_configure().
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), and ROC_INTERFACE_AUDIO_CONTROL (optionally, for control messages) to remote endpoints (e.g. be an RTP/FECFRAME/RTCP sender).
Slots can be removed using roc_sender_unlink(). Removing a slot also removes all its interfaces and terminates all associated connections.
Slots can be added and removed at any time on fly and from any thread. It is safe to do it from another thread concurrently with writing frames. Operations with slots won’t block concurrent writes.
FEC schemes
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 and ROC_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 and ROC_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_ENCODING_RS8M is used, the protocols should be ROC_PROTO_RTP_RS8M_SOURCE and ROC_PROTO_RS8M_REPAIR.
Transcoding
If encoding of sender frames and network packets are different, sender automatically performs all necessary transcoding.
Latency tuning and bounding
Usually latency tuning and bounding is done on receiver side, but it’s possible to disable it on receiver and enable on sender. It is useful if receiver is does not support it or does not have enough CPU to do it with good quality. This feature requires use of ROC_PROTO_RTCP to deliver necessary latency metrics from receiver to sender.
If latency tuning is enabled (which is by default disabled on sender), sender monitors latency and adjusts connection clock to keep latency close to the target value. The user can configure how the latency is measured, how smooth is the tuning, and the target value.
If latency bounding is enabled (which is also by default disabled on sender), sender also ensures that latency lies within allowed boundaries, and restarts connection otherwise. The user can configure those boundaries.
To adjust connection clock, sender uses resampling with a scaling factor slightly above or below 1.0. Since resampling may be a quite time-consuming operation, the user can choose between several resampler backends and profiles providing different compromises between CPU consumption, quality, and precision.
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_SOURCE_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_SOURCE_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 itattaches created sender to
context
; the user should not close context before closing sender
-
int roc_sender_configure(roc_sender *sender, roc_slot slot, roc_interface iface, const roc_interface_config *config)¶
Set sender interface configuration.
Updates configuration of specified interface of specified slot. If called, the call should be done before calling roc_sender_bind() or roc_sender_connect() for the same interface.
Automatically initializes slot with given index if it’s used first time.
If an error happens during configure, the whole slot is disabled and marked broken. The slot index remains reserved. The user is responsible for removing the slot using roc_sender_unlink(), after which slot index can be reused.
Parameters
sender
should point to an opened senderslot
specifies the sender slot index (if in doubt, useROC_SLOT_DEFAULT
)iface
specifies the sender interfaceconfig
should be point to an initialized config
Returns
returns zero if config was successfully updated
returns a negative value if the arguments are invalid
returns a negative value if slot is already bound or connected
Ownership
doesn’t take or share the ownership of
config
; it may be safely deallocated after the function returns
-
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.
If an error happens during connect, the whole slot is disabled and marked broken. The slot index remains reserved. The user is responsible for removing the slot using roc_sender_unlink(), after which slot index can be reused.
Parameters
sender
should point to an opened senderslot
specifies the sender slot (if in doubt, useROC_SLOT_DEFAULT
)iface
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_query(roc_sender *sender, roc_slot slot, roc_sender_metrics *slot_metrics, roc_connection_metrics *conn_metrics, size_t *conn_metrics_count)¶
Query sender slot metrics.
Reads metrics into provided structs.
To retrieve metrics of the slot as a whole, set
slot_metrics
to point to a single roc_sender_metrics struct.To retrieve metrics of specific connections of the slot, set
conn_metrics
to point to an array of roc_connection_metrics structs, andconn_metrics_count
to the number of elements in the array. The function will write metrcis to the array (no more than array size) and updateconn_metrics_count
with the number of elements written.Actual number of connections (regardless of the array size) is also written to
connection_count
field of roc_sender_metrics.Parameters
sender
should point to an opened senderslot
specifies the sender slot (if in doubt, useROC_SLOT_DEFAULT
)slot_metrics
defines a struct where to write slot metrics (may be NULL)conn_metrics
defines an array of structs where to write connection metrics (may be NULL)conn_metrics_count
defines number of elements in array (may be NULL ifconn_metrics
is NULL)
Returns
returns zero if the metrics were successfully retrieved
returns a negative value if the arguments are invalid
returns a negative value if the slot does not exist
Ownership
doesn’t take or share the ownership of the provided buffers; they may be safely deallocated after the function returns
-
int roc_sender_unlink(roc_sender *sender, roc_slot slot)¶
Delete sender slot.
Disconnects, unbinds, and removes all slot interfaces and removes the slot. All associated connections to remote peers are properly terminated.
After unlinking the slot, it can be re-created again by re-using slot index.
Parameters
sender
should point to an opened senderslot
specifies the sender slot
Returns
returns zero if the slot was successfully removed
returns a negative value if the arguments are invalid
returns a negative value if the slot does not exist
-
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_SOURCE_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 senderframe
should point to an initialized frame; it should contain pointer to a buffer and it’s size; the buffer is fully copied into the sender
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_configure().
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), and ROC_INTERFACE_AUDIO_CONTROL (optionally, for control messages) to local endpoints (e.g. be an RTP/FECFRAME/RTCP receiver).
Slots can be removed using roc_receiver_unlink(). Removing a slot also removes all its interfaces and terminates all associated connections.
Slots can be added and removed at any time on fly and from any thread. It is safe to do it from another thread concurrently with reading frames. Operations with slots won’t block concurrent reads.
FEC schemes
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 and ROC_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 and ROC_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_ENCODING_RS8M is used, the protocols should be ROC_PROTO_RTP_RS8M_SOURCE and ROC_PROTO_RS8M_REPAIR.
Connections
Receiver creates a connection object for every sender connected to it. Connections can appear and disappear at any time. Multiple connections can be active at the same time.
A connection may contain multiple streams sent to different receiver ports. If the sender employs FEC, connection usually has source, repair, and control streams. Otherwise, connection usually has source and control streams.
Connection is created automatically on the reception of the first packet from a new sender, and terminated when there are no packets during a timeout. Connection can also be terminated on other events like a large latency underrun or overrun or continous stuttering, but if the sender continues to send packets, connection will be created again shortly.
Mixing
Receiver mixes audio streams from all currently active connections into a single output stream.
The output stream continues no matter how much active connections there are at the moment. In particular, if there are no connections, the receiver produces a stream with all zeros.
Connections can be added and removed from the output stream at any time, probably in the middle of a frame.
Transcoding
Every connection may have a different sample rate, channel layout, and encoding.
Before mixing, receiver automatically transcodes all incoming streams to the format of receiver frames.
Latency tuning and bounding
If latency tuning is enabled (which is by default enabled on receiver), receiver monitors latency of each connection and adjusts per-connection clock to keep latency close to the target value. The user can configure how the latency is measured, how smooth is the tuning, and the target value.
If latency bounding is enabled (which is also by default enabled on receiver), receiver also ensures that latency lies within allowed boundaries, and terminates connection otherwise. The user can configure those boundaries.
To adjust connection clock, receiver uses resampling with a scaling factor slightly above or below 1.0. Since resampling may be a quite time-consuming operation, the user can choose between several resampler backends and profiles providing different compromises between CPU consumption, quality, and precision.
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_SOURCE_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_SOURCE_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 itattaches created receiver to
context
; the user should not close context before closing receiver
-
int roc_receiver_configure(roc_receiver *receiver, roc_slot slot, roc_interface iface, const roc_interface_config *config)¶
Set receiver interface configuration.
Updates configuration of specified interface of specified slot. If called, the call should be done before calling roc_receiver_bind() or roc_receiver_connect() for the same interface.
Automatically initializes slot with given index if it’s used first time.
If an error happens during configure, the whole slot is disabled and marked broken. The slot index remains reserved. The user is responsible for removing the slot using roc_receiver_unlink(), after which slot index can be reused.
Parameters
receiver
should point to an opened receiverslot
specifies the receiver slot (if in doubt, useROC_SLOT_DEFAULT
)iface
specifies the receiver interfaceconfig
should be point to an initialized config
Returns
returns zero if config was successfully updated
returns a negative value if the arguments are invalid
returns a negative value if slot is already bound or connected
Ownership
doesn’t take or share the ownership of
config
; it may be safely deallocated after the function returns
-
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 an error happens during bind, the whole slot is disabled and marked broken. The slot index remains reserved. The user is responsible for removing the slot using roc_receiver_unlink(), after which slot index can be reused.
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 slot (if in doubt, useROC_SLOT_DEFAULT
)iface
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_query(roc_receiver *receiver, roc_slot slot, roc_receiver_metrics *slot_metrics, roc_connection_metrics *conn_metrics, size_t *conn_metrics_count)¶
Query receiver slot metrics.
Reads metrics into provided structs.
To retrieve metrics of the slot as a whole, set
slot_metrics
to point to a single roc_receiver_metrics struct.To retrieve metrics of specific connections of the slot, set
conn_metrics
to point to an array of roc_connection_metrics structs, andconn_metrics_count
to the number of elements in the array. The function will write metrcis to the array (no more than array size) and updateconn_metrics_count
with the number of elements written.Actual number of connections (regardless of the array size) is also written to
connection_count
field of roc_receiver_metrics.Parameters
receiver
should point to an opened receiverslot
specifies the receiver slot (if in doubt, useROC_SLOT_DEFAULT
)slot_metrics
defines a struct where to write slot metrics (may be NULL)conn_metrics
defines an array of structs where to write connection metrics (may be NULL)conn_metrics_count
defines number of elements in array (may be NULL ifconn_metrics
is NULL)
Returns
returns zero if the metrics were successfully retrieved
returns a negative value if the arguments are invalid
returns a negative value if the slot does not exist
Ownership
doesn’t take or share the ownership of the provided buffers; they may be safely deallocated after the function returns
-
int roc_receiver_unlink(roc_receiver *receiver, roc_slot slot)¶
Delete receiver slot.
Disconnects, unbinds, and removes all slot interfaces and removes the slot. All associated connections to remote peers are properly terminated.
After unlinking the slot, it can be re-created again by re-using slot index.
Parameters
receiver
should point to an opened receiverslot
specifies the receiver slot
Returns
returns zero if the slot was successfully removed
returns a negative value if the arguments are invalid
returns a negative value if the slot does not exist
-
int roc_receiver_read(roc_receiver *receiver, roc_frame *frame)¶
Read samples from the receiver.
Reads retrieved network packets, decodes packets, repairs losses, extracts samples, adjusts sample rate and channel layout, compensates clock drift, mixes samples from all connections, and finally stores samples into the provided frame.
If ROC_CLOCK_SOURCE_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; it should contain pointer to a buffer and it’s size; the buffer is fully filled with data from receiver
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_sender_encoder¶
#include <roc/sender_encoder.h>
-
typedef struct roc_sender_encoder roc_sender_encoder¶
Sender encoder.
Sender encoder gets an audio stream from the user, encodes it into network packets, and provides encoded packets to the user.
Sender encoder is a networkless single-stream version of roc_sender. It implements the same pipeline, but instead of sending packets to network, it returns them to the user. The user is responsible for carrying packets over network. Unlike roc_sender, it doesn’t support multiple slots and connections. It produces traffic for a single remote peer.
For detailed description of sender pipeline, see documentation for roc_sender.
Life cycle
Encoder is created using roc_sender_encoder_open().
The user activates one or more interfaces by invoking roc_sender_encoder_activate(). This tells encoder what types of streams to produces and what protocols to use for them (e.g. only audio packets or also redundancy packets).
The audio stream is iteratively pushed to the encoder using roc_sender_encoder_push_frame(). The sender encodes the stream into packets and accumulates them in internal queue.
The packet stream is iteratively popped from the encoder internal queue using roc_sender_encoder_pop_packet(). User should retrieve all available packets from all activated interfaces every time after pushing a frame.
User is responsible for delivering packets to roc_receiver_decoder and pushing them to appropriate interfaces of decoder.
In addition, if a control interface is activated, the stream of encoded feedback packets from decoder is pushed to encoder internal queue using roc_sender_encoder_push_feedback_packet().
User is responsible for delivering feedback packets from roc_receiver_decoder and pushing them to appropriate interfaces of encoder.
Encoder is eventually destroyed using roc_sender_encoder_close().
Interfaces and protocols
Sender encoder may have one or several interfaces, as 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.
Each interface has its own outbound packet queue. When a frame is pushed to the encoder, it may produce multiple packets for each interface queue. The user then should pop packets from each interface that was activated.
Feedback packets
Control interface in addition has inbound packet queue. The user should push feedback packets from decoder to this queue. When a frame is pushed to encoder, it consumes those accumulated packets.
The user should deliver feedback packets from decoder back to encoder. Feedback packets allow decoder and encoder to exchange metrics like latency and losses, and several features like latency calculations require feedback to function properly.
Thread safety
Can be used concurrently.
-
int roc_sender_encoder_open(roc_context *context, const roc_sender_config *config, roc_sender_encoder **result)¶
Open a new encoder.
Allocates and initializes a new encoder, 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_encoder pointer
Returns
returns zero if the encoder 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_encoder_close() to free itattaches created encoder to
context
; the user should not close context before closing encoder
-
int roc_sender_encoder_activate(roc_sender_encoder *encoder, roc_interface iface, roc_protocol proto)¶
Activate encoder interface.
Checks that the protocol is valid and supported by the interface, and initializes given interface with given protocol.
The user should invoke roc_sender_encoder_pop_packet() for all activated interfaces and deliver packets to appropriate interfaces of roc_receiver_decoder.
Parameters
encoder
should point to an opened encoderiface
specifies the encoder interfaceproto
specifies the encoder protocol
Returns
returns zero if interface was successfully activated
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
-
int roc_sender_encoder_query(roc_sender_encoder *encoder, roc_sender_metrics *encoder_metrics, roc_connection_metrics *conn_metrics)¶
Query encoder metrics.
Reads metrics into provided structs.
Metrics for encoder as a whole are written in
encoder_metrics
. If connection was already established (which happens after pushing feedback packets from remote peer to encoder), metrics for connection are written toconn_metrics
.Encoder can have either no connections or one connection. This is reported via
connection_count
field ofencoder_metrics
, which is set to either 0 or 1.Parameters
sender
should point to an opened senderencoder_metrics
defines a struct where to write metrics for decoderconn_metrics
defines a struct where to write metrics for connection (ifconnection_count
is non-zero)
Returns
returns zero if the metrics were successfully retrieved
returns a negative value if the arguments are invalid
Ownership
doesn’t take or share the ownership of the provided buffers; they may be safely deallocated after the function returns
-
int roc_sender_encoder_push_frame(roc_sender_encoder *encoder, const roc_frame *frame)¶
Write frame to encoder.
Encodes samples to into network packets and enqueues them to internal queues of activated interfaces.
If ROC_CLOCK_SOURCE_INTERNAL is used, the function blocks until it’s time to encode the samples according to the configured sample rate.
Until at least one interface is activated, the stream is just dropped.
Parameters
encoder
should point to an opened encoderframe
should point to an initialized frame; it should contain pointer to a buffer and it’s size; the buffer is fully copied into encoder
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_encoder_push_feedback_packet(roc_sender_encoder *encoder, roc_interface iface, const roc_packet *packet)¶
Write feedback packet to encoder.
Adds encoded feedback packet to the interface queue.
The user should iteratively push all delivered feedback packets to appropriate interfaces. They will be later consumed by roc_sender_encoder_push_frame().
Parameters
encoder
should point to an opened encoderpacket
should point to an initialized packet; it should contain pointer to a buffer and it’s size; the buffer is fully copied into encoder
Returns
returns zero if a packet was successfully copied to encoder
returns a negative value if the interface is not activated
returns a negative value if the buffer size of the provided packet is too large
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
packet
; it may be safely deallocated after the function returns
-
int roc_sender_encoder_pop_packet(roc_sender_encoder *encoder, roc_interface iface, roc_packet *packet)¶
Read packet from encoder.
Removes encoded packet from interface queue and returns it to the user.
Packets are added to the queue from roc_sender_encoder_push_frame(). Each push may produce multiple packets, so the user should iteratively pop packets until error. This should be repeated for all activated interfaces.
Parameters
encoder
should point to an opened encoderpacket
should point to an initialized packet; it should contain pointer to a buffer and it’s size; packet bytes are copied to user’s buffer and the size field is updated with the actual packet size
Returns
returns zero if a packet was successfully copied from encoder
returns a negative value if there are no more packets for this interface
returns a negative value if the interface is not activated
returns a negative value if the buffer size of the provided packet is too small
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
packet
; it may be safely deallocated after the function returns
-
int roc_sender_encoder_close(roc_sender_encoder *encoder)¶
Close encoder.
Deinitializes and deallocates the encoder, and detaches it from the context. The user should ensure that nobody uses the encoder during and after this call. If this function fails, the encoder is kept opened and attached to the context.
Parameters
encoder
should point to an opened encoder
Returns
returns zero if the encoder was successfully closed
returns a negative value if the arguments are invalid
Ownership
ends the user ownership of
encoder
; it can’t be used anymore after the function returns
roc_receiver_decoder¶
#include <roc/receiver_decoder.h>
-
typedef struct roc_receiver_decoder roc_receiver_decoder¶
Receiver decoder.
Receiver decoder gets an encoded network packets from the user, decodes audio stream from them, and provides decoded stream to the user.
Receiver decoder is a networkless version of roc_receiver. It implements the same pipeline, but instead of receiving packets from network, it gets them from the user. The user is responsible for carrying packets over network. Unlike roc_receiver, it doesn’t support multiple slots and conenctions. It consumes traffic from a single remote peer.
For detailed description of receiver pipeline, see documentation for roc_receiver.
Life cycle
Decoder is created using roc_receiver_decoder_open().
The user activates one or more interfaces by invoking roc_receiver_decoder_activate(). This tells decoder what types of streams to consume and what protocols to use for them (e.g. only audio packets or also redundancy and control packets).
The per-interface streams of encoded packets are iteratively pushed to the decoder using roc_receiver_decoder_push_packet().
The audio stream is iteratively popped from the decoder using roc_receiver_decoder_pop_frame(). User should push all available packets to all interfaces before popping a frame.
User is responsible for delivering packets from roc_sender_encoder and pushing them to appropriate interfaces of decoder.
In addition, if a control interface is activated, the stream of encoded feedback packets is popped from decoder internal queue using roc_receiver_decoder_pop_feedback_packet().
User is responsible for delivering feedback packets back to roc_sender_encoder and pushing them to appropriate interfaces of encoder.
Decoder is eventually destroyed using roc_receiver_decoder_close().
Interfaces and protocols
Receiver decoder may have one or several interfaces, as 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.Each interface has its own inbound packet queue. When a packet is pushed to the decoder, it is accumulated in the queue. When a frame is popped from the decoder, it consumes those accumulated packets.
Feedback packets
Control interface in addition has outbound packet queue. When a frame is popped from decoder, it generates feedback packets and pushes them to the queue. Then those packets are popped from the queue.
The user should deliver feedback packets from decoder back to encoder. Feedback packets allow decoder and encoder to exchange metrics like latency and losses, and several features like latency calculations require feedback to function properly.
Thread safety
Can be used concurrently.
-
int roc_receiver_decoder_open(roc_context *context, const roc_receiver_config *config, roc_receiver_decoder **result)¶
Open a new decoder.
Allocates and initializes a new decoder, 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_decoder pointer
Returns
returns zero if the decoder 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_decoder_close() to free itattaches created decoder to
context
; the user should not close context before closing decoder
-
int roc_receiver_decoder_activate(roc_receiver_decoder *decoder, roc_interface iface, roc_protocol proto)¶
Activate decoder interface.
Checks that the protocol is valid and supported by the interface, and initializes given interface with given protocol.
The user should invoke roc_receiver_decoder_push_packet() for all activated interfaces and deliver packets from appropriate interfaces of roc_sender_encoder.
Parameters
decoder
should point to an opened decoderiface
specifies the decoder interfaceproto
specifies the decoder protocol
Returns
returns zero if interface was successfully activated
returns a negative value if the arguments are invalid
returns a negative value on resource allocation failure
-
int roc_receiver_decoder_query(roc_receiver_decoder *decoder, roc_receiver_metrics *decoder_metrics, roc_connection_metrics *conn_metrics)¶
Query decoder metrics.
Reads metrics into provided structs.
Metrics for decoder as a whole are written in
decoder_metrics
. If connection was already established (which happens after pushing some packets from remote peer to decoder), metrics for connection are written toconn_metrics
.Decoder can have either no connections or one connection. This is reported via
connection_count
field ofdecoder_metrics
, which is set to either 0 or 1.Parameters
receiver
should point to an opened receiverdecoder_metrics
defines a struct where to write metrics for decoderconn_metrics
defines a struct where to write metrics for connection (ifconnection_count
is non-zero)
Returns
returns zero if the metrics were successfully retrieved
returns a negative value if the arguments are invalid
Ownership
doesn’t take or share the ownership of the provided buffers; they may be safely deallocated after the function returns
-
int roc_receiver_decoder_push_packet(roc_receiver_decoder *decoder, roc_interface iface, const roc_packet *packet)¶
Write packet to decoder.
Adds encoded packet to the interface queue.
The user should iteratively push all delivered packets to appropriate interfaces. They will be later consumed by roc_receiver_decoder_pop_frame().
Parameters
decoder
should point to an opened decoderpacket
should point to an initialized packet; it should contain pointer to a buffer and it’s size; the buffer is fully copied into decoder
Returns
returns zero if a packet was successfully copied to decoder
returns a negative value if the interface is not activated
returns a negative value if the buffer size of the provided packet is too large
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
packet
; it may be safely deallocated after the function returns
-
int roc_receiver_decoder_pop_feedback_packet(roc_receiver_decoder *decoder, roc_interface iface, roc_packet *packet)¶
Read feedback packet from decoder.
Removes encoded feedback packet from control interface queue and returns it to the user.
Feedback packets are added to the queue from roc_receiver_decoder_pop_frame(). Each frame pop may produce multiple packets, so the user should iteratively pop packets until error. This should be repeated for all activated control interfaces.
Parameters
decoder
should point to an opened decoderpacket
should point to an initialized packet; it should contain pointer to a buffer and it’s size; packet bytes are copied to user’s buffer and the size field is updated with the actual packet size
Returns
returns zero if a packet was successfully copied from decoder
returns a negative value if there are no more packets for this interface
returns a negative value if the interface is not activated
returns a negative value if the buffer size of the provided packet is too small
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
packet
; it may be safely deallocated after the function returns
-
int roc_receiver_decoder_pop_frame(roc_receiver_decoder *decoder, roc_frame *frame)¶
Read samples from decoder.
Reads pushed network packets, decodes packets, repairs losses, extracts samples, adjusts sample rate and channel layout, compensates clock drift, and stores samples into the provided frame.
If ROC_CLOCK_SOURCE_INTERNAL is used, the function blocks until it’s time to decode the samples according to the configured sample rate.
Until at least one interface is activated, decoder produces silence.
Parameters
decoder
should point to an opened decoderframe
should point to an initialized frame; it should contain pointer to a buffer and it’s size; the buffer is fully filled with data from decoder
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_decoder_close(roc_receiver_decoder *decoder)¶
Close decoder.
Deinitializes and deallocates the decoder, and detaches it from the context. The user should ensure that nobody uses the decoder during and after this call. If this function fails, the decoder is kept opened and attached to the context.
Parameters
decoder
should point to an opened decoder
Returns
returns zero if the decoder was successfully closed
returns a negative value if the arguments are invalid
Ownership
ends the user ownership of
decoder
; 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_packet¶
#include <roc/packet.h>
-
struct roc_packet¶
Network packet.
Represents opaque encoded binary packet.
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 long long 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, or you can use multiple slots on receiver to bind it to multiple receiver addresses.
Inside each slot, there can be up to one endpoint for each interface type, for example one source endpoint, one control endpoint, and so on. See roc_interface for more details.
Slots are created implicitly. Just specify slot index when binding or connecting endpoint, and slot will be automatically created if it doesn’t exist yet. Slot indices can be arbitrary numbers and does not need to be continuous.
In simple cases, when one slot is enough, just use
ROC_SLOT_DEFAULT
, which is an alias for slot index zero.
-
static const roc_slot ROC_SLOT_DEFAULT = 0¶
Alias for the slot with index zero.
Has no special meaning. Exists for convenience, since most times user doesn’t need to bother about multiple slots.
See also
-
enum roc_interface¶
Network interface.
Interface is a way to access the peer (sender or receiver) via network.
Each slot of a peer (see roc_slot) has multiple interfaces, one for each of the interface types. The user interconnects peers by binding an interface of one peer to an URI, and then connecting the corresponding interface of another peer 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 bidirectional 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:
encodings registered using roc_context_register_encoding()
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.
Each packet encoding defines sample format, channel layout, and rate. Each packet encoding is compatible with specific protocols.
Values:
-
enumerator ROC_PACKET_ENCODING_AVP_L16_MONO¶
PCM signed 16-bit, 1 channel, 44100 rate.
Represents 1-channel L16 stereo encoding from RTP A/V Profile (RFC 3551). Uses uncompressed samples coded as interleaved 16-bit signed big-endian integers in two’s complement notation.
Supported by protocols:
-
enumerator ROC_PACKET_ENCODING_AVP_L16_STEREO¶
PCM signed 16-bit, 2 channels, 44100 rate.
Represents 2-channel L16 stereo encoding from RTP A/V Profile (RFC 3551). Uses uncompressed samples coded as interleaved 16-bit signed big-endian integers in two’s complement notation.
Supported by protocols:
-
enumerator ROC_PACKET_ENCODING_AVP_L16_MONO¶
-
enum roc_fec_encoding¶
Forward Error Correction encoding.
Each FEC encoding is compatible with specific protocols.
Values:
-
enumerator ROC_FEC_ENCODING_DISABLE¶
No FEC encoding.
Compatible with ROC_PROTO_RTP protocol.
Pros:
compatible with third-party software that does not support FECFRAME
Cons:
no packet recovery
-
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.
Pros:
good repair capabilities even on small block sizes
Cons:
high CPU usage on large block sizes
-
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.
Pros:
low CPU usage even on large block sizes
Cons:
low repair capabilities on small block sizes
-
enumerator ROC_FEC_ENCODING_DISABLE¶
-
enum roc_format¶
Sample format.
Defines how each sample is represented. Does not define channels layout and sample rate.
Values:
-
enumerator ROC_FORMAT_PCM_FLOAT32¶
PCM floats.
Uncompressed samples coded as 32-bit native-endian floats in range [-1; 1]. Channels are interleaved, e.g. two channels are encoded as “L R L R …”.
-
enumerator ROC_FORMAT_PCM_FLOAT32¶
-
enum roc_channel_layout¶
Channel layout.
Defines number of channels and meaning of each channel.
Values:
-
enumerator ROC_CHANNEL_LAYOUT_MULTITRACK¶
Multi-track audio.
In multitrack layout, stream contains multiple channels which represent independent “tracks” without any special meaning (unlike stereo or surround) and hence without any special processing or mapping.
The number of channels is arbitrary and is defined by
tracks
field of roc_media_encoding struct.
-
enumerator ROC_CHANNEL_LAYOUT_MONO¶
Mono.
One channel with monophonic sound.
-
enumerator ROC_CHANNEL_LAYOUT_STEREO¶
Stereo.
Two channels: left, right.
-
enumerator ROC_CHANNEL_LAYOUT_MULTITRACK¶
-
struct roc_media_encoding¶
Media encoding.
Defines format and parameters of samples encoded in frames or packets.
Public Members
-
unsigned int rate¶
Sample frequency.
Defines number of samples per channel per second (e.g. 44100).
-
roc_format format¶
Sample format.
Defines sample precision and encoding.
-
roc_channel_layout channels¶
Channel layout.
Defines number of channels and meaning of each channel.
-
unsigned int tracks¶
Multi-track channel count.
If
channels
is ROC_CHANNEL_LAYOUT_MULTITRACK, defines number of channels (which represent independent “tracks”). For other channel layouts should be zero.Should be in range [1; 1024].
-
unsigned int rate¶
-
enum roc_clock_source¶
Clock source for sender or receiver.
Defines wo is responsible to invoke read or write in proper time.
Values:
-
enumerator ROC_CLOCK_SOURCE_DEFAULT¶
Default clock source.
Current default is
ROC_CLOCK_SOURCE_EXTERNAL
.
-
enumerator ROC_CLOCK_SOURCE_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.
Use when samples source (from where you read them to pass to receiver) or destination (to where you write them after obtaining from sender) is active and has its own clock, e.g. it is a sound card.
-
enumerator ROC_CLOCK_SOURCE_INTERNAL¶
Sender or receiver is clocked by an internal pipeline 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, based on a CPU timer.
Use when samples source (from where you read them to pass to receiver) or destination (to where you write them after obtaining from sender) is passive and does now have clock, e.g. it is a file on disk.
-
enumerator ROC_CLOCK_SOURCE_DEFAULT¶
-
enum roc_latency_tuner_backend¶
Latency tuner backend.
Defines which latency is monitored and tuned by latency tuner.
Values:
-
enumerator ROC_LATENCY_TUNER_BACKEND_DEFAULT¶
Default backend.
Current default is
ROC_LATENCY_TUNER_BACKEND_NIQ
.
-
enumerator ROC_LATENCY_TUNER_BACKEND_NIQ¶
Latency tuning is based on network incoming queue length.
In this mode, latency is defined as incoming queue length (in nanoseconds). Latency tuner monitors queue length and and adjusts playback clock speed to keep queue length close to configured target latency.
Keeping constant queue length allows to match playback clock speed with the capture clock speed and to keep the overall latency constant (yet unknown).
On receiver, this backend is always available, without any protocol help. On sender, this backend works only if RTCP is enabled and both sender and receiver are implemented with roc-toolkit, as it relies on a non-standard RTCP extension to report receiver queue length to sender.
Pros:
works with any protocol if used on receiver (does not require RTCP or NTP)
Cons:
synchronizes only clock speed, but not position; different receivers will have different (constant) delays
affected by network jitter; spikes in packet delivery will cause slow oscillations in clock speed
-
enumerator ROC_LATENCY_TUNER_BACKEND_DEFAULT¶
-
enum roc_latency_tuner_profile¶
Latency tuner profile.
Defines whether latency tuning is enabled and which algorithm is used.
Values:
-
enumerator ROC_LATENCY_TUNER_PROFILE_DEFAULT¶
Default profile.
On receiver, when ROC_LATENCY_TUNER_BACKEND_NIQ is used, selects ROC_LATENCY_TUNER_PROFILE_RESPONSIVE if target latency is low, and ROC_LATENCY_TUNER_PROFILE_GRADUAL if target latency is high.
On sender, selects ROC_LATENCY_TUNER_PROFILE_INTACT.
-
enumerator ROC_LATENCY_TUNER_PROFILE_INTACT¶
No latency tuning.
In this mode, clock speed is not adjusted. Default on sender.
You can set this mode on receiver, and set some other mode on sender, to do latency tuning on sender side instead of recever side. It’s useful when receiver is CPU-constrained and sender is not, because latency tuner relies on resampling, which is CPU-demanding.
You can also set this mode on both sender and receiver if you don’t need latency tuning at all. However, if sender and receiver have independent clocks (which is typically the case), clock drift will lead to periodic playback disruptions caused by underruns and overruns.
-
enumerator ROC_LATENCY_TUNER_PROFILE_RESPONSIVE¶
Responsive latency tuning.
Clock speed is adjusted quickly and accurately.
Requires high precision clock adjustment, hence recommended for use with ROC_RESAMPLER_BACKEND_BUILTIN.
Pros:
allows very low latency and synchronization error
Cons:
does not work well with some resampler backends
does not work well with ROC_LATENCY_TUNER_BACKEND_NIQ if network jitter is high
-
enumerator ROC_LATENCY_TUNER_PROFILE_GRADUAL¶
Gradual latency tuning.
Clock speed is adjusted slowly and smoothly.
Pros:
works well even with high network jitter
works well with any resampler backend
Cons:
does not allow very low latency and synchronization error
-
enumerator ROC_LATENCY_TUNER_PROFILE_DEFAULT¶
-
enum roc_resampler_backend¶
Resampler backend.
Affects CPU usage, quality, and clock synchronization precision. Some backends may be disabled at build time.
Values:
-
enumerator ROC_RESAMPLER_BACKEND_DEFAULT¶
Default backend.
Selects ROC_RESAMPLER_BACKEND_BUILTIN when using ROC_LATENCY_TUNER_PROFILE_RESPONSIVE, or when SpeexDSP is disabled.
Otherwise, selects ROC_RESAMPLER_BACKEND_SPEEX.
-
enumerator ROC_RESAMPLER_BACKEND_BUILTIN¶
CPU-intensive good-quality high-precision built-in resampler.
This backend controls clock speed with very high precision, and hence is useful when latency or synchronization error should be very low.
This backend has higher CPU usage, especially on high resampling quality and on CPUs with small L3 caches.
The implementation is based on bandlimited interpolation algorithm.
This backend is always available.
Recommended for ROC_LATENCY_TUNER_PROFILE_RESPONSIVE and on good CPUs.
-
enumerator ROC_RESAMPLER_BACKEND_SPEEX¶
Fast good-quality low-precision resampler based on SpeexDSP.
This backend has low CPU usage even on high resampler quality and cheap CPUs.
This backend controls clock speed with lower precision, and is not so good when latency or synchronization error should be very low.
This backend is available only when SpeexDSP was enabled at build time.
Recommended for ROC_LATENCY_TUNER_PROFILE_GRADUAL and on cheap CPUs.
-
enumerator ROC_RESAMPLER_BACKEND_SPEEXDEC¶
Fast medium-quality and medium-precision resampler combining SpeexDSP with decimation.
This backend uses SpeexDSP for converting between base rates (e.g. 44100 vs 48000) and decimation/expansion (dropping or duplicating samples) for clock drift compensation.
Typical decimation rate needed to compensate clock drift is below 0.5ms/second (20 samples/second on 48Khz), which gives tolerable quality despite usage of decimation, especially for speech.
When frame and packet sample rates are equal (e.g. both are 44100), only decimation stage is needed, and this becomes fastest possible backend working almost as fast as memcpy().
When frame and packet rates are different, usage of this backend compared to
ROC_RESAMPLER_BACKEND_SPEEX
allows to sacrify some quality, but somewhat improve scaling precision and CPU usage in return.This backend is available only when SpeexDSP was enabled at build time.
Recommended when CPU resources are extremely limited.
-
enumerator ROC_RESAMPLER_BACKEND_DEFAULT¶
-
enum roc_resampler_profile¶
Resampler profile.
Affects CPU usage and quality. Each resampler backend treats profile in its own way.
Values:
-
enumerator ROC_RESAMPLER_PROFILE_DEFAULT¶
Default profile.
Current default is
ROC_RESAMPLER_PROFILE_MEDIUM
.
-
enumerator ROC_RESAMPLER_PROFILE_HIGH¶
High quality, higher CPU usage.
-
enumerator ROC_RESAMPLER_PROFILE_MEDIUM¶
Medium quality, medium CPU usage.
-
enumerator ROC_RESAMPLER_PROFILE_LOW¶
Low quality, lower CPU usage.
-
enumerator ROC_RESAMPLER_PROFILE_DEFAULT¶
-
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.
For most fields, zero value means “use default”, and you can memset() this struct with zeros and then set only a few fields that don’t have defaults. It is safe to use memcpy() to get a copy of config, the struct is flat.
See also
Public Members
-
roc_media_encoding frame_encoding¶
The encoding used in frames passed to sender.
Frame encoding defines sample format, channel layout, and sample rate in local frames created by user and passed to sender.
Should be set explicitly (zero value is invalid).
-
roc_packet_encoding packet_encoding¶
The encoding used for packets produced by sender.
Packet encoding defines sample format, channel layout, and sample rate in network packets. If packet encoding differs from frame encoding, conversion is performed automatically.
If zero, sender selects packet encoding automatically based on
frame_encoding
. This automatic selection matches only encodings that have exact same sample rate and channel layout, and hence don’t require conversions. If you need conversions, you should set packet encoding explicitly.If you want to force specific packet encoding, and built-in set of encodings is not enough, you can use roc_context_register_encoding() to register custom encoding, and set
packet_encoding
to registered identifier. If you use signaling protocol like RTSP, it’s enough to register in just on sender; otherwise, you need to do the same on receiver as well.
-
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 does not allow smaller 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_fec_encoding fec_encoding¶
FEC encoding to use.
If FEC is enabled, the sender employs a FEC encoding to generate redundant packet which may be used on receiver to restore lost packets. This requires both sender and receiver to use two separate source and repair endpoints.
If zero, default encoding is used (ROC_FEC_ENCODING_DEFAULT).
-
unsigned int fec_block_source_packets¶
Number of source packets per FEC block.
Used if some FEC encoding is selected.
Sender divides stream into blocks of N source (media) packets, and adds M repair (redundancy) packets to each block, where N is
fec_block_source_packets
and M isfec_block_repair_packets
.Larger number of source packets in block increases robustness (repair ratio), 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.
Sender divides stream into blocks of N source (media) packets, and adds M repair (redundancy) packets to each block, where N is
fec_block_source_packets
and M isfec_block_repair_packets
.Larger number of repair packets in block increases robustness (repair ratio), but also increases traffic. Number of repair packets usually should be 1/2 or 2/3 of the number of source packets.
If zero, default value is used.
-
roc_clock_source clock_source¶
Clock source to use.
Defines whether write operation is blocking or non-blocking.
If zero, default value is used (ROC_CLOCK_SOURCE_DEFAULT).
-
roc_latency_tuner_backend latency_tuner_backend¶
Latency tuner backend.
Defines which latency is monitored and controlled by latency tuner. Defines semantics of
target_latency
,min_latency
, andmax_latency
fields.If zero, default backend is used (ROC_LATENCY_TUNER_BACKEND_DEFAULT).
-
roc_latency_tuner_profile latency_tuner_profile¶
Latency tuner profile.
Defines whether latency tuning is enabled and which algorithm is used.
If zero, default profile is used (ROC_LATENCY_TUNER_PROFILE_DEFAULT).
By default, latency tuning is disabled on sender. If you enable it on sender, you need to disable it on receiver. You also need to set
target_latency
to the exact same value on both sides.
-
roc_resampler_backend resampler_backend¶
Resampler backend.
Affects CPU usage, quality, and clock synchronization precision (if latency tuning is enabled).
If zero, default backend is used (ROC_RESAMPLER_BACKEND_DEFAULT).
-
roc_resampler_profile resampler_profile¶
Resampler profile.
Affects CPU usage and quality.
If zero, default profile is used (ROC_RESAMPLER_PROFILE_DEFAULT).
-
unsigned long long target_latency¶
Target latency, in nanoseconds.
How latency is calculated depends on
latency_tuner_backend
field.If latency tuning is enabled on sender (if
latency_tuner_profile
is not ROC_LATENCY_TUNER_PROFILE_INTACT), sender adjusts its clock to keep actual latency as close as possible to the target.By default, latency tuning is disabled on sender. If you enable it on sender, you need to disable it on receiver. You also need to set
target_latency
to the exact same value on both sides.If latency tuning is enabled,
target_latency
should be non-zero.
-
unsigned long long latency_tolerance¶
Maximum allowed delta between current and target latency, in nanoseconds.
How latency is calculated depends on
latency_tuner_backend
field.If latency tuning is enabled on sender (if
latency_tuner_profile
is not ROC_LATENCY_TUNER_PROFILE_INTACT), sender monitors current latency, and if it differs fromtarget_latency
more than bylatency_tolerance
, sender restarts connection to receiver.By default, latency bounding is disabled on sender. If you enable it on sender, you likely want to disable it on receiver.
If zero, default value is used (if latency tuning is enabled on sender).
-
roc_media_encoding frame_encoding¶
-
struct roc_receiver_config¶
Receiver configuration.
For most fields, zero value means “use default”, and you can memset() this struct with zeros and then set only a few fields that don’t have defaults. It is safe to use memcpy() to get a copy of config, the struct is flat.
See also
Public Members
-
roc_media_encoding frame_encoding¶
The encoding used in frames returned by receiver.
Frame encoding defines sample format, channel layout, and sample rate in local frames returned by receiver to user.
Should be set (zero value is invalid).
-
roc_clock_source clock_source¶
Clock source.
Defines whether read operation is blocking or non-blocking.
If zero, default value is used (ROC_CLOCK_SOURCE_DEFAULT).
-
roc_latency_tuner_backend latency_tuner_backend¶
Latency tuner backend.
Defines which latency is monitored and controlled by latency tuner. Defines semantics of
target_latency
,min_latency
, andmax_latency
fields.If zero, default backend is used (ROC_LATENCY_TUNER_BACKEND_DEFAULT).
-
roc_latency_tuner_profile latency_tuner_profile¶
Latency tuner profile.
Defines whether latency tuning is enabled and which algorithm is used.
If zero, default profile is used (ROC_LATENCY_TUNER_PROFILE_DEFAULT).
By default, latency tuning is enabled on receiver. If you disable it on receiver, you usually need to enable it on sender. In that case you also need to set
target_latency
to the same value on both sides.
-
roc_resampler_backend resampler_backend¶
Resampler backend.
Affects CPU usage, quality, and clock synchronization precision (if latency tuning is enabled).
If zero, default backend is used (ROC_RESAMPLER_BACKEND_DEFAULT).
-
roc_resampler_profile resampler_profile¶
Resampler profile.
Affects CPU usage and quality.
If zero, default profile is used (ROC_RESAMPLER_PROFILE_DEFAULT).
-
unsigned long long target_latency¶
Target latency, in nanoseconds.
How latency is calculated depends on
latency_tuner_backend
field.If latency tuning is enabled on receiver (if
latency_tuner_profile
is not ROC_LATENCY_TUNER_PROFILE_INTACT), receiver adjusts its clock to keep actual latency as close as possible to the target.By default, latency tuning is enabled on receiver. If you disable it on receiver, you likely want to enable it on sender. In this case you also need to set
target_latency
to the exact same value on both sides.If zero, default value is used.
-
unsigned long long latency_tolerance¶
Maximum allowed delta between current and target latency, in nanoseconds.
How latency is calculated depends on
latency_tuner_backend
field.If latency tuning is enabled on receiver (if
latency_tuner_profile
is not ROC_LATENCY_TUNER_PROFILE_INTACT), receiver monitors current latency, and if it differs fromtarget_latency
more than bylatency_tolerance
, receiver terminates connection to sender (but it then restarts if sender continues streaming).By default, latency bounding is enabled on receiver. If you disable it on receiver, you likely want to enable it on sender.
If zero, default value is used (if latency tuning is enabled on receiver).
-
long long no_playback_timeout¶
Timeout for the lack of playback, in nanoseconds.
If there is no playback during this period, receiver terminates connection to to sender (but it then restarts if sender continues streaming).
This mechanism allows to detect dead, hanging, or incompatible clients that generate unparseable packets.
If zero, default value is used. If negative, the check is disabled.
-
long long choppy_playback_timeout¶
Timeout for choppy playback, in nanoseconds.
If there is constant stuttering during this period, receiver terminates connection to sender (but it then restarts if sender continues streaming).
This mechanism allows to detect situations when playback continues but there are frequent glitches, for example because there is a high ratio of late packets.
If zero, default value is used. If negative, the check is disabled.
-
roc_media_encoding frame_encoding¶
roc_metrics¶
#include <roc/metrics.h>
-
struct roc_connection_metrics¶
Metrics for a single connection between sender and receiver.
On receiver, represents one connected sender. Similarly, on sender represents one connected receiver. It doesn’t matter who initiated connection, sender or receiver.
Some metrics are calculated locally, and some are periodically retrieved from remote side via control protocol like ROC_PROTO_RTCP.
Public Members
-
unsigned long long e2e_latency¶
Estimated end-to-end latency, in nanoseconds.
Defines how much time passes after a frame is written to sender and before it is read from receiver. Consists of sender latency, network latency, and receiver latency.
Computations are based on RTCP and system clock. If ROC_PROTO_RTCP is not used, latency will be zero. If system clocks of sender and receiver are not synchronized, latency will be calculated incorrectly.
May be zero initially, until enough statistics is accumulated.
-
unsigned long long e2e_latency¶
-
struct roc_sender_metrics¶
Sender metrics.
Holds sender-side metrics that are not specific to connection. If multiple slots are used, each slot has its own metrics.
Public Members
-
unsigned int connection_count¶
Number of active connections.
Defines how much receivers are currently discovered.
If a control or signaling protocol like ROC_PROTO_RTSP or ROC_PROTO_RTCP is not used, sender doesn’t know about receivers and doesn’t have connection metrics.
If such a protocol is used, in case of unicast, sender will have a single connection, and in case of multicast, sender may have multiple connections, one per each discovered receiver.
-
unsigned int connection_count¶
-
struct roc_receiver_metrics¶
Receiver metrics.
Holds receiver-side metrics that are not specific to connection. If multiple slots are used, each slot has its own metrics.
Public Members
-
unsigned int connection_count¶
Number of active connections.
Defines how much senders are currently connected to receiver. When there are no connections, receiver produces silence.
-
unsigned int connection_count¶
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.
-
enumerator ROC_LOG_INFO¶
Informational messages.
Setting this level enables logging of important high-level events, like binding a new port or accepting a new connection.
-
enumerator ROC_LOG_NOTE¶
Noteworthy debug messages.
Setting this level enables logging of debug messages, but only those which are generated for more rare and important events, like changing latency.
-
enumerator ROC_LOG_DEBUG¶
Debug messages.
Setting this level enables logging of debug messages.
-
enumerator ROC_LOG_TRACE¶
Extra verbose debug messages; Setting this level enables verbose tracing.
Unlike all other levels, 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.
-
ROC_VERSION¶
Numeric version code.
See also
-
ROC_VERSION_CODE(major, minor, patch)¶
Convert version triple to numeric version code.
Version codes can be compared direcrly, e.g.:
#if ROC_VERSION < ROC_VERSION_CODE(1, 2, 3) ... #endif
-
struct roc_version¶
Version components.
-
void roc_version_load(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.