/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of oRTP.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* \file rtpsession.h
* \brief The RtpSession api
*
* The RtpSession objects represent a RTP session: once it is configured with
* local and remote network addresses and a payload type is given, it let you send
* and recv a media stream.
**/
#ifndef RTPSESSION_H
#define RTPSESSION_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ORTP_AVPF_FEATURE_NONE 0
#define ORTP_AVPF_FEATURE_TMMBR (1 << 0)
#define ORTP_AVPF_FEATURE_GENERIC_NACK (1 << 1)
#define ORTP_AVPF_FEATURE_IMMEDIATE_NACK (1 << 2)
typedef enum {
RTP_SESSION_RECVONLY,
RTP_SESSION_SENDONLY,
RTP_SESSION_SENDRECV
} RtpSessionMode;
typedef enum _OrtpJitterBufferAlgorithm {
OrtpJitterBufferBasic,
OrtpJitterBufferRecursiveLeastSquare,
} OrtpJitterBufferAlgorithm;
/*! Jitter buffer parameters
*/
typedef struct _JBParameters{
int min_size; /*(adaptive=TRUE only) maximum dynamic delay to be added to incoming packets (ms) */
int nom_size; /*(adaptive=TRUE only) initial dynamic delay to be added to incoming packets (ms) */
int max_size; /*(adaptive=TRUE only) minimum dynamic delay to be added to incoming packets (ms) */
bool_t adaptive; /*either a dynamic buffer should be used or not to compensate bursts */
bool_t enabled; /*whether jitter buffer is enabled*/
bool_t pad[2]; /*(dev only) alignment pad: insert your bool_t here*/
int max_packets; /**max number of packets allowed to be queued in the jitter buffer */
OrtpJitterBufferAlgorithm buffer_algorithm;
int refresh_ms; /* (adaptive=TRUE only) dynamic buffer size update frequency (ms) */
int ramp_threshold; /*(adaptive=TRUE, algo=RLS only) Percentage in [0;100] threshold between current jitter and previous jitter to enable smooth ramp*/
int ramp_step_ms; /*(adaptive=TRUE, algo=RLS only) In smooth ramp, how much we should reduce jitter size on each step*/
int ramp_refresh_ms; /*(adaptive=TRUE, algo=RLS only) In smooth ramp, frequency of step*/
} JBParameters;
typedef struct _JitterControl
{
JBParameters params;
unsigned int count; /* number of packets handled in jitter_control_new_packet. Used internally only. */
int jitt_comp_ts; /* the nominal jitter buffer size converted in rtp time (same unit as timestamp) */
int adapt_jitt_comp_ts;
int32_t clock_offset_ts; /*offset difference between local and distant clock, in timestamp units*/
int32_t prev_clock_offset_ts;
int32_t olddiff;
float jitter;
float inter_jitter; /* interarrival jitter as defined in the RFC */
float jitter_buffer_mean_size; /*effective size (fullness) of jitter buffer*/
int corrective_step;
int corrective_slide;
uint64_t cum_jitter_buffer_size; /*in timestamp units*/
unsigned int cum_jitter_buffer_count; /*used for computation of jitter buffer size*/
int clock_rate;
uint32_t adapt_refresh_prev_ts; /*last time we refreshed the buffer*/
OrtpExtremum max_ts_deviation; /*maximum difference between packet and expected timestamps */
OrtpKalmanRLS kalman_rls;
double capped_clock_ratio;
uint32_t last_log_ts;
uint32_t local_ts_start;
uint32_t remote_ts_start;
uint32_t diverged_start_ts;
bool_t is_diverging;
bool_t jb_size_updated;
bool_t pad[2];
} JitterControl;
typedef struct _WaitPoint
{
ortp_mutex_t lock;
ortp_cond_t cond;
uint32_t time;
bool_t wakeup;
} WaitPoint;
typedef struct _RtpTransportModifier
{
void *data;
struct _RtpSession *session;//flags|=(flag)
#define rtp_session_unset_flag(session,flag) (session)->flags&=~(flag)
ORTP_PUBLIC void rtp_session_uninit(RtpSession *session);
ORTP_PUBLIC void rtp_session_dispatch_event(RtpSession *session, OrtpEvent *ev);
ORTP_PUBLIC void rtp_session_set_reuseaddr(RtpSession *session, bool_t yes);
ORTP_PUBLIC int meta_rtp_transport_sendto(RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen);
ORTP_PUBLIC int meta_rtp_transport_modifier_inject_packet_to_send(RtpTransport *t, RtpTransportModifier *tpm, mblk_t *msg, int flags);
ORTP_PUBLIC int meta_rtp_transport_modifier_inject_packet_to_send_to(RtpTransport *t, RtpTransportModifier *tpm, mblk_t *msg, int flags, const struct sockaddr *to, socklen_t tolen);
ORTP_PUBLIC int meta_rtp_transport_modifier_inject_packet_to_recv(RtpTransport *t, RtpTransportModifier *tpm, mblk_t *msg, int flags);
/**
* get endpoint if any
* @param[in] transport RtpTransport object.
* @return #_RtpTransport
*
* */
ORTP_PUBLIC RtpTransport* meta_rtp_transport_get_endpoint(const RtpTransport *transport);
/**
* set endpoint
* @param[in] transport RtpTransport object.
* @param[in] endpoint RtpEndpoint.
*
* */
ORTP_PUBLIC void meta_rtp_transport_set_endpoint(RtpTransport *transport,RtpTransport *endpoint);
ORTP_PUBLIC void meta_rtp_transport_destroy(RtpTransport *tp);
ORTP_PUBLIC void meta_rtp_transport_append_modifier(RtpTransport *tp,RtpTransportModifier *tpm);
ORTP_PUBLIC void meta_rtp_transport_prepend_modifier(RtpTransport *tp,RtpTransportModifier *tpm);
ORTP_PUBLIC void meta_rtp_transport_remove_modifier(RtpTransport *tp, RtpTransportModifier *tpm);
ORTP_PUBLIC int rtp_session_splice(RtpSession *session, RtpSession *to_session);
ORTP_PUBLIC int rtp_session_unsplice(RtpSession *session, RtpSession *to_session);
ORTP_PUBLIC bool_t ortp_stream_is_ipv6(OrtpStream *os);
/* RtpBundle api */
typedef struct _RtpBundle RtpBundle;
ORTP_PUBLIC RtpBundle* rtp_bundle_new(void);
ORTP_PUBLIC void rtp_bundle_delete(RtpBundle *bundle);
ORTP_PUBLIC int rtp_bundle_get_mid_extension_id(RtpBundle *bundle);
ORTP_PUBLIC void rtp_bundle_set_mid_extension_id(RtpBundle *bundle, int id);
ORTP_PUBLIC void rtp_bundle_add_session(RtpBundle *bundle, const char *mid, RtpSession *session);
ORTP_PUBLIC void rtp_bundle_remove_session_by_id(RtpBundle *bundle, const char *mid);
ORTP_PUBLIC void rtp_bundle_remove_session(RtpBundle *bundle, RtpSession *session);
ORTP_PUBLIC void rtp_bundle_clear(RtpBundle *bundle);
ORTP_PUBLIC RtpSession* rtp_bundle_get_primary_session(RtpBundle *bundle);
ORTP_PUBLIC void rtp_bundle_set_primary_session(RtpBundle *bundle, const char * mid);
ORTP_PUBLIC const char *rtp_bundle_get_session_mid(RtpBundle *bundle, RtpSession *session);
ORTP_PUBLIC int rtp_bundle_send_through_primary(RtpBundle *bundle, bool_t is_rtp, mblk_t *m, int flags, const struct sockaddr *destaddr, socklen_t destlen);
/* Returns FALSE if the rtp packet or at least one of the RTCP packet (compound) was for the primary */
ORTP_PUBLIC bool_t rtp_bundle_dispatch(RtpBundle *bundle, bool_t is_rtp, mblk_t *m, bool_t received_by_rtcp_mux);
ORTP_PUBLIC void rtp_session_use_local_addr(RtpSession * session, const char * rtp_local_addr, const char * rtcp_local_addr);
#ifdef __cplusplus
}
#endif
#endif