diff options
-rw-r--r-- | player.c | 5 | ||||
-rw-r--r-- | player.h | 3 | ||||
-rw-r--r-- | rtp.c | 21 |
3 files changed, 19 insertions, 10 deletions
@@ -2416,7 +2416,8 @@ void *player_thread_func(void *arg) { "%*d," /* max buffer occupancy */ "%*.2f," /* input frame rate */ "%*.2f," /* output frame rate */ - "%*.2f", /* client clock to local clock drift in ppm */ + "%*.2f," /* output frame rate */ + "%*d", /* sample count */ 10, 1000 * moving_average_sync_error / config.output_rate, 10, moving_average_correction * 1000000 / (352 * conn->output_sample_ratio), @@ -2425,7 +2426,7 @@ void *player_thread_func(void *arg) { 12, play_number, 7, conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets, 7, conn->resend_requests, 7, minimum_dac_queue_size, 5, minimum_buffer_occupancy, 5, - maximum_buffer_occupancy, 11, conn->input_frame_rate, 11, conn->frame_rate , 10, (1.0-conn->local_to_remote_time_gradient)*1000000); + maximum_buffer_occupancy, 11, conn->input_frame_rate, 11, conn->frame_rate , 10, (1.0-conn->local_to_remote_time_gradient)*1000000, 6, conn->local_to_remote_time_gradient_sample_count); } else { inform("%*.2f," /* Sync error in milliseconds */ "%*d," /* total packets */ @@ -24,7 +24,7 @@ #include "alac.h" #include "audio.h" -#define time_ping_history 32 +#define time_ping_history 64 // at 1 per three seconds, approximately three minutes of records typedef struct time_ping_record { uint64_t local_to_remote_difference; @@ -207,6 +207,7 @@ typedef struct { pthread_mutex_t reference_time_mutex; double local_to_remote_time_gradient; // if no drift, this would be exactly 1.0; likely it's slightly above or below. + int local_to_remote_time_gradient_sample_count; // the number of samples used to calculate the gradient uint64_t local_to_remote_time_difference; // used to switch between local and remote clocks uint64_t local_to_remote_time_difference_measurement_time; // when the above was calculated @@ -702,9 +702,12 @@ void *rtp_timing_receiver(void *arg) { uint64_t x_bar = 0; // local timestamp average int sample_count = 0; - + // approximate time in seconds to let the system settle down + const int settling_time = 60; + // number of points to have for calculating a valid drift + const int sample_point_minimum = 8; for (cc = 0; cc < conn->time_ping_count; cc++) - if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>9)) { // wait for a minute or so.... + if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>(settling_time/3))) { // wait for a approximate settling time y_bar += (conn->time_pings[cc].remote_time>>12); //precision is down to 1/4th of a microsecond x_bar += (conn->time_pings[cc].local_time>>12); sample_count++; @@ -717,7 +720,7 @@ void *rtp_timing_receiver(void *arg) { int64_t mtl, mbl; mtl=0;mbl=0; for (cc = 0; cc < conn->time_ping_count; cc++) - if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>9)) { + if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>(settling_time/3))) { uint64_t slt = conn->time_pings[cc].local_time>>12; if (slt > x_bar) @@ -734,8 +737,9 @@ void *rtp_timing_receiver(void *arg) { mtl = mtl + xid*yid; mbl = mbl + xid*xid; } - if (sample_count > 2) { - conn->local_to_remote_time_gradient = (1.0*mtl)/mbl; + conn->local_to_remote_time_gradient_sample_count = sample_count; + if (sample_count > sample_point_minimum) { + conn->local_to_remote_time_gradient = (1.0*mtl)/mbl; // debug(1,"Drift is %12.2f ppm, based on %d samples.",(1.0-conn->local_to_remote_time_gradient)*1000000,sample_count); } else { conn->local_to_remote_time_gradient = 1.0; @@ -971,13 +975,16 @@ int have_timestamp_timing_information(rtsp_conn_info *conn) { return 1; } +// set this to zero to use the rates supplied by the sources, which might not always be completely right... +const int use_nominal_rate = 1; // specify whether to use the nominal input rate, usually 44100 fps + int sanitised_source_rate_information(int64_t *frames, uint64_t *time, rtsp_conn_info *conn) { int result = 0; - *frames = conn->input_rate; + *frames = conn->input_rate; *time = (uint64_t)(0x100000000); // one second in fp form int64_t local_frames = conn->reference_to_previous_frame_difference; uint64_t local_time = conn->reference_to_previous_time_difference; - if ((local_frames == 0) || (local_time == 0)) { + if ((local_frames == 0) || (local_time == 0) || (use_nominal_rate)) { result = 1; } else { double calculated_frame_rate = ((1.0*local_frames)/local_time)*(uint64_t)0x100000000; |