Asterisk - The Open Source Telephony Project GIT-master-7e7a603
abstract_jb.c
Go to the documentation of this file.
1/*
2 * abstract_jb: common implementation-independent jitterbuffer stuff
3 *
4 * Copyright (C) 2005, Attractel OOD
5 *
6 * Contributors:
7 * Slav Klenov <slav@securax.org>
8 *
9 * See http://www.asterisk.org for more information about
10 * the Asterisk project. Please do not directly contact
11 * any of the maintainers of this project for assistance;
12 * the project provides a web site, mailing lists and IRC
13 * channels for your use.
14 *
15 * This program is free software, distributed under the terms of
16 * the GNU General Public License Version 2. See the LICENSE file
17 * at the top of the source tree.
18 *
19 * A license has been granted to Digium (via disclaimer) for the use of
20 * this code.
21 */
22
23/*! \file
24 *
25 * \brief Common implementation-independent jitterbuffer stuff.
26 *
27 * \author Slav Klenov <slav@securax.org>
28 *
29 *
30 */
31
32/*** MODULEINFO
33 <support_level>core</support_level>
34 ***/
35
36#include "asterisk.h"
37
38#include "asterisk/frame.h"
39#include "asterisk/channel.h"
40#include "asterisk/term.h"
41#include "asterisk/utils.h"
42#include "asterisk/pbx.h"
43#include "asterisk/timing.h"
44#include "asterisk/rtp_engine.h"
46
48#include "fixedjitterbuf.h"
49#include "jitterbuf.h"
50
51/*! Internal jb flags */
52enum {
53 JB_USE = (1 << 0),
55 JB_CREATED = (1 << 2)
56};
57
58/*! The maximum size we allow the early frame buffer to get */
59#define MAXIMUM_EARLY_FRAME_COUNT 200
60
61
62/* Implementation functions */
63/* fixed */
64static void *jb_create_fixed(struct ast_jb_conf *general_config);
65static void jb_destroy_fixed(void *jb);
66static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now);
67static int jb_put_fixed(void *jb, struct ast_frame *fin, long now);
68static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl);
69static long jb_next_fixed(void *jb);
70static int jb_remove_fixed(void *jb, struct ast_frame **fout);
71static void jb_force_resynch_fixed(void *jb);
72static void jb_empty_and_reset_fixed(void *jb);
73static int jb_is_late_fixed(void *jb, long ts);
74/* adaptive */
75static void * jb_create_adaptive(struct ast_jb_conf *general_config);
76static void jb_destroy_adaptive(void *jb);
77static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now);
78static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now);
79static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl);
80static long jb_next_adaptive(void *jb);
81static int jb_remove_adaptive(void *jb, struct ast_frame **fout);
82static void jb_force_resynch_adaptive(void *jb);
83static void jb_empty_and_reset_adaptive(void *jb);
84static int jb_is_late_adaptive(void *jb, long ts);
85
86/* Available jb implementations */
87static const struct ast_jb_impl avail_impl[] = {
88 {
89 .name = "fixed",
90 .type = AST_JB_FIXED,
91 .create = jb_create_fixed,
92 .destroy = jb_destroy_fixed,
93 .put_first = jb_put_first_fixed,
94 .put = jb_put_fixed,
95 .get = jb_get_fixed,
96 .next = jb_next_fixed,
97 .remove = jb_remove_fixed,
98 .force_resync = jb_force_resynch_fixed,
99 .empty_and_reset = jb_empty_and_reset_fixed,
100 .is_late = jb_is_late_fixed,
101 },
102 {
103 .name = "adaptive",
104 .type = AST_JB_ADAPTIVE,
105 .create = jb_create_adaptive,
106 .destroy = jb_destroy_adaptive,
107 .put_first = jb_put_first_adaptive,
108 .put = jb_put_adaptive,
109 .get = jb_get_adaptive,
110 .next = jb_next_adaptive,
111 .remove = jb_remove_adaptive,
112 .force_resync = jb_force_resynch_adaptive,
113 .empty_and_reset = jb_empty_and_reset_adaptive,
114 .is_late = jb_is_late_adaptive,
115 }
116};
117
118static int default_impl = 0;
119
120/* Translations between impl and abstract return codes */
121static const int fixed_to_abstract_code[] =
123static const int adaptive_to_abstract_code[] =
125
126/* JB_GET actions (used only for the frames log) */
127static const char * const jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"};
128
129/*! \brief Macros for the frame log files */
130#define jb_framelog(...) do { \
131 if (jb->logfile) { \
132 fprintf(jb->logfile, __VA_ARGS__); \
133 fflush(jb->logfile); \
134 } \
135} while (0)
136
137
138/* Internal utility functions */
139static void jb_choose_impl(struct ast_channel *chan);
140static void jb_get_and_deliver(struct ast_channel *chan);
141static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame);
142static long get_now(struct ast_jb *jb, struct timeval *tv);
143
144
145/* Interface ast jb functions impl */
146
147
148static void jb_choose_impl(struct ast_channel *chan)
149{
150 struct ast_jb *jb = ast_channel_jb(chan);
151 struct ast_jb_conf *jbconf = &jb->conf;
152 const struct ast_jb_impl *test_impl;
153 int i, avail_impl_count = ARRAY_LEN(avail_impl);
154
156
157 if (ast_strlen_zero(jbconf->impl)) {
158 return;
159 }
160
161 for (i = 0; i < avail_impl_count; i++) {
162 test_impl = &avail_impl[i];
163 if (!strcasecmp(jbconf->impl, test_impl->name)) {
164 jb->impl = test_impl;
165 return;
166 }
167 }
168}
169
170int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1)
171{
172 struct ast_jb *jb0 = ast_channel_jb(c0);
173 struct ast_jb *jb1 = ast_channel_jb(c1);
174 struct ast_jb_conf *conf0 = &jb0->conf;
175 struct ast_jb_conf *conf1 = &jb1->conf;
176 int c0_wants_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_WANTSJITTER;
177 int c0_creates_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_CREATESJITTER;
178 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
179 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
180 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
181 int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
182 int c1_wants_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_WANTSJITTER;
183 int c1_creates_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_CREATESJITTER;
184 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
185 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
186 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
187 int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
188 int inuse = 0;
189
190 /* Determine whether audio going to c0 needs a jitter buffer */
191 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
192 ast_set_flag(jb0, JB_USE);
193 if (!c0_jb_timebase_initialized) {
194 if (c1_jb_timebase_initialized) {
195 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
196 } else {
197 gettimeofday(&jb0->timebase, NULL);
198 }
200 }
201
202 if (!c0_jb_created) {
203 jb_choose_impl(c0);
204 }
205
206 inuse = 1;
207 }
208
209 /* Determine whether audio going to c1 needs a jitter buffer */
210 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
211 ast_set_flag(jb1, JB_USE);
212 if (!c1_jb_timebase_initialized) {
213 if (c0_jb_timebase_initialized) {
214 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
215 } else {
216 gettimeofday(&jb1->timebase, NULL);
217 }
219 }
220
221 if (!c1_jb_created) {
222 jb_choose_impl(c1);
223 }
224
225 inuse = 1;
226 }
227
228 return inuse;
229}
230
231int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left)
232{
233 struct ast_jb *jb0 = ast_channel_jb(c0);
234 struct ast_jb *jb1 = ast_channel_jb(c1);
235 int c0_use_jb = ast_test_flag(jb0, JB_USE);
236 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
237 int c1_use_jb = ast_test_flag(jb1, JB_USE);
238 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
239 int wait, wait0, wait1;
240 struct timeval tv_now;
241
242 if (time_left == 0) {
243 /* No time left - the bridge will be retried */
244 /* TODO: Test disable this */
245 /*return 0;*/
246 }
247
248 if (time_left < 0) {
249 time_left = INT_MAX;
250 }
251
252 gettimeofday(&tv_now, NULL);
253
254 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
255 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
256
257 wait = wait0 < wait1 ? wait0 : wait1;
258 wait = wait < time_left ? wait : time_left;
259
260 if (wait == INT_MAX) {
261 wait = -1;
262 } else if (wait < 1) {
263 /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */
264 wait = 1;
265 }
266
267 return wait;
268}
269
270
271int ast_jb_put(struct ast_channel *chan, struct ast_frame *f)
272{
273 struct ast_jb *jb = ast_channel_jb(chan);
274 const struct ast_jb_impl *jbimpl = jb->impl;
275 void *jbobj = jb->jbobj;
276 struct ast_frame *frr;
277 long now = 0;
278
279 if (!ast_test_flag(jb, JB_USE))
280 return -1;
281
282 if (f->frametype != AST_FRAME_VOICE) {
284 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
285 jbimpl->force_resync(jbobj);
286 }
287
288 return -1;
289 }
290
291 /* We consider an enabled jitterbuffer should receive frames with valid timing info. */
292 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
293 ast_log(LOG_WARNING, "%s received frame with invalid timing info: "
294 "has_timing_info=%u, len=%ld, ts=%ld, src=%s\n",
296 return -1;
297 }
298
299 frr = ast_frdup(f);
300
301 if (!frr) {
302 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", ast_channel_name(chan));
303 return -1;
304 }
305
306 if (!ast_test_flag(jb, JB_CREATED)) {
307 if (create_jb(chan, frr)) {
308 ast_frfree(frr);
309 /* Disable the jitterbuffer */
311 return -1;
312 }
313
315 return 0;
316 } else {
317 now = get_now(jb, NULL);
318 if (jbimpl->put(jbobj, frr, now) != AST_JB_IMPL_OK) {
319 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
320 ast_frfree(frr);
321 /*return -1;*/
322 /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't
323 be delivered at all */
324 return 0;
325 }
326
327 jb->next = jbimpl->next(jbobj);
328
329 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
330
331 return 0;
332 }
333}
334
335
337{
338 struct ast_jb *jb0 = ast_channel_jb(c0);
339 struct ast_jb *jb1 = ast_channel_jb(c1);
340 int c0_use_jb = ast_test_flag(jb0, JB_USE);
341 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
342 int c1_use_jb = ast_test_flag(jb1, JB_USE);
343 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
344
345 if (c0_use_jb && c0_jb_is_created)
347
348 if (c1_use_jb && c1_jb_is_created)
350}
351
352
353static void jb_get_and_deliver(struct ast_channel *chan)
354{
355 struct ast_jb *jb = ast_channel_jb(chan);
356 const struct ast_jb_impl *jbimpl = jb->impl;
357 void *jbobj = jb->jbobj;
358 struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, };
359 long now;
360 int interpolation_len, res;
361
362 now = get_now(jb, NULL);
363 jb->next = jbimpl->next(jbobj);
364 if (now < jb->next) {
365 jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next);
366 return;
367 }
368
369 while (now >= jb->next) {
370 interpolation_len = ast_format_get_default_ms(jb->last_format);
371
372 res = jbimpl->get(jbobj, &f, now, interpolation_len);
373
374 switch (res) {
375 case AST_JB_IMPL_OK:
376 /* deliver the frame */
377 ast_write(chan, f);
378 case AST_JB_IMPL_DROP:
379 jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
380 now, jb_get_actions[res], f->ts, f->len);
382 ast_frfree(f);
383 break;
385 /* interpolate a frame */
386 f = &finterp;
387 f->subclass.format = jb->last_format;
388 f->samples = interpolation_len * 8;
389 f->src = "JB interpolation";
390 f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
392 /* deliver the interpolated frame */
393 ast_write(chan, f);
394 jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
395 break;
398 "AST_JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
399 jbimpl->name, now, jb->next, jbimpl->next(jbobj));
400 jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now);
401 return;
402 default:
403 ast_log(LOG_ERROR, "This should never happen!\n");
404 ast_assert("JB type unknown" == NULL);
405 break;
406 }
407
408 jb->next = jbimpl->next(jbobj);
409 }
410}
411
412
413static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
414{
415 struct ast_jb *jb = ast_channel_jb(chan);
416 struct ast_jb_conf *jbconf = &jb->conf;
417 const struct ast_jb_impl *jbimpl = jb->impl;
418 void *jbobj;
419 long now;
420 char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1];
421 char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp;
422 int res;
423
424 jbobj = jb->jbobj = jbimpl->create(jbconf);
425 if (!jbobj) {
426 ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", ast_channel_name(chan));
427 return -1;
428 }
429
430 now = get_now(jb, NULL);
431 res = jbimpl->put_first(jbobj, frr, now);
432
433 /* The result of putting the first frame should not differ from OK. However, its possible
434 some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */
435 if (res != AST_JB_IMPL_OK) {
436 ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", ast_channel_name(chan));
437 /*
438 jbimpl->destroy(jbobj);
439 return -1;
440 */
441 }
442
443 /* Init next */
444 jb->next = jbimpl->next(jbobj);
445
446 /* Init last format for a first time. */
448
449 /* Create a frame log file */
450 if (ast_test_flag(jbconf, AST_JB_LOG)) {
451 struct ast_channel *bridged = ast_channel_bridge_peer(chan);
452 char safe_logfile[30] = "/tmp/logfile-XXXXXX";
453 int safe_fd;
454
455 snprintf(name2, sizeof(name2), "%s", ast_channel_name(chan));
456 while ((tmp = strchr(name2, '/'))) {
457 *tmp = '#';
458 }
459
460 /* We should always have bridged chan if a jitterbuffer is in use */
461 ast_assert(bridged != NULL);
462
463 snprintf(name1, sizeof(name1), "%s", ast_channel_name(bridged));
464 while ((tmp = strchr(name1, '/'))) {
465 *tmp = '#';
466 }
467
468 snprintf(logfile_pathname, sizeof(logfile_pathname),
469 "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2);
470 unlink(logfile_pathname);
471 safe_fd = mkstemp(safe_logfile);
472 if (safe_fd < 0 || link(safe_logfile, logfile_pathname) || unlink(safe_logfile) || !(jb->logfile = fdopen(safe_fd, "w+b"))) {
473 ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s': %s\n", logfile_pathname, strerror(errno));
474 jb->logfile = NULL;
475 if (safe_fd > -1) {
476 close(safe_fd);
477 }
478 }
479
480 if (res == AST_JB_IMPL_OK) {
481 jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n",
482 now, frr->ts, frr->len);
483 } else {
484 jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
485 now, frr->ts, frr->len);
486 }
487
488 ast_channel_cleanup(bridged);
489 }
490
491 ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, ast_channel_name(chan));
492
493 /* Free the frame if it has not been queued in the jb */
494 if (res != AST_JB_IMPL_OK) {
495 ast_frfree(frr);
496 }
497
498 return 0;
499}
500
501
502void ast_jb_destroy(struct ast_channel *chan)
503{
504 struct ast_jb *jb = ast_channel_jb(chan);
505 const struct ast_jb_impl *jbimpl = jb->impl;
506 void *jbobj = jb->jbobj;
507 struct ast_frame *f;
508
509 if (jb->logfile) {
510 fclose(jb->logfile);
511 jb->logfile = NULL;
512 }
513
515
516 if (ast_test_flag(jb, JB_CREATED)) {
517 /* Remove and free all frames still queued in jb */
518 while (jbimpl->remove(jbobj, &f) == AST_JB_IMPL_OK) {
519 ast_frfree(f);
520 }
521
522 jbimpl->destroy(jbobj);
523 jb->jbobj = NULL;
524
526
527 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan));
528 }
529}
530
531
532static long get_now(struct ast_jb *jb, struct timeval *when)
533{
534 struct timeval now;
535
536 if (!when) {
537 when = &now;
538 gettimeofday(when, NULL);
539 }
540
541 return ast_tvdiff_ms(*when, jb->timebase);
542}
543
544
545int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
546{
547 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
548 const char *name;
549 int tmp;
550
551 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) {
552 return -1;
553 }
554
555 name = varname + prefixlen;
556
557 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
559 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
561 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
562 if ((tmp = atoi(value)) > 0)
563 conf->max_size = tmp;
564 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
565 if ((tmp = atoi(value)) > 0)
566 conf->resync_threshold = tmp;
567 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
569 snprintf(conf->impl, sizeof(conf->impl), "%s", value);
570 } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
571 if (sscanf(value, "%30d", &tmp) == 1) {
572 conf->target_extra = tmp;
573 }
574 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
576 } else if (!strcasecmp(name, AST_JB_CONF_SYNC_VIDEO)) {
578 } else {
579 return -1;
580 }
581
582 return 0;
583}
584
586{
587 struct ast_jb_conf conf = ast_channel_jb(chan)->conf;
589 ast_jb_create_framehook(chan, &conf, 1);
590 }
591}
592
593void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
594{
595 memcpy(&ast_channel_jb(chan)->conf, conf, sizeof(*conf));
596}
597
598
599void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
600{
601 memcpy(conf, &ast_channel_jb((struct ast_channel *) chan)->conf, sizeof(*conf));
602}
603
605{
606 struct ast_jb *jb0 = ast_channel_jb(c0);
607 struct ast_jb *jb1 = ast_channel_jb(c1);
608 int c0_use_jb = ast_test_flag(jb0, JB_USE);
609 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
610 int c1_use_jb = ast_test_flag(jb1, JB_USE);
611 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
612
613 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
614 jb0->impl->empty_and_reset(jb0->jbobj);
615 }
616
617 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
618 jb1->impl->empty_and_reset(jb1->jbobj);
619 }
620}
621
622/* Implementation functions */
623
624/* fixed */
625static void * jb_create_fixed(struct ast_jb_conf *general_config)
626{
627 struct fixed_jb_conf conf;
628
629 conf.jbsize = general_config->max_size;
630 conf.resync_threshold = general_config->resync_threshold;
631
632 return fixed_jb_new(&conf);
633}
634
635static void jb_destroy_fixed(void *jb)
636{
637 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
638
639 /* Ensure the fixed jb is empty - otherwise it will raise an ASSERT */
641
642 /* destroy the jb */
643 fixed_jb_destroy(fixedjb);
644}
645
646
647static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
648{
649 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
650 int res;
651
652 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
653
654 return fixed_to_abstract_code[res];
655}
656
657
658static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
659{
660 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
661 int res;
662
663 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
664
665 return fixed_to_abstract_code[res];
666}
667
668
669static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
670{
671 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
672 struct fixed_jb_frame frame = { .data = &ast_null_frame };
673 int res;
674
675 res = fixed_jb_get(fixedjb, &frame, now, interpl);
676 *fout = frame.data;
677
678 return fixed_to_abstract_code[res];
679}
680
681
682static long jb_next_fixed(void *jb)
683{
684 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
685
686 return fixed_jb_next(fixedjb);
687}
688
689
690static int jb_remove_fixed(void *jb, struct ast_frame **fout)
691{
692 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
693 struct fixed_jb_frame frame;
694 int res;
695
696 res = fixed_jb_remove(fixedjb, &frame);
697 *fout = frame.data;
698
699 return fixed_to_abstract_code[res];
700}
701
702
703static void jb_force_resynch_fixed(void *jb)
704{
705 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
706
708}
709
710static void jb_empty_and_reset_fixed(void *jb)
711{
712 struct fixed_jb *fixedjb = jb;
713 struct fixed_jb_frame f;
714
715 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) {
716 ast_frfree(f.data);
717 }
718}
719
720static int jb_is_late_fixed(void *jb, long ts)
721{
722 return fixed_jb_is_late(jb, ts);
723}
724
725/* adaptive */
726
727static void *jb_create_adaptive(struct ast_jb_conf *general_config)
728{
729 jb_conf jbconf;
730 jitterbuf *adaptivejb;
731
732 adaptivejb = jb_new();
733 if (adaptivejb) {
734 jbconf.max_jitterbuf = general_config->max_size;
735 jbconf.resync_threshold = general_config->resync_threshold;
736 jbconf.max_contig_interp = 10;
737 jbconf.target_extra = general_config->target_extra;
738 jb_setconf(adaptivejb, &jbconf);
739 }
740
741 return adaptivejb;
742}
743
744
745static void jb_destroy_adaptive(void *jb)
746{
747 jitterbuf *adaptivejb = (jitterbuf *) jb;
748
749 jb_destroy(adaptivejb);
750}
751
752
753static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
754{
755 return jb_put_adaptive(jb, fin, now);
756}
757
758
759static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
760{
761 jitterbuf *adaptivejb = (jitterbuf *) jb;
762 int res;
763
764 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
765
766 return adaptive_to_abstract_code[res];
767}
768
769
770static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
771{
772 jitterbuf *adaptivejb = (jitterbuf *) jb;
773 jb_frame frame = { .data = &ast_null_frame };
774 int res;
775
776 res = jb_get(adaptivejb, &frame, now, interpl);
777 *fout = frame.data;
778
779 return adaptive_to_abstract_code[res];
780}
781
782
783static long jb_next_adaptive(void *jb)
784{
785 jitterbuf *adaptivejb = (jitterbuf *) jb;
786
787 return jb_next(adaptivejb);
788}
789
790
791static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
792{
793 jitterbuf *adaptivejb = (jitterbuf *) jb;
794 jb_frame frame;
795 int res;
796
797 res = jb_getall(adaptivejb, &frame);
798 *fout = frame.data;
799
800 return adaptive_to_abstract_code[res];
801}
802
803
804static void jb_force_resynch_adaptive(void *jb)
805{
806}
807
808static void jb_empty_and_reset_adaptive(void *jb)
809{
810 jitterbuf *adaptivejb = jb;
811 jb_frame f;
812
813 while (jb_getall(adaptivejb, &f) == JB_OK) {
814 ast_frfree(f.data);
815 }
816
817 jb_reset(adaptivejb);
818}
819
821{
822 int i;
823 for (i = 0; i < ARRAY_LEN(avail_impl); i++) {
824 if (avail_impl[i].type == type) {
825 return &avail_impl[i];
826 }
827 }
828 return NULL;
829}
830
831static int jb_is_late_adaptive(void *jb, long ts)
832{
833 return jb_is_late(jb, ts);
834}
835
836#define DEFAULT_TIMER_INTERVAL 20
837#define DEFAULT_SIZE 200
838#define DEFAULT_TARGET_EXTRA 40
839#define DEFAULT_RESYNC 1000
840#define DEFAULT_TYPE AST_JB_FIXED
841
843 unsigned int timestamp;
844 struct timeval ntp;
845};
846
848 const struct ast_jb_impl *jb_impl;
850 struct timeval start_tv;
853 int timer_interval; /* ms between deliveries */
855 int first;
861 unsigned int early_frame_count;
864 void *jb_obj;
865};
866
867static void jb_framedata_destroy(struct jb_framedata *framedata)
868{
869 struct ast_frame *frame;
870
871 if (framedata->timer) {
872 ast_timer_close(framedata->timer);
873 framedata->timer = NULL;
874 }
875 if (framedata->jb_impl && framedata->jb_obj) {
876 struct ast_frame *f;
877 while (framedata->jb_impl->remove(framedata->jb_obj, &f) == AST_JB_IMPL_OK) {
878 ast_frfree(f);
879 }
880 framedata->jb_impl->destroy(framedata->jb_obj);
881 framedata->jb_obj = NULL;
882 }
883 ao2_cleanup(framedata->last_format);
884 while ((frame = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list))) {
885 ast_frfree(frame);
886 }
887 ast_free(framedata);
888}
889
891{
893 conf->max_size = DEFAULT_SIZE;
894 conf->resync_threshold = DEFAULT_RESYNC;
895 ast_copy_string(conf->impl, "fixed", sizeof(conf->impl));
896 conf->target_extra = DEFAULT_TARGET_EXTRA;
897}
898
899static void datastore_destroy_cb(void *data) {
900 ast_free(data);
901 ast_debug(1, "JITTERBUFFER datastore destroyed\n");
902}
903
904static const struct ast_datastore_info jb_datastore = {
905 .type = "jitterbuffer",
906 .destroy = datastore_destroy_cb
907};
908
909static void hook_destroy_cb(void *framedata)
910{
911 ast_debug(1, "JITTERBUFFER hook destroyed\n");
912 jb_framedata_destroy((struct jb_framedata *) framedata);
913}
914
915static struct timeval jitterbuffer_frame_get_ntp_timestamp(const struct jb_stream_sync *stream_sync, const struct ast_frame *frame)
916{
917 int timestamp_diff;
918 unsigned int rate;
919
920 /* It's possible for us to receive frames before we receive the information allowing
921 * us to do NTP/RTP timestamp calculations. Since the information isn't available we
922 * can't generate one and give an empty timestamp.
923 */
924 if (ast_tvzero(stream_sync->ntp)) {
925 return ast_tv(0, 0);
926 }
927
928 /* Convert the Asterisk timestamp into an RTP timestamp, and then based on the difference we can
929 * determine how many samples are in the frame and how long has elapsed since the synchronization
930 * RTP and NTP timestamps were received giving us the NTP timestamp for this frame.
931 */
932 if (frame->frametype == AST_FRAME_VOICE) {
933 rate = ast_rtp_get_rate(frame->subclass.format);
934 timestamp_diff = (frame->ts * (rate / 1000)) - stream_sync->timestamp;
935 } else {
936 /* Video is special - internally we reference it as 1000 to preserve the RTP timestamp but
937 * it is actually 90000, this is why we can just directly subtract the timestamp.
938 */
939 rate = 90000;
940 timestamp_diff = frame->ts - stream_sync->timestamp;
941 }
942
943 if (timestamp_diff < 0) {
944 /* It's possible for us to be asked for an NTP timestamp from before our latest
945 * RTCP SR report. To handle this we subtract so we go back in time.
946 */
947 return ast_tvsub(stream_sync->ntp, ast_samp2tv(abs(timestamp_diff), rate));
948 } else {
949 return ast_tvadd(stream_sync->ntp, ast_samp2tv(timestamp_diff, rate));
950 }
951}
952
953static struct ast_frame *hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
954{
955 struct jb_framedata *framedata = data;
956 struct timeval now_tv;
957 int64_t relative_frame_start;
958 int putframe = 0; /* signifies if audio frame was placed into the buffer or not */
959
960 switch (event) {
962 break;
966 return frame;
967 }
968
969 if (ast_channel_fdno(chan) == AST_JITTERBUFFER_FD && framedata->timer) {
970 if (ast_timer_ack(framedata->timer, 1) < 0) {
971 ast_log(LOG_ERROR, "Failed to acknowledge timer in jitter buffer\n");
972 return frame;
973 }
974 }
975
976 /*
977 * If the frame has been requeued (for instance when the translate core returns
978 * more than one frame) then if the frame is late we want to immediately return
979 * it. Otherwise attempt to insert it into the jitterbuffer.
980 *
981 * If the frame is requeued and late then in all likely hood it's a frame that
982 * that was previously retrieved from the jitterbuffer, passed to the translate
983 * core, and then put back into the channel read queue. Even if it had not been
984 * in the jitterbuffer prior to now it needs to be the next frame "out".
985 *
986 * However late arriving frames that have not been requeued (i.e. regular frames)
987 * need to be passed to the jitterbuffer so they can be appropriately dropped. As
988 * well any requeued frames that are not late should be put into the jitterbuffer.
989 */
990 if (!frame || (ast_test_flag(frame, AST_FRFLAG_REQUEUED) &&
991 framedata->jb_impl->is_late(framedata->jb_obj, frame->ts))) {
992 return frame;
993 }
994
995 if (ast_test_flag(&framedata->jb_conf, AST_JB_SYNC_VIDEO)) {
996 if (frame->frametype == AST_FRAME_VOICE) {
997 /* Store the stream identifier for the audio stream so we can associate the incoming RTCP SR
998 * with the correct stream sync structure.
999 */
1000 framedata->audio_stream_id = frame->stream_num;
1001 } else if (frame->frametype == AST_FRAME_RTCP && frame->subclass.integer == AST_RTP_RTCP_SR) {
1002 struct ast_rtp_rtcp_report *rtcp_report = frame->data.ptr;
1003 struct jb_stream_sync *stream_sync = NULL;
1004
1005 /* Determine which stream this RTCP is in regards to */
1006 if (framedata->audio_stream_id == frame->stream_num) {
1007 stream_sync = &framedata->audio_stream_sync;
1008 } else if (framedata->video_stream_id == frame->stream_num) {
1009 stream_sync = &framedata->video_stream_sync;
1010 }
1011
1012 if (stream_sync) {
1013 /* Store the RTP and NTP timestamp mapping so we can derive an NTP timestamp for each frame */
1014 stream_sync->timestamp = rtcp_report->sender_information.rtp_timestamp;
1015 stream_sync->ntp = rtcp_report->sender_information.ntp_timestamp;
1016 }
1017 } else if (frame->frametype == AST_FRAME_VIDEO) {
1018 /* If a video frame is late according to the audio timestamp don't stash it away, just return it.
1019 * If however it is ahead then we keep it until such time as the audio catches up.
1020 */
1021 struct ast_frame *jbframe;
1022
1023 framedata->video_stream_id = frame->stream_num;
1024
1025 /* If no timing information is available we can't store this away, so just let it through now */
1027 return frame;
1028 }
1029
1030 /* To ensure that the video starts when the audio starts we only start allowing frames through once
1031 * audio starts flowing.
1032 */
1033 if (framedata->audio_flowing) {
1034 struct timeval video_timestamp;
1035
1036 video_timestamp = jitterbuffer_frame_get_ntp_timestamp(&framedata->video_stream_sync, frame);
1037 if (ast_tvdiff_ms(framedata->last_audio_ntp_timestamp, video_timestamp) >= 0) {
1038 return frame;
1039 }
1040 }
1041
1042 /* To prevent the early frame buffer from growing uncontrolled we impose a maximum count that it can
1043 * get to. If this is reached then we drop a video frame, which should cause the receiver to ask for a
1044 * new key frame.
1045 */
1046 if (framedata->early_frame_count == MAXIMUM_EARLY_FRAME_COUNT) {
1047 jbframe = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list);
1048 framedata->early_frame_count--;
1049 ast_frfree(jbframe);
1050 }
1051
1052 jbframe = ast_frisolate(frame);
1053 if (!jbframe) {
1054 /* If we can't isolate the frame the safest thing we can do is return it, even if the A/V sync
1055 * may be off.
1056 */
1057 return frame;
1058 }
1059
1060 AST_LIST_INSERT_TAIL(&framedata->early_frames, jbframe, frame_list);
1061 framedata->early_frame_count++;
1062 return &ast_null_frame;
1063 }
1064 }
1065
1066 now_tv = ast_tvnow();
1067 relative_frame_start = ast_tvdiff_ms(now_tv, framedata->start_tv);
1068 if (relative_frame_start < 0) {
1069 /*
1070 * The only way for this to happen is if the system time has
1071 * stepped backwards between the time framedata->start_tv was
1072 * set and now. Think an ntpd or systemd-timesyncd adjustment.
1073 *
1074 * Just pass the frame through.
1075 */
1076 return frame;
1077 }
1078
1079 if (frame->frametype == AST_FRAME_VOICE) {
1080 int res;
1081 struct ast_frame *jbframe;
1082
1083 if (!ast_test_flag(frame, AST_FRFLAG_HAS_TIMING_INFO) || frame->len < 2 || frame->ts < 0) {
1084 /* only frames with timing info can enter the jitterbuffer */
1085 return frame;
1086 }
1087
1088 jbframe = ast_frisolate(frame);
1089 ao2_replace(framedata->last_format, frame->subclass.format);
1090
1091 if (frame->len && (frame->len != framedata->timer_interval)) {
1092 framedata->timer_interval = frame->len;
1093 ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
1094 }
1095 if (!framedata->first) {
1096 framedata->first = 1;
1097 res = framedata->jb_impl->put_first(framedata->jb_obj, jbframe, relative_frame_start);
1098 } else {
1099 res = framedata->jb_impl->put(framedata->jb_obj, jbframe, relative_frame_start);
1100 }
1101
1102 if (res == AST_JB_IMPL_OK) {
1103 if (jbframe != frame) {
1104 ast_frfree(frame);
1105 }
1106 frame = &ast_null_frame;
1107 } else if (jbframe != frame) {
1108 ast_frfree(jbframe);
1109 }
1110 putframe = 1;
1111 }
1112
1113 if (frame->frametype == AST_FRAME_NULL) {
1114 int res;
1115 long next = framedata->jb_impl->next(framedata->jb_obj);
1116
1117 /* If relative_frame_start is earlier than the next expected output frame
1118 * from the jitterbuffer we may choose to pass on retrieving
1119 * a frame during this read iteration. The only exception
1120 * to this rule is when an audio frame is placed into the buffer
1121 * and the time for the next frame to come out of the buffer is
1122 * at least within the timer_interval of the next output frame. By
1123 * doing this we are able to feed off the timing of the input frames
1124 * and only rely on our jitterbuffer timer when frames are dropped.
1125 * During testing, this hybrid form of timing gave more reliable results. */
1126 if (relative_frame_start < next) {
1127 long int diff = next - relative_frame_start;
1128 if (!putframe) {
1129 return frame;
1130 } else if (diff >= framedata->timer_interval) {
1131 return frame;
1132 }
1133 }
1134
1135 ast_frfree(frame);
1136 frame = &ast_null_frame;
1137 res = framedata->jb_impl->get(framedata->jb_obj, &frame, relative_frame_start, framedata->timer_interval);
1138 switch (res) {
1139 case AST_JB_IMPL_OK:
1140 /* got it, and pass it through */
1141 break;
1142 case AST_JB_IMPL_DROP:
1143 ast_frfree(frame);
1144 frame = &ast_null_frame;
1145 break;
1146 case AST_JB_IMPL_INTERP:
1147 if (framedata->last_format) {
1148 struct ast_frame tmp = { 0, };
1149
1150 tmp.frametype = AST_FRAME_VOICE;
1151 tmp.subclass.format = framedata->last_format;
1152 /* example: 8000hz / (1000 / 20ms) = 160 samples */
1153 tmp.samples = ast_format_get_sample_rate(framedata->last_format) / (1000 / framedata->timer_interval);
1154 tmp.delivery = ast_tvadd(framedata->start_tv, ast_samp2tv(next, 1000));
1155 tmp.offset = AST_FRIENDLY_OFFSET;
1156 tmp.src = "func_jitterbuffer interpolation";
1157 ast_frfree(frame);
1158 frame = ast_frdup(&tmp);
1159 break;
1160 }
1161 /* else fall through */
1163 ast_frfree(frame);
1164 frame = &ast_null_frame;
1165 break;
1166 }
1167 }
1168
1169 if (frame->frametype == AST_FRAME_CONTROL) {
1170 struct ast_frame *early_frame;
1171
1172 switch(frame->subclass.integer) {
1173 case AST_CONTROL_HOLD:
1174 case AST_CONTROL_UNHOLD:
1178 framedata->jb_impl->force_resync(framedata->jb_obj);
1179 /* Since we are resyncing go ahead and clear out the video frames too */
1180 while ((early_frame = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list))) {
1181 ast_frfree(early_frame);
1182 }
1183 framedata->audio_flowing = 0;
1184 framedata->early_frame_count = 0;
1185 break;
1186 default:
1187 break;
1188 }
1189 }
1190
1191 /* If a voice frame is being passed through see if we need to add any additional frames to it */
1192 if (ast_test_flag(&framedata->jb_conf, AST_JB_SYNC_VIDEO) && frame->frametype == AST_FRAME_VOICE) {
1193 AST_LIST_HEAD_NOLOCK(, ast_frame) additional_frames;
1194 struct ast_frame *early_frame;
1195
1196 /* We store the last NTP timestamp for the audio given to the core so that subsequents frames which
1197 * are late can be passed immediately through (this will occur for video frames which are returned here)
1198 */
1200 framedata->audio_flowing = 1;
1201
1202 AST_LIST_HEAD_INIT_NOLOCK(&additional_frames);
1203
1204 AST_LIST_TRAVERSE_SAFE_BEGIN(&framedata->early_frames, early_frame, frame_list) {
1205 struct timeval early_timestamp = jitterbuffer_frame_get_ntp_timestamp(&framedata->video_stream_sync, early_frame);
1206 int diff = ast_tvdiff_ms(framedata->last_audio_ntp_timestamp, early_timestamp);
1207
1208 /* If this frame is from the past we need to include it with the audio frame that is going
1209 * out.
1210 */
1211 if (diff >= 0) {
1213 framedata->early_frame_count--;
1214 AST_LIST_INSERT_TAIL(&additional_frames, early_frame, frame_list);
1215 }
1216 }
1218
1219 /* Append any additional frames we may want to include (such as video) */
1220 AST_LIST_NEXT(frame, frame_list) = AST_LIST_FIRST(&additional_frames);
1221 }
1222
1223 return frame;
1224}
1225
1226/* set defaults */
1227static int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
1228{
1229 int jb_impl_type = DEFAULT_TYPE;
1230 /* Initialize defaults */
1231 framedata->timer_fd = -1;
1232 memcpy(&framedata->jb_conf, jb_conf, sizeof(*jb_conf));
1233
1234 /* Figure out implementation type from the configuration implementation string */
1235 if (!ast_strlen_zero(jb_conf->impl)) {
1236 if (!strcasecmp(jb_conf->impl, "fixed")) {
1237 jb_impl_type = AST_JB_FIXED;
1238 } else if (!strcasecmp(jb_conf->impl, "adaptive")) {
1239 jb_impl_type = AST_JB_ADAPTIVE;
1240 } else {
1241 ast_log(LOG_WARNING, "Unknown Jitterbuffer type %s. Failed to create jitterbuffer.\n", jb_conf->impl);
1242 return -1;
1243 }
1244 }
1245
1246 if (!(framedata->jb_impl = ast_jb_get_impl(jb_impl_type))) {
1247 return -1;
1248 }
1249
1250 if (!(framedata->timer = ast_timer_open())) {
1251 return -1;
1252 }
1253
1254 framedata->audio_stream_id = -1;
1255 framedata->video_stream_id = -1;
1257 framedata->timer_fd = ast_timer_fd(framedata->timer);
1259 ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
1260 framedata->start_tv = ast_tvnow();
1261
1262 framedata->jb_obj = framedata->jb_impl->create(&framedata->jb_conf);
1263 return 0;
1264}
1265
1266
1267void ast_jb_create_framehook(struct ast_channel *chan, struct ast_jb_conf *jb_conf, int prefer_existing)
1268{
1269 struct jb_framedata *framedata;
1270 struct ast_datastore *datastore = NULL;
1271 struct ast_framehook_interface interface = {
1273 .event_cb = hook_event_cb,
1274 .destroy_cb = hook_destroy_cb,
1275 };
1276 int i = 0;
1277
1278 /* If disabled, strip any existing jitterbuffer and don't replace it. */
1279 if (!strcasecmp(jb_conf->impl, "disabled")) {
1280 int *id;
1281 ast_channel_lock(chan);
1282 if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1283 id = datastore->data;
1284 ast_framehook_detach(chan, *id);
1285 ast_channel_datastore_remove(chan, datastore);
1286 ast_datastore_free(datastore);
1287 }
1288 ast_channel_unlock(chan);
1289 return;
1290 }
1291
1292 if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
1293 return;
1294 }
1295
1296 if (jb_framedata_init(framedata, jb_conf)) {
1297 jb_framedata_destroy(framedata);
1298 return;
1299 }
1300
1301 interface.data = framedata;
1302
1303 ast_channel_lock(chan);
1304 i = ast_framehook_attach(chan, &interface);
1305 if (i >= 0) {
1306 int *id;
1307 if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1308 /* There is already a jitterbuffer on the channel. */
1309 if (prefer_existing) {
1310 /* We prefer the existing jitterbuffer, so remove the new one and keep the old one. */
1311 ast_framehook_detach(chan, i);
1312 ast_channel_unlock(chan);
1313 return;
1314 }
1315 /* We prefer the new jitterbuffer, so strip the old one. */
1316 id = datastore->data;
1317 ast_framehook_detach(chan, *id);
1318 ast_channel_datastore_remove(chan, datastore);
1319 ast_datastore_free(datastore);
1320 }
1321
1322 if (!(datastore = ast_datastore_alloc(&jb_datastore, NULL))) {
1323 ast_framehook_detach(chan, i);
1324 ast_channel_unlock(chan);
1325 return;
1326 }
1327
1328 if (!(id = ast_calloc(1, sizeof(int)))) {
1329 ast_datastore_free(datastore);
1330 ast_framehook_detach(chan, i);
1331 ast_channel_unlock(chan);
1332 return;
1333 }
1334
1335 *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
1336 datastore->data = id;
1337 ast_channel_datastore_add(chan, datastore);
1338
1340 } else {
1341 jb_framedata_destroy(framedata);
1342 framedata = NULL;
1343 }
1344 ast_channel_unlock(chan);
1345}
void ast_jb_create_framehook(struct ast_channel *chan, struct ast_jb_conf *jb_conf, int prefer_existing)
Applies a jitterbuffer framehook to a channel based on a provided jitterbuffer config.
Definition: abstract_jb.c:1267
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
Definition: abstract_jb.c:658
static int jb_remove_fixed(void *jb, struct ast_frame **fout)
Definition: abstract_jb.c:690
#define MAXIMUM_EARLY_FRAME_COUNT
Definition: abstract_jb.c:59
static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame)
Definition: abstract_jb.c:413
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1)
drops all frames from a jitterbuffer and resets it
Definition: abstract_jb.c:604
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
static struct timeval jitterbuffer_frame_get_ntp_timestamp(const struct jb_stream_sync *stream_sync, const struct ast_frame *frame)
Definition: abstract_jb.c:915
static int jb_is_late_adaptive(void *jb, long ts)
Definition: abstract_jb.c:831
static void jb_framedata_destroy(struct jb_framedata *framedata)
Definition: abstract_jb.c:867
static void jb_force_resynch_fixed(void *jb)
Definition: abstract_jb.c:703
static const int fixed_to_abstract_code[]
Definition: abstract_jb.c:121
static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
Definition: abstract_jb.c:759
void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1)
Deliver the queued frames that should be delivered now for both channels.
Definition: abstract_jb.c:336
static long jb_next_adaptive(void *jb)
Definition: abstract_jb.c:783
static void jb_get_and_deliver(struct ast_channel *chan)
Definition: abstract_jb.c:353
static long jb_next_fixed(void *jb)
Definition: abstract_jb.c:682
#define DEFAULT_TARGET_EXTRA
Definition: abstract_jb.c:838
static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
Definition: abstract_jb.c:770
void ast_jb_conf_default(struct ast_jb_conf *conf)
Sets the contents of an ast_jb_conf struct to the default jitterbuffer settings.
Definition: abstract_jb.c:890
#define DEFAULT_RESYNC
Definition: abstract_jb.c:839
@ JB_CREATED
Definition: abstract_jb.c:55
@ JB_USE
Definition: abstract_jb.c:53
@ JB_TIMEBASE_INITIALIZED
Definition: abstract_jb.c:54
void ast_jb_enable_for_channel(struct ast_channel *chan)
Sets a jitterbuffer frame hook on the channel based on the channel's stored jitterbuffer configuratio...
Definition: abstract_jb.c:585
#define DEFAULT_TIMER_INTERVAL
Definition: abstract_jb.c:836
static int default_impl
Definition: abstract_jb.c:118
static const struct ast_datastore_info jb_datastore
Definition: abstract_jb.c:904
#define DEFAULT_TYPE
Definition: abstract_jb.c:840
int ast_jb_put(struct ast_channel *chan, struct ast_frame *f)
Puts a frame into a channel jitterbuffer.
Definition: abstract_jb.c:271
#define DEFAULT_SIZE
Definition: abstract_jb.c:837
static const struct ast_jb_impl avail_impl[]
Definition: abstract_jb.c:87
static const char *const jb_get_actions[]
Definition: abstract_jb.c:127
static void jb_force_resynch_adaptive(void *jb)
Definition: abstract_jb.c:804
static struct ast_frame * hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
Definition: abstract_jb.c:953
static const int adaptive_to_abstract_code[]
Definition: abstract_jb.c:123
void ast_jb_destroy(struct ast_channel *chan)
Destroys jitterbuffer on a channel.
Definition: abstract_jb.c:502
static void jb_empty_and_reset_adaptive(void *jb)
Definition: abstract_jb.c:808
static void hook_destroy_cb(void *framedata)
Definition: abstract_jb.c:909
static void jb_choose_impl(struct ast_channel *chan)
Definition: abstract_jb.c:148
static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
Definition: abstract_jb.c:753
static void datastore_destroy_cb(void *data)
Definition: abstract_jb.c:899
static void * jb_create_fixed(struct ast_jb_conf *general_config)
Definition: abstract_jb.c:625
static void jb_destroy_fixed(void *jb)
Definition: abstract_jb.c:635
const struct ast_jb_impl * ast_jb_get_impl(enum ast_jb_type type)
Definition: abstract_jb.c:820
static void jb_destroy_adaptive(void *jb)
Definition: abstract_jb.c:745
int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1)
Checks the need of a jb use in a generic bridge.
Definition: abstract_jb.c:170
static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
Definition: abstract_jb.c:791
int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left)
Calculates the time, left to the closest delivery moment in a bridge.
Definition: abstract_jb.c:231
static void jb_empty_and_reset_fixed(void *jb)
Definition: abstract_jb.c:710
static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
Definition: abstract_jb.c:669
void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
Copies a channel's jitterbuffer configuration.
Definition: abstract_jb.c:599
static int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
Definition: abstract_jb.c:1227
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:545
static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
Definition: abstract_jb.c:647
static void * jb_create_adaptive(struct ast_jb_conf *general_config)
Definition: abstract_jb.c:727
static int jb_is_late_fixed(void *jb, long ts)
Definition: abstract_jb.c:720
Common implementation-independent jitterbuffer stuff.
#define AST_JB_CONF_ENABLE
Definition: abstract_jb.h:86
@ AST_JB_IMPL_INTERP
Definition: abstract_jb.h:60
@ AST_JB_IMPL_OK
Definition: abstract_jb.h:58
@ AST_JB_IMPL_NOFRAME
Definition: abstract_jb.h:61
@ AST_JB_IMPL_DROP
Definition: abstract_jb.h:59
#define AST_JB_CONF_RESYNCH_THRESHOLD
Definition: abstract_jb.h:89
#define AST_JB_CONF_IMPL
Definition: abstract_jb.h:91
#define AST_JB_CONF_LOG
Definition: abstract_jb.h:92
ast_jb_type
Definition: abstract_jb.h:51
@ AST_JB_ADAPTIVE
Definition: abstract_jb.h:53
@ AST_JB_FIXED
Definition: abstract_jb.h:52
@ AST_JB_SYNC_VIDEO
Definition: abstract_jb.h:48
@ AST_JB_FORCED
Definition: abstract_jb.h:46
@ AST_JB_LOG
Definition: abstract_jb.h:47
@ AST_JB_ENABLED
Definition: abstract_jb.h:45
#define AST_JB_CONF_SYNC_VIDEO
Definition: abstract_jb.h:93
#define AST_JB_CONF_FORCE
Definition: abstract_jb.h:87
#define AST_JB_CONF_MAX_SIZE
Definition: abstract_jb.h:88
#define AST_JB_CONF_TARGET_EXTRA
Definition: abstract_jb.h:90
#define AST_JB_IMPL_NAME_SIZE
Definition: abstract_jb.h:64
#define AST_JB_CONF_PREFIX
Definition: abstract_jb.h:85
enum queue_result id
Definition: app_queue.c:1638
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int tmp()
Definition: bt_open.c:389
static const char type[]
Definition: chan_ooh323.c:109
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:960
@ AST_CHAN_TP_CREATESJITTER
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:965
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: channel.c:10564
int ast_channel_fdno(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5144
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition: channel.h:171
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
#define AST_JITTERBUFFER_FD
Definition: channel.h:204
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
#define ast_channel_unlock(chan)
Definition: channel.h:2923
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define abs(x)
Definition: f2c.h:195
struct fixed_jb * fixed_jb_new(struct fixed_jb_conf *conf)
int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
long fixed_jb_next(struct fixed_jb *jb)
int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
int fixed_jb_is_late(struct fixed_jb *jb, long ts)
Checks if the given time stamp is late.
void fixed_jb_destroy(struct fixed_jb *jb)
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
void fixed_jb_set_force_resynch(struct fixed_jb *jb)
Jitterbuffering algorithm.
@ FIXED_JB_OK
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
Media Format Cache API.
static const char name[]
Definition: format_mp3.c:68
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
Definition: framehook.h:151
@ AST_FRAMEHOOK_EVENT_ATTACHED
Definition: framehook.h:154
@ AST_FRAMEHOOK_EVENT_DETACHED
Definition: framehook.h:155
@ AST_FRAMEHOOK_EVENT_WRITE
Definition: framehook.h:153
@ AST_FRAMEHOOK_EVENT_READ
Definition: framehook.h:152
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
Asterisk internal frame definitions.
@ AST_FRFLAG_HAS_TIMING_INFO
@ AST_FRFLAG_REQUEUED
#define AST_FRAME_DTMF
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ast_frdup(fr)
Copies a frame.
#define ast_frfree(fr)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
@ AST_FRAME_VIDEO
@ AST_FRAME_NULL
@ AST_FRAME_VOICE
@ AST_FRAME_RTCP
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_HOLD
@ AST_CONTROL_SRCCHANGE
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_WARNING
jitterbuf: an application-independent jitterbuffer jitterbuf.c
int jb_is_late(jitterbuf *jb, long ts)
Checks if the given time stamp is late.
Definition: jitterbuf.c:846
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
Definition: jitterbuf.c:99
void jb_reset(jitterbuf *jb)
reset jitterbuf
Definition: jitterbuf.c:72
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl)
get a frame for time now (receiver's time) return value is one of JB_OK: You've got frame!...
Definition: jitterbuf.c:785
jitterbuf * jb_new(void)
new jitterbuf
Definition: jitterbuf.c:86
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
queue a frame
Definition: jitterbuf.c:525
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver's time (0=EMPTY) This value may change as frames are adde...
Definition: jitterbuf.c:767
@ JB_TYPE_VOICE
Definition: jitterbuf.h:62
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
Definition: jitterbuf.c:825
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
Definition: jitterbuf.c:801
@ JB_OK
Definition: jitterbuf.h:51
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:225
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
int errno
Core PBX routines and definitions.
#define NULL
Definition: resample.c:96
Pluggable RTP Architecture.
#define AST_RTP_RTCP_SR
Definition: rtp_engine.h:318
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4108
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Main Channel structure associated with a channel.
struct ast_jb jb
Structure for a data store type.
Definition: datastore.h:31
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Definition of a media format.
Definition: format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
struct timeval delivery
enum ast_frame_type frametype
struct ast_frame * next
const char * src
General jitterbuffer configuration.
Definition: abstract_jb.h:70
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
Jitterbuffer implementation struct.
Definition: abstract_jb.h:122
jb_get_impl get
Definition: abstract_jb.h:129
jb_is_late_impl is_late
Definition: abstract_jb.h:134
jb_put_first_impl put_first
Definition: abstract_jb.h:127
jb_destroy_impl destroy
Definition: abstract_jb.h:126
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
jb_remove_impl remove
Definition: abstract_jb.h:131
jb_empty_and_reset_impl empty_and_reset
Definition: abstract_jb.h:133
jb_next_impl next
Definition: abstract_jb.h:130
jb_create_impl create
Definition: abstract_jb.h:125
jb_put_impl put
Definition: abstract_jb.h:128
jb_force_resynch_impl force_resync
Definition: abstract_jb.h:132
General jitterbuffer state.
Definition: abstract_jb.h:141
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
long next
The time the next frame should be played.
Definition: abstract_jb.h:151
struct ast_format * last_format
Voice format of the last frame in.
Definition: abstract_jb.h:153
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149
FILE * logfile
File for frame timestamp tracing.
Definition: abstract_jb.h:155
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:356
struct ast_rtp_rtcp_report::@273 sender_information
unsigned int rtp_timestamp
Definition: rtp_engine.h:362
struct timeval ntp_timestamp
Definition: rtp_engine.h:361
All configuration options for http media cache.
Definition: astman.c:222
private fixed_jb structure
long target_extra
Definition: jitterbuf.h:72
long max_jitterbuf
Definition: jitterbuf.h:69
long resync_threshold
Definition: jitterbuf.h:70
long max_contig_interp
Definition: jitterbuf.h:71
void * data
Definition: jitterbuf.h:102
struct ast_jb_conf jb_conf
Definition: abstract_jb.c:849
struct jb_stream_sync audio_stream_sync
Definition: abstract_jb.c:857
void * jb_obj
Definition: abstract_jb.c:864
int audio_stream_id
Definition: abstract_jb.c:856
struct jb_stream_sync video_stream_sync
Definition: abstract_jb.c:859
struct timeval start_tv
Definition: abstract_jb.c:850
struct ast_format * last_format
Definition: abstract_jb.c:851
unsigned int early_frame_count
Definition: abstract_jb.c:861
struct timeval last_audio_ntp_timestamp
Definition: abstract_jb.c:862
struct ast_timer * timer
Definition: abstract_jb.c:852
int video_stream_id
Definition: abstract_jb.c:858
int timer_interval
Definition: abstract_jb.c:853
struct jb_framedata::@292 early_frames
const struct ast_jb_impl * jb_impl
Definition: abstract_jb.c:848
struct timeval ntp
Definition: abstract_jb.c:844
unsigned int timestamp
Definition: abstract_jb.c:843
int value
Definition: syslog.c:37
Handy terminal functions for vt* terms.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
Timing source management.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:154
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:171
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161
Utility functions.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_assert(a)
Definition: utils.h:739
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ARRAY_LEN(a)
Definition: utils.h:666
#define AST_FLAGS_ALL
Definition: utils.h:196