Only request a resend one time, after about a second. Stop making resend requests if there is a send-to error for 10 seconds.
This commit is contained in:
@@ -142,7 +142,6 @@ int64_t monotonic_timestamp(uint32_t timestamp, rtsp_conn_info *conn) {
|
||||
conn->timestamp_epoch--;
|
||||
}
|
||||
}
|
||||
conn->last_timestamp = timestamp;
|
||||
return_value = conn->timestamp_epoch;
|
||||
return_value <<= 32;
|
||||
return_value += timestamp;
|
||||
@@ -155,6 +154,7 @@ int64_t monotonic_timestamp(uint32_t timestamp, rtsp_conn_info *conn) {
|
||||
}
|
||||
if (return_value < 0)
|
||||
debug(1, "monotonic rtptime is negative!");
|
||||
conn->last_timestamp = timestamp;
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@@ -870,8 +870,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
if (local_time_now >= conn->first_packet_time_to_play) {
|
||||
debug(
|
||||
1,
|
||||
"First packet is late! It should have played before now. Flushing 0.1 seconds");
|
||||
player_flush(conn->first_packet_timestamp + 4410 * conn->output_sample_ratio, conn);
|
||||
"First packet is late! It should have played before now. Flushing 0.5 seconds");
|
||||
player_flush(conn->first_packet_timestamp + 5 * 4410 * conn->output_sample_ratio, conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1155,7 +1155,11 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
// packets have arrived... last-chance resend
|
||||
|
||||
if (!conn->ab_buffering) {
|
||||
for (i = 64; i < (seq_diff(conn->ab_read, conn->ab_write, conn->ab_read) / 2); i = (i * 2)) {
|
||||
// check at half second intervals
|
||||
// for (i = 500000/7982 ; i < (seq_diff(conn->ab_read, conn->ab_write, conn->ab_read)); i += 500000/7982) {
|
||||
// check once, after a second has elapsed, assuming 352 frames per packet
|
||||
i = 44100/352;
|
||||
if (i<seq_diff(conn->ab_read, conn->ab_write, conn->ab_read)) {
|
||||
seq_t next = seq_sum(conn->ab_read, i);
|
||||
abuf = conn->audio_buffer + BUFIDX(next);
|
||||
if (!abuf->ready) {
|
||||
@@ -1420,7 +1424,7 @@ static void *player_thread_func(void *arg) {
|
||||
|
||||
conn->timestamp_epoch = 0; // indicate that the next timestamp will be the first one.
|
||||
conn->maximum_timestamp_interval =
|
||||
conn->input_rate * 60; // actually there shouldn't be more than about 13v
|
||||
conn->input_rate * 60; // actually there shouldn't be more than about 13
|
||||
// seconds of a gap between successive rtptimes, at
|
||||
// worst
|
||||
|
||||
@@ -1429,7 +1433,7 @@ static void *player_thread_func(void *arg) {
|
||||
// debug(1, "Output sample ratio is %d.", conn->output_sample_ratio);
|
||||
|
||||
conn->max_frame_size_change =
|
||||
500 * conn->output_sample_ratio; // we add or subtract one frame at the nominal
|
||||
1 * conn->output_sample_ratio; // we add or subtract one frame at the nominal
|
||||
// rate, multiply it by the frame ratio.
|
||||
// but, on some occasions, more than one frame could be added
|
||||
|
||||
|
||||
@@ -129,6 +129,8 @@ typedef struct {
|
||||
// RTP stuff
|
||||
// only one RTP session can be active at a time.
|
||||
int rtp_running;
|
||||
uint64_t rtp_time_of_last_resend_request_error_fp;
|
||||
|
||||
|
||||
char client_ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client
|
||||
char self_ip_string[INET6_ADDRSTRLEN]; // the ip string being used by this program -- it
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
void memory_barrier();
|
||||
|
||||
void rtp_initialise(rtsp_conn_info *conn) {
|
||||
|
||||
conn->rtp_time_of_last_resend_request_error_fp = 0;
|
||||
conn->rtp_running = 0;
|
||||
// initialise the timer mutex
|
||||
int rc = pthread_mutex_init(&conn->reference_time_mutex, NULL);
|
||||
@@ -131,7 +131,7 @@ void *rtp_audio_receiver(void *arg) {
|
||||
pktp += 4;
|
||||
plen -= 4;
|
||||
}
|
||||
seq_t seqno = ntohs(*(unsigned short *)(pktp + 2));
|
||||
seq_t seqno = ntohs(*(uint16_t *)(pktp + 2));
|
||||
// increment last_seqno and see if it's the same as the incoming seqno
|
||||
|
||||
if (last_seqno == -1)
|
||||
@@ -142,7 +142,7 @@ void *rtp_audio_receiver(void *arg) {
|
||||
// debug(3, "RTP: Packets out of sequence: expected: %d, got %d.", last_seqno, seqno);
|
||||
last_seqno = seqno; // reset warning...
|
||||
}
|
||||
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)), conn);
|
||||
int64_t timestamp = monotonic_timestamp(ntohl(*(uint32_t*)(pktp + 4)), conn);
|
||||
|
||||
// if (packet[1]&0x10)
|
||||
// debug(1,"Audio packet Extension bit set.");
|
||||
@@ -224,6 +224,8 @@ void *rtp_control_receiver(void *arg) {
|
||||
// debug(1,"Remote Sync Time: %0llx.",remote_time_of_sync);
|
||||
|
||||
sync_rtp_timestamp = monotonic_timestamp(ntohl(*((uint32_t *)&packet[16])), conn);
|
||||
|
||||
debug(1,"Sync timestamp is %u.",ntohl(*((uint32_t *)&packet[16])));
|
||||
|
||||
if (config.userSuppliedLatency) {
|
||||
if (config.userSuppliedLatency != conn->latency) {
|
||||
@@ -232,6 +234,7 @@ void *rtp_control_receiver(void *arg) {
|
||||
conn->latency = config.userSuppliedLatency;
|
||||
} else if (packet[0] &
|
||||
0x10) { // only set latency if it's a packet just after a flush or resume
|
||||
debug(1,"Set latency");
|
||||
int64_t rtp_timestamp_less_latency =
|
||||
monotonic_timestamp(ntohl(*((uint32_t *)&packet[4])), conn);
|
||||
int64_t la = sync_rtp_timestamp - rtp_timestamp_less_latency + config.fixedLatencyOffset;
|
||||
@@ -277,12 +280,12 @@ void *rtp_control_receiver(void *arg) {
|
||||
debug(1, "Sync packet received before we got a timing packet back.");
|
||||
}
|
||||
} else if (packet[1] == 0xd6) { // resent audio data in the control path -- whaale only?
|
||||
// debug(1, "Control Port -- Retransmitted Audio Data Packet received.");
|
||||
debug(1, "Control Port -- Retransmitted Audio Data Packet received.");
|
||||
pktp = packet + 4;
|
||||
plen -= 4;
|
||||
seq_t seqno = ntohs(*(unsigned short *)(pktp + 2));
|
||||
seq_t seqno = ntohs(*(uint16_t*)(pktp + 2));
|
||||
|
||||
int64_t timestamp = monotonic_timestamp(ntohl(*(unsigned long *)(pktp + 4)), conn);
|
||||
int64_t timestamp = monotonic_timestamp(ntohl(*(uint32_t*)(pktp + 4)), conn);
|
||||
|
||||
pktp += 12;
|
||||
plen -= 12;
|
||||
@@ -446,9 +449,12 @@ void *rtp_timing_receiver(void *arg) {
|
||||
return_time = arrival_time - conn->departure_time;
|
||||
|
||||
uint64_t rtus = (return_time * 1000000) >> 32;
|
||||
|
||||
|
||||
if (rtus < 300000) {
|
||||
|
||||
// debug(2,"Synchronisation ping return time is %f milliseconds.",(rtus*1.0)/1000);
|
||||
|
||||
// distant_receive_time =
|
||||
// ((uint64_t)ntohl(*((uint32_t*)&packet[16])))<<32+ntohl(*((uint32_t*)&packet[20]));
|
||||
|
||||
@@ -829,11 +835,18 @@ void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) {
|
||||
msgsize = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#endif
|
||||
if (sendto(conn->audio_socket, req, sizeof(req), 0,
|
||||
(struct sockaddr *)&conn->rtp_client_control_socket, msgsize) == -1) {
|
||||
char em[1024];
|
||||
strerror_r(errno, em, sizeof(em));
|
||||
debug(1, "Error %d using send-to to an audio socket: \"%s\".", errno, em);
|
||||
uint64_t time_of_sending_fp = get_absolute_time_in_fp();
|
||||
uint64_t resend_error_backoff_time = (uint64_t)10<<32; // ten seconds
|
||||
if ((conn->rtp_time_of_last_resend_request_error_fp) || ((time_of_sending_fp-conn->rtp_time_of_last_resend_request_error_fp)>resend_error_backoff_time)) {
|
||||
if (sendto(conn->audio_socket, req, sizeof(req), 0,
|
||||
(struct sockaddr *)&conn->rtp_client_control_socket, msgsize) == -1) {
|
||||
char em[1024];
|
||||
strerror_r(errno, em, sizeof(em));
|
||||
debug(1, "Error %d using send-to to an audio socket: \"%s\". ", errno, em);
|
||||
conn->rtp_time_of_last_resend_request_error_fp = time_of_sending_fp;
|
||||
} else {
|
||||
conn->rtp_time_of_last_resend_request_error_fp=0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if (!request_sent) {
|
||||
|
||||
Reference in New Issue
Block a user