00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
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;
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
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
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
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
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;
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
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
00268
00269
00270
00271
00272
00273
00274
00275
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
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
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
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;
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