Bug Summary

File:switch_jitterbuffer.c
Warning:line 1029, column 8
2nd function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name switch_jitterbuffer.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=none -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-11/lib/clang/11.0.1 -D HAVE_CONFIG_H -I . -I ./src/include -I ./libs/esl/src/include -I ./libs/xmlrpc-c -I /drone/src/libs/libvpx -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -D _REENTRANT -D _GNU_SOURCE -I /drone/src/libs/apr/include -I /drone/src/libs/srtp/include -I /drone/src/libs/libyuv/include -D SWITCH_HAVE_YUV -I /drone/src/libs/srtp/crypto/include -I libs/srtp/crypto/include -D SWITCH_HAVE_VPX -D ENABLE_SRTP -D SWITCH_HAVE_ODBC -I /usr/include -D SWITCH_HAVE_PNG -I /usr/include/libpng16 -D SWITCH_HAVE_FREETYPE -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/editline -D HAVE_OPENSSL -I /usr/include/sofia-sip-1.13 -I /usr/include/uuid -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -D HAVE_OPENSSL -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wno-misleading-indentation -std=c99 -fdebug-compilation-dir /drone/src -ferror-limit 19 -fvisibility hidden -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /drone/src/scan-build/2024-01-11-151439-462-1 -x c src/switch_jitterbuffer.c
1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Dragos Oancea <dragos@freeswitch.org>
28 *
29 * switch_jitterbuffer.c -- Audio/Video Jitter Buffer
30 *
31 */
32#include <switch.h>
33#include <switch_jitterbuffer.h>
34#include "private/switch_hashtable_private.h"
35
36#define NACK_TIME80000 80000
37#define RENACK_TIME100000 100000
38#define MAX_FRAME_PADDING2 2
39#define MAX_MISSING_SEQ20 20
40#define jb_debug(_jb, _level, _format, ...)if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 40, switch_core_session_get_uuid
((_jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
_format, (void *) _jb, (jb->type == SJB_TEXT ? "txt" : (jb
->type == SJB_AUDIO ? "aud" : "vid")), _jb->allocated_nodes
, _jb->visible_nodes, _level, 40, _jb->min_frame_len, _jb
->max_frame_len, _jb->frame_len, _jb->complete_frames
, _jb->period_count, _jb->consec_good_count, _jb->period_good_count
, _jb->consec_miss_count, _jb->period_miss_count, _jb->
period_miss_pct, ...)
if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session)SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 40, switch_core_session_get_uuid((_jb->session
))
, SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), _jb->allocated_nodes, _jb->visible_nodes, _level, __LINE__40, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__)
41
42//const char *TOKEN_1 = "ONE";
43//const char *TOKEN_2 = "TWO";
44
45struct switch_jb_s;
46
47static inline int check_jb_size(switch_jb_t *jb);
48
49typedef struct switch_jb_node_s {
50 struct switch_jb_s *parent;
51 switch_rtp_packet_t packet;
52 uint32_t len;
53 uint8_t visible;
54 uint8_t bad_hits;
55 struct switch_jb_node_s *prev;
56 struct switch_jb_node_s *next;
57 /* used for counting the number of partial or complete frames currently in the JB */
58 switch_bool_t complete_frame_mark;
59} switch_jb_node_t;
60
61typedef struct switch_jb_stats_s {
62 uint32_t reset_too_big;
63 uint32_t reset_too_expanded;
64 uint32_t reset_missing_frames;
65 uint32_t reset_ts_jump;
66 uint32_t reset_error;
67 uint32_t reset;
68 uint32_t size_max;
69 uint32_t size_est;
70 uint32_t acceleration;
71 uint32_t fast_acceleration;
72 uint32_t forced_acceleration;
73 uint32_t expand;
74 uint32_t consecutive_miss;
75 int32_t expand_frame_len;
76 uint32_t jitter_max_ms;
77 uint32_t buffering_skip;
78 int estimate_ms;
79 int buffer_size_ms;
80} switch_jb_stats_t;
81
82typedef struct switch_jb_jitter_s {
83 double *estimate;
84 uint32_t samples_per_second;
85 uint32_t samples_per_frame;
86 uint32_t drop_gap;
87 switch_jb_stats_t stats;
88} switch_jb_jitter_t;
89
90struct switch_jb_s {
91 struct switch_jb_node_s *node_list;
92 uint32_t last_target_seq;
93 uint32_t highest_read_ts;
94 uint32_t highest_dropped_ts;
95 uint32_t highest_read_seq;
96 uint32_t highest_wrote_ts;
97 uint16_t highest_wrote_seq;
98 uint16_t target_seq;
99 uint32_t target_ts;
100 uint32_t last_target_ts;
101 uint16_t psuedo_seq;
102 uint16_t last_psuedo_seq;
103 uint32_t visible_nodes;
104 uint32_t allocated_nodes;
105 uint32_t complete_frames;
106 uint32_t frame_len;
107 uint32_t min_frame_len;
108 uint32_t max_frame_len;
109 uint32_t highest_frame_len;
110 uint32_t period_miss_count;
111 uint32_t consec_miss_count;
112 uint32_t period_miss_inc;
113 double period_miss_pct;
114 uint32_t period_good_count;
115 uint32_t consec_good_count;
116 uint32_t period_count;
117 uint32_t dropped;
118 uint32_t samples_per_frame;
119 uint32_t samples_per_second;
120 uint32_t bitrate_control;
121 uint32_t video_low_bitrate;
122 uint8_t write_init;
123 uint8_t read_init;
124 uint8_t debug_level;
125 uint16_t next_seq;
126 switch_size_t last_len;
127 switch_inthash_t *missing_seq_hash;
128 switch_inthash_t *node_hash;
129 switch_inthash_t *node_hash_ts;
130 switch_mutex_t *mutex;
131 switch_mutex_t *list_mutex;
132 switch_memory_pool_t *pool;
133 int free_pool;
134 int drop_flag;
135 switch_jb_flag_t flags;
136 switch_jb_type_t type;
137 switch_core_session_t *session;
138 switch_jb_jitter_t jitter;
139 switch_channel_t *channel;
140 uint32_t buffer_lag;
141 uint32_t flush;
142 uint32_t packet_count;
143 int32_t packets_in_buffer;
144 uint32_t max_packet_len;
145 uint32_t period_len;
146 uint32_t nack_saved_the_day;
147 uint32_t nack_didnt_save_the_day;
148 switch_bool_t elastic;
149 switch_codec_t *codec;
150};
151
152
153static int node_cmp(const void *l, const void *r)
154{
155 switch_jb_node_t *a = (switch_jb_node_t *) l;
156 switch_jb_node_t *b = (switch_jb_node_t *) r;
157
158 if (!a->visible) return 0;
159 if (!b->visible) return 1;
160
161 return ntohs(a->packet.header.seq)__bswap_16 (a->packet.header.seq) - ntohs(b->packet.header.seq)__bswap_16 (b->packet.header.seq);
162}
163
164//http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
165switch_jb_node_t *sort_nodes(switch_jb_node_t *list, int (*cmp)(const void *, const void *)) {
166 switch_jb_node_t *p, *q, *e, *tail;
167 int insize, nmerges, psize, qsize, i;
168
169 if (!list) {
170 return NULL((void*)0);
171 }
172
173 insize = 1;
174
175 while (1) {
176 p = list;
177 list = NULL((void*)0);
178 tail = NULL((void*)0);
179
180 nmerges = 0; /* count number of merges we do in this pass */
181
182 while (p) {
183 nmerges++; /* there exists a merge to be done */
184 /* step `insize' places along from p */
185 q = p;
186 psize = 0;
187 for (i = 0; i < insize; i++) {
188 psize++;
189 q = q->next;
190 if (!q) break;
191 }
192
193 /* if q hasn't fallen off end, we have two lists to merge */
194 qsize = insize;
195
196 /* now we have two lists; merge them */
197 while (psize > 0 || (qsize > 0 && q)) {
198
199 /* decide whether next switch_jb_node_t of merge comes from p or q */
200 if (psize == 0) {
201 /* p is empty; e must come from q. */
202 e = q; q = q->next; qsize--;
203 } else if (qsize == 0 || !q) {
204 /* q is empty; e must come from p. */
205 e = p; p = p->next; psize--;
206 } else if (cmp(p,q) <= 0) {
207 /* First switch_jb_node_t of p is lower (or same);
208 * e must come from p. */
209 e = p; p = p->next; psize--;
210 } else {
211 /* First switch_jb_node_t of q is lower; e must come from q. */
212 e = q; q = q->next; qsize--;
213 }
214
215 /* add the next switch_jb_node_t to the merged list */
216 if (tail) {
217 tail->next = e;
218 } else {
219 list = e;
220 }
221
222 /* Maintain reverse pointers in a doubly linked list. */
223 e->prev = tail;
224
225 tail = e;
226 }
227
228 /* now p has stepped `insize' places along, and q has too */
229 p = q;
230 }
231
232 tail->next = NULL((void*)0);
233
234 /* If we have done only one merge, we're finished. */
235 if (nmerges <= 1) /* allow for nmerges==0, the empty list case */
236 return list;
237
238 /* Otherwise repeat, merging lists twice the size */
239 insize *= 2;
240 }
241}
242
243// static inline void thin_frames(switch_jb_t *jb, int freq, int max);
244
245
246static inline switch_jb_node_t *new_node(switch_jb_t *jb)
247{
248 switch_jb_node_t *np;
249
250 switch_mutex_lock(jb->list_mutex);
251
252 for (np = jb->node_list; np; np = np->next) {
253 if (!np->visible) {
254 break;
255 }
256 }
257
258 if (!np) {
259 int mult = 2;
260
261 if (jb->type != SJB_VIDEO) {
262 mult = 2;
263 } else {
264 if (jb->max_packet_len > mult) {
265 mult = jb->max_packet_len;
266 }
267 }
268
269 if (jb->allocated_nodes > jb->max_frame_len * mult) {
270 jb_debug(jb, 2, "ALLOCATED FRAMES TOO HIGH! %d\n", jb->allocated_nodes)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 270, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"ALLOCATED FRAMES TOO HIGH! %d\n", (void *) jb, (jb->type
== SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 270, jb->
min_frame_len, jb->max_frame_len, jb->frame_len, jb->
complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, jb->allocated_nodes
)
;
271 jb->jitter.stats.reset_too_big++;
272 switch_jb_reset(jb);
273 switch_mutex_unlock(jb->list_mutex);
274 return NULL((void*)0);
275 }
276
277 np = switch_core_alloc(jb->pool, sizeof(*np))switch_core_perform_alloc(jb->pool, sizeof(*np), "src/switch_jitterbuffer.c"
, (const char *)__func__, 277)
;
278 jb->allocated_nodes++;
279 np->next = jb->node_list;
280 if (np->next) {
281 np->next->prev = np;
282 }
283 jb->node_list = np;
284
285 }
286
287 switch_assert(np)((np) ? (void) (0) : __assert_fail ("np", "src/switch_jitterbuffer.c"
, 287, __extension__ __PRETTY_FUNCTION__))
;
288 np->bad_hits = 0;
289 np->visible = 1;
290 jb->visible_nodes++;
291 np->parent = jb;
292
293 switch_mutex_unlock(jb->list_mutex);
294
295 return np;
296}
297
298static inline void push_to_top(switch_jb_t *jb, switch_jb_node_t *node)
299{
300 if (node == jb->node_list) {
301 jb->node_list = node->next;
302 } else if (node->prev) {
303 node->prev->next = node->next;
304 }
305
306 if (node->next) {
307 node->next->prev = node->prev;
308 }
309
310 node->next = jb->node_list;
311 node->prev = NULL((void*)0);
312
313 if (node->next) {
314 node->next->prev = node;
315 }
316
317 jb->node_list = node;
318
319 switch_assert(node->next != node)((node->next != node) ? (void) (0) : __assert_fail ("node->next != node"
, "src/switch_jitterbuffer.c", 319, __extension__ __PRETTY_FUNCTION__
))
;
320 switch_assert(node->prev != node)((node->prev != node) ? (void) (0) : __assert_fail ("node->prev != node"
, "src/switch_jitterbuffer.c", 320, __extension__ __PRETTY_FUNCTION__
))
;
321}
322
323static inline void hide_node(switch_jb_node_t *node, switch_bool_t pop)
324{
325 switch_jb_t *jb = node->parent;
326
327 switch_mutex_lock(jb->list_mutex);
328
329 if (node->visible) {
330 node->visible = 0;
331 node->bad_hits = 0;
332 jb->visible_nodes--;
333
334 if (pop) {
335 push_to_top(jb, node);
336 }
337 }
338
339 if (jb->node_hash_ts) {
340 switch_core_inthash_delete(jb->node_hash_ts, node->packet.header.ts);
341 }
342
343 if (switch_core_inthash_delete(jb->node_hash, node->packet.header.seq)) {
344 if (node->complete_frame_mark && jb->type == SJB_VIDEO) {
345 jb->complete_frames--;
346 node->complete_frame_mark = FALSE0;
347 }
348 }
349
350 switch_mutex_unlock(jb->list_mutex);
351}
352
353static inline void sort_free_nodes(switch_jb_t *jb)
354{
355 switch_mutex_lock(jb->list_mutex);
356 jb->node_list = sort_nodes(jb->node_list, node_cmp);
357 switch_mutex_unlock(jb->list_mutex);
358}
359
360static inline void hide_nodes(switch_jb_t *jb)
361{
362 switch_jb_node_t *np;
363
364 switch_mutex_lock(jb->list_mutex);
365 for (np = jb->node_list; np; np = np->next) {
366 hide_node(np, SWITCH_FALSE);
367 }
368 switch_mutex_unlock(jb->list_mutex);
369}
370
371static inline switch_bool_t packet_vad(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) {
372 void *payload = packet ? (packet->ebody ? packet->ebody : packet->body) : NULL((void*)0);
373 uint16_t payload_len = len;
374
375 if (payload && payload_len > 0) {
376 switch_bool_t ret = SWITCH_FALSE, *ret_p = &ret;
377 switch_codec_control_type_t ret_t;
378
379 switch_core_media_codec_control(jb->session, SWITCH_MEDIA_TYPE_AUDIO,
380 SWITCH_IO_WRITE, SCC_AUDIO_VAD,
381 SCCT_STRING, (void *)payload,
382 SCCT_INT, (void *)&payload_len,
383 &ret_t, (void *)&ret_p);
384
385 return ret;
386 }
387
388 return SWITCH_TRUE;
389}
390
391static inline void drop_ts(switch_jb_t *jb, uint32_t ts)
392{
393 switch_jb_node_t *np;
394 int x = 0;
395
396 switch_mutex_lock(jb->list_mutex);
397 for (np = jb->node_list; np; np = np->next) {
398 if (!np->visible) continue;
399
400 if (ts == np->packet.header.ts) {
401 hide_node(np, SWITCH_FALSE);
402 x++;
403 }
404 }
405
406 if (x) {
407 sort_free_nodes(jb);
408 }
409
410 switch_mutex_unlock(jb->list_mutex);
411}
412
413static inline switch_jb_node_t *jb_find_lowest_seq(switch_jb_t *jb, uint32_t ts)
414{
415 switch_jb_node_t *np, *lowest = NULL((void*)0);
416
417 switch_mutex_lock(jb->list_mutex);
418 for (np = jb->node_list; np; np = np->next) {
419 if (!np->visible) continue;
420
421 if (ts && ts != np->packet.header.ts) continue;
422
423 if (!lowest || ntohs(lowest->packet.header.seq)__bswap_16 (lowest->packet.header.seq) > ntohs(np->packet.header.seq)__bswap_16 (np->packet.header.seq)) {
424 lowest = np;
425 }
426 }
427 switch_mutex_unlock(jb->list_mutex);
428
429 return lowest;
430}
431
432static inline switch_jb_node_t *jb_find_lowest_node(switch_jb_t *jb)
433{
434 switch_jb_node_t *np, *lowest = NULL((void*)0);
435
436 switch_mutex_lock(jb->list_mutex);
437 for (np = jb->node_list; np; np = np->next) {
438 if (!np->visible) continue;
439
440 if (!lowest || ntohl(lowest->packet.header.ts)__bswap_32 (lowest->packet.header.ts) > ntohl(np->packet.header.ts)__bswap_32 (np->packet.header.ts)) {
441 lowest = np;
442 }
443 }
444 switch_mutex_unlock(jb->list_mutex);
445
446 return lowest ? lowest : NULL((void*)0);
447}
448
449static inline uint32_t jb_find_lowest_ts(switch_jb_t *jb)
450{
451 switch_jb_node_t *lowest = jb_find_lowest_node(jb);
452
453 return lowest ? lowest->packet.header.ts : 0;
454}
455
456#if 0
457static inline void thin_frames(switch_jb_t *jb, int freq, int max)
458{
459 switch_jb_node_t *node, *this_node;
460 int i = -1;
461 int dropped = 0;
462
463 switch_mutex_lock(jb->list_mutex);
464 node = jb->node_list;
465
466 while (node && dropped <= max) {
467 this_node = node;
468 node = node->next;
469
470 if (this_node->visible) {
471 i++;
472 } else {
473 continue;
474 }
475
476 if ((i % freq) == 0) {
477 drop_ts(jb, this_node->packet.header.ts);
478 dropped++;
479 }
480 }
481
482 sort_free_nodes(jb);
483 switch_mutex_unlock(jb->list_mutex);
484}
485
486static inline switch_jb_node_t *jb_find_highest_node(switch_jb_t *jb)
487{
488 switch_jb_node_t *np, *highest = NULL((void*)0);
489
490 switch_mutex_lock(jb->list_mutex);
491 for (np = jb->node_list; np; np = np->next) {
492 if (!np->visible) continue;
493
494 if (!highest || ntohl(highest->packet.header.ts)__bswap_32 (highest->packet.header.ts) < ntohl(np->packet.header.ts)__bswap_32 (np->packet.header.ts)) {
495 highest = np;
496 }
497 }
498 switch_mutex_unlock(jb->list_mutex);
499
500 return highest ? highest : NULL((void*)0);
501}
502
503
504static inline uint32_t jb_find_highest_ts(switch_jb_t *jb)
505{
506 switch_jb_node_t *highest = jb_find_highest_node(jb);
507
508 return highest ? highest->packet.header.ts : 0;
509}
510
511static inline void drop_newest_frame(switch_jb_t *jb)
512{
513 uint32_t ts = jb_find_highest_ts(jb);
514
515 drop_ts(jb, ts);
516 jb_debug(jb, 1, "Dropping highest frame ts:%u\n", ntohl(ts))if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 516, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Dropping highest frame ts:%u\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 1, 516, jb->
min_frame_len, jb->max_frame_len, jb->frame_len, jb->
complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (ts))
;
517}
518
519
520
521
522static inline switch_jb_node_t *jb_find_penultimate_node(switch_jb_t *jb)
523{
524 switch_jb_node_t *np, *highest = NULL((void*)0), *second_highest = NULL((void*)0);
525
526 switch_mutex_lock(jb->list_mutex);
527 for (np = jb->node_list; np; np = np->next) {
528 if (!np->visible) continue;
529
530 if (!highest || ntohl(highest->packet.header.ts)__bswap_32 (highest->packet.header.ts) < ntohl(np->packet.header.ts)__bswap_32 (np->packet.header.ts)) {
531 if (highest) second_highest = highest;
532 highest = np;
533 }
534 }
535 switch_mutex_unlock(jb->list_mutex);
536
537 return second_highest ? second_highest : highest;
538}
539#endif
540
541static inline void jb_hit(switch_jb_t *jb)
542{
543 jb->period_good_count++;
544 jb->consec_good_count++;
545 jb->consec_miss_count = 0;
546}
547
548static void jb_frame_inc_line(switch_jb_t *jb, int i, int line)
549{
550 uint32_t old_frame_len = jb->frame_len;
551
552 if (i == 0) {
553 jb->frame_len = jb->min_frame_len;
554 goto end;
555 }
556
557 if (i > 0) {
558 if ((jb->frame_len + i) < jb->max_frame_len) {
559 jb->frame_len += i;
560 } else {
561 jb->frame_len = jb->max_frame_len;
562 }
563
564 goto end;
565 }
566
567 /* i < 0 */
568 if ((jb->frame_len + i) > jb->min_frame_len) {
569 jb->frame_len += i;
570 } else {
571 jb->frame_len = jb->min_frame_len;
572 }
573
574 end:
575
576 if (jb->frame_len > jb->highest_frame_len) {
577 jb->highest_frame_len = jb->frame_len;
578 }
579
580 if (old_frame_len != jb->frame_len) {
581 jb_debug(jb, 1, "%d Change framelen from %u to %u\n", line, old_frame_len, jb->frame_len)if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 581, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%d Change framelen from %u to %u\n", (void *) jb, (jb->type
== SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 1, 581, jb->
min_frame_len, jb->max_frame_len, jb->frame_len, jb->
complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, line, old_frame_len
, jb->frame_len)
;
582
583 //if (jb->session) {
584 // switch_core_session_request_video_refresh(jb->session);
585 //}
586 }
587
588}
589
590#define jb_frame_inc(_jb, _i)jb_frame_inc_line(_jb, _i, 590) jb_frame_inc_line(_jb, _i, __LINE__590)
591
592
593static inline void jb_miss(switch_jb_t *jb)
594{
595 jb->period_miss_count++;
596 jb->consec_miss_count++;
597 jb->consec_good_count = 0;
598}
599
600#if 0
601static inline int verify_oldest_frame(switch_jb_t *jb)
602{
603 switch_jb_node_t *lowest = NULL((void*)0), *np = NULL((void*)0);
604 int r = 0;
605
606 lowest = jb_find_lowest_node(jb);
607
608 if (!lowest || !(lowest = jb_find_lowest_seq(jb, lowest->packet.header.ts))) {
609 goto end;
610 }
611
612 switch_mutex_lock(jb->mutex);
613
614 jb->node_list = sort_nodes(jb->node_list, node_cmp);
615
616 for (np = lowest->next; np; np = np->next) {
617
618 if (!np->visible) continue;
619
620 if (ntohs(np->packet.header.seq)__bswap_16 (np->packet.header.seq) != ntohs(np->prev->packet.header.seq)__bswap_16 (np->prev->packet.header.seq) + 1) {
621 uint32_t val = (uint32_t)htons(ntohs(np->prev->packet.header.seq) + 1)__bswap_16 (__bswap_16 (np->prev->packet.header.seq) + 1
)
;
622
623 if (!switch_core_inthash_find(jb->missing_seq_hash, val)) {
624 switch_core_inthash_insert(jb->missing_seq_hash, val, (void *)(intptr_t)1);
625 }
626 break;
627 }
628
629 if (np->packet.header.ts != lowest->packet.header.ts || !np->next) {
630 r = 1;
631 }
632 }
633
634 switch_mutex_unlock(jb->mutex);
635
636 end:
637
638 return r;
639}
640#endif
641
642static inline void drop_oldest_frame(switch_jb_t *jb)
643{
644 uint32_t ts = jb_find_lowest_ts(jb);
645
646 drop_ts(jb, ts);
647 jb_debug(jb, 1, "Dropping oldest frame ts:%u\n", ntohl(ts))if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 647, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Dropping oldest frame ts:%u\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 1, 647, jb->
min_frame_len, jb->max_frame_len, jb->frame_len, jb->
complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (ts))
;
648}
649
650
651
652#if 0
653static inline void drop_second_newest_frame(switch_jb_t *jb)
654{
655 switch_jb_node_t *second_newest = jb_find_penultimate_node(jb);
656
657 if (second_newest) {
658 drop_ts(jb, second_newest->packet.header.ts);
659 jb_debug(jb, 1, "Dropping second highest frame ts:%u\n", ntohl(second_newest->packet.header.ts))if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 659, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Dropping second highest frame ts:%u\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, 1, 659
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (second_newest
->packet.header.ts))
;
660 }
661}
662#endif
663
664static inline int check_seq(uint16_t a, uint16_t b)
665{
666 a = ntohs(a)__bswap_16 (a);
667 b = ntohs(b)__bswap_16 (b);
668
669 if (a >= b || (b > a && b > USHRT_MAX(32767 *2 +1) / 2 && a < USHRT_MAX(32767 *2 +1) / 2)) {
670 return 1;
671 }
672
673 return 0;
674}
675
676static inline int check_ts(uint32_t a, uint32_t b)
677{
678 a = ntohl(a)__bswap_32 (a);
679 b = ntohl(b)__bswap_32 (b);
680
681 if (a > b || (b > a && b > UINT_MAX(2147483647 *2U +1U) / 2 && a < UINT_MAX(2147483647 *2U +1U) / 2)) {
682 return 1;
683 }
684
685 return 0;
686}
687
688static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
689{
690 switch_jb_node_t *node = new_node(jb);
691
692 if (!node) {
693 return;
694 }
695
696
697 node->packet = *packet;
698 node->len = len;
699
700 switch_core_inthash_insert(jb->node_hash, node->packet.header.seq, node);
701
702 if (jb->node_hash_ts) {
703 switch_core_inthash_insert(jb->node_hash_ts, node->packet.header.ts, node);
704 }
705
706 jb_debug(jb, (packet->header.m ? 2 : 3), "PUT packet last_ts:%u ts:%u seq:%u%s\n",if (jb->debug_level >= (packet->header.m ? 2 : 3)) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 707, switch_core_session_get_uuid((jb->session
)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"PUT packet last_ts:%u ts:%u seq:%u%s\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, (packet
->header.m ? 2 : 3), 707, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, __bswap_32 (jb->highest_wrote_ts), __bswap_32 (node->
packet.header.ts), __bswap_16 (node->packet.header.seq), packet
->header.m ? " <MARK>" : "")
707 ntohl(jb->highest_wrote_ts), ntohl(node->packet.header.ts), ntohs(node->packet.header.seq), packet->header.m ? " <MARK>" : "")if (jb->debug_level >= (packet->header.m ? 2 : 3)) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 707, switch_core_session_get_uuid((jb->session
)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"PUT packet last_ts:%u ts:%u seq:%u%s\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, (packet
->header.m ? 2 : 3), 707, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, __bswap_32 (jb->highest_wrote_ts), __bswap_32 (node->
packet.header.ts), __bswap_16 (node->packet.header.seq), packet
->header.m ? " <MARK>" : "")
;
708
709 if (jb->write_init && jb->type == SJB_VIDEO) {
710 int seq_diff = 0, ts_diff = 0;
711
712 if (ntohs(jb->highest_wrote_seq)__bswap_16 (jb->highest_wrote_seq) > (USHRT_MAX(32767 *2 +1) - 100) && ntohs(packet->header.seq)__bswap_16 (packet->header.seq) < 100) {
713 seq_diff = (USHRT_MAX(32767 *2 +1) - ntohs(jb->highest_wrote_seq)__bswap_16 (jb->highest_wrote_seq)) + ntohs(packet->header.seq)__bswap_16 (packet->header.seq);
714 } else {
715 seq_diff = abs(((int)ntohs(packet->header.seq)__bswap_16 (packet->header.seq) - ntohs(jb->highest_wrote_seq)__bswap_16 (jb->highest_wrote_seq)));
716 }
717
718 if (ntohl(jb->highest_wrote_ts)__bswap_32 (jb->highest_wrote_ts) > (UINT_MAX(2147483647 *2U +1U) - 1000) && ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts) < 1000) {
719 ts_diff = (UINT_MAX(2147483647 *2U +1U) - ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts)) + ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts);
720 } else {
721 ts_diff = abs((int)((int64_t)ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts)__bswap_32 (jb->highest_wrote_ts)));
722 }
723
724 if (((seq_diff >= 100) || (ts_diff > (900000 * 5)))) {
725 jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 725, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"CHANGE DETECTED, PUNT %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 725, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, abs(((int)__bswap_16 (packet->header.seq)
- __bswap_16 (jb->highest_wrote_seq))))
;
726 jb->jitter.stats.reset_ts_jump++;
727 switch_jb_reset(jb);
728 }
729 }
730
731 if (!jb->write_init || ntohs(packet->header.seq)__bswap_16 (packet->header.seq) > ntohs(jb->highest_wrote_seq)__bswap_16 (jb->highest_wrote_seq) ||
732 (ntohs(jb->highest_wrote_seq)__bswap_16 (jb->highest_wrote_seq) > USHRT_MAX(32767 *2 +1) - 100 && ntohs(packet->header.seq)__bswap_16 (packet->header.seq) < 100) ) {
733 jb->highest_wrote_seq = packet->header.seq;
734 }
735
736 if (jb->type == SJB_VIDEO) {
737 jb->packet_count++;
738
739 if (jb->write_init && check_seq(packet->header.seq, jb->highest_wrote_seq) && check_ts(node->packet.header.ts, jb->highest_wrote_ts)) {
740 jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 740, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"WRITE frame ts: %u complete=%u/%u n:%u\n", (void *) jb, (jb
->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud"
: "vid")), jb->allocated_nodes, jb->visible_nodes, 2, 740
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (node->
packet.header.ts), jb->complete_frames , jb->frame_len,
jb->visible_nodes)
;
741 jb->highest_wrote_ts = packet->header.ts;
742 jb->complete_frames++;
743
744 jb->packet_count--;
745 if (jb->packet_count > jb->max_packet_len) {
746 jb->max_packet_len = jb->packet_count;
747 }
748 jb->packet_count = 1;
749 node->complete_frame_mark = TRUE(!0);
750 } else if (!jb->write_init) {
751 jb->highest_wrote_ts = packet->header.ts;
752 }
753 } else {
754 if (jb->write_init || jb->type == SJB_TEXT || jb->type == SJB_AUDIO) {
755 jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 755, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"WRITE frame ts: %u complete=%u/%u n:%u\n", (void *) jb, (jb
->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud"
: "vid")), jb->allocated_nodes, jb->visible_nodes, 2, 755
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (node->
packet.header.ts), jb->complete_frames , jb->frame_len,
jb->visible_nodes)
;
756 jb->complete_frames++;
757 } else {
758 jb->highest_wrote_ts = packet->header.ts;
759 }
760 }
761
762 if (!jb->write_init) jb->write_init = 1;
763}
764
765static inline void increment_ts(switch_jb_t *jb)
766{
767 if (!jb->target_ts) return;
768
769 jb->last_psuedo_seq = jb->psuedo_seq;
770 jb->last_target_ts = jb->target_ts;
771 jb->target_ts = htonl((ntohl(jb->target_ts) + jb->samples_per_frame))__bswap_32 ((__bswap_32 (jb->target_ts) + jb->samples_per_frame
))
;
772 jb->psuedo_seq++;
773}
774
775static inline void set_read_ts(switch_jb_t *jb, uint32_t ts)
776{
777 if (!ts) return;
778
779 jb->last_psuedo_seq = jb->psuedo_seq;
780 jb->last_target_ts = ts;
781 jb->target_ts = htonl((ntohl(jb->last_target_ts) + jb->samples_per_frame))__bswap_32 ((__bswap_32 (jb->last_target_ts) + jb->samples_per_frame
))
;
782 jb->psuedo_seq++;
783}
784
785
786static inline void increment_seq(switch_jb_t *jb)
787{
788 jb->last_target_seq = jb->target_seq;
789 jb->target_seq = htons((ntohs(jb->target_seq) + 1))__bswap_16 ((__bswap_16 (jb->target_seq) + 1));
790}
791
792static inline void decrement_seq(switch_jb_t *jb)
793{
794 jb->target_seq = htons((ntohs(jb->target_seq) - 1))__bswap_16 ((__bswap_16 (jb->target_seq) - 1));
795 jb->last_target_seq = htons((ntohs(jb->target_seq) - 1))__bswap_16 ((__bswap_16 (jb->target_seq) - 1));
796}
797
798static inline void set_read_seq(switch_jb_t *jb, uint16_t seq)
799{
800 jb->last_target_seq = seq;
801 jb->target_seq = htons((ntohs(jb->last_target_seq) + 1))__bswap_16 ((__bswap_16 (jb->last_target_seq) + 1));
802}
803
804static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_node_t **nodep)
805{
806 switch_jb_node_t *node = NULL((void*)0);
807
808 top:
809
810 if (jb->type == SJB_VIDEO) {
811 if (jb->dropped) {
812 jb->dropped = 0;
813 jb_debug(jb, 2, "%s", "DROPPED FRAME DETECTED RESYNCING\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 813, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 813, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "DROPPED FRAME DETECTED RESYNCING\n")
;
814 jb->target_seq = 0;
815
816 if (jb->session) {
817 switch_core_session_request_video_refresh(jb->session)_switch_core_session_request_video_refresh(jb->session, 0,
"src/switch_jitterbuffer.c", (const char *)__func__, 817)
;
818 }
819 }
820 }
821
822 if (!jb->target_seq) {
823 if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) {
824 jb_debug(jb, 2, "FOUND rollover seq: %u\n", ntohs(jb->target_seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 824, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"FOUND rollover seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 824, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (jb->target_seq))
;
825 } else if ((node = jb_find_lowest_seq(jb, 0))) {
826 jb_debug(jb, 2, "No target seq using seq: %u as a starting point\n", ntohs(node->packet.header.seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 826, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"No target seq using seq: %u as a starting point\n", (void *
) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 2, 826, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, __bswap_16
(node->packet.header.seq))
;
827 } else {
828 jb_debug(jb, 1, "%s", "No nodes available....\n")if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 828, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 1, 828, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "No nodes available....\n")
;
829 }
830 jb_hit(jb);
831 } else if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) {
832 jb_debug(jb, 2, "FOUND desired seq: %u\n", ntohs(jb->target_seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 832, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"FOUND desired seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 832, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (jb->target_seq))
;
833 jb_hit(jb);
834 } else {
835 jb_debug(jb, 2, "MISSING desired seq: %u\n", ntohs(jb->target_seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 835, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"MISSING desired seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 835, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (jb->target_seq))
;
836 jb_miss(jb);
837
838 if (jb->type == SJB_VIDEO) {
839 int x;
840
841 if (jb->session) {
842 switch_core_session_request_video_refresh(jb->session)_switch_core_session_request_video_refresh(jb->session, 0,
"src/switch_jitterbuffer.c", (const char *)__func__, 842)
;
843 }
844
845 for (x = 0; x < 10; x++) {
846 increment_seq(jb);
847 if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) {
848 jb_debug(jb, 2, "FOUND incremental seq: %u\n", ntohs(jb->target_seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 848, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"FOUND incremental seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 848, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (jb->target_seq))
;
849
850 if (node->packet.header.m || node->packet.header.ts == jb->highest_read_ts) {
851 jb_debug(jb, 2, "%s", "SAME FRAME DROPPING\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 851, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 851, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "SAME FRAME DROPPING\n")
;
852 jb->dropped++;
853 drop_ts(jb, node->packet.header.ts);
854 jb->highest_dropped_ts = ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts);
855
856
857 if (jb->period_miss_count > 2 && jb->period_miss_inc < 1) {
858 jb->period_miss_inc++;
859 jb_frame_inc(jb, 1)jb_frame_inc_line(jb, 1, 859);
860 }
861
862 node = NULL((void*)0);
863 goto top;
864 }
865 break;
866 } else {
867 jb_debug(jb, 2, "MISSING incremental seq: %u\n", ntohs(jb->target_seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 867, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"MISSING incremental seq: %u\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 867, jb->
min_frame_len, jb->max_frame_len, jb->frame_len, jb->
complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_16 (jb->
target_seq))
;
868 }
869 }
870
871 } else {
872 increment_seq(jb);
873 }
874 }
875
876 *nodep = node;
877
878 if (node) {
879 set_read_seq(jb, node->packet.header.seq);
880 return SWITCH_STATUS_SUCCESS;
881 }
882
883 return SWITCH_STATUS_NOTFOUND;
884
885}
886
887
888static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_node_t **nodep)
889{
890 switch_jb_node_t *node = NULL((void*)0);
891
892 if (!jb->target_ts) {
893 if ((node = jb_find_lowest_node(jb))) {
894 jb_debug(jb, 2, "No target ts using ts: %u as a starting point\n", ntohl(node->packet.header.ts))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 894, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"No target ts using ts: %u as a starting point\n", (void *) jb
, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 2, 894, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, __bswap_32
(node->packet.header.ts))
;
895 } else {
896 jb_debug(jb, 1, "%s", "No nodes available....\n")if (jb->debug_level >= 1) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 896, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 1, 896, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "No nodes available....\n")
;
897 }
898 jb_hit(jb);
899 } else if ((node = switch_core_inthash_find(jb->node_hash_ts, jb->target_ts))) {
900 jb_debug(jb, 2, "FOUND desired ts: %u\n", ntohl(jb->target_ts))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 900, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"FOUND desired ts: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 900, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_32 (jb->target_ts))
;
901 jb_hit(jb);
902 } else {
903 jb_debug(jb, 2, "MISSING desired ts: %u\n", ntohl(jb->target_ts))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 903, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"MISSING desired ts: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 903, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_32 (jb->target_ts))
;
904 jb_miss(jb);
905 increment_ts(jb);
906 }
907
908 *nodep = node;
909
910 if (node) {
911 set_read_ts(jb, node->packet.header.ts);
912 node->packet.header.seq = htons(jb->psuedo_seq)__bswap_16 (jb->psuedo_seq);
913 return SWITCH_STATUS_SUCCESS;
914 }
915
916 return SWITCH_STATUS_NOTFOUND;
917
918}
919
920static inline int check_jb_size(switch_jb_t *jb)
921{
922 switch_jb_node_t *np;
923 uint16_t seq_hs, target_seq_hs;
924 uint16_t l_seq = 0;
925 uint16_t h_seq = 0;
926 uint16_t count = 0;
927 uint16_t old = 0;
928
929 switch_mutex_lock(jb->list_mutex);
930
931 target_seq_hs = ntohs(jb->target_seq)__bswap_16 (jb->target_seq);
932
933 for (np = jb->node_list; np; np = np->next) {
934 if (!np->visible) {
935 continue;
936 }
937
938 seq_hs = ntohs(np->packet.header.seq)__bswap_16 (np->packet.header.seq);
939 if (target_seq_hs > seq_hs) {
940 const int MAX_DROPOUT = 3000;
941 uint16_t udelta = target_seq_hs - seq_hs;
942 if (udelta > 1 && udelta < MAX_DROPOUT) {
943 // not a sequence id roll-over, this is an old packet, we can hide it
944 hide_node(np, SWITCH_FALSE);
945 old++;
946 continue;
947 }
948 }
949
950 if (count == 0) {
951 l_seq = h_seq = seq_hs;
952 }
953
954 count++;
955
956 if (seq_hs < l_seq) {
957 l_seq = seq_hs;
958 }
959
960 if (seq_hs > h_seq) {
961 h_seq = seq_hs;
962 }
963 }
964
965 if (count > jb->jitter.stats.size_max) {
966 jb->jitter.stats.size_max = count;
967 }
968
969 if (jb->jitter.stats.size_est == 0) {
970 jb->jitter.stats.size_est = count;
971 } else {
972 jb->jitter.stats.size_est = ((99 * jb->jitter.stats.size_est) + (1 * count)) / 100;
973 }
974
975 /* update the stats every x packets */
976 if (target_seq_hs % 50 == 0) {
977 int packet_ms = jb->jitter.samples_per_frame / (jb->jitter.samples_per_second / 1000);
978
979 jb->jitter.stats.estimate_ms = (*jb->jitter.estimate) / jb->jitter.samples_per_second * 1000;
980 if (jb->channel) {
981 switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_max_ms", "%u", jb->jitter.stats.size_max * packet_ms);
982 switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_est_ms", "%u", jb->jitter.stats.size_est * packet_ms);
983 switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", jb->jitter.stats.acceleration * packet_ms);
984 switch_channel_set_variable_printf(jb->channel, "rtp_jb_fast_acceleration_ms", "%u", jb->jitter.stats.fast_acceleration * packet_ms);
985 switch_channel_set_variable_printf(jb->channel, "rtp_jb_forced_acceleration_ms", "%u", jb->jitter.stats.forced_acceleration * packet_ms);
986 switch_channel_set_variable_printf(jb->channel, "rtp_jb_buffering_skip", "%u", jb->jitter.stats.buffering_skip);
987 switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", jb->jitter.stats.expand * packet_ms);
988 }
989
990 if (jb->jitter.stats.jitter_max_ms < jb->jitter.stats.estimate_ms) {
991 jb->jitter.stats.jitter_max_ms = jb->jitter.stats.estimate_ms;
992 }
993
994 if (jb->channel) {
995 switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", jb->jitter.stats.jitter_max_ms);
996 switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_est_ms", "%u", jb->jitter.stats.estimate_ms);
997 }
998 }
999
1000 if (old) {
1001 sort_free_nodes(jb);
1002 }
1003
1004 switch_mutex_unlock(jb->list_mutex);
1005
1006 jb_debug(jb, SWITCH_LOG_INFO, "JITTER buffersize %u == %u old[%u] target[%u] seq[%u|%u]\n", count, h_seq - l_seq + 1, old, target_seq_hs, l_seq, h_seq)if (jb->debug_level >= SWITCH_LOG_INFO) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1006, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER buffersize %u == %u old[%u] target[%u] seq[%u|%u]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_INFO, 1006, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, count, h_seq - l_seq + 1, old, target_seq_hs
, l_seq, h_seq)
;
1007
1008 return count;
1009}
1010
1011static inline switch_status_t jb_next_packet_by_seq_with_acceleration(switch_jb_t *jb, switch_jb_node_t **nodep)
1012{
1013 switch_status_t status = jb_next_packet_by_seq(jb, nodep);
1014 switch_rtp_packet_t *packet;
14
'packet' declared without an initial value
1015 uint32_t len;
1016 uint16_t seq = ntohs(jb->target_seq)__bswap_16 (jb->target_seq);
1017
1018 /* When using a Codec that provides voice activity detection ex. Opus, use it to
1019 select packet to drop/accelerate. */
1020
1021 if (jb->elastic && jb->jitter.estimate && (jb->visible_nodes * jb->jitter.samples_per_frame) > 0 && jb->jitter.samples_per_second) {
15
Assuming field 'elastic' is not equal to 0
16
Assuming field 'estimate' is non-null
17
Assuming the condition is true
18
Assuming field 'samples_per_second' is not equal to 0
19
Taking true branch
1022 jb->packets_in_buffer = check_jb_size(jb);
1023
1024 jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate) / ((jb->jitter.samples_per_second)) * 1000);
1025 jb->jitter.stats.buffer_size_ms = (int)((jb->packets_in_buffer * jb->jitter.samples_per_frame) / (jb->jitter.samples_per_second / 1000));
1026
1027 /* If the jitter buffer size is above the its max size, we force accelerate */
1028 if (jb->packets_in_buffer >= jb->max_frame_len) {
20
Assuming field 'packets_in_buffer' is >= field 'max_frame_len'
21
Taking true branch
1029 if (packet_vad(jb, packet, len) == SWITCH_FALSE) {
22
2nd function call argument is an uninitialized value
1030 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER_BUFFER above max size: [%d>%d] inactive fast acceleration\n", jb->packets_in_buffer, jb->max_frame_len)if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1030, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER_BUFFER above max size: [%d>%d] inactive fast acceleration\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1030, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->packets_in_buffer, jb->max_frame_len
)
;
1031 jb->jitter.drop_gap = 3;
1032 jb->jitter.stats.acceleration++;
1033 jb->jitter.stats.expand_frame_len--;
1034 jb->jitter.stats.fast_acceleration++;
1035 return jb_next_packet_by_seq(jb, nodep);
1036 } else {
1037 if (jb->jitter.drop_gap > 0) {
1038 jb->jitter.drop_gap--;
1039 } else {
1040 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER_BUFFER above max size: [%d>%d] forced acceleration\n", jb->packets_in_buffer, jb->max_frame_len)if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1040, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER_BUFFER above max size: [%d>%d] forced acceleration\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1040, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->packets_in_buffer, jb->max_frame_len
)
;
1041 jb->jitter.drop_gap = 10;
1042 jb->jitter.stats.acceleration++;
1043 jb->jitter.stats.expand_frame_len--;
1044 jb->jitter.stats.forced_acceleration++;
1045 return jb_next_packet_by_seq(jb, nodep);
1046 }
1047 }
1048 }
1049
1050 /* We try to accelerate in order to remove delay when the jitter buffer is 3x larger than the estimation. */
1051 if (jb->jitter.stats.buffer_size_ms > (3 * jb->jitter.stats.estimate_ms) && jb->jitter.stats.buffer_size_ms > 60) {
1052 if (status == SWITCH_STATUS_SUCCESS) {
1053 packet = &(*nodep)->packet;
1054 seq = ntohs((*nodep)->packet.header.seq)__bswap_16 ((*nodep)->packet.header.seq);
1055 len = (*nodep)->len;
1056 }
1057
1058 if (jb->jitter.drop_gap > 0) {
1059 jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-gap][%d]\n",if (jb->debug_level >= SWITCH_LOG_INFO) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1060, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-gap][%d]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_INFO, 1060, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq, jb
->jitter.drop_gap)
1060 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq, jb->jitter.drop_gap)if (jb->debug_level >= SWITCH_LOG_INFO) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1060, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-gap][%d]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_INFO, 1060, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq, jb
->jitter.drop_gap)
;
1061 jb->jitter.drop_gap--;
1062 } else {
1063 if (status != SWITCH_STATUS_SUCCESS || packet_vad(jb, packet, len) == SWITCH_FALSE) {
1064 jb->jitter.drop_gap = 3;
1065 if (status != SWITCH_STATUS_SUCCESS) {
1066 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER estimation n/a buffersize %d/%d %dms seq:%u [drop-missing/no-plc]\n",if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1067, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation n/a buffersize %d/%d %dms seq:%u [drop-missing/no-plc]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1067, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->complete_frames, jb->frame_len, jb
->jitter.stats.buffer_size_ms, seq)
1067 jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1067, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation n/a buffersize %d/%d %dms seq:%u [drop-missing/no-plc]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1067, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->complete_frames, jb->frame_len, jb
->jitter.stats.buffer_size_ms, seq)
;
1068 } else {
1069 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER estimation %dms buffersize %d/%d %dms seq:%u ACCELERATE [drop]\n",if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1070, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u ACCELERATE [drop]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1070, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)
1070 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1070, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u ACCELERATE [drop]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1070, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)
;
1071 }
1072
1073 jb->jitter.stats.acceleration++;
1074 jb->jitter.stats.expand_frame_len--;
1075
1076 return jb_next_packet_by_seq(jb, nodep);
1077 } else {
1078 jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-skip-vad]\n",if (jb->debug_level >= SWITCH_LOG_INFO) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1079, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-skip-vad]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_INFO, 1079, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)
1079 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)if (jb->debug_level >= SWITCH_LOG_INFO) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1079, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms seq:%u [drop-skip-vad]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_INFO, 1079, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, seq)
;
1080 }
1081 }
1082 } else {
1083 jb_debug(jb, 2, "JITTER estimation %dms buffersize %d/%d %dms\n",if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1084, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms\n", (void *) jb
, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 2, 1084, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, jb->jitter
.stats.estimate_ms, jb->complete_frames, jb->frame_len,
jb->jitter.stats.buffer_size_ms)
1084 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1084, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms\n", (void *) jb
, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 2, 1084, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, jb->jitter
.stats.estimate_ms, jb->complete_frames, jb->frame_len,
jb->jitter.stats.buffer_size_ms)
;
1085 }
1086 }
1087
1088 return status;
1089}
1090
1091static inline switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep)
1092{
1093 if (jb->samples_per_frame) {
9
Assuming field 'samples_per_frame' is 0
10
Taking false branch
1094 return jb_next_packet_by_ts(jb, nodep);
1095 }
1096
1097 if (jb->elastic
10.1
Field 'elastic' is not equal to 0
&& jb->jitter.estimate) {
11
Assuming field 'estimate' is non-null
12
Taking true branch
1098 return jb_next_packet_by_seq_with_acceleration(jb, nodep);
13
Calling 'jb_next_packet_by_seq_with_acceleration'
1099 }
1100
1101 return jb_next_packet_by_seq(jb, nodep);
1102}
1103
1104static inline void free_nodes(switch_jb_t *jb)
1105{
1106 switch_mutex_lock(jb->list_mutex);
1107 jb->node_list = NULL((void*)0);
1108 switch_mutex_unlock(jb->list_mutex);
1109}
1110
1111SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second)
1112{
1113 jb->samples_per_frame = samples_per_frame;
1114 jb->samples_per_second = samples_per_second;
1115 switch_core_inthash_init(&jb->node_hash_ts);
1116}
1117
1118SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second)
1119{
1120 if (jb && jitter) {
1121 memset(&jb->jitter, 0, sizeof(switch_jb_jitter_t));
1122 if (jb->channel) {
1123 switch_channel_set_variable_printf(jb->channel, "rtp_jb_max_ms", "%u", 0);
1124 switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_ms", "%u", 0);
1125 switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", 0);
1126 switch_channel_set_variable_printf(jb->channel, "rtp_jb_fast_acceleration_ms", "%u", 0);
1127 switch_channel_set_variable_printf(jb->channel, "rtp_jb_forced_acceleration_ms", "%u", 0);
1128 switch_channel_set_variable_printf(jb->channel, "rtp_jb_buffering_skip", "%u", 0);
1129 switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", 0);
1130 switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", 0);
1131 switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_ms", "%u", 0);
1132 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", 0);
1133 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", 0);
1134 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", 0);
1135 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", 0);
1136 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", 0);
1137 }
1138
1139 jb->jitter.estimate = jitter;
1140 jb->jitter.samples_per_frame = samples_per_frame;
1141 jb->jitter.samples_per_second = samples_per_second;
1142 jb->jitter.drop_gap = 5;
1143 }
1144}
1145
1146SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session)
1147{
1148 const char *var;
1149
1150 if (session) {
1151 jb->codec = switch_core_session_get_read_codec(session);
1152 jb->session = session;
1153 jb->channel = switch_core_session_get_channel(session);
1154 if (jb->type == SJB_AUDIO) {
1155 if (!strcmp(jb->codec->implementation->iananame, "opus")) {
1156 if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) {
1157 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_jitterbuffer.c", (const
char *)__func__, 1157, (const char*)switch_core_session_type_check
(session)
, SWITCH_LOG_DEBUG, "audio codec is %s, accelerate on\n", jb->codec->implementation->iananame);
1158 jb->elastic = SWITCH_TRUE;
1159 } else {
1160 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_jitterbuffer.c", (const
char *)__func__, 1160, (const char*)switch_core_session_type_check
(session)
, SWITCH_LOG_DEBUG1, "audio codec is %s, accelerate off\n", jb->codec->implementation->iananame);
1161 jb->elastic = SWITCH_FALSE;
1162 }
1163 } else {
1164 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_jitterbuffer.c", (const
char *)__func__, 1164, (const char*)switch_core_session_type_check
(session)
, SWITCH_LOG_DEBUG1, "audio codec is not Opus: %s\n", jb->codec->implementation->iananame);
1165 jb->elastic = SWITCH_FALSE;
1166 }
1167 }
1168
1169 if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY)((jb)->flags & SJB_QUEUE_ONLY) &&
1170 (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
1171 int tmp = atoi(var);
1172
1173 if (tmp >= 128 && tmp <= 10240) {
1174 jb->video_low_bitrate = (uint32_t)tmp;
1175 }
1176 }
1177 }
1178}
1179
1180SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag)
1181{
1182 switch_set_flag(jb, flag)(jb)->flags |= (flag);
1183}
1184
1185SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag)
1186{
1187 switch_clear_flag(jb, flag)(jb)->flags &= ~(flag);
1188}
1189
1190SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_jb_poll(switch_jb_t *jb)
1191{
1192 if (jb->type == SJB_TEXT) {
1193 if (jb->complete_frames < jb->frame_len) {
1194 if (jb->complete_frames && !jb->buffer_lag) {
1195 jb->buffer_lag = 10;
1196 }
1197 if (jb->buffer_lag && --jb->buffer_lag == 0) {
1198 jb->flush = 1;
1199 }
1200 }
1201 }
1202
1203 return (jb->complete_frames >= jb->frame_len) || jb->flush;
1204}
1205
1206SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_jb_frame_count(switch_jb_t *jb)
1207{
1208 return jb->complete_frames;
1209}
1210
1211SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_debug_level(switch_jb_t *jb, uint8_t level)
1212{
1213 jb->debug_level = level;
1214}
1215
1216SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_jb_reset(switch_jb_t *jb)
1217{
1218 jb->jitter.stats.reset++;
1219 jb->jitter.stats.expand_frame_len = 0;
1220 if (jb->channel) {
1221 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", jb->jitter.stats.reset);
1222 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", jb->jitter.stats.reset_too_big);
1223 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_expanded", "%u", jb->jitter.stats.reset_too_expanded);
1224 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", jb->jitter.stats.reset_missing_frames);
1225 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", jb->jitter.stats.reset_ts_jump);
1226 switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", jb->jitter.stats.reset_error);
1227 switch_channel_set_variable_printf(jb->channel, "rtp_jb_buffering_skip", "%u", jb->jitter.stats.buffering_skip);
1228 }
1229
1230 if (jb->type == SJB_VIDEO) {
1231 switch_mutex_lock(jb->mutex);
1232 switch_core_inthash_destroy(&jb->missing_seq_hash);
1233 switch_core_inthash_init(&jb->missing_seq_hash);
1234 switch_mutex_unlock(jb->mutex);
1235
1236 if (jb->session) {
1237 switch_core_session_request_video_refresh(jb->session)_switch_core_session_request_video_refresh(jb->session, 0,
"src/switch_jitterbuffer.c", (const char *)__func__, 1237)
;
1238 }
1239 }
1240
1241 jb_debug(jb, 2, "%s", "RESET BUFFER\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1241, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1241, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "RESET BUFFER\n")
;
1242
1243 switch_mutex_lock(jb->mutex);
1244 hide_nodes(jb);
1245 switch_mutex_unlock(jb->mutex);
1246
1247 jb->drop_flag = 0;
1248 jb->last_target_seq = 0;
1249 jb->target_seq = 0;
1250 jb->write_init = 0;
1251 jb->highest_wrote_seq = 0;
1252 jb->highest_wrote_ts = 0;
1253 jb->next_seq = 0;
1254 jb->highest_read_ts = 0;
1255 jb->highest_read_seq = 0;
1256 jb->read_init = 0;
1257 jb->complete_frames = 0;
1258 jb->period_miss_count = 0;
1259 jb->consec_miss_count = 0;
1260 jb->period_miss_pct = 0;
1261 jb->period_good_count = 0;
1262 jb->consec_good_count = 0;
1263 jb->period_count = 0;
1264 jb->period_miss_inc = 0;
1265 jb->target_ts = 0;
1266 jb->last_target_ts = 0;
1267}
1268
1269SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_jb_get_nack_success(switch_jb_t *jb)
1270{
1271 uint32_t nack_recovered; /*count*/
1272 switch_mutex_lock(jb->mutex);
1273 nack_recovered = jb->nack_saved_the_day + jb->nack_didnt_save_the_day;
1274 switch_mutex_unlock(jb->mutex);
1275 return nack_recovered;
1276}
1277
1278SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_jb_get_packets_per_frame(switch_jb_t *jb)
1279{
1280 uint32_t ppf;
1281 switch_mutex_lock(jb->mutex);
1282 ppf = jb->packet_count; /* get current packets per frame */
1283 switch_mutex_unlock(jb->mutex);
1284 return ppf;
1285}
1286
1287SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame)
1288{
1289 switch_jb_node_t *node = NULL((void*)0);
1290 if (seq) {
1291 uint16_t want_seq = seq + peek;
1292 node = switch_core_inthash_find(jb->node_hash, htons(want_seq)__bswap_16 (want_seq));
1293 } else if (ts && jb->samples_per_frame) {
1294 uint32_t want_ts = ts + (peek * jb->samples_per_frame);
1295 node = switch_core_inthash_find(jb->node_hash_ts, htonl(want_ts)__bswap_32 (want_ts));
1296 }
1297
1298 if (node) {
1299 frame->seq = ntohs(node->packet.header.seq)__bswap_16 (node->packet.header.seq);
1300 frame->timestamp = ntohl(node->packet.header.ts)__bswap_32 (node->packet.header.ts);
1301 frame->m = node->packet.header.m;
1302 frame->datalen = node->len - SWITCH_RTP_HEADER_LENsizeof(switch_rtp_hdr_t);
1303
1304 if (frame->data && frame->buflen > node->len - SWITCH_RTP_HEADER_LENsizeof(switch_rtp_hdr_t)) {
1305 memcpy(frame->data, node->packet.body, node->len - SWITCH_RTP_HEADER_LENsizeof(switch_rtp_hdr_t));
1306 }
1307 return SWITCH_STATUS_SUCCESS;
1308 }
1309
1310 return SWITCH_STATUS_FALSE;
1311}
1312
1313SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_get_frames(switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len)
1314{
1315
1316 switch_mutex_lock(jb->mutex);
1317
1318 if (min_frame_len) {
1319 *min_frame_len = jb->min_frame_len;
1320 }
1321
1322 if (max_frame_len) {
1323 *max_frame_len = jb->max_frame_len;
1324 }
1325
1326 if (cur_frame_len) {
1327 *cur_frame_len = jb->frame_len;
1328 }
1329
1330 switch_mutex_unlock(jb->mutex);
1331
1332 return SWITCH_STATUS_SUCCESS;
1333}
1334
1335SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_set_frames(switch_jb_t *jb, uint32_t min_frame_len, uint32_t max_frame_len)
1336{
1337 int lowest = 0;
1338
1339 switch_mutex_lock(jb->mutex);
1340
1341 if (jb->frame_len == jb->min_frame_len) lowest = 1;
1342
1343 jb->min_frame_len = min_frame_len;
1344 jb->max_frame_len = max_frame_len;
1345
1346 if (jb->frame_len > jb->max_frame_len) {
1347 jb->frame_len = jb->max_frame_len;
1348 }
1349
1350 if (jb->frame_len < jb->min_frame_len) {
1351 jb->frame_len = jb->min_frame_len;
1352 }
1353
1354 if (jb->frame_len > jb->highest_frame_len) {
1355 jb->highest_frame_len = jb->frame_len;
1356 }
1357
1358 if (lowest) {
1359 jb->frame_len = jb->min_frame_len;
1360 }
1361
1362 switch_mutex_unlock(jb->mutex);
1363
1364 return SWITCH_STATUS_SUCCESS;
1365}
1366
1367SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_create(switch_jb_t **jbp, switch_jb_type_t type,
1368 uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool)
1369{
1370 switch_jb_t *jb;
1371 int free_pool = 0;
1372
1373 if (!pool) {
1374 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_jitterbuffer.c"
, (const char *)__func__, 1374)
;
1375 free_pool = 1;
1376 }
1377
1378 jb = switch_core_alloc(pool, sizeof(*jb))switch_core_perform_alloc(pool, sizeof(*jb), "src/switch_jitterbuffer.c"
, (const char *)__func__, 1378)
;
1379 jb->free_pool = free_pool;
1380 jb->min_frame_len = jb->frame_len = min_frame_len;
1381 jb->max_frame_len = max_frame_len;
1382 jb->pool = pool;
1383 jb->type = type;
1384 jb->highest_frame_len = jb->frame_len;
1385
1386 if (jb->type == SJB_VIDEO) {
1387 switch_core_inthash_init(&jb->missing_seq_hash);
1388 jb->period_len = 2500;
1389 } else {
1390 jb->period_len = 250;
1391 }
1392
1393 switch_core_inthash_init(&jb->node_hash);
1394 switch_mutex_init(&jb->mutex, SWITCH_MUTEX_NESTED0x1, pool);
1395 switch_mutex_init(&jb->list_mutex, SWITCH_MUTEX_NESTED0x1, pool);
1396
1397 *jbp = jb;
1398
1399 return SWITCH_STATUS_SUCCESS;
1400}
1401
1402SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_destroy(switch_jb_t **jbp)
1403{
1404 switch_jb_t *jb = *jbp;
1405 *jbp = NULL((void*)0);
1406
1407 if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY)((jb)->flags & SJB_QUEUE_ONLY)) {
1408 jb_debug(jb, 3, "Stats: NACK saved the day: %u\n", jb->nack_saved_the_day)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1408, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Stats: NACK saved the day: %u\n", (void *) jb, (jb->type
== SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 3, 1408, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, jb->nack_saved_the_day
)
;
1409 jb_debug(jb, 3, "Stats: NACK was late: %u\n", jb->nack_didnt_save_the_day)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1409, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Stats: NACK was late: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 3, 1409, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->nack_didnt_save_the_day)
;
1410 jb_debug(jb, 3, "Stats: Hash entrycount: missing_seq_hash %u\n", switch_hashtable_count(jb->missing_seq_hash))if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1410, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Stats: Hash entrycount: missing_seq_hash %u\n", (void *) jb
, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 3, 1410, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, switch_hashtable_count
(jb->missing_seq_hash))
;
1411 }
1412 if (jb->type == SJB_VIDEO) {
1413 switch_core_inthash_destroy(&jb->missing_seq_hash);
1414 }
1415 switch_core_inthash_destroy(&jb->node_hash);
1416
1417 if (jb->node_hash_ts) {
1418 switch_core_inthash_destroy(&jb->node_hash_ts);
1419 }
1420
1421 free_nodes(jb);
1422
1423 if (jb->free_pool) {
1424 switch_core_destroy_memory_pool(&jb->pool)switch_core_perform_destroy_memory_pool(&jb->pool, "src/switch_jitterbuffer.c"
, (const char *)__func__, 1424)
;
1425 }
1426
1427 return SWITCH_STATUS_SUCCESS;
1428}
1429
1430SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_jb_pop_nack(switch_jb_t *jb)
1431{
1432 switch_hash_index_t *hi = NULL((void*)0);
1433 uint32_t nack = 0;
1434 uint16_t blp = 0;
1435 uint16_t least = 0;
1436 int i = 0;
1437 void *val;
1438 const void *var;
1439
1440 if (jb->type != SJB_VIDEO) {
1441 return 0;
1442 }
1443
1444 switch_mutex_lock(jb->mutex);
1445
1446 top:
1447
1448 for (hi = switch_core_hash_first_iter(jb->missing_seq_hash, hi); hi; hi = switch_core_hash_next(&hi)) {
1449 uint16_t seq;
1450 //const char *token;
1451 switch_time_t then = 0;
1452
1453 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
1454 //token = (const char *) val;
1455
1456 //if (token == TOKEN_2) {
1457 //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token);
1458 //printf("WTf\n");
1459 // continue;
1460 //}
1461
1462 seq = ntohs(*((uint16_t *) var))__bswap_16 (*((uint16_t *) var));
1463 then = (intptr_t) val;
1464
1465 if (then != 1 && ((uint32_t)(switch_time_now() - then)) < RENACK_TIME100000) {
1466 jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1466, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"NACKABLE seq %u too soon to repeat\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, 3, 1466
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, seq)
;
1467 continue;
1468 }
1469
1470 //if (then != 1) {
1471 // jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then);
1472 //}
1473
1474 if (seq < ntohs(jb->target_seq)__bswap_16 (jb->target_seq) - jb->frame_len) {
1475 jb_debug(jb, 3, "NACKABLE seq %u expired\n", seq)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1475, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"NACKABLE seq %u expired\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 3, 1475, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, seq)
;
1476 switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(seq)__bswap_16 (seq));
1477 goto top;
1478 }
1479
1480 if (!least || seq < least) {
1481 least = seq;
1482 }
1483 }
1484
1485 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
1486
1487 if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least)__bswap_16 (least))) {
1488 jb_debug(jb, 3, "Found NACKABLE seq %u\n", least)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1488, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Found NACKABLE seq %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 3, 1488, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, least)
;
1489 nack = (uint32_t) htons(least)__bswap_16 (least);
1490 switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) (intptr_t)switch_time_now());
1491
1492 for(i = 0; i < 16; i++) {
1493 if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least + i + 1)__bswap_16 (least + i + 1))) {
1494 switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(least + i + 1)__bswap_16 (least + i + 1), (void *)(intptr_t)switch_time_now());
1495 jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1)if (jb->debug_level >= 3) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1495, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Found addtl NACKABLE seq %u\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 3, 1495, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, least + i + 1)
;
1496 blp |= (1 << i);
1497 }
1498 }
1499
1500 blp = htons(blp)__bswap_16 (blp);
1501 nack |= (uint32_t) blp << 16;
1502
1503 //jb_frame_inc(jb, 1);
1504 }
1505
1506 switch_mutex_unlock(jb->mutex);
1507
1508
1509 return nack;
1510}
1511
1512SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
1513{
1514 uint32_t i;
1515 uint16_t want = ntohs(jb->next_seq)__bswap_16 (jb->next_seq), got = ntohs(packet->header.seq)__bswap_16 (packet->header.seq);
1516
1517 if (len >= SWITCH_RTP_MAX_PACKET_LEN(16384 + sizeof(switch_rtp_hdr_t))) {
1518 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_jitterbuffer.c", (const char
*)__func__, 1518, ((void*)0)
, SWITCH_LOG_WARNING, "trying to put %" SWITCH_SIZE_T_FMT"ld" " bytes exceeding buffer, truncate to %" SWITCH_SIZE_T_FMT"ld" "\n", len, SWITCH_RTP_MAX_PACKET_LEN(16384 + sizeof(switch_rtp_hdr_t)));
1519 len = SWITCH_RTP_MAX_PACKET_LEN(16384 + sizeof(switch_rtp_hdr_t));
1520 }
1521
1522 switch_mutex_lock(jb->mutex);
1523
1524 if (jb->highest_dropped_ts) {
1525 if (ntohl(packet->header.ts)__bswap_32 (packet->header.ts) < jb->highest_dropped_ts) {
1526 jb_debug(jb, 2, "%s", "TS ALREADY DROPPED, DROPPING PACKET\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1526, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1526, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "TS ALREADY DROPPED, DROPPING PACKET\n")
;
1527 switch_mutex_unlock(jb->mutex);
1528 return SWITCH_STATUS_SUCCESS;
1529 }
1530 jb->highest_dropped_ts = 0;
1531 }
1532
1533
1534 if (!want) want = got;
1535
1536 if (switch_test_flag(jb, SJB_QUEUE_ONLY)((jb)->flags & SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO || jb->type == SJB_TEXT) {
1537 jb->next_seq = htons(got + 1)__bswap_16 (got + 1);
1538 } else {
1539
1540 if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got)__bswap_16 (got))) {
1541 if (got < ntohs(jb->target_seq)__bswap_16 (jb->target_seq)) {
1542 jb_debug(jb, 2, "got nacked seq %u too late\n", got)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1542, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"got nacked seq %u too late\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 1542, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, got)
;
1543 jb_frame_inc(jb, 1)jb_frame_inc_line(jb, 1, 1543);
1544 jb->nack_didnt_save_the_day++;
1545 } else {
1546 jb_debug(jb, 2, "got nacked %u saved the day!\n", got)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1546, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"got nacked %u saved the day!\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 1546, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, got)
;
1547 jb->nack_saved_the_day++;
1548 }
1549 }
1550
1551 if (got > want) {
1552 if (got - want > jb->max_frame_len && got - want > 17) {
1553 jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1553, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Missing %u frames, Resetting\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 1553, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, got - want)
;
1554 jb->jitter.stats.reset_missing_frames++;
1555 switch_jb_reset(jb);
1556 } else {
1557 if (jb->type != SJB_VIDEO && jb->frame_len < got - want) {
1558 jb_frame_inc(jb, 1)jb_frame_inc_line(jb, 1, 1558);
1559 }
1560
1561 jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1561, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", (void *) jb
, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO
? "aud" : "vid")), jb->allocated_nodes, jb->visible_nodes
, 2, 1561, jb->min_frame_len, jb->max_frame_len, jb->
frame_len, jb->complete_frames, jb->period_count, jb->
consec_good_count, jb->period_good_count, jb->consec_miss_count
, jb->period_miss_count, jb->period_miss_pct, got, want
, want, got - 1)
;
1562
1563 for (i = want; i < got; i++) {
1564 jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1564, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"MARK MISSING %u ts:%u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1564, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, i, __bswap_32 (packet->header.ts))
;
1565 switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i)__bswap_16 (i), (void *)(intptr_t)1);
1566 }
1567 }
1568 }
1569
1570 if (got >= want || (want - got) > 1000) {
1571 jb->next_seq = htons(got + 1)__bswap_16 (got + 1);
1572 }
1573 }
1574
1575 add_node(jb, packet, len);
1576
1577 if (switch_test_flag(jb, SJB_QUEUE_ONLY)((jb)->flags & SJB_QUEUE_ONLY) && jb->max_packet_len && jb->max_frame_len * 2 > jb->max_packet_len &&
1578 jb->allocated_nodes > jb->max_frame_len * 2 - 1) {
1579 while ((jb->max_frame_len * 2 - jb->visible_nodes) < jb->max_packet_len) {
1580 drop_oldest_frame(jb);
1581 }
1582 } else if (switch_test_flag(jb, SJB_QUEUE_ONLY)((jb)->flags & SJB_QUEUE_ONLY) && jb->max_packet_len && jb->max_frame_len * 2 < jb->max_packet_len) {
1583 /* rtp_nack_buffer_size less than initial max_packet_len */
1584 drop_oldest_frame(jb);
1585 }
1586
1587 switch_mutex_unlock(jb->mutex);
1588
1589 return SWITCH_STATUS_SUCCESS;
1590}
1591
1592SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len)
1593{
1594 switch_jb_node_t *node;
1595 switch_status_t status = SWITCH_STATUS_NOTFOUND;
1596
1597 switch_mutex_lock(jb->mutex);
1598 if ((node = switch_core_inthash_find(jb->node_hash, seq))) {
1599 jb_debug(jb, 2, "Found buffered seq: %u\n", ntohs(seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1599, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Found buffered seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1599, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (seq))
;
1600 *packet = node->packet;
1601 *len = node->len;
1602 packet->header.version = 2;
1603 status = SWITCH_STATUS_SUCCESS;
1604 } else {
1605 jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1605, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Missing buffered seq: %u\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1605, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, __bswap_16 (seq))
;
1606 }
1607 switch_mutex_unlock(jb->mutex);
1608
1609 return status;
1610}
1611
1612SWITCH_DECLARE(switch_size_t)__attribute__((visibility("default"))) switch_size_t switch_jb_get_last_read_len(switch_jb_t *jb)
1613{
1614 return jb->last_len;
1615}
1616
1617SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
1618{
1619 switch_jb_node_t *node = NULL((void*)0);
1620 switch_status_t status;
1621 int plc = 0;
1622
1623 switch_mutex_lock(jb->mutex);
1624
1625 if (jb->complete_frames == 0) {
1
Assuming field 'complete_frames' is not equal to 0
2
Taking false branch
1626 jb->flush = 0;
1627 switch_goto_status(SWITCH_STATUS_BREAK, end)status = SWITCH_STATUS_BREAK; goto end;
1628 }
1629
1630 if (!jb->elastic && (jb->complete_frames < jb->frame_len)) {
3
Assuming field 'elastic' is not equal to 0
1631
1632 switch_jb_poll(jb);
1633
1634 if (!jb->flush) {
1635 jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1635, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"BUFFERING %u/%u\n", (void *) jb, (jb->type == SJB_TEXT ?
"txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1635, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->complete_frames , jb->frame_len)
;
1636 jb->jitter.stats.buffering_skip++;
1637 switch_channel_set_variable_printf(jb->channel, "rtp_jb_buffering_skip", "%u", jb->jitter.stats.buffering_skip);
1638 switch_goto_status(SWITCH_STATUS_MORE_DATA, end)status = SWITCH_STATUS_MORE_DATA; goto end;
1639 }
1640 }
1641
1642 jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1642, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"GET PACKET %u/%u n:%d\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1642, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->complete_frames , jb->frame_len, jb
->visible_nodes)
;
4
Assuming field 'debug_level' is < 2
5
Taking false branch
1643
1644 if (++jb->period_count >= jb->period_len) {
6
Assuming the condition is false
7
Taking false branch
1645
1646 if (jb->consec_good_count >= (jb->period_len - 5)) {
1647 jb_frame_inc(jb, -1)jb_frame_inc_line(jb, -1, 1647);
1648 }
1649
1650 jb->period_count = 1;
1651 jb->period_miss_inc = 0;
1652 jb->period_miss_count = 0;
1653 jb->period_good_count = 0;
1654 jb->consec_miss_count = 0;
1655 jb->consec_good_count = 0;
1656
1657 if (jb->type == SJB_VIDEO && jb->channel && jb->video_low_bitrate) {
1658 //switch_time_t now = switch_time_now();
1659 //int ok = (now - jb->last_bitrate_change) > 10000;
1660
1661 if (switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len == jb->min_frame_len) {
1662 jb_debug(jb, 2, "%s", "Allow BITRATE changes\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1662, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1662, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Allow BITRATE changes\n")
;
1663 switch_channel_clear_flag_recursive(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE);
1664 jb->bitrate_control = 0;
1665 if (jb->session) {
1666 switch_core_session_request_video_refresh(jb->session)_switch_core_session_request_video_refresh(jb->session, 0,
"src/switch_jitterbuffer.c", (const char *)__func__, 1666)
;
1667 }
1668 } else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->max_frame_len / 2) {
1669 switch_core_session_message_t msg = { 0 };
1670
1671 jb->bitrate_control = jb->video_low_bitrate;
1672
1673 msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
1674 msg.numeric_arg = jb->bitrate_control * 1024;
1675 msg.from = __FILE__"src/switch_jitterbuffer.c";
1676
1677 jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1677, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Force BITRATE to %d\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1677, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->bitrate_control)
;
1678
1679 switch_core_session_receive_message(jb->session, &msg)switch_core_session_perform_receive_message(jb->session, &
msg, "src/switch_jitterbuffer.c", (const char *)__func__, 1679
)
;
1680 switch_channel_set_flag_recursive(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE);
1681 if (jb->session) {
1682 switch_core_session_request_video_refresh(jb->session)_switch_core_session_request_video_refresh(jb->session, 0,
"src/switch_jitterbuffer.c", (const char *)__func__, 1682)
;
1683 }
1684 }
1685 }
1686 }
1687
1688
1689 jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
1690
1691 //if (jb->period_miss_pct > 60.0f) {
1692 // jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct);
1693 // switch_jb_reset(jb);
1694 //}
1695
1696 if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
8
Calling 'jb_next_packet'
1697 jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq))if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1697, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"Found next frame cur ts: %u seq: %u\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, 2, 1697
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (node->
packet.header.ts), __bswap_16 (node->packet.header.seq))
;
1698
1699 if (!jb->read_init || check_seq(node->packet.header.seq, jb->highest_read_seq)) {
1700 jb->highest_read_seq = node->packet.header.seq;
1701 }
1702
1703 if (jb->type != SJB_VIDEO ||
1704 (jb->read_init && check_seq(node->packet.header.seq, jb->highest_read_seq) && check_ts(node->packet.header.ts, jb->highest_read_ts))) {
1705
1706 if (jb->type != SJB_VIDEO) {
1707 jb->complete_frames--;
1708 }
1709 jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1709, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"READ frame ts: %u complete=%u/%u n:%u\n", (void *) jb, (jb->
type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" :
"vid")), jb->allocated_nodes, jb->visible_nodes, 2, 1709
, jb->min_frame_len, jb->max_frame_len, jb->frame_len
, jb->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (node->
packet.header.ts), jb->complete_frames , jb->frame_len,
jb->visible_nodes)
;
1710 jb->highest_read_ts = node->packet.header.ts;
1711 } else if (!jb->read_init) {
1712 jb->highest_read_ts = node->packet.header.ts;
1713 }
1714
1715 if (!jb->read_init) jb->read_init = 1;
1716 } else {
1717 if (jb->type == SJB_VIDEO) {
1718 //switch_jb_reset(jb);
1719
1720 switch(status) {
1721 case SWITCH_STATUS_RESTART:
1722 jb_debug(jb, 2, "%s", "Error encountered ask for new keyframe\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1722, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1722, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Error encountered ask for new keyframe\n")
;
1723 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1724 case SWITCH_STATUS_NOTFOUND:
1725 default:
1726 jb_debug(jb, 2, "%s", "No frames found wait for more\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1726, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1726, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "No frames found wait for more\n")
;
1727 switch_goto_status(SWITCH_STATUS_MORE_DATA, end)status = SWITCH_STATUS_MORE_DATA; goto end;
1728 }
1729 } else {
1730 switch(status) {
1731 case SWITCH_STATUS_RESTART:
1732 jb_debug(jb, 2, "%s", "Error encountered\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1732, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1732, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Error encountered\n")
;
1733 jb->jitter.stats.reset_error++;
1734 switch_jb_reset(jb);
1735 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1736 case SWITCH_STATUS_NOTFOUND:
1737 default:
1738 if (jb->consec_miss_count > jb->frame_len) {
1739 //switch_jb_reset(jb);
1740 jb_frame_inc(jb, 1)jb_frame_inc_line(jb, 1, 1740);
1741 jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1741, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1741, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Too many frames not found, RESIZE\n")
;
1742 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1743 } else {
1744 if (jb->elastic) {
1745 jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate) / ((jb->jitter.samples_per_second)) * 1000);
1746 jb->jitter.stats.buffer_size_ms = (int)((jb->packets_in_buffer * jb->jitter.samples_per_frame) / (jb->jitter.samples_per_second / 1000));
1747 /* When playing PLC, we take the oportunity to expand the buffer if the jitter buffer is smaller than the 3x the estimated jitter. */
1748 if (jb->jitter.stats.expand_frame_len < 0) jb->jitter.stats.expand_frame_len = 0;
1749
1750 if (jb->jitter.stats.expand_frame_len > jb->max_frame_len) {
1751 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER estimation %dms buffersize %d/%d %dms RESET TOO BIG [%d>%d] target seq[%u]\n",if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1753, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms RESET TOO BIG [%d>%d] target seq[%u]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1753, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, jb->
jitter.stats.expand_frame_len, jb->max_frame_len, __bswap_16
(jb->target_seq))
1752 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms,if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1753, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms RESET TOO BIG [%d>%d] target seq[%u]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1753, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, jb->
jitter.stats.expand_frame_len, jb->max_frame_len, __bswap_16
(jb->target_seq))
1753 jb->jitter.stats.expand_frame_len, jb->max_frame_len, ntohs(jb->target_seq))if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1753, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms RESET TOO BIG [%d>%d] target seq[%u]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1753, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, jb->
jitter.stats.expand_frame_len, jb->max_frame_len, __bswap_16
(jb->target_seq))
;
1754 jb->jitter.stats.reset_too_expanded++;
1755 jb->jitter.stats.expand_frame_len=0;
1756 switch_jb_reset(jb);
1757 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1758 } else if (jb->jitter.stats.buffer_size_ms < (3 * jb->jitter.stats.estimate_ms)) {
1759 jb_debug(jb, SWITCH_LOG_ALERT, "JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc] target_seq[%u] expand[%d] now[%ld]\n",if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1761, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc] target_seq[%u] expand[%d] now[%ld]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1761, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, __bswap_16
(jb->target_seq), jb->jitter.stats.expand_frame_len, (
int64_t)(switch_micro_time_now()/1000))
1760 jb->jitter.stats.estimate_ms, jb->complete_frames, jb->frame_len, jb->jitter.stats.buffer_size_ms,if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1761, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc] target_seq[%u] expand[%d] now[%ld]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1761, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, __bswap_16
(jb->target_seq), jb->jitter.stats.expand_frame_len, (
int64_t)(switch_micro_time_now()/1000))
1761 ntohs(jb->target_seq), jb->jitter.stats.expand_frame_len, (int64_t)(switch_micro_time_now()/1000))if (jb->debug_level >= SWITCH_LOG_ALERT) switch_log_printf
(SWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_jitterbuffer.c", (const
char *)__func__, 1761, switch_core_session_get_uuid((jb->
session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc] target_seq[%u] expand[%d] now[%ld]\n"
, (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->type
== SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb->
visible_nodes, SWITCH_LOG_ALERT, 1761, jb->min_frame_len, jb
->max_frame_len, jb->frame_len, jb->complete_frames,
jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->jitter.stats.estimate_ms, jb->complete_frames
, jb->frame_len, jb->jitter.stats.buffer_size_ms, __bswap_16
(jb->target_seq), jb->jitter.stats.expand_frame_len, (
int64_t)(switch_micro_time_now()/1000))
;
1762 jb->jitter.stats.expand++;
1763 jb->jitter.stats.expand_frame_len++;
1764 decrement_seq(jb);
1765 } else if (jb->jitter.stats.expand_frame_len >= jb->max_frame_len) {
1766 jb->jitter.stats.reset_error++;
1767 jb->jitter.stats.expand_frame_len=0;
1768 switch_jb_reset(jb);
1769 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1770 } else {
1771 jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1771, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1771, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Frame not found suggest PLC\n")
;
1772 }
1773 } else {
1774 jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1774, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"%s", (void *) jb, (jb->type == SJB_TEXT ? "txt" : (jb->
type == SJB_AUDIO ? "aud" : "vid")), jb->allocated_nodes, jb
->visible_nodes, 2, 1774, jb->min_frame_len, jb->max_frame_len
, jb->frame_len, jb->complete_frames, jb->period_count
, jb->consec_good_count, jb->period_good_count, jb->
consec_miss_count, jb->period_miss_count, jb->period_miss_pct
, "Frame not found suggest PLC\n")
;
1775 }
1776
1777 if (jb->elastic) {
1778 jb->jitter.stats.consecutive_miss++;
1779 if (jb->jitter.stats.consecutive_miss > 100) {
1780 jb->jitter.stats.reset_missing_frames++;
1781 jb->jitter.stats.consecutive_miss=0;
1782 jb->elastic = SWITCH_FALSE;
1783 switch_jb_reset(jb);
1784 switch_goto_status(SWITCH_STATUS_RESTART, end)status = SWITCH_STATUS_RESTART; goto end;
1785 }
1786 }
1787 plc = 1;
1788 switch_goto_status(SWITCH_STATUS_NOTFOUND, end)status = SWITCH_STATUS_NOTFOUND; goto end;
1789 }
1790 }
1791 }
1792 }
1793
1794 *packet = node->packet;
1795 *len = node->len;
1796 jb->last_len = *len;
1797 packet->header.version = 2;
1798 hide_node(node, SWITCH_TRUE);
1799
1800 jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "")if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1800, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"GET packet ts:%u seq:%u %s\n", (void *) jb, (jb->type ==
SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid"
)), jb->allocated_nodes, jb->visible_nodes, 2, 1800, jb
->min_frame_len, jb->max_frame_len, jb->frame_len, jb
->complete_frames, jb->period_count, jb->consec_good_count
, jb->period_good_count, jb->consec_miss_count, jb->
period_miss_count, jb->period_miss_pct, __bswap_32 (packet
->header.ts), __bswap_16 (packet->header.seq), packet->
header.m ? " <MARK>" : "")
;
1801
1802 end:
1803
1804 if (plc) {
1805 uint16_t seq;
1806 uint32_t ts = 0;
1807
1808 if (jb->samples_per_frame) {
1809 seq = htons(jb->last_psuedo_seq)__bswap_16 (jb->last_psuedo_seq);
1810 ts = jb->last_target_ts;
1811 } else {
1812 seq = jb->last_target_seq;
1813 }
1814
1815 packet->header.seq = seq;
1816 packet->header.ts = ts;
1817 } else {
1818 jb->jitter.stats.consecutive_miss=0;
1819 }
1820
1821 switch_mutex_unlock(jb->mutex);
1822
1823 if (jb->type == SJB_VIDEO) {
1824 if (jb->complete_frames > jb->max_frame_len * 2) {
1825 jb_debug(jb, 2, "JB TOO BIG (%d), RESET\n", jb->complete_frames)if (jb->debug_level >= 2) switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN
, "src/switch_jitterbuffer.c", (const char *)__func__, 1825, switch_core_session_get_uuid
((jb->session)), SWITCH_LOG_ALERT, "JB:%p:%s:%d/%d lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->"
"JB TOO BIG (%d), RESET\n", (void *) jb, (jb->type == SJB_TEXT
? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), jb->
allocated_nodes, jb->visible_nodes, 2, 1825, jb->min_frame_len
, jb->max_frame_len, jb->frame_len, jb->complete_frames
, jb->period_count, jb->consec_good_count, jb->period_good_count
, jb->consec_miss_count, jb->period_miss_count, jb->
period_miss_pct, jb->complete_frames)
;
1826 switch_jb_reset(jb);
1827 }
1828 } else {
1829 int too_big = (int)(jb->max_frame_len * 1.5);
1830 if (jb->visible_nodes > too_big && status == SWITCH_STATUS_SUCCESS) {
1831 status = SWITCH_STATUS_TIMEOUT;
1832 }
1833 }
1834
1835 return status;
1836}
1837
1838/* For Emacs:
1839 * Local Variables:
1840 * mode:c
1841 * indent-tabs-mode:t
1842 * tab-width:4
1843 * c-basic-offset:4
1844 * End:
1845 * For VIM:
1846 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1847 */