1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Andrey Volk <andywolk@gmail.com>
28 *
29 *
30 * switch_loadable_module.h -- Loadable Modules
31 *
32 */
33 /*! \file switch_loadable_module.h
34 \brief Loadable Module Routines
35
36 This module is the gateway between external modules and the core of the application.
37 it contains all the access points to the various pluggable interfaces including the codecs
38 and API modules.
39
40 */
41
42 #ifndef SWITCH_LOADABLE_MODULE_H
43 #define SWITCH_LOADABLE_MODULE_H
44
45 #include <switch_log.h>
46 #include <switch.h>
47 #include <switch_module_interfaces.h>
48
49 SWITCH_BEGIN_EXTERN_C
50 /*!
51 \defgroup mods Loadable Module Functions
52 \ingroup core1
53 \{
54 */
55
56 /*! \brief List of loadable module types */
57 typedef enum {
58 SWITCH_LOADABLE_MODULE_TYPE_PRELOAD,
59 SWITCH_LOADABLE_MODULE_TYPE_COMMON,
60 SWITCH_LOADABLE_MODULE_TYPE_POSTLOAD
61 } switch_loadable_module_type_t;
62
63 /*! \brief The abstraction of a loadable module */
64 struct switch_loadable_module_interface {
65 /*! the name of the module */
66 const char *module_name;
67 /*! the table of endpoints the module has implemented */
68 switch_endpoint_interface_t *endpoint_interface;
69 /*! the table of timers the module has implemented */
70 switch_timer_interface_t *timer_interface;
71 /*! the table of dialplans the module has implemented */
72 switch_dialplan_interface_t *dialplan_interface;
73 /*! the table of codecs the module has implemented */
74 switch_codec_interface_t *codec_interface;
75 /*! the table of applications the module has implemented */
76 switch_application_interface_t *application_interface;
77 /*! the table of chat applications the module has implemented */
78 switch_chat_application_interface_t *chat_application_interface;
79 /*! the table of api functions the module has implemented */
80 switch_api_interface_t *api_interface;
81 /*! the table of json api functions the module has implemented */
82 switch_json_api_interface_t *json_api_interface;
83 /*! the table of file formats the module has implemented */
84 switch_file_interface_t *file_interface;
85 /*! the table of speech interfaces the module has implemented */
86 switch_speech_interface_t *speech_interface;
87 /*! the table of directory interfaces the module has implemented */
88 switch_directory_interface_t *directory_interface;
89 /*! the table of chat interfaces the module has implemented */
90 switch_chat_interface_t *chat_interface;
91 /*! the table of say interfaces the module has implemented */
92 switch_say_interface_t *say_interface;
93 /*! the table of asr interfaces the module has implemented */
94 switch_asr_interface_t *asr_interface;
95 /*! the table of management interfaces the module has implemented */
96 switch_management_interface_t *management_interface;
97 /*! the table of limit interfaces the module has implemented */
98 switch_limit_interface_t *limit_interface;
99 /*! the table of database interfaces the module has implemented */
100 switch_database_interface_t *database_interface;
101 switch_thread_rwlock_t *rwlock;
102 int refs;
103 switch_memory_pool_t *pool;
104 };
105
106 /*!
107 \brief Initilize the module backend and load all the modules
108 \return SWITCH_STATUS_SUCCESS when complete
109 */
110 SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autoload);
111
112 /*!
113 \brief Shutdown the module backend and call the shutdown routine in all loaded modules
114 */
115 SWITCH_DECLARE(void) switch_loadable_module_shutdown(void);
116
117 /*!
118 \brief Retrieve the endpoint interface by it's registered name
119 \param name the name of the endpoint
120 \return the desired endpoint interface
121 */
122 SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(const char *name);
123
124 /*!
125 \brief Retrieve the codec interface by it's registered name
126 \param name the name of the codec
127 \return the desired codec interface
128 */
129 SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name, const char *modname);
130
131 SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp);
132
133 /*!
134 \brief Retrieve the dialplan interface by it's registered name
135 \param name the name of the dialplan
136 \return the desired dialplan interface
137 */
138 SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(const char *name);
139
140 /*!
141 \brief Enumerates a list of all modules discovered in a directory
142 \param the directory to look for modules in
143 \param memory pool
144 \param callback function to call for each module found
145 \param user data argument to pass to the callback function
146 \return the resulting status
147 */
148 SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data);
149
150
151 /*!
152 \brief Enumerates a list of all currently loaded modules
153 \param callback function to call for each module found
154 \param user data argument to pass to the callback function
155 \return the resulting status
156 */
157 SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data);
158
159 /*!
160 \brief build a dynamic module object and register it (for use in double embeded modules)
161 \param filename the name of the modules source file
162 \param switch_module_load the function to call when the module is loaded
163 \param switch_module_runtime a function requested to be started in it's own thread once loaded
164 \param switch_module_shutdown the function to call when the system is shutdown
165 \param runtime start the runtime thread or not
166 \return the resulting status
167 \note only use this function if you are making a module that in turn gateways module loading to another technology
168 */
169 SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filename,
170 switch_module_load_t switch_module_load,
171 switch_module_runtime_t switch_module_runtime,
172 switch_module_shutdown_t switch_module_shutdown, switch_bool_t runtime);
173
174
175 /*!
176 \brief Retrieve the timer interface by it's registered name
177 \param name the name of the timer
178 \return the desired timer interface
179 */
180 SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(const char *name);
181
182 /*!
183 \brief Retrieve the application interface by it's registered name
184 \param name the name of the application
185 \return the desired application interface
186 */
187 SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(const char *name);
188
189 /*!
190 \brief Retrieve the chat application interface by it's registered name
191 \param name the name of the chat application
192 \return the desired chat application interface
193 */
194 SWITCH_DECLARE(switch_chat_application_interface_t *) switch_loadable_module_get_chat_application_interface(const char *name);
195
196 SWITCH_DECLARE(switch_status_t) switch_core_execute_chat_app(switch_event_t *message, const char *app, const char *data);
197
198 /*!
199 \brief Retrieve the API interface by it's registered name
200 \param name the name of the API
201 \return the desired API interface
202 */
203 SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(const char *name);
204
205 /*!
206 \brief Retrieve the JSON API interface by it's registered name
207 \param name the name of the API
208 \return the desired API interface
209 */
210 SWITCH_DECLARE(switch_json_api_interface_t *) switch_loadable_module_get_json_api_interface(const char *name);
211
212 /*!
213 \brief Retrieve the file format interface by it's registered name
214 \param name the name of the file format
215 \return the desired file format interface
216 */
217 SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name, const char *modname);
218
219 /*!
220 \brief Retrieve the database interface by it's registered name
221 \param name the name of the dsn prefix
222 \return the desired database format interface
223 */
224 SWITCH_DECLARE(switch_database_interface_t *) switch_loadable_module_get_database_interface(const char *name, const char *modname);
225
226 /*!
227 \brief Retrieve the speech interface by it's registered name
228 \param name the name of the speech interface
229 \return the desired speech interface
230 */
231 SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(const char *name);
232
233 /*!
234 \brief Retrieve the asr interface by it's registered name
235 \param name the name of the asr interface
236 \return the desired asr interface
237 */
238 SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(const char *name);
239
240 /*!
241 \brief Retrieve the directory interface by it's registered name
242 \param name the name of the directory interface
243 \return the desired directory interface
244 */
245 SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(const char *name);
246
247 /*!
248 \brief Retrieve the chat interface by it's registered name
249 \param name the name of the chat interface
250 \return the desired chat interface
251 */
252 SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(const char *name);
253
254 /*!
255 \brief Retrieve the say interface by it's registered name
256 \param name the name of the say interface
257 \return the desired say interface
258 */
259 SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(const char *name);
260
261 /*!
262 \brief Retrieve the management interface by it's registered name
263 \param relative_oid the relative oid of the management interface
264 \return the desired management interface
265 */
266 SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(const char *relative_oid);
267
268 /*!
269 \brief Retrieve the limit interface by it's registered name
270 \param name the name of the limit interface
271 \return the desired limit interface
272 */
273 SWITCH_DECLARE(switch_limit_interface_t *) switch_loadable_module_get_limit_interface(const char *name);
274
275 /*!
276 \brief Retrieve the list of loaded codecs into an array
277 \param array the array to populate
278 \param arraylen the max size in elements of the array
279 \return the number of elements added to the array
280 */
281 SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen);
282
283
284 /*!
285 \brief Retrieve the list of loaded codecs into an array based on another array showing the sorted order
286 \param array the array to populate
287 \param arraylen the max size in elements of the array
288 \param prefs the array of preferred codec names
289 \param preflen the size in elements of the prefs
290 \return the number of elements added to the array
291 \note this function only considers codecs that are listed in the "prefs" array and ignores the rest.
292 */
293 SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen);
294
295 /*!
296 \brief Execute a registered API command
297 \param cmd the name of the API command to execute
298 \param arg the optional arguement to the command
299 \param session an optional session
300 \param stream stream for output
301 \return the status returned by the API call
302 */
303 SWITCH_DECLARE(switch_status_t) switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
304
305 /*!
306 \brief Execute a registered JSON API command
307 \param json the name of the JSON API command to execute
308 \param arg the optional arguement to the command
309 \param session an optional session
310 \param stream stream for output
311 \return the status returned by the API call
312 */
313 SWITCH_DECLARE(switch_status_t) switch_json_api_execute(cJSON *json, switch_core_session_t *session, cJSON **retval);
314
315 /*!
316 \brief Load a module
317 \param dir the directory where the module resides
318 \param fname the file name of the module
319 \param runtime option to start the runtime thread if it exists
320 \param err pointer to error message
321 \return the status
322 */
323 SWITCH_DECLARE(switch_status_t) switch_loadable_module_load_module(const char *dir, const char *fname, switch_bool_t runtime, const char **err);
324
325 /*!
326 \brief Check if a module is loaded
327 \param mod the module name
328 \return the status
329 */
330 SWITCH_DECLARE(switch_status_t) switch_loadable_module_exists(const char *mod);
331
332 /*!
333 \brief Protect module from beeing unloaded
334 \param mod the module name
335 \return the status
336 */
337 SWITCH_DECLARE(switch_status_t) switch_loadable_module_protect(const char *mod);
338
339 /*!
340 \brief Unoad a module
341 \param dir the directory where the module resides
342 \param fname the file name of the module
343 \param err pointer to error message
344 \return the status
345 */
346 SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(const char *dir, const char *fname, switch_bool_t force, const char **err);
347
348 /* Prototypes of module interface functions */
349
350 /*!
351 \brief Load a module
352 \param module_interface a pointer to a pointer to aim at your module's local interface
353 \param filename the path to the module's dll or so file
354 \return SWITCH_STATUS_SUCCESS on a successful load
355 */
356 SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(switch_loadable_module_interface_t ** module_interface, const char *filename);
357 SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void);
358
359 /*!
360 \brief Shutdown a module
361 \return SWITCH_STATUS_SUCCESS on a successful shutdown
362 */
363 SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void);
364
365 #define SWITCH_ADD_API(api_int, int_name, descript, funcptr, syntax_string) \
366 for (;;) { \
367 api_int = (switch_api_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_API_INTERFACE); \
368 api_int->interface_name = int_name; \
369 api_int->desc = descript; \
370 api_int->function = funcptr; \
371 api_int->syntax = syntax_string; \
372 break; \
373 }
374
375 #define SWITCH_ADD_JSON_API(json_api_int, int_name, descript, funcptr, syntax_string) \
376 for (;;) { \
377 json_api_int = (switch_json_api_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_JSON_API_INTERFACE); \
378 json_api_int->interface_name = int_name; \
379 json_api_int->desc = descript; \
380 json_api_int->function = funcptr; \
381 json_api_int->syntax = syntax_string; \
382 break; \
383 }
384
385 #define SWITCH_ADD_CHAT(chat_int, int_name, funcptr) \
386 for (;;) { \
387 chat_int = (switch_chat_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_CHAT_INTERFACE); \
388 chat_int->chat_send = funcptr; \
389 chat_int->interface_name = int_name; \
390 break; \
391 }
392
393 #define SWITCH_ADD_APP(app_int, int_name, short_descript, long_descript, funcptr, syntax_string, app_flags) \
394 for (;;) { \
395 app_int = (switch_application_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_APPLICATION_INTERFACE); \
396 app_int->interface_name = int_name; \
397 app_int->application_function = funcptr; \
398 app_int->short_desc = short_descript; \
399 app_int->long_desc = long_descript; \
400 app_int->syntax = syntax_string; \
401 app_int->flags = app_flags; \
402 break; \
403 }
404
405 #define SWITCH_ADD_CHAT_APP(app_int, int_name, short_descript, long_descript, funcptr, syntax_string, app_flags) \
406 for (;;) { \
407 app_int = (switch_chat_application_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_CHAT_APPLICATION_INTERFACE); \
408 app_int->interface_name = int_name; \
409 app_int->chat_application_function = funcptr; \
410 app_int->short_desc = short_descript; \
411 app_int->long_desc = long_descript; \
412 app_int->syntax = syntax_string; \
413 app_int->flags = app_flags; \
414 break; \
415 }
416
417 #define SWITCH_ADD_DIALPLAN(dp_int, int_name, funcptr) \
418 for (;;) { \
419 dp_int = (switch_dialplan_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_DIALPLAN_INTERFACE); \
420 dp_int->hunt_function = funcptr; \
421 dp_int->interface_name = int_name; \
422 break; \
423 }
424
425 #define SWITCH_ADD_LIMIT(limit_int, int_name, incrptr, releaseptr, usageptr, resetptr, statusptr, interval_resetptr) \
426 for (;;) { \
427 limit_int = (switch_limit_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_LIMIT_INTERFACE); \
428 limit_int->incr = incrptr; \
429 limit_int->release = releaseptr; \
430 limit_int->usage = usageptr; \
431 limit_int->reset = resetptr; \
432 limit_int->interval_reset = interval_resetptr; \
433 limit_int->status = statusptr; \
434 limit_int->interface_name = int_name; \
435 break; \
436 }
437
438 SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void);
439
440 #define SWITCH_ADD_CODEC(codec_int, int_name) \
441 for (;;) { \
442 codec_int = (switch_codec_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_CODEC_INTERFACE); \
443 codec_int->modname = switch_core_strdup(pool, (*module_interface)->module_name); \
444 codec_int->interface_name = switch_core_strdup(pool, int_name); \
445 codec_int->codec_id = switch_core_codec_next_id(); \
446 break; \
447 }
448
switch_check_interval(uint32_t rate,uint32_t ptime)449 static inline int switch_check_interval(uint32_t rate, uint32_t ptime)
450 {
451 uint32_t max_ms = 0, ptime_div = 0;
452
453 switch (rate) {
454 case 22050:
455 case 11025:
456 if (ptime < 120)
457 return 1;
458 break;
459 case 48000:
460 case 44100:
461 max_ms = 40;
462 ptime_div = 2;
463 break;
464 case 32000:
465 case 24000:
466 case 16000:
467 max_ms = 60;
468 ptime_div = 2;
469 break;
470 case 12000:
471 max_ms = 100;
472 ptime_div = 2;
473 break;
474 case 8000:
475 max_ms = 120;
476 ptime_div = 2;
477 break;
478 }
479
480 if (max_ms && ptime_div && (ptime <= max_ms && (ptime % ptime_div) == 0) && ((rate / 1000) * ptime) < SWITCH_RECOMMENDED_BUFFER_SIZE) {
481 return 1;
482 }
483
484 return 0;
485 }
486
switch_core_codec_add_implementation(switch_memory_pool_t * pool,switch_codec_interface_t * codec_interface,const switch_codec_type_t codec_type,switch_payload_t ianacode,const char * iananame,char * fmtp,uint32_t samples_per_second,uint32_t actual_samples_per_second,int bits_per_second,int microseconds_per_packet,uint32_t samples_per_packet,uint32_t decoded_bytes_per_packet,uint32_t encoded_bytes_per_packet,uint8_t number_of_channels,int codec_frames_per_packet,switch_core_codec_init_func_t init,switch_core_codec_encode_func_t encode,switch_core_codec_decode_func_t decode,switch_core_codec_destroy_func_t destroy)487 static inline void switch_core_codec_add_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface,
488 /*! enumeration defining the type of the codec */
489 const switch_codec_type_t codec_type,
490 /*! the IANA code number */
491 switch_payload_t ianacode,
492 /*! the IANA code name */
493 const char *iananame,
494 /*! default fmtp to send (can be overridden by the init function) */
495 char *fmtp,
496 /*! samples transferred per second */
497 uint32_t samples_per_second,
498 /*! actual samples transferred per second for those who are not moron g722 RFC writers */
499 uint32_t actual_samples_per_second,
500 /*! bits transferred per second */
501 int bits_per_second,
502 /*! number of microseconds that denote one frame */
503 int microseconds_per_packet,
504 /*! number of samples that denote one frame */
505 uint32_t samples_per_packet,
506 /*! number of bytes that denote one frame decompressed */
507 uint32_t decoded_bytes_per_packet,
508 /*! number of bytes that denote one frame compressed */
509 uint32_t encoded_bytes_per_packet,
510 /*! number of channels represented */
511 uint8_t number_of_channels,
512 /*! number of frames to send in one network packet */
513 int codec_frames_per_packet,
514 /*! function to initialize a codec handle using this implementation */
515 switch_core_codec_init_func_t init,
516 /*! function to encode raw data into encoded data */
517 switch_core_codec_encode_func_t encode,
518 /*! function to decode encoded data into raw data */
519 switch_core_codec_decode_func_t decode,
520 /*! deinitalize a codec handle using this implementation */
521 switch_core_codec_destroy_func_t destroy)
522 {
523
524 if (decoded_bytes_per_packet > SWITCH_RECOMMENDED_BUFFER_SIZE) {
525 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Rejected codec name: %s rate: %u ptime: %d channels %d not enough buffer space %u > %d\n",
526 iananame, actual_samples_per_second, microseconds_per_packet / 1000, number_of_channels, decoded_bytes_per_packet, SWITCH_RECOMMENDED_BUFFER_SIZE);
527 } else if (codec_type == SWITCH_CODEC_TYPE_VIDEO || switch_check_interval(actual_samples_per_second, microseconds_per_packet / 1000)) {
528 switch_codec_implementation_t *impl = (switch_codec_implementation_t *) switch_core_alloc(pool, sizeof(*impl));
529 impl->codec_type = codec_type;
530 impl->ianacode = ianacode;
531 impl->iananame = switch_core_strdup(pool, iananame);
532 impl->fmtp = switch_core_strdup(pool, fmtp);
533 impl->samples_per_second = samples_per_second;
534 impl->actual_samples_per_second = actual_samples_per_second;
535 impl->bits_per_second = bits_per_second;
536 impl->microseconds_per_packet = microseconds_per_packet;
537 impl->samples_per_packet = samples_per_packet;
538 impl->decoded_bytes_per_packet = decoded_bytes_per_packet;
539 impl->encoded_bytes_per_packet = encoded_bytes_per_packet;
540 impl->number_of_channels = number_of_channels;
541 impl->codec_frames_per_packet = codec_frames_per_packet;
542 impl->init = init;
543 impl->encode = encode;
544 impl->decode = decode;
545 impl->destroy = destroy;
546 impl->codec_id = codec_interface->codec_id;
547 impl->next = codec_interface->implementations;
548 impl->impl_id = switch_core_codec_next_id();
549 impl->modname = codec_interface->modname;
550 codec_interface->implementations = impl;
551 } else {
552 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Rejected codec name: %s rate: %u ptime: %d channels: %d\n",
553 iananame, actual_samples_per_second, microseconds_per_packet / 1000, number_of_channels);
554 }
555 }
556
557 ///\}
558
switch_core_codec_add_video_implementation(switch_memory_pool_t * pool,switch_codec_interface_t * codec_interface,switch_payload_t ianacode,const char * iananame,char * fmtp,switch_core_codec_init_func_t init,switch_core_codec_video_encode_func_t encode,switch_core_codec_video_decode_func_t decode,switch_core_codec_control_func_t control,switch_core_codec_destroy_func_t destroy)559 static inline void switch_core_codec_add_video_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface,
560 /*! the IANA code number */
561 switch_payload_t ianacode,
562 /*! the IANA code name */
563 const char *iananame,
564 /*! default fmtp to send (can be overridden by the init function) */
565 char *fmtp,
566 switch_core_codec_init_func_t init,
567 /*! function to encode raw data into encoded data */
568 switch_core_codec_video_encode_func_t encode,
569 /*! function to decode encoded data into raw data */
570 switch_core_codec_video_decode_func_t decode,
571 /*! function to send control messages to the codec */
572 switch_core_codec_control_func_t control,
573 /*! deinitalize a codec handle using this implementation */
574 switch_core_codec_destroy_func_t destroy)
575 {
576
577 switch_codec_implementation_t *impl = (switch_codec_implementation_t *) switch_core_alloc(pool, sizeof(*impl));
578 memset(impl, 0, sizeof(*impl));
579 impl->codec_type = SWITCH_CODEC_TYPE_VIDEO;
580 impl->ianacode = ianacode;
581 impl->iananame = switch_core_strdup(pool, iananame);
582 impl->fmtp = switch_core_strdup(pool, fmtp);
583 impl->samples_per_second = 90000;
584 impl->actual_samples_per_second = 90000;
585 impl->bits_per_second = 0;
586 impl->microseconds_per_packet = 0;
587 impl->samples_per_packet = 0;
588 impl->number_of_channels = 1;
589 impl->codec_frames_per_packet = 1;
590 impl->init = init;
591 impl->encode_video = encode;
592 impl->decode_video = decode;
593 impl->codec_control = control;
594 impl->destroy = destroy;
595 impl->codec_id = codec_interface->codec_id;
596 impl->next = codec_interface->implementations;
597 impl->impl_id = switch_core_codec_next_id();
598 impl->modname = codec_interface->modname;
599 codec_interface->implementations = impl;
600 }
601
602 #define SWITCH_DECLARE_STATIC_MODULE(init, load, run, shut) void init(void) { \
603 switch_loadable_module_build_dynamic(__FILE__, load, run, shut, SWITCH_FALSE); \
604 }
605
606
switch_core_codec_ready(switch_codec_t * codec)607 static inline switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
608 {
609 return (codec && (codec->flags & SWITCH_CODEC_FLAG_READY) && codec->mutex && codec->codec_interface && codec->implementation) ? SWITCH_TRUE : SWITCH_FALSE;
610 }
611
612
613 SWITCH_DECLARE(switch_core_recover_callback_t) switch_core_get_secondary_recover_callback(const char *key);
614 SWITCH_DECLARE(switch_status_t) switch_core_register_secondary_recover_callback(const char *key, switch_core_recover_callback_t cb);
615 SWITCH_DECLARE(void) switch_core_unregister_secondary_recover_callback(const char *key);
616
617 SWITCH_END_EXTERN_C
618 #endif
619 /* For Emacs:
620 * Local Variables:
621 * mode:c
622 * indent-tabs-mode:t
623 * tab-width:4
624 * c-basic-offset:4
625 * End:
626 * For VIM:
627 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
628 */
629