summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--player.c5
-rw-r--r--player.h3
-rw-r--r--rtp.c21
3 files changed, 19 insertions, 10 deletions
diff --git a/player.c b/player.c
index 595c1fd..f2e1a7f 100644
--- a/player.c
+++ b/player.c
@@ -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 */
diff --git a/player.h b/player.h
index 5402a18..a7d961a 100644
--- a/player.h
+++ b/player.h
@@ -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
diff --git a/rtp.c b/rtp.c
index df71f41..96bb0fc 100644
--- a/rtp.c
+++ b/rtp.c
@@ -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;