func_pjsip_endpoint: Add PJSIP_ENDPOINT function for querying endpoint details
[asterisk/asterisk.git] / funcs / func_jitterbuffer.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2011, Digium, Inc.
5  *
6  * David Vossel <dvossel@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Put a jitterbuffer on the read side of a channel
22  *
23  * \author David Vossel <dvossel@digium.com>
24  *
25  * \ingroup functions
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include "asterisk/module.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/framehook.h"
39 #include "asterisk/frame.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/abstract_jb.h"
42 #include "asterisk/timing.h"
43 #include "asterisk/app.h"
44
45 /*** DOCUMENTATION
46         <function name="JITTERBUFFER" language="en_US">
47                 <synopsis>
48                         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.
49                 </synopsis>
50                 <syntax>
51                         <parameter name="jitterbuffer type" required="true">
52                                 <para>Jitterbuffer type can be <literal>fixed</literal>, <literal>adaptive</literal>, or
53                                         <literal>disabled</literal>.</para>
54                                 <para>Used as follows. </para>
55                                 <para>Set(JITTERBUFFER(type)=max_size[,resync_threshold[,target_extra]])</para>
56                                 <para>Set(JITTERBUFFER(type)=default) </para>
57                         </parameter>
58                 </syntax>
59                 <description>
60                         <para>max_size: Defaults to 200 ms</para>
61                         <para>Length in milliseconds of buffer.</para>
62                         <para> </para>
63                         <para>resync_threshold: Defaults to 1000ms </para>
64                         <para>The length in milliseconds over which a timestamp difference will result in resyncing the jitterbuffer. </para>
65                         <para> </para>
66                         <para>target_extra: Defaults to 40ms</para>
67                         <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>
68                         <para> </para>
69                         <para>Examples:</para>
70                         <para>exten => 1,1,Set(JITTERBUFFER(fixed)=default);Fixed with defaults. </para>
71                         <para>exten => 1,1,Set(JITTERBUFFER(fixed)=200);Fixed with max size 200ms, default resync threshold and target extra. </para>
72                         <para>exten => 1,1,Set(JITTERBUFFER(fixed)=200,1500);Fixed with max size 200ms resync threshold 1500. </para>
73                         <para>exten => 1,1,Set(JITTERBUFFER(adaptive)=default);Adaptive with defaults. </para>
74                         <para>exten => 1,1,Set(JITTERBUFFER(adaptive)=200,,60);Adaptive with max size 200ms, default resync threshold and 40ms target extra. </para>
75                         <para>exten => 1,n,Set(JITTERBUFFER(disabled)=);Remove previously applied jitterbuffer </para>
76                         <note><para>If a channel specifies a jitterbuffer due to channel driver configuration and
77                         the JITTERBUFFER function has set a jitterbuffer for that channel, the jitterbuffer set by
78                         the JITTERBUFFER function will take priority and the jitterbuffer set by the channel
79                         configuration will not be applied.</para></note>
80                 </description>
81         </function>
82  ***/
83
84 static int jb_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)
85 {
86         struct ast_jb_conf jb_conf;
87
88         /* Initialize and set jb_conf */
89         ast_jb_conf_default(&jb_conf);
90
91         /* Now check user options to see if any of the defaults need to change. */
92         if (!ast_strlen_zero(data)) {
93                 if (strcasecmp(data, "fixed") &&
94                                 strcasecmp(data, "adaptive") &&
95                                 strcasecmp(data, "disabled")) {
96                         ast_log(LOG_WARNING, "Unknown Jitterbuffer type %s. Failed to create jitterbuffer.\n", data);
97                         return -1;
98                 }
99                 ast_copy_string(jb_conf.impl, data, sizeof(jb_conf.impl));
100         }
101
102         if (!ast_strlen_zero(value) && strcasecmp(value, "default")) {
103                 char *parse = ast_strdupa(value);
104                 int res = 0;
105                 AST_DECLARE_APP_ARGS(args,
106                         AST_APP_ARG(max_size);
107                         AST_APP_ARG(resync_threshold);
108                         AST_APP_ARG(target_extra);
109                 );
110
111                 AST_STANDARD_APP_ARGS(args, parse);
112                 if (!ast_strlen_zero(args.max_size)) {
113                         res |= ast_jb_read_conf(&jb_conf,
114                                 "jbmaxsize",
115                                 args.max_size);
116                 }
117                 if (!ast_strlen_zero(args.resync_threshold)) {
118                         res |= ast_jb_read_conf(&jb_conf,
119                                 "jbresyncthreshold",
120                                 args.resync_threshold);
121                 }
122                 if (!ast_strlen_zero(args.target_extra)) {
123                         res |= ast_jb_read_conf(&jb_conf,
124                                 "jbtargetextra",
125                                 args.target_extra);
126                 }
127                 if (res) {
128                         ast_log(LOG_WARNING, "Invalid jitterbuffer parameters %s\n", value);
129                 }
130         }
131
132         ast_jb_create_framehook(chan, &jb_conf, 0);
133
134         return 0;
135 }
136
137
138 static struct ast_custom_function jb_function = {
139         .name = "JITTERBUFFER",
140         .write = jb_helper,
141 };
142
143 static int unload_module(void)
144 {
145         return ast_custom_function_unregister(&jb_function);
146 }
147
148 static int load_module(void)
149 {
150         int res = ast_custom_function_register(&jb_function);
151         return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
152 }
153
154 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitter buffer for read side of channel.");
155