Move initial delay when using a new bus master to rtp.c and wait, if possible, whenever a new master comes along, to allow it to settle before using it.
This commit is contained in:
@@ -51,7 +51,8 @@ typedef enum {
|
||||
clock_no_master,
|
||||
clock_version_mismatch,
|
||||
clock_not_synchronised,
|
||||
clock_not_valid
|
||||
clock_not_valid,
|
||||
clock_not_ready,
|
||||
} clock_status_t;
|
||||
|
||||
typedef uint16_t seq_t;
|
||||
|
||||
+7
-14
@@ -60,7 +60,7 @@ int get_nqptp_data(struct shm_structure *nqptp_data) {
|
||||
return response;
|
||||
}
|
||||
|
||||
int ptp_get_clock_info(uint64_t *actual_clock_id, uint64_t *raw_offset) {
|
||||
int ptp_get_clock_info(uint64_t *actual_clock_id, uint64_t *raw_offset, uint64_t *mastership_start_time) {
|
||||
int response = clock_ok;
|
||||
pthread_cleanup_debug_mutex_lock(&ptp_access_mutex, 10000, 1);
|
||||
if (actual_clock_id != NULL)
|
||||
@@ -74,19 +74,12 @@ int ptp_get_clock_info(uint64_t *actual_clock_id, uint64_t *raw_offset) {
|
||||
if (nqptp_data.version == NQPTP_SHM_STRUCTURES_VERSION) {
|
||||
// assuming a clock id can not be zero
|
||||
if (nqptp_data.master_clock_id != 0) {
|
||||
// find out how long it's been since it became master
|
||||
uint64_t time_now = get_absolute_time_in_ns();
|
||||
int64_t time_of_mastership = time_now - nqptp_data.master_clock_start_time;
|
||||
// if (0) {
|
||||
if (time_of_mastership < 700000000) {
|
||||
// should get between 3 and 4 pings in this time -- less likely to get a bad start
|
||||
response = clock_no_master; // not ready yet
|
||||
} else {
|
||||
if (actual_clock_id != NULL)
|
||||
*actual_clock_id = nqptp_data.master_clock_id;
|
||||
if (raw_offset != NULL)
|
||||
*raw_offset = nqptp_data.local_to_master_time_offset;
|
||||
}
|
||||
if (actual_clock_id != NULL)
|
||||
*actual_clock_id = nqptp_data.master_clock_id;
|
||||
if (raw_offset != NULL)
|
||||
*raw_offset = nqptp_data.local_to_master_time_offset;
|
||||
if (mastership_start_time != NULL)
|
||||
*mastership_start_time = nqptp_data.master_clock_start_time;
|
||||
} else {
|
||||
response = clock_no_master;
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
int ptp_get_clock_info(uint64_t *clock_id, uint64_t *offset);
|
||||
int ptp_get_clock_info(uint64_t *actual_clock_id, uint64_t *raw_offset, uint64_t *mastership_start_time);
|
||||
|
||||
void ptp_send_control_message_string(const char *msg);
|
||||
|
||||
|
||||
@@ -1210,7 +1210,7 @@ void rtp_request_resend(seq_t first, uint32_t count, rtsp_conn_info *conn) {
|
||||
void set_ptp_anchor_info(rtsp_conn_info *conn, uint64_t clock_id, uint32_t rtptime,
|
||||
uint64_t networktime) {
|
||||
if (conn->anchor_clock != clock_id) {
|
||||
debug(1, "Connection %d: Set Anchor Clock: %" PRIx64 ".", conn->connection_number, clock_id);
|
||||
debug(2, "Connection %d: Set Anchor Clock: %" PRIx64 ".", conn->connection_number, clock_id);
|
||||
conn->anchor_clock_is_new = 1;
|
||||
}
|
||||
conn->anchor_remote_info_is_valid = 1;
|
||||
@@ -1227,22 +1227,34 @@ void reset_ptp_anchor_info(rtsp_conn_info *conn) {
|
||||
|
||||
int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
|
||||
uint64_t *anchorLocalTime) {
|
||||
uint64_t actual_clock_id, actual_offset;
|
||||
int response = ptp_get_clock_info(&actual_clock_id, &actual_offset);
|
||||
uint64_t actual_clock_id, actual_offset, start_of_mastership;
|
||||
int response = ptp_get_clock_info(&actual_clock_id, &actual_offset, &start_of_mastership);
|
||||
|
||||
if (response == clock_ok) {
|
||||
if (conn->anchor_remote_info_is_valid !=
|
||||
0) { // i.e. if we have anchor clock ID and anchor time / rtptime
|
||||
// figure out how long the clock has been master
|
||||
uint64_t time_now = get_absolute_time_in_ns();
|
||||
int64_t duration_of_mastership = time_now - start_of_mastership;
|
||||
// if we have an alternative, i.e. if last anchor stuff is valid
|
||||
// then we can wait for a long time to let the new master settle
|
||||
// if we do not, we can wait for some different (shorter) time before
|
||||
// using the master clock timing
|
||||
|
||||
if (actual_clock_id == conn->anchor_clock) {
|
||||
// if the master clock and the anchor clock are the same
|
||||
conn->last_anchor_clock = conn->anchor_clock;
|
||||
conn->last_anchor_rtptime = conn->anchor_rtptime;
|
||||
conn->last_anchor_local_time = conn->anchor_time - actual_offset;
|
||||
conn->last_anchor_time_of_update = get_absolute_time_in_ns();
|
||||
conn->last_anchor_info_is_valid = 1;
|
||||
if (conn->anchor_clock_is_new != 0)
|
||||
debug(1,"new anchor recognised");
|
||||
conn->anchor_clock_is_new = 0;
|
||||
if (duration_of_mastership < 700000000) {
|
||||
response = clock_not_ready;
|
||||
} else if ((duration_of_mastership > 5000000000) || (conn->last_anchor_info_is_valid == 0)) {
|
||||
conn->last_anchor_clock = conn->anchor_clock;
|
||||
conn->last_anchor_rtptime = conn->anchor_rtptime;
|
||||
conn->last_anchor_local_time = conn->anchor_time - actual_offset;
|
||||
conn->last_anchor_time_of_update = get_absolute_time_in_ns();
|
||||
conn->last_anchor_info_is_valid = 1;
|
||||
if (conn->anchor_clock_is_new != 0)
|
||||
debug(1,"Connection %d: New anchor clock %" PRIx64 " recognised.", conn->connection_number, conn->anchor_clock);
|
||||
conn->anchor_clock_is_new = 0;
|
||||
}
|
||||
} else {
|
||||
// the anchor clock and the actual clock are different
|
||||
// this could happen because
|
||||
@@ -1251,13 +1263,13 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
|
||||
|
||||
// so, if the anchor has not changed, it must be that the master clock has changed
|
||||
if (conn->anchor_clock_is_new != 0)
|
||||
debug(1,"anchor has changed");
|
||||
debug(1,"Connection %d: Anchor clock has changed to %" PRIx64 ", master clock is: %" PRIx64 ".", conn->connection_number, conn->anchor_clock, actual_clock_id);
|
||||
|
||||
if ((conn->last_anchor_info_is_valid != 0) && (conn->anchor_clock_is_new == 0)) {
|
||||
int64_t time_since_last_update =
|
||||
get_absolute_time_in_ns() - conn->last_anchor_time_of_update;
|
||||
if (time_since_last_update > 5000000000) {
|
||||
debug(1, "change master clock to %" PRIx64 ".", actual_clock_id);
|
||||
debug(1, "Connection %d: Master clock has changed to %" PRIx64 ".", conn->connection_number, actual_clock_id);
|
||||
// here we adjust the time of the anchor rtptime
|
||||
// we know its local time, so we use the new clocks's offset to
|
||||
// calculate what time that must be on the new clock
|
||||
@@ -1277,9 +1289,12 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
|
||||
if ((clock_status_t)response != conn->clock_status) {
|
||||
switch (response) {
|
||||
case clock_ok:
|
||||
debug(1, "Connection %d: NQPTP new master clock % " PRIx64 ".", conn->connection_number,
|
||||
debug(2, "Connection %d: NQPTP new master clock %" PRIx64 ".", conn->connection_number,
|
||||
actual_clock_id);
|
||||
break;
|
||||
case clock_not_ready:
|
||||
debug(2, "Connection %d: NQPTP master clock %" PRIx64 " is available but not ready.", conn->connection_number, actual_clock_id);
|
||||
break;
|
||||
case clock_service_unavailable:
|
||||
debug(1, "Connection %d: NQPTP clock is not available.", conn->connection_number);
|
||||
warn("Can't access the NQPTP clock. Is NQPTP running?");
|
||||
|
||||
Reference in New Issue
Block a user