1 /*
2  * The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) implementation with additional features.
3  * Copyright (C) 2017 Belledonne Communications SARL
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 /***************************************************************************
20  *            jitterctl.c
21  *
22  *  Mon Nov  8 11:53:21 2004
23  *  Copyright  2004  Simon MORLAT
24  *  Email simon.morlat@linphone.org
25  ****************************************************************************/
26 
27 #include "ortp/rtpsession.h"
28 #include "ortp/payloadtype.h"
29 #include "ortp/ortp.h"
30 #include "utils.h"
31 #include "rtpsession_priv.h"
32 #include <math.h>
33 
34 #define JC_BETA .01
35 #define JC_GAMMA (JC_BETA)
36 
37 #include "jitterctl.h"
38 
jitter_control_init(JitterControl * ctl,PayloadType * payload)39 void jitter_control_init(JitterControl *ctl, PayloadType *payload){
40 	ctl->count=0;
41 	ctl->clock_offset_ts=0;
42 	ctl->prev_clock_offset_ts=0;
43 	ctl->jitter=0;
44 	ctl->inter_jitter=0;
45 	ctl->cum_jitter_buffer_count=0;
46 	ctl->cum_jitter_buffer_size=0;
47 	ctl->corrective_slide=0;
48 
49 	ctl->clock_rate=8000;
50 	ctl->adapt_refresh_prev_ts=0;
51 
52 	if (payload!=NULL){
53 		jitter_control_set_payload(ctl,payload);
54 	}
55 }
56 
57 
jitter_control_enable_adaptive(JitterControl * ctl,bool_t val)58 void jitter_control_enable_adaptive(JitterControl *ctl, bool_t val){
59 	ctl->params.adaptive=val;
60 }
61 
jitter_control_set_payload(JitterControl * ctl,PayloadType * pt)62 void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt){
63 	ctl->jitt_comp_ts =
64 			(int) (((double) ctl->params.nom_size / 1000.0) * (pt->clock_rate));
65 	/*make correction by not less than 10ms */
66 	ctl->corrective_step=(int) (0.01 * (float)pt->clock_rate);
67 	ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts;
68 	ctl->clock_rate=pt->clock_rate;
69 }
70 
71 
jitter_control_dump_stats(JitterControl * ctl)72 void jitter_control_dump_stats(JitterControl *ctl){
73 	ortp_message("JitterControl:\n\tslide=%g,jitter=%g,adapt_jitt_comp_ts=%i,corrective_slide=%i, count=%i",
74 			(double)ctl->clock_offset_ts,ctl->jitter, ctl->adapt_jitt_comp_ts, ctl->corrective_slide,ctl->count);
75 }
76 
77 /*the goal of this method is to compute "corrective_slide": a timestamp unit'd value to be added
78  to recv timestamp to make them reflect the instant they are delivered by the jitter buffer. */
jitter_control_update_corrective_slide(JitterControl * ctl)79 void jitter_control_update_corrective_slide(JitterControl *ctl){
80 	int tmp;
81 	tmp=(int)(ctl->clock_offset_ts-ctl->prev_clock_offset_ts);
82 	if (tmp>ctl->corrective_step) {
83 		ctl->corrective_slide+=ctl->corrective_step;
84 		ctl->prev_clock_offset_ts=ctl->clock_offset_ts+ctl->corrective_step;
85 	}
86 	else if (tmp<-ctl->corrective_step) {
87 		ctl->corrective_slide-=ctl->corrective_step;
88 		ctl->prev_clock_offset_ts=ctl->clock_offset_ts-ctl->corrective_step;
89 	}
90 }
91 
jitter_control_update_size(JitterControl * ctl,queue_t * q)92 void jitter_control_update_size(JitterControl *ctl, queue_t *q){
93 	mblk_t *newest=qlast(q);
94 	mblk_t *oldest=qbegin(q);
95 	uint32_t newest_ts,oldest_ts;
96 	if (newest==NULL) return;
97 	newest_ts=rtp_get_timestamp(newest);
98 	oldest_ts=rtp_get_timestamp(oldest);
99 	ctl->cum_jitter_buffer_count++;
100 	ctl->cum_jitter_buffer_size+=(uint32_t)(newest_ts-oldest_ts);
101 }
102 
jitter_control_compute_mean_size(JitterControl * ctl)103 float jitter_control_compute_mean_size(JitterControl *ctl){
104 	if (ctl->cum_jitter_buffer_count!=0){
105 		double tmp=((double)ctl->cum_jitter_buffer_size)/(double)ctl->cum_jitter_buffer_count;
106 		ctl->cum_jitter_buffer_size=0;
107 		ctl->cum_jitter_buffer_count=0;
108 		ctl->jitter_buffer_mean_size = 1000.0f*(float)tmp/(float)ctl->clock_rate;
109 		return ctl->jitter_buffer_mean_size;
110 	}
111 	return 0;
112 }
113 
rtp_session_init_jitter_buffer(RtpSession * session)114 void rtp_session_init_jitter_buffer(RtpSession *session){
115 	PayloadType *payload=NULL;
116 
117 	if (session->rcv.pt!=-1) {
118 		payload = rtp_profile_get_payload (session->rcv.profile,session->rcv.pt);
119 	}/*else not set yet */
120 	jitter_control_init(&session->rtp.jittctl,payload);
121 }
122 
123 /**
124  *@param session: a RtpSession
125  *@param milisec: the time interval in milisec to be jitter compensed.
126  *
127  * Sets the time interval for which packet are buffered instead of being delivered to the
128  * application.
129  **/
130 void
rtp_session_set_jitter_compensation(RtpSession * session,int milisec)131 rtp_session_set_jitter_compensation (RtpSession * session, int milisec)
132 {
133 	session->rtp.jittctl.params.min_size = session->rtp.jittctl.params.nom_size = milisec;
134 	rtp_session_init_jitter_buffer(session);
135 }
136 
rtp_session_enable_adaptive_jitter_compensation(RtpSession * session,bool_t val)137 void rtp_session_enable_adaptive_jitter_compensation(RtpSession *session, bool_t val){
138 	jitter_control_enable_adaptive(&session->rtp.jittctl,val);
139 }
140 
rtp_session_adaptive_jitter_compensation_enabled(RtpSession * session)141 bool_t rtp_session_adaptive_jitter_compensation_enabled(RtpSession *session){
142 	return session->rtp.jittctl.params.adaptive;
143 }
144 
rtp_session_enable_jitter_buffer(RtpSession * session,bool_t enabled)145 void rtp_session_enable_jitter_buffer(RtpSession *session, bool_t enabled){
146 	session->rtp.jittctl.params.enabled = enabled;
147 	session->flags|=RTP_SESSION_RECV_SYNC;
148 }
149 
rtp_session_jitter_buffer_enabled(const RtpSession * session)150 bool_t rtp_session_jitter_buffer_enabled(const RtpSession *session){
151 	return session->rtp.jittctl.params.enabled;
152 }
153 
rtp_session_set_jitter_buffer_params(RtpSession * session,const JBParameters * par)154 void rtp_session_set_jitter_buffer_params(RtpSession *session, const JBParameters *par){
155 	if (par == &session->rtp.jittctl.params) return;
156 	memcpy(&session->rtp.jittctl.params, par, sizeof (JBParameters));
157 	rtp_session_init_jitter_buffer(session);
158 }
159 
rtp_session_get_jitter_buffer_params(RtpSession * session,JBParameters * par)160 void rtp_session_get_jitter_buffer_params(RtpSession *session, JBParameters *par){
161 	memcpy(par, &session->rtp.jittctl.params, sizeof(JBParameters));
162 }
163 
164 
165 /*
166  The algorithm computes two values:
167 	slide: an average of difference between the expected and the socket-received timestamp
168 	jitter: an average of the absolute value of the difference between socket-received timestamp and slide.
169 	slide is used to make clock-slide detection and correction.
170 	jitter is added to the initial jitt_comp_time value. It compensates bursty packets arrival (packets
171 	not arriving at regular interval ).
172 */
jitter_control_new_packet(JitterControl * ctl,uint32_t packet_ts,uint32_t cur_str_ts)173 void jitter_control_new_packet(JitterControl *ctl, uint32_t packet_ts, uint32_t cur_str_ts){
174 	switch (ctl->params.buffer_algorithm){
175 		case OrtpJitterBufferBasic:
176 			jitter_control_new_packet_basic (ctl, packet_ts, cur_str_ts);
177 		break;
178 		case OrtpJitterBufferRecursiveLeastSquare:
179 			jitter_control_new_packet_rls (ctl, packet_ts, cur_str_ts);
180 		break;
181 		default:
182 			ortp_fatal("No such new packet strategy: %d", ctl->params.buffer_algorithm);
183 		break;
184 	}
185 	ctl->count++;
186 }
187 
jitter_control_update_interarrival_jitter(JitterControl * ctl,int32_t diff)188 static void jitter_control_update_interarrival_jitter(JitterControl *ctl, int32_t diff){
189 	/*compute interarrival jitter*/
190 	int32_t delta;
191 	delta=diff-ctl->olddiff;
192 	ctl->inter_jitter=(float) (ctl->inter_jitter+ (( (float)abs(delta) - ctl->inter_jitter)*(1/16.0)));
193 	ctl->olddiff=diff;
194 }
195 
jitter_control_new_packet_basic(JitterControl * ctl,uint32_t packet_ts,uint32_t cur_str_ts)196 void jitter_control_new_packet_basic(JitterControl *ctl, uint32_t packet_ts, uint32_t cur_str_ts){
197 	int32_t diff = packet_ts - cur_str_ts;
198 	double gap,slide;
199 
200 	if (ctl->count==0){
201 		ctl->clock_offset_ts=ctl->prev_clock_offset_ts=diff;
202 		slide=(double)diff;
203 		ctl->olddiff=diff;
204 		ctl->jitter=0;
205 	}else{
206 		slide=((double)ctl->clock_offset_ts*(1-JC_BETA)) + ((double)diff*JC_BETA);
207 	}
208 	gap=(double)diff - slide;
209 	gap=gap<0 ? -gap : 0; /*compute only for late packets*/
210 	ctl->jitter=(float) ((ctl->jitter*(1-JC_GAMMA)) + (gap*JC_GAMMA));
211 	jitter_control_update_interarrival_jitter(ctl, diff);
212 
213 	if (ctl->params.adaptive){
214 		if (ctl->count%50==0) {
215 			ctl->adapt_jitt_comp_ts=(int) MAX(ctl->jitt_comp_ts,2*ctl->jitter);
216 			//jitter_control_dump_stats(ctl);
217 		}
218 		ctl->clock_offset_ts=(int32_t)slide;
219 	}else {
220 		/*ctl->slide and jitter size are not updated*/
221 	}
222 }
223 
time_for_log(JitterControl * ctl,uint32_t cur_str_ts)224 static bool_t time_for_log(JitterControl *ctl, uint32_t cur_str_ts){
225 	int32_t elapsed = (int32_t)(cur_str_ts - ctl->last_log_ts);
226 	if (elapsed >= 5*ctl->clock_rate){
227 		ctl->last_log_ts = cur_str_ts;
228 		return TRUE;
229 	}
230 	return FALSE;
231 }
232 
jitter_control_local_ts_to_remote_ts_rls(JitterControl * ctl,uint32_t local_ts)233 static uint32_t jitter_control_local_ts_to_remote_ts_rls(JitterControl *ctl, uint32_t local_ts){
234 	return (uint32_t)( (int64_t)(ctl->capped_clock_ratio*(double)(local_ts - ctl->local_ts_start) + ctl->clock_offset_ts));
235 }
236 
237 /**************************** RLS *********************************/
jitter_control_new_packet_rls(JitterControl * ctl,uint32_t packet_ts,uint32_t cur_str_ts)238 void jitter_control_new_packet_rls(JitterControl *ctl, uint32_t packet_ts, uint32_t cur_str_ts){
239 	int32_t diff = packet_ts - cur_str_ts;
240 	int deviation;
241 	bool_t jb_size_updated = FALSE;
242 
243 	if (ctl->count==0){
244 		ctl->clock_offset_ts = ctl->prev_clock_offset_ts = (int32_t)packet_ts;
245 		/*
246 		 * Offset compensation. In order to avoid managing the rollover of the uint32_t timestamp, the timestamps passed
247 		 * to the kalman filter are substracted with their initial value.
248 		 * This allows a video stream to run 13hours (clockrate: 90 000), which looks at first sight
249 		 * sufficient for a VoIP application.
250 		 */
251 		ctl->local_ts_start = cur_str_ts;
252 		ctl->remote_ts_start = packet_ts;
253 		ctl->olddiff = diff;
254 		ctl->jitter = 0;
255 
256 		ortp_extremum_init(&ctl->max_ts_deviation, (int)(ctl->params.refresh_ms / 1000.f * ctl->clock_rate));
257 		ortp_extremum_record_max(&ctl->max_ts_deviation, 0, (float)ctl->jitt_comp_ts);
258 
259 		// clock rates should be the same
260 		ortp_kalman_rls_init(&ctl->kalman_rls, 1.0, 0.0);
261 		ctl->capped_clock_ratio = ctl->kalman_rls.m;
262 	}
263 
264 	/*Compute the deviation from the value predicted by the kalman filter*/
265 	deviation = abs((int32_t)(packet_ts - jitter_control_local_ts_to_remote_ts_rls(ctl, cur_str_ts)));
266 
267 	/*update the kalman filter*/
268 	ortp_kalman_rls_record(&ctl->kalman_rls, cur_str_ts - ctl->local_ts_start, packet_ts - ctl->remote_ts_start);
269 
270 	ctl->capped_clock_ratio = MAX(.5, MIN(ctl->kalman_rls.m, 2));
271 
272 	if (.5f<ctl->kalman_rls.m && ctl->kalman_rls.m<2.f){
273 		/*realistic clock ratio, the filter is well converged*/
274 		ctl->clock_offset_ts = (int32_t)((int32_t)ctl->kalman_rls.b + ctl->remote_ts_start);
275 	}else{
276 		ctl->clock_offset_ts = diff;
277 	}
278 
279 	/*ortp_message("deviation=%g ms", 1000.0*deviation/(double)ctl->clock_rate);*/
280 
281 	jitter_control_update_interarrival_jitter(ctl, diff);
282 	cur_str_ts -= ctl->local_ts_start;
283 
284 	if (ctl->params.adaptive){
285 		bool_t max_updated = ortp_extremum_record_max(&ctl->max_ts_deviation, cur_str_ts, (float)deviation);
286 		float max_deviation = MAX(ortp_extremum_get_previous(&ctl->max_ts_deviation), ortp_extremum_get_current(&ctl->max_ts_deviation));
287 		if (max_updated && max_deviation > ctl->adapt_jitt_comp_ts){
288 			ctl->adapt_jitt_comp_ts=(int)max_deviation;
289 			jb_size_updated = TRUE;
290 		}else if (max_deviation < ctl->params.ramp_threshold/100.f*ctl->adapt_jitt_comp_ts){
291 			/*Jitter is decreasing. Make a smooth descent to avoid dropping lot of packets*/
292 			if ( (int32_t)(cur_str_ts - ctl->adapt_refresh_prev_ts) > ((ctl->params.ramp_refresh_ms*ctl->clock_rate)/1000)) {
293 				ctl->adapt_jitt_comp_ts -= (ctl->params.ramp_step_ms * ctl->clock_rate) / 1000;
294 				jb_size_updated = TRUE;
295 			}
296 		}
297 		if (jb_size_updated){
298 			int min_size_ts = (ctl->params.min_size * ctl->clock_rate) / 1000;
299 			int max_size_ts = (ctl->params.max_size * ctl->clock_rate) / 1000;
300 			if (ctl->adapt_jitt_comp_ts < min_size_ts){
301 				ctl->adapt_jitt_comp_ts = min_size_ts;
302 			}else if (ctl->adapt_jitt_comp_ts > max_size_ts){
303 				ctl->adapt_jitt_comp_ts = max_size_ts;
304 			}
305 			ctl->adapt_refresh_prev_ts = cur_str_ts;
306 			jb_size_updated = TRUE;
307 		}
308 	}
309 	if (time_for_log(ctl, cur_str_ts)){
310 		ortp_message("jitter buffer %s: target-size: %f ms, effective-size: %f (min: %i nom: %i, max: %i)",jb_size_updated ? "updated" : "stable",
311 			((float)ctl->adapt_jitt_comp_ts/(float)ctl->clock_rate)*1000.0,
312 			ctl->jitter_buffer_mean_size,
313 			ctl->params.min_size, ctl->params.nom_size, ctl->params.max_size);
314 		ortp_message("jitter buffer rls stats: count=%d, clockrate=%i"
315 			", offset=%g clock_ratio=%g"
316 			", capped_offset=%i capped_clock_ratio=%f"
317 			", max_ts_deviation=%f prev_max_ts_deviation=%f"
318 			", deviation=%i"
319 			", RLS VARIABLES: P[0][0]=%f, P[1][0]=%f, P[0][1]=%f, P[1][1]=%f"
320 			, ctl->count, ctl->clock_rate
321 			, ctl->kalman_rls.b, ctl->kalman_rls.m
322 			, (int) ctl->clock_offset_ts, (float)ctl->capped_clock_ratio
323 			, ortp_extremum_get_current(&ctl->max_ts_deviation), ortp_extremum_get_previous(&ctl->max_ts_deviation)
324 			, deviation
325 			, ctl->kalman_rls.P[0][0], ctl->kalman_rls.P[1][0], ctl->kalman_rls.P[0][1], ctl->kalman_rls.P[1][1]);
326 	}
327 }
328 
jitter_control_get_compensated_timestamp(JitterControl * obj,uint32_t user_ts)329 uint32_t jitter_control_get_compensated_timestamp(JitterControl *obj , uint32_t user_ts){
330 	uint32_t ret = 0;
331 	switch (obj->params.buffer_algorithm){
332 		case OrtpJitterBufferBasic:
333 			ret = (uint32_t)( (int64_t)user_ts+obj->clock_offset_ts-(int64_t)obj->adapt_jitt_comp_ts);
334 		break;
335 		case OrtpJitterBufferRecursiveLeastSquare:
336 			ret = jitter_control_local_ts_to_remote_ts_rls(obj, user_ts) - obj->adapt_jitt_comp_ts;
337 		break;
338 		default:
339 			ortp_fatal("No such new packet strategy: %d", obj->params.buffer_algorithm);
340 		break;
341 	}
342 	return ret;
343 }
344 
345