RTP: work also with time in NS

This commit is contained in:
Martin Pulec
2022-03-16 11:29:52 +01:00
parent 4b315f93de
commit d1f3206077
15 changed files with 120 additions and 149 deletions

View File

@@ -662,10 +662,8 @@ static void *audio_receiver_thread(void *arg)
bool decoded = false;
if (s->receiver == NET_NATIVE || s->receiver == NET_STANDARD) {
time_ns_t time_ns = get_time_in_ns();
uint32_t ts = (time_ns - s->start_time) / 100'000 * 9; // at 90000 Hz
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
uint32_t ts = (curr_time - s->start_time) / 100'000 * 9; // at 90000 Hz
rtp_update(s->audio_network_device, curr_time);
rtp_send_ctrl(s->audio_network_device, ts, 0, curr_time);
struct timeval timeout;
@@ -713,14 +711,14 @@ static void *audio_receiver_thread(void *arg)
// We iterate in loop since there can be more than one frmae present in
// the playout buffer and it would be discarded by following pbuf_remove()
// call.
while (pbuf_decode(cp->playout_buffer, time_ns, s->receiver == NET_NATIVE ? decode_audio_frame : decode_audio_frame_mulaw, &dec_state->pbuf_data)) {
while (pbuf_decode(cp->playout_buffer, curr_time, s->receiver == NET_NATIVE ? decode_audio_frame : decode_audio_frame_mulaw, &dec_state->pbuf_data)) {
current_pbuf = &dec_state->pbuf_data;
decoded = true;
}
}
pbuf_remove(cp->playout_buffer, time_ns);
pbuf_remove(cp->playout_buffer, curr_time);
cp = pdb_iter_next(&it);
if (decoded && !playback_supports_multiple_streams)
@@ -1002,9 +1000,8 @@ static void *audio_sender_thread(void *arg)
}
if ((s->audio_tx_mode & MODE_RECEIVER) == 0) { // otherwise receiver thread does the stuff...
uint32_t ts = (get_time_in_ns() - s->start_time) / 10'0000 * 9; // at 90000 Hz
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
uint32_t ts = (curr_time - s->start_time) / 10'0000 * 9; // at 90000 Hz
rtp_update(s->audio_network_device, curr_time);
rtp_send_ctrl(s->audio_network_device, ts, 0, curr_time);

View File

@@ -278,7 +278,7 @@ static struct pdb_e *pdb_create_item(uint32_t ssrc, volatile int *delay_ms)
{
struct pdb_e *p = malloc(sizeof(struct pdb_e));
if (p != NULL) {
gettimeofday(&(p->creation_time), NULL);
p->creation_time = get_time_in_ns();
p->ssrc = ssrc;
p->sdes_cname = NULL;
p->sdes_name = NULL;

View File

@@ -52,6 +52,8 @@
*
*/
#include "tv.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -81,7 +83,7 @@ struct pdb_e {
uint8_t pt; /* Last seen RTP payload type for this participant */
struct pbuf *playout_buffer;
struct tfrc *tfrc_state;
struct timeval creation_time; /* Time this entry was created */
time_ns_t creation_time; /* Time this entry was created */
};
struct pdb; /* The participant database */

View File

@@ -192,7 +192,7 @@ typedef struct _rtcp_rr_wrapper {
uint32_t reporter_ssrc;
rtcp_rr *rr;
rtcp_rx *rx;
struct timeval ts; /* Arrival time of this RR */
time_ns_t ts; /* Arrival time of this RR */
} rtcp_rr_wrapper;
/*
@@ -215,7 +215,7 @@ typedef struct _source {
rtcp_sr *sr;
uint32_t last_sr_sec;
uint32_t last_sr_frac;
struct timeval last_active;
time_ns_t last_active;
int should_advertise_sdes; /* TRUE if this source is a CSRC which we need to advertise SDES for */
int sender;
int got_bye; /* TRUE if we've received an RTCP bye from this source */
@@ -292,10 +292,10 @@ struct rtp {
double avg_rtcp_size;
int we_sent;
double rtcp_bw; /* RTCP bandwidth fraction, in octets per second. */
struct timeval last_update;
struct timeval last_rtp_send_time;
struct timeval last_rtcp_send_time;
struct timeval next_rtcp_send_time;
time_ns_t last_update;
time_ns_t last_rtp_send_time;
time_ns_t last_rtcp_send_time;
time_ns_t next_rtcp_send_time;
double rtcp_interval;
int sdes_count_pri;
int sdes_count_sec;
@@ -407,7 +407,7 @@ static void insert_rr(struct rtp *session, uint32_t reporter_ssrc, rtcp_rr * rr,
free(cur->rx);
cur->rr = rr;
cur->rx = rx;
gettimeofday(&cur->ts, NULL);
cur->ts = get_time_in_ns();
return;
}
cur = cur->next;
@@ -418,7 +418,7 @@ static void insert_rr(struct rtp *session, uint32_t reporter_ssrc, rtcp_rr * rr,
cur->reporter_ssrc = reporter_ssrc;
cur->rr = rr;
cur->rx = rx;
gettimeofday(&cur->ts, NULL);
cur->ts = get_time_in_ns();
/* Fix links */
cur->next = start->next;
cur->next->prev = cur;
@@ -472,7 +472,7 @@ static void remove_rr(struct rtp *session, uint32_t ssrc)
}
}
static void timeout_rr(struct rtp *session, struct timeval *curr_ts)
static void timeout_rr(struct rtp *session, time_ns_t curr_ts)
{
/* Timeout any reception reports which have been in the database for more than 3 */
/* times the RTCP reporting interval without refresh. */
@@ -485,8 +485,8 @@ static void timeout_rr(struct rtp *session, struct timeval *curr_ts)
start = &session->rr[i][j];
cur = start->next;
while (cur != start) {
if (tv_diff(*curr_ts, cur->ts) >
(session->rtcp_interval * 3)) {
if (curr_ts - cur->ts >
session->rtcp_interval * 3 * NS_IN_SEC) {
/* Signal the application... */
if (!filter_event
(session, cur->reporter_ssrc)) {
@@ -633,7 +633,7 @@ static source *really_create_source(struct rtp *session, uint32_t ssrc,
s->probation = 0;
}
gettimeofday(&(s->last_active), NULL);
s->last_active = get_time_in_ns();
/* Now, add it to the database... */
if (session->db[h] != NULL) {
session->db[h]->prev = s;
@@ -667,7 +667,7 @@ static inline source *create_source(struct rtp *session, uint32_t ssrc,
}
/* Source is already in the database... Mark it as */
/* active and exit (this is the common case...) */
gettimeofday(&(s->last_active), NULL);
s->last_active = get_time_in_ns();
return s;
}
@@ -677,12 +677,10 @@ static void delete_source(struct rtp *session, uint32_t ssrc)
source *s = get_source(session, ssrc);
int h = ssrc_hash(ssrc);
rtp_event event;
struct timeval event_ts;
time_ns_t event_ts = get_time_in_ns();
assert(s != NULL); /* Deleting a source which doesn't exist is an error... */
gettimeofday(&event_ts, NULL);
check_source(s);
check_database(session);
if (session->db[h] == s) {
@@ -735,14 +733,14 @@ static void delete_source(struct rtp *session, uint32_t ssrc)
/* o The value of pmembers is set equal to members. */
session->ssrc_count--;
if (session->ssrc_count < session->ssrc_count_prev) {
gettimeofday(&(session->next_rtcp_send_time), NULL);
gettimeofday(&(session->last_rtcp_send_time), NULL);
tv_add(&(session->next_rtcp_send_time),
session->next_rtcp_send_time =
session->last_rtcp_send_time = get_time_in_ns();
session->next_rtcp_send_time +=
(session->ssrc_count / session->ssrc_count_prev)
* tv_diff(session->next_rtcp_send_time, event_ts));
tv_add(&(session->last_rtcp_send_time),
-((session->ssrc_count / session->ssrc_count_prev)
* tv_diff(event_ts, session->last_rtcp_send_time)));
* (session->next_rtcp_send_time - event_ts) * NS_IN_SEC;
session->last_rtcp_send_time -=
((session->ssrc_count / session->ssrc_count_prev)
* (event_ts - session->last_rtcp_send_time)) * NS_IN_SEC;
session->ssrc_count_prev = session->ssrc_count;
}
@@ -1170,14 +1168,14 @@ struct rtp *rtp_init_if(const char *addr, const char *iface,
session->tfrc_on = tfrc_on;
session->rtp_bcount = 0;
session->rtp_bytes_sent = 0;
gettimeofday(&(session->last_update), NULL);
gettimeofday(&(session->last_rtcp_send_time), NULL);
gettimeofday(&(session->next_rtcp_send_time), NULL);
session->last_update =
session->last_rtcp_send_time =
session->next_rtcp_send_time = get_time_in_ns();
session->encryption_enabled = 0;
session->encryption_algorithm = NULL;
/* Calculate when we're supposed to send our first RTCP packet... */
tv_add(&(session->next_rtcp_send_time), rtcp_interval(session));
session->next_rtcp_send_time += rtcp_interval(session) * NS_IN_SEC;
/* Initialise the source database... */
for (i = 0; i < RTP_DB_SIZE; i++) {
@@ -1263,14 +1261,14 @@ rtp_t rtp_init_with_udp_socket(struct socket_udp_local *l, struct sockaddr *sa,
session->tfrc_on = tfrc_on;
session->rtp_bcount = 0;
session->rtp_bytes_sent = 0;
gettimeofday(&(session->last_update), NULL);
gettimeofday(&(session->last_rtcp_send_time), NULL);
gettimeofday(&(session->next_rtcp_send_time), NULL);
session->last_update =
session->last_rtcp_send_time =
session->next_rtcp_send_time = get_time_in_ns();
session->encryption_enabled = 0;
session->encryption_algorithm = NULL;
/* Calculate when we're supposed to send our first RTCP packet... */
tv_add(&(session->next_rtcp_send_time), rtcp_interval(session));
session->next_rtcp_send_time += NS_IN_SEC * rtcp_interval(session);
/* Initialise the source database... */
for (i = 0; i < RTP_DB_SIZE; i++) {
@@ -2967,7 +2965,7 @@ rtp_send_data_hdr(struct rtp *session,
session->rtp_pcount += 1;
session->rtp_bcount += buffer_len;
session->rtp_bytes_sent += buffer_len + data_len;
gettimeofday(&session->last_rtp_send_time, NULL);
session->last_rtp_send_time = get_time_in_ns();
check_database(session);
return rc;
@@ -3445,31 +3443,25 @@ static void send_rtcp(struct rtp *session, uint32_t rtp_ts,
* frequently.
*/
void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts,
rtcp_app_callback appcallback, struct timeval curr_time)
rtcp_app_callback appcallback, time_ns_t curr_time)
{
/* Send an RTCP packet, if one is due... */
check_database(session);
if (tv_gt(curr_time, session->next_rtcp_send_time)) {
if (curr_time > session->next_rtcp_send_time) {
/* The RTCP transmission timer has expired. The following */
/* implements draft-ietf-avt-rtp-new-02.txt section 6.3.6 */
int h;
source *s;
struct timeval new_send_time;
double new_interval;
new_interval =
double new_interval =
rtcp_interval(session) / (session->csrc_count + 1);
new_send_time = session->last_rtcp_send_time;
tv_add(&new_send_time, new_interval);
if (tv_gt(curr_time, new_send_time)) {
time_ns_t new_send_time = session->last_rtcp_send_time + new_interval * NS_IN_SEC;
if (curr_time > new_send_time) {
send_rtcp(session, rtp_ts, appcallback);
session->initial_rtcp = FALSE;
session->last_rtcp_send_time = curr_time;
session->next_rtcp_send_time = curr_time;
tv_add(&(session->next_rtcp_send_time),
rtcp_interval(session) / (session->csrc_count +
1));
session->next_rtcp_send_time = curr_time + (rtcp_interval(session) / (session->csrc_count +
1)) * NS_IN_SEC;
/* We're starting a new RTCP reporting interval, zero out */
/* the per-interval statistics. */
session->sender_count = 0;
@@ -3497,22 +3489,21 @@ void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts,
* through the data structures to once per second, it can be safely
* called more frequently.
*/
void rtp_update(struct rtp *session, struct timeval curr_time)
void rtp_update(struct rtp *session, time_ns_t curr_time)
{
/* Perform housekeeping on the source database... */
int h;
source *s, *n;
double delay;
if (tv_diff(curr_time, session->last_update) < 1.0) {
if (curr_time - session->last_update < 1 * NS_IN_SEC) {
/* We only perform housekeeping once per second... */
return;
}
session->last_update = curr_time;
/* Update we_sent (section 6.3.8 of RTP spec) */
delay = tv_diff(curr_time, session->last_rtp_send_time);
if (delay >= 2 * rtcp_interval(session)) {
time_ns_t delay = curr_time - session->last_rtp_send_time;
if (delay >= 2 * NS_IN_SEC * rtcp_interval(session)) {
session->we_sent = FALSE;
}
@@ -3526,24 +3517,24 @@ void rtp_update(struct rtp *session, struct timeval curr_time)
/* Section 6.2.1 of the RTP specification details the timers used. */
/* How int since we last heard from this source? */
delay = tv_diff(curr_time, s->last_active);
delay = curr_time - s->last_active;
/* Check if we've received a BYE packet from this source. */
/* If we have, and it was received more than 2 seconds ago */
/* then the source is deleted. The arbitrary 2 second delay */
/* is to ensure that all delayed packets are received before */
/* the source is timed out. */
if (s->got_bye && (delay > 2.0)) {
if (s->got_bye && (delay > 2 * NS_IN_SEC)) {
debug_msg
("Deleting source 0x%08" PRIx32 " due to reception of BYE %f seconds ago...\n",
s->ssrc, delay);
s->ssrc, (double) delay / NS_IN_SEC);
delete_source(session, s->ssrc);
}
/* Sources are marked as inactive if they haven't been heard */
/* from for more than 2 intervals (RTP section 6.3.5) */
if ((s->ssrc != rtp_my_ssrc(session))
&& (delay > (session->rtcp_interval * 2))) {
&& (delay > (session->rtcp_interval * 2 * NS_IN_SEC))) {
if (s->sender) {
s->sender = FALSE;
session->sender_count--;
@@ -3553,7 +3544,7 @@ void rtp_update(struct rtp *session, struct timeval curr_time)
/* If a source hasn't been heard from for more than 5 RTCP */
/* reporting intervals, we delete it from our database... */
if ((s->ssrc != rtp_my_ssrc(session))
&& (delay > (session->rtcp_interval * 5))) {
&& (delay > (session->rtcp_interval * 5 * NS_IN_SEC))) {
debug_msg
("Deleting source 0x%08" PRIx32 " due to timeout...\n",
s->ssrc);
@@ -3563,7 +3554,7 @@ void rtp_update(struct rtp *session, struct timeval curr_time)
}
/* Timeout those reception reports which haven't been refreshed for a int time */
timeout_rr(session, &curr_time);
timeout_rr(session, curr_time);
check_database(session);
}
@@ -3642,7 +3633,6 @@ static void rtp_send_bye_now(struct rtp *session)
*/
void rtp_send_bye(struct rtp *session)
{
struct timeval curr_time, timeout, new_send_time;
uint8_t buffer[RTP_MAX_PACKET_LEN];
int buflen;
double new_interval;
@@ -3661,28 +3651,25 @@ void rtp_send_bye(struct rtp *session)
if (session->ssrc_count < 50) {
rtp_send_bye_now(session);
} else {
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
session->sending_bye = TRUE;
session->last_rtcp_send_time = curr_time;
session->next_rtcp_send_time = curr_time;
session->last_rtcp_send_time =
session->next_rtcp_send_time = curr_time;
session->bye_count = 1;
session->initial_rtcp = TRUE;
session->we_sent = FALSE;
session->sender_count = 0;
session->avg_rtcp_size = 70.0 + RTP_LOWER_LAYER_OVERHEAD; /* FIXME */
tv_add(&session->next_rtcp_send_time,
rtcp_interval(session) / (session->csrc_count + 1));
session->next_rtcp_send_time += (rtcp_interval(session) / (session->csrc_count + 1)) * NS_IN_SEC;
debug_msg("Preparing to send BYE...\n");
while (1) {
/* Schedule us to block in udp_select() until the time we are due to send our */
/* BYE packet. If we receive an RTCP packet from another participant before */
/* then, we are woken up to handle it... */
timeout.tv_sec = 0;
timeout.tv_usec = 0;
tv_add(&timeout,
tv_diff(session->next_rtcp_send_time,
curr_time));
long long ms = (session->next_rtcp_send_time - curr_time) / NS_IN_MS;
lldiv_t d = lldiv(ms, MS_IN_SEC);
struct timeval timeout = { .tv_sec = d.quot, .tv_usec = d.rem };
udp_fd_zero();
udp_fd_set(session->rtcp_socket);
if ((udp_select(&timeout) > 0)
@@ -3695,12 +3682,11 @@ void rtp_send_bye(struct rtp *session)
rtp_process_ctrl(session, buffer, buflen);
}
/* Is it time to send our BYE? */
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
new_interval =
rtcp_interval(session) / (session->csrc_count + 1);
new_send_time = session->last_rtcp_send_time;
tv_add(&new_send_time, new_interval);
if (tv_gt(curr_time, new_send_time)) {
time_ns_t new_send_time = session->last_rtcp_send_time + new_interval * NS_IN_SEC;
if (curr_time > new_send_time) {
debug_msg("Sent BYE...\n");
rtp_send_bye_now(session);
break;
@@ -3708,8 +3694,7 @@ void rtp_send_bye(struct rtp *session)
/* No, we reconsider... */
session->next_rtcp_send_time = new_send_time;
debug_msg("Reconsidered sending BYE... delay = %f\n",
tv_diff(session->next_rtcp_send_time,
curr_time));
(session->next_rtcp_send_time - curr_time) / (double) NS_IN_SEC);
/* ...and perform housekeeping in the usual manner */
rtp_update(session, curr_time);
}

View File

@@ -46,6 +46,8 @@
#include <stdint.h>
#endif
#include "tv.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -268,8 +270,8 @@ int rtp_send_data_hdr(struct rtp *session,
char *data, int data_len,
char *extn, uint16_t extn_len, uint16_t extn_type);
void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts,
rtcp_app_callback appcallback, struct timeval curr_time);
void rtp_update(struct rtp *session, struct timeval curr_time);
rtcp_app_callback appcallback, time_ns_t curr_time);
void rtp_update(struct rtp *session, time_ns_t curr_time);
uint32_t rtp_my_ssrc(struct rtp *session);
bool rtp_add_csrc(struct rtp *session, uint32_t csrc);

View File

@@ -204,12 +204,10 @@ void rtp_recv_callback(struct rtp *session, rtp_event * e)
rtp_packet *pckt_rtp = (rtp_packet *) e->data;
struct pdb *participants = (struct pdb *)rtp_get_userdata(session);
struct pdb_e *state = pdb_get(participants, e->ssrc);
struct timeval curr_time;
switch (e->type) {
case RX_RTP:
gettimeofday(&curr_time, NULL);
tfrc_recv_data(state->tfrc_state, curr_time, pckt_rtp->seq,
tfrc_recv_data(state->tfrc_state, get_time_in_ns(), pckt_rtp->seq,
pckt_rtp->data_len + 40);
if (pckt_rtp->data_len > 0) { /* Only process packets that contain data... */
pbuf_insert(state->playout_buffer, pckt_rtp);
@@ -237,8 +235,7 @@ void rtp_recv_callback(struct rtp *session, rtp_event * e)
if (strncmp(pckt_app->name, "RTT_", 4) == 0) {
assert(pckt_app->length == 3);
assert(pckt_app->subtype == 0);
gettimeofday(&curr_time, NULL);
// tfrc_recv_rtt(state->tfrc_state, curr_time, ntohl(*((int *) pckt_app->data)));
// tfrc_recv_rtt(state->tfrc_state, get_time_in_ns(), ntohl(*((int *) pckt_app->data)));
}
break;
case RX_BYE:

View File

@@ -71,10 +71,10 @@ struct tfrc {
int ooo;
int cycles; /* number of times seq number cycles 65535 */
uint32_t RTT; /* received from sender in app packet */
struct timeval feedback_timer; /* indicates points in time when p should be computed */
time_ns_t feedback_timer; /* indicates points in time when p should be computed */
double p, p_prev;
int s;
struct timeval start_time;
time_ns_t start_time;
int loss_count;
int interval_count;
int gap[20];
@@ -130,10 +130,10 @@ static double transfer_rate(double p)
static void compute_transfer_rate(void)
{
double t1;
struct timeval now;
time_ns_t now;
t1 = transfer_rate(p);
gettimeofday(&now, NULL);
now = get_time_in_ns()
}
#endif
@@ -245,7 +245,7 @@ record_loss(struct tfrc *state, uint32_t s1, uint32_t s2, uint32_t ts1,
}
static void
save_arrival(struct tfrc *state, struct timeval curr_time, uint16_t seq)
save_arrival(struct tfrc *state, time_ns_t curr_time, uint16_t seq)
{
int kk, inc, last_jj;
uint16_t udelta;
@@ -255,8 +255,8 @@ save_arrival(struct tfrc *state, struct timeval curr_time, uint16_t seq)
static uint32_t ext_last_ack;
static int last_ack_jj = 0;
gettimeofday(&curr_time, NULL);
now = tv_diff_usec(curr_time, state->start_time);
curr_time = get_time_in_ns();
now = (curr_time - state->start_time) / 1000;
if (state->jj == -1) {
/* first packet arrival */
@@ -330,7 +330,6 @@ static double compute_loss_event(struct tfrc *state)
int i;
uint32_t t __attribute__((unused));
uint32_t temp, I_tot0 = 0, I_tot1 = 0, I_tot = 0;
struct timeval now;
double I_mean, p;
if (state->ii < N) {
@@ -352,8 +351,7 @@ static double compute_loss_event(struct tfrc *state)
I_mean = I_tot / state->W_tot;
p = 1 / I_mean;
gettimeofday(&now, NULL);
t = tv_diff_usec(now, state->start_time);
t = (get_time_in_ns() - state->start_time) / 1000;
return p;
@@ -364,7 +362,7 @@ static double compute_loss_event(struct tfrc *state)
*
*/
struct tfrc *tfrc_init(struct timeval curr_time)
struct tfrc *tfrc_init(time_ns_t curr_time)
{
struct tfrc *state;
int i;
@@ -435,7 +433,7 @@ void tfrc_done(struct tfrc *state)
}
void
tfrc_recv_data(struct tfrc *state, struct timeval curr_time, uint16_t seqnum,
tfrc_recv_data(struct tfrc *state, time_ns_t curr_time, uint16_t seqnum,
unsigned length)
{
/* This is called each time an RTP packet is received. Accordingly, */
@@ -459,7 +457,7 @@ tfrc_recv_data(struct tfrc *state, struct timeval curr_time, uint16_t seqnum,
state->s = length; /* packet size is needed transfer_rate */
}
void tfrc_recv_rtt(struct tfrc *state, struct timeval curr_time, uint32_t rtt)
void tfrc_recv_rtt(struct tfrc *state, time_ns_t curr_time, uint32_t rtt)
{
/* Called whenever the receiver gets an RTCP APP packet telling */
/* it the RTT to the sender. Not performance critical. */
@@ -468,25 +466,24 @@ void tfrc_recv_rtt(struct tfrc *state, struct timeval curr_time, uint32_t rtt)
validate_tfrc_state(state);
if (state->RTT == 0) {
state->feedback_timer = curr_time;
tv_add(&(state->feedback_timer), rtt);
state->feedback_timer = curr_time + rtt * NS_IN_SEC;
}
state->RTT = rtt;
}
int tfrc_feedback_is_due(struct tfrc *state, struct timeval curr_time)
int tfrc_feedback_is_due(struct tfrc *state, time_ns_t curr_time)
{
/* Determine if it is time to send feedback to the sender */
validate_tfrc_state(state);
if ((state->RTT == 0) || tv_gt(state->feedback_timer, curr_time)) {
if ((state->RTT == 0) || state->feedback_timer > curr_time) {
/* Not yet time to send feedback to the sender... */
return FALSE;
}
return TRUE;
}
double tfrc_feedback_txrate(struct tfrc *state, struct timeval curr_time)
double tfrc_feedback_txrate(struct tfrc *state, time_ns_t curr_time)
{
/* Calculate the appropriate transmission rate, to be included */
/* in a feedback message to the sender. */
@@ -495,9 +492,7 @@ double tfrc_feedback_txrate(struct tfrc *state, struct timeval curr_time)
assert(tfrc_feedback_is_due(state, curr_time));
state->feedback_timer.tv_sec = curr_time.tv_sec;
state->feedback_timer.tv_usec = curr_time.tv_usec;
tv_add(&(state->feedback_timer), state->RTT);
state->feedback_timer = curr_time + state->RTT * NS_IN_SEC;
state->p = compute_loss_event(state);
//compute_transfer_rate ();
if (state->ii >= N) {

View File

@@ -47,15 +47,17 @@
extern "C" {
#endif
#include "tv.h"
struct tfrc;
struct tfrc *tfrc_init(struct timeval curr_time);
struct tfrc *tfrc_init(time_ns_t curr_time);
void tfrc_done(struct tfrc *state);
void tfrc_recv_data (struct tfrc *state, struct timeval curr_time, uint16_t seqnum, unsigned length);
void tfrc_recv_rtt (struct tfrc *state, struct timeval curr_time, uint32_t rtt);
double tfrc_feedback_txrate(struct tfrc *state, struct timeval curr_time);
int tfrc_feedback_is_due(struct tfrc *state, struct timeval curr_time);
void tfrc_recv_data (struct tfrc *state, time_ns_t curr_time, uint16_t seqnum, unsigned length);
void tfrc_recv_rtt (struct tfrc *state, time_ns_t curr_time, uint32_t rtt);
double tfrc_feedback_txrate(struct tfrc *state, time_ns_t curr_time);
int tfrc_feedback_is_due(struct tfrc *state, time_ns_t curr_time);
#ifdef __cplusplus
}

View File

@@ -894,7 +894,6 @@ void audio_tx_send_standard(struct tx* tx, struct rtp *rtp_session,
int pt;
uint32_t ts;
static uint32_t ts_prev = 0;
struct timeval curr_time;
// Configure the right Payload type,
// 8000 Hz, 1 channel and 2 bps is the ITU-T G.711 standard (should be 1 bps...)
@@ -952,8 +951,7 @@ void audio_tx_send_standard(struct tx* tx, struct rtp *rtp_session,
} else {
ts = get_std_audio_local_mediatime((double) pkt_len / (double) buffer->get_channel_count() / (double) buffer->get_sample_rate(), buffer->get_sample_rate());
}
gettimeofday(&curr_time, NULL);
rtp_send_ctrl(rtp_session, ts_prev, 0, curr_time); //send RTCP SR
rtp_send_ctrl(rtp_session, ts_prev, 0, get_time_in_ns()); //send RTCP SR
ts_prev = ts;
// Send the packet
rtp_send_data(rtp_session, ts, pt, 0, 0, /* contributing sources */

View File

@@ -51,8 +51,6 @@
#include "crypto/random.h"
#include "tv.h"
#define MS_IN_SEC 1000000LL
uint32_t get_local_mediatime(void)
{
static struct timeval start_time;

View File

@@ -68,7 +68,9 @@ uint32_t get_std_audio_local_mediatime(double samples, int rate);
uint32_t get_std_video_local_mediatime(void);
typedef long long time_ns_t;
#define MS_IN_SEC 1000000LL
#define NS_IN_SEC 1000000000LL
#define NS_IN_MS (NS_IN_SEC/MS_IN_SEC)
static inline time_ns_t get_time_in_ns() {
struct timespec ts = { 0, 0 };
timespec_get(&ts, TIME_UTC);

View File

@@ -292,10 +292,8 @@ vidcap_rtsp_thread(void *arg) {
struct video_frame *frame = vf_alloc_desc_data(s->vrtsp_state.desc);
while (!s->should_exit) {
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
time_ns_t time_ns = get_time_in_ns();
uint32_t timestamp = (time_ns - start_time) / 100'000 * 9; // at 90000 Hz
time_ns_t curr_time = get_time_in_ns();
uint32_t timestamp = (curr_time - start_time) / 100'000 * 9; // at 90000 Hz
rtp_update(s->vrtsp_state.device, curr_time);
@@ -312,7 +310,7 @@ vidcap_rtsp_thread(void *arg) {
d.frame = frame;
d.offset_len = s->vrtsp_state.h264_offset_len;
d.video_pt = s->vrtsp_state.pt;
if (pbuf_decode(cp->playout_buffer, time_ns,
if (pbuf_decode(cp->playout_buffer, curr_time,
decode_frame_by_pt, &d))
{
pthread_mutex_lock(&s->vrtsp_state.lock);
@@ -331,7 +329,7 @@ vidcap_rtsp_thread(void *arg) {
pthread_mutex_unlock(&s->vrtsp_state.lock);
}
}
pbuf_remove(cp->playout_buffer, time_ns);
pbuf_remove(cp->playout_buffer, curr_time);
cp = pdb_iter_next(&it);
}

View File

@@ -91,9 +91,8 @@ void h264_rtp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
}
}
if ((m_rxtx_mode & MODE_RECEIVER) == 0) { // send RTCP (receiver thread would otherwise do this
uint32_t ts = (get_time_in_ns() - m_start_time) / 100'000 * 9; // at 90000 Hz
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
uint32_t ts = (curr_time - m_start_time) / 100'000 * 9; // at 90000 Hz
rtp_update(m_network_devices[0], curr_time);
rtp_send_ctrl(m_network_devices[0], ts, 0, curr_time);

View File

@@ -218,9 +218,8 @@ void h264_sdp_video_rxtx::send_frame(shared_ptr<video_frame> tx_frame)
}
}
if ((m_rxtx_mode & MODE_RECEIVER) == 0) { // send RTCP (receiver thread would otherwise do this
struct timeval curr_time;
uint32_t ts = get_std_video_local_mediatime();
gettimeofday(&curr_time, NULL);
time_ns_t curr_time = get_time_in_ns();
rtp_update(m_network_devices[0], curr_time);
rtp_send_ctrl(m_network_devices[0], ts, 0, curr_time);

View File

@@ -171,9 +171,8 @@ void ultragrid_rtp_video_rxtx::send_frame_async(shared_ptr<video_frame> tx_frame
}
if ((m_rxtx_mode & MODE_RECEIVER) == 0) { // otherwise receiver thread does the stuff...
struct timeval curr_time;
gettimeofday(&curr_time, NULL);
uint32_t ts = (get_time_in_ns() - m_start_time) / 100'000 * 9; // at 90000 Hz
time_ns_t curr_time = get_time_in_ns();
uint32_t ts = (curr_time - m_start_time) / 100'000 * 9; // at 90000 Hz
rtp_update(m_network_devices[0], curr_time);
rtp_send_ctrl(m_network_devices[0], ts, 0, curr_time);
@@ -296,11 +295,10 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
{
set_thread_name(__func__);
struct pdb_e *cp;
struct timeval curr_time;
int fr;
int ret;
int tiles_post = 0;
struct timeval last_tile_received = {0, 0};
time_ns_t last_tile_received = 0;
int last_buf_size = INITIAL_VIDEO_RECV_BUFFER_SIZE;
#ifdef SHARED_DECODER
@@ -319,9 +317,8 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
while (!should_exit) {
struct timeval timeout;
/* Housekeeping and RTCP... */
gettimeofday(&curr_time, NULL);
time_ns_t time_ns = get_time_in_ns();
uint32_t ts = (m_start_time - time_ns) / 100'000 * 9; // at 90000 Hz
time_ns_t curr_time = get_time_in_ns();
uint32_t ts = (m_start_time - curr_time) / 100'000 * 9; // at 90000 Hz
rtp_update(m_network_devices[0], curr_time);
rtp_send_ctrl(m_network_devices[0], ts, 0, curr_time);
@@ -329,7 +326,7 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
/* Receive packets from the network... The timeout is adjusted */
/* to match the video capture rate, so the transmitter works. */
if (fr) {
gettimeofday(&curr_time, NULL);
curr_time = get_time_in_ns();
receiver_process_messages();
fr = 0;
}
@@ -337,7 +334,7 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
timeout.tv_sec = 0;
//timeout.tv_usec = 999999 / 59.94;
// use longer timeout when we are not receivng any data
if ((last_not_timeout - time_ns) > NS_IN_SEC) {
if ((last_not_timeout - curr_time) > NS_IN_SEC) {
timeout.tv_usec = 100000;
} else {
timeout.tv_usec = 1000;
@@ -350,7 +347,7 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
receiver_process_messages();
//printf("Failed to receive data\n");
} else {
last_not_timeout = time_ns;
last_not_timeout = curr_time;
}
/* Decode and render for each participant in the conference... */
@@ -404,13 +401,13 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
/* Decode and render video... */
if (pbuf_decode
(cp->playout_buffer, time_ns, decode_video_frame, vdecoder_state)) {
(cp->playout_buffer, curr_time, decode_video_frame, vdecoder_state)) {
tiles_post++;
/* we have data from all connections we need */
if(tiles_post == m_connections_count)
{
tiles_post = 0;
gettimeofday(&curr_time, NULL);
curr_time = get_time_in_ns();
fr = 1;
#if 0
display_put_frame(uv->display_device,
@@ -423,10 +420,10 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
}
/* dual-link TIMEOUT - we won't wait for next tiles */
if(tiles_post > 1 && tv_diff(curr_time, last_tile_received) >
if(tiles_post > 1 && (last_tile_received - curr_time) / (double) NS_IN_SEC >
999999 / 59.94 / m_connections_count) {
tiles_post = 0;
gettimeofday(&curr_time, NULL);
curr_time = get_time_in_ns();
fr = 1;
#if 0
display_put_frame(uv->display_device,
@@ -453,7 +450,7 @@ void *ultragrid_rtp_video_rxtx::receiver_loop()
}
}
pbuf_remove(cp->playout_buffer, time_ns);
pbuf_remove(cp->playout_buffer, curr_time);
cp = pdb_iter_next(&it);
}
pdb_iter_done(&it);