Sat Apr 26 2014 22:01:37

Asterisk developer's documentation


func_jitterbuffer.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2011, Digium, Inc.
00005  *
00006  * David Vossel <dvossel@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Put a jitterbuffer on the read side of a channel
00022  *
00023  * \author David Vossel <dvossel@digium.com>
00024  *
00025  * \ingroup functions
00026  */
00027 
00028 /*** MODULEINFO
00029    <support_level>core</support_level>
00030  ***/
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411314 $")
00035 
00036 #include "asterisk/module.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/framehook.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/abstract_jb.h"
00041 #include "asterisk/timing.h"
00042 #include "asterisk/app.h"
00043 
00044 /*** DOCUMENTATION
00045    <function name="JITTERBUFFER" language="en_US">
00046       <synopsis>
00047          Add a Jitterbuffer to the Read side of the channel.  This dejitters the audio stream before it reaches the Asterisk core. This is a write only function.
00048       </synopsis>
00049       <syntax>
00050          <parameter name="jitterbuffer type" required="true">
00051             <para>Jitterbuffer type can be either <literal>fixed</literal> or <literal>adaptive</literal>.</para>
00052             <para>Used as follows. </para>
00053             <para>Set(JITTERBUFFER(type)=max_size[,resync_threshold[,target_extra]])</para>
00054             <para>Set(JITTERBUFFER(type)=default) </para>
00055          </parameter>
00056       </syntax>
00057       <description>
00058          <para>max_size: Defaults to 200 ms</para>
00059          <para>Length in milliseconds of buffer.</para>
00060          <para> </para>
00061          <para>resync_threshold: Defaults to 1000ms </para>
00062          <para>The length in milliseconds over which a timestamp difference will result in resyncing the jitterbuffer. </para>
00063          <para> </para>
00064          <para>target_extra: Defaults to 40ms</para>
00065          <para>This option only affects the adaptive jitterbuffer. It represents the amount time in milliseconds by which the new jitter buffer will pad its size.</para>
00066          <para> </para>
00067          <para>Examples:</para>
00068          <para>exten => 1,1,Set(JITTERBUFFER(fixed)=default);Fixed with defaults. </para>
00069          <para>exten => 1,1,Set(JITTERBUFFER(fixed)=200);Fixed with max size 200ms, default resync threshold and target extra. </para>
00070          <para>exten => 1,1,Set(JITTERBUFFER(fixed)=200,1500);Fixed with max size 200ms resync threshold 1500. </para>
00071          <para>exten => 1,1,Set(JITTERBUFFER(adaptive)=default);Adaptive with defaults. </para>
00072          <para>exten => 1,1,Set(JITTERBUFFER(adaptive)=200,,60);Adaptive with max size 200ms, default resync threshold and 40ms target extra. </para>
00073       </description>
00074    </function>
00075  ***/
00076 
00077 #define DEFAULT_TIMER_INTERVAL 20
00078 #define DEFAULT_SIZE  200
00079 #define DEFAULT_TARGET_EXTRA  40
00080 #define DEFAULT_RESYNC  1000
00081 #define DEFAULT_TYPE AST_JB_FIXED
00082 
00083 struct jb_framedata {
00084    const struct ast_jb_impl *jb_impl;
00085    struct ast_jb_conf jb_conf;
00086    struct timeval start_tv;
00087    struct ast_format last_format;
00088    struct ast_timer *timer;
00089    int timer_interval; /* ms between deliveries */
00090    int timer_fd;
00091    int first;
00092    void *jb_obj;
00093 };
00094 
00095 static void jb_framedata_destroy(struct jb_framedata *framedata)
00096 {
00097    if (framedata->timer) {
00098       ast_timer_close(framedata->timer);
00099       framedata->timer = NULL;
00100    }
00101    if (framedata->jb_impl && framedata->jb_obj) {
00102       struct ast_frame *f;
00103       while (framedata->jb_impl->remove(framedata->jb_obj, &f) == AST_JB_IMPL_OK) {
00104          ast_frfree(f);
00105       }
00106       framedata->jb_impl->destroy(framedata->jb_obj);
00107       framedata->jb_obj = NULL;
00108    }
00109    ast_free(framedata);
00110 }
00111 
00112 static void jb_conf_default(struct ast_jb_conf *conf)
00113 {
00114    conf->max_size = DEFAULT_SIZE;
00115    conf->resync_threshold = DEFAULT_RESYNC;
00116    ast_copy_string(conf->impl, "fixed", sizeof(conf->impl));
00117    conf->target_extra = DEFAULT_TARGET_EXTRA;
00118 }
00119 
00120 /* set defaults */
00121 static int jb_framedata_init(struct jb_framedata *framedata, const char *data, const char *value)
00122 {
00123    int jb_impl_type = DEFAULT_TYPE;
00124 
00125    /* Initialize defaults */
00126    framedata->timer_fd = -1;
00127    jb_conf_default(&framedata->jb_conf);
00128    if (!(framedata->jb_impl = ast_jb_get_impl(jb_impl_type))) {
00129       return -1;
00130    }
00131    if (!(framedata->timer = ast_timer_open())) {
00132       return -1;
00133    }
00134    framedata->timer_fd = ast_timer_fd(framedata->timer);
00135    framedata->timer_interval = DEFAULT_TIMER_INTERVAL;
00136    ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
00137    framedata->start_tv = ast_tvnow();
00138 
00139 
00140 
00141    /* Now check user options to see if any of the defaults need to change. */
00142    if (!ast_strlen_zero(data)) {
00143       if (!strcasecmp(data, "fixed")) {
00144          jb_impl_type = AST_JB_FIXED;
00145       } else if (!strcasecmp(data, "adaptive")) {
00146          jb_impl_type = AST_JB_ADAPTIVE;
00147       } else {
00148          ast_log(LOG_WARNING, "Unknown Jitterbuffer type %s. Failed to create jitterbuffer.\n", data);
00149          return -1;
00150       }
00151       ast_copy_string(framedata->jb_conf.impl, data, sizeof(framedata->jb_conf.impl));
00152    }
00153 
00154    if (!ast_strlen_zero(value) && strcasecmp(value, "default")) {
00155       char *parse = ast_strdupa(value);
00156       int res = 0;
00157       AST_DECLARE_APP_ARGS(args,
00158          AST_APP_ARG(max_size);
00159          AST_APP_ARG(resync_threshold);
00160          AST_APP_ARG(target_extra);
00161       );
00162 
00163       AST_STANDARD_APP_ARGS(args, parse);
00164       if (!ast_strlen_zero(args.max_size)) {
00165          res |= ast_jb_read_conf(&framedata->jb_conf,
00166             "jbmaxsize",
00167             args.max_size);
00168       }
00169       if (!ast_strlen_zero(args.resync_threshold)) {
00170          res |= ast_jb_read_conf(&framedata->jb_conf,
00171             "jbresyncthreshold",
00172             args.resync_threshold);
00173       }
00174       if (!ast_strlen_zero(args.target_extra)) {
00175          res |= ast_jb_read_conf(&framedata->jb_conf,
00176             "jbtargetextra",
00177             args.target_extra);
00178       }
00179       if (res) {
00180          ast_log(LOG_WARNING, "Invalid jitterbuffer parameters %s\n", value);
00181       }
00182    }
00183 
00184    /* now that all the user parsing is done and nothing will change, create the jb obj */
00185    framedata->jb_obj = framedata->jb_impl->create(&framedata->jb_conf);
00186    return 0;
00187 }
00188 
00189 static void datastore_destroy_cb(void *data) {
00190    ast_free(data);
00191    ast_debug(1, "JITTERBUFFER datastore destroyed\n");
00192 }
00193 
00194 static const struct ast_datastore_info jb_datastore = {
00195    .type = "jitterbuffer",
00196    .destroy = datastore_destroy_cb
00197 };
00198 
00199 static void hook_destroy_cb(void *framedata)
00200 {
00201    ast_debug(1, "JITTERBUFFER hook destroyed\n");
00202    jb_framedata_destroy((struct jb_framedata *) framedata);
00203 }
00204 
00205 static struct ast_frame *hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
00206 {
00207    struct jb_framedata *framedata = data;
00208    struct timeval now_tv;
00209    unsigned long now;
00210    int putframe = 0; /* signifies if audio frame was placed into the buffer or not */
00211 
00212    switch (event) {
00213    case AST_FRAMEHOOK_EVENT_READ:
00214       break;
00215    case AST_FRAMEHOOK_EVENT_ATTACHED:
00216    case AST_FRAMEHOOK_EVENT_DETACHED:
00217    case AST_FRAMEHOOK_EVENT_WRITE:
00218       return frame;
00219    }
00220 
00221    if (ast_channel_fdno(chan) == AST_JITTERBUFFER_FD && framedata->timer) {
00222       if (ast_timer_ack(framedata->timer, 1) < 0) {
00223          ast_log(LOG_ERROR, "Failed to acknowledge timer in jitter buffer\n");
00224          return frame;
00225       }
00226    }
00227 
00228    if (!frame) {
00229       return frame;
00230    }
00231 
00232    now_tv = ast_tvnow();
00233    now = ast_tvdiff_ms(now_tv, framedata->start_tv);
00234 
00235    if (frame->frametype == AST_FRAME_VOICE) {
00236       int res;
00237       struct ast_frame *jbframe;
00238 
00239       if (!ast_test_flag(frame, AST_FRFLAG_HAS_TIMING_INFO) || frame->len < 2 || frame->ts < 0) {
00240          /* only frames with timing info can enter the jitterbuffer */
00241          return frame;
00242       }
00243 
00244       jbframe = ast_frisolate(frame);
00245       ast_format_copy(&framedata->last_format, &frame->subclass.format);
00246 
00247       if (frame->len && (frame->len != framedata->timer_interval)) {
00248          framedata->timer_interval = frame->len;
00249          ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
00250       }
00251       if (!framedata->first) {
00252          framedata->first = 1;
00253          res = framedata->jb_impl->put_first(framedata->jb_obj, jbframe, now);
00254       } else {
00255          res = framedata->jb_impl->put(framedata->jb_obj, jbframe, now);
00256       }
00257       if (res == AST_JB_IMPL_OK) {
00258          frame = &ast_null_frame;
00259       }
00260       putframe = 1;
00261    }
00262 
00263    if (frame->frametype == AST_FRAME_NULL) {
00264       int res;
00265       long next = framedata->jb_impl->next(framedata->jb_obj);
00266 
00267       /* If now is earlier than the next expected output frame
00268        * from the jitterbuffer we may choose to pass on retrieving
00269        * a frame during this read iteration.  The only exception
00270        * to this rule is when an audio frame is placed into the buffer
00271        * and the time for the next frame to come out of the buffer is
00272        * at least within the timer_interval of the next output frame. By
00273        * doing this we are able to feed off the timing of the input frames
00274        * and only rely on our jitterbuffer timer when frames are dropped.
00275        * During testing, this hybrid form of timing gave more reliable results. */
00276       if (now < next) {
00277          long int diff = next - now;
00278          if (!putframe) {
00279             return frame;
00280          } else if (diff >= framedata->timer_interval) {
00281             return frame;
00282          }
00283       }
00284 
00285       res = framedata->jb_impl->get(framedata->jb_obj, &frame, now, framedata->timer_interval);
00286       switch (res) {
00287       case AST_JB_IMPL_OK:
00288          /* got it, and pass it through */
00289          break;
00290       case AST_JB_IMPL_DROP:
00291          ast_frfree(frame);
00292          frame = &ast_null_frame;
00293          break;
00294       case AST_JB_IMPL_INTERP:
00295          if (framedata->last_format.id) {
00296             struct ast_frame tmp = { 0, };
00297             tmp.frametype = AST_FRAME_VOICE;
00298             ast_format_copy(&tmp.subclass.format, &framedata->last_format);
00299             /* example: 8000hz / (1000 / 20ms) = 160 samples */
00300             tmp.samples = ast_format_rate(&framedata->last_format) / (1000 / framedata->timer_interval);
00301             tmp.delivery = ast_tvadd(framedata->start_tv, ast_samp2tv(next, 1000));
00302             tmp.offset = AST_FRIENDLY_OFFSET;
00303             tmp.src  = "func_jitterbuffer interpolation";
00304             frame = ast_frdup(&tmp);
00305             break;
00306          }
00307          /* else fall through */
00308       case AST_JB_IMPL_NOFRAME:
00309          frame = &ast_null_frame;
00310          break;
00311       }
00312    }
00313 
00314    return frame;
00315 }
00316 
00317 static int jb_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)
00318 {
00319    struct jb_framedata *framedata;
00320    struct ast_datastore *datastore = NULL;
00321    struct ast_framehook_interface interface = {
00322       .version = AST_FRAMEHOOK_INTERFACE_VERSION,
00323       .event_cb = hook_event_cb,
00324       .destroy_cb = hook_destroy_cb,
00325    };
00326    int i = 0;
00327 
00328    if (!chan) {
00329       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00330       return -1;
00331    }
00332 
00333    if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
00334       return 0;
00335    }
00336 
00337    if (jb_framedata_init(framedata, data, value)) {
00338       jb_framedata_destroy(framedata);
00339       return 0;
00340    }
00341 
00342    interface.data = framedata;
00343 
00344    ast_channel_lock(chan);
00345    i = ast_framehook_attach(chan, &interface);
00346    if (i >= 0) {
00347       int *id;
00348       if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
00349          id = datastore->data;
00350          ast_framehook_detach(chan, *id);
00351          ast_channel_datastore_remove(chan, datastore);
00352       }
00353 
00354       if (!(datastore = ast_datastore_alloc(&jb_datastore, NULL))) {
00355          ast_framehook_detach(chan, i);
00356          ast_channel_unlock(chan);
00357          return 0;
00358       }
00359 
00360       if (!(id = ast_calloc(1, sizeof(int)))) {
00361          ast_datastore_free(datastore);
00362          ast_framehook_detach(chan, i);
00363          ast_channel_unlock(chan);
00364          return 0;
00365       }
00366 
00367       *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
00368       datastore->data = id;
00369       ast_channel_datastore_add(chan, datastore);
00370 
00371       ast_channel_set_fd(chan, AST_JITTERBUFFER_FD, framedata->timer_fd);
00372    } else {
00373       jb_framedata_destroy(framedata);
00374       framedata = NULL;
00375    }
00376    ast_channel_unlock(chan);
00377 
00378    return 0;
00379 }
00380 
00381 static struct ast_custom_function jb_function = {
00382    .name = "JITTERBUFFER",
00383    .write = jb_helper,
00384 };
00385 
00386 static int unload_module(void)
00387 {
00388    return ast_custom_function_unregister(&jb_function);
00389 }
00390 
00391 static int load_module(void)
00392 {
00393    int res = ast_custom_function_register(&jb_function);
00394    return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00395 }
00396 
00397 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitter buffer for read side of channel.");
00398