#ifndef _SSRC_H_ #define _SSRC_H_ #include #include #include "compat.h" #include "aux.h" #include "obj.h" #include "codeclib.h" struct call; struct call_media; struct timeval; struct rtp_payload_type; struct ssrc_entry; struct ssrc_entry_call; enum ssrc_dir; typedef struct ssrc_entry *(*ssrc_create_func_t)(void *uptr); struct ssrc_hash { GHashTable *ht; GQueue q; rwlock_t lock; ssrc_create_func_t create_func; void *uptr; volatile struct ssrc_entry *cache; // last used entry volatile struct ssrc_entry *precreat; // next used entry }; struct payload_tracker { mutex_t lock; unsigned char last[32]; // must be <= 255 unsigned int last_idx; // rolling index into pt_last unsigned char count[128]; // how many of each pt unsigned char idx[128]; // each pt's index into most[] unsigned char most[128]; // sorted list of pts unsigned int most_len; // idx for new entries }; struct ssrc_ctx { struct ssrc_entry_call *parent; struct payload_tracker tracker; // XXX lock this? u_int64_t srtp_index, srtcp_index; // XXX move entire crypto context in here? // for transcoding u_int32_t ssrc_map_out; // RTCP stats atomic64 packets, octets, packets_lost, duplicates, last_seq, // XXX dup with srtp_index? last_ts; }; struct ssrc_stats_block { struct timeval reported; u_int64_t jitter; // ms u_int64_t rtt; // us - combined from both sides u_int64_t packetloss; // percent u_int64_t mos; // nominal range of 10 - 50 for MOS values 1.0 to 5.0 }; struct ssrc_entry { struct obj obj; mutex_t lock; u_int32_t ssrc; time_t last_used; }; struct ssrc_entry_call { struct ssrc_entry h; // must be first struct ssrc_ctx input_ctx, output_ctx; GQueue sender_reports; // as received via RTCP GQueue rr_time_reports; // as received via RTCP GQueue stats_blocks; // calculated struct ssrc_stats_block *lowest_mos, *highest_mos, average_mos; // contains a running tally of all stats blocks unsigned int last_rtt; // last calculated raw rtt without rtt from opposide side // for transcoding // input only packet_sequencer_t sequencer; // output only uint16_t seq_diff; }; enum ssrc_dir { // these values must not be used externally SSRC_DIR_INPUT = G_STRUCT_OFFSET(struct ssrc_entry_call, input_ctx), SSRC_DIR_OUTPUT = G_STRUCT_OFFSET(struct ssrc_entry_call, output_ctx), }; struct ssrc_time_item { struct timeval received; u_int32_t ntp_middle_bits; // to match up with lsr/dlrr double ntp_ts; // XXX convert to int? }; struct ssrc_sender_report { u_int32_t ssrc; u_int32_t ntp_msw; u_int32_t ntp_lsw; u_int32_t timestamp; u_int32_t packet_count; u_int32_t octet_count; }; struct ssrc_sender_report_item { struct ssrc_time_item time_item; // must be first; struct ssrc_sender_report report; }; struct ssrc_receiver_report { u_int32_t from; u_int32_t ssrc; unsigned char fraction_lost; u_int32_t packets_lost; u_int32_t high_seq_received; u_int32_t jitter; u_int32_t lsr; u_int32_t dlsr; }; //struct ssrc_receiver_report_item { // struct timeval received; // struct ssrc_receiver_report report; //}; struct ssrc_xr_rr_time { u_int32_t ssrc; u_int32_t ntp_msw; u_int32_t ntp_lsw; }; struct ssrc_rr_time_item { struct ssrc_time_item time_item; // must be first; }; struct ssrc_xr_dlrr { u_int32_t from; u_int32_t ssrc; u_int32_t lrr; u_int32_t dlrr; }; struct ssrc_xr_voip_metrics { u_int32_t from; u_int32_t ssrc; u_int8_t loss_rate; u_int8_t discard_rate; u_int8_t burst_den; u_int8_t gap_den; u_int16_t burst_dur; u_int16_t gap_dur; u_int16_t rnd_trip_delay; u_int16_t end_sys_delay; u_int8_t signal_lvl; u_int8_t noise_lvl; u_int8_t rerl; u_int8_t gmin; u_int8_t r_factor; u_int8_t ext_r_factor; u_int8_t mos_lq; u_int8_t mos_cq; u_int8_t rx_config; u_int16_t jb_nom; u_int16_t jb_max; u_int16_t jb_abs_max; }; void free_ssrc_hash(struct ssrc_hash **); struct ssrc_hash *create_ssrc_hash_full(ssrc_create_func_t, void *uptr); struct ssrc_hash *create_ssrc_hash_call(void); void *get_ssrc(u_int32_t, struct ssrc_hash * /* , int *created */); // creates new entry if not found struct ssrc_ctx *get_ssrc_ctx(u_int32_t, struct ssrc_hash *, enum ssrc_dir); // creates new entry if not found void ssrc_sender_report(struct call_media *, const struct ssrc_sender_report *, const struct timeval *); void ssrc_receiver_report(struct call_media *, const struct ssrc_receiver_report *, const struct timeval *); void ssrc_receiver_rr_time(struct call_media *m, const struct ssrc_xr_rr_time *rr, const struct timeval *); void ssrc_receiver_dlrr(struct call_media *m, const struct ssrc_xr_dlrr *dlrr, const struct timeval *); void ssrc_voip_metrics(struct call_media *m, const struct ssrc_xr_voip_metrics *vm, const struct timeval *); void payload_tracker_init(struct payload_tracker *t); void payload_tracker_add(struct payload_tracker *, int); #endif