1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 #ifndef mscommon_h
20 #define mscommon_h
21 
22 #include <bctoolbox/port.h>
23 #include <bctoolbox/list.h>
24 #include <ortp/logging.h>
25 #include <ortp/port.h>
26 #include <ortp/str_utils.h>
27 #include <ortp/payloadtype.h>
28 #include <time.h>
29 #if defined(__APPLE__)
30 #include "TargetConditionals.h"
31 #endif
32 
33 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM)
34 #define MS_HAS_ARM 1
35 #endif
36 #if defined(__ARM_NEON__) || defined(__ARM_NEON)
37 #define MS_HAS_ARM_NEON 1
38 #endif
39 #if MS_HAS_ARM_NEON && !(defined(__arm64__) || defined(__aarch64__))
40 #define MS_HAS_ARM_NEON_32 1
41 #endif
42 
43 #ifndef MS2_DEPRECATED
44 #if defined(_MSC_VER)
45 #define MS2_DEPRECATED __declspec(deprecated)
46 #else
47 #define MS2_DEPRECATED __attribute__ ((deprecated))
48 #endif
49 #endif
50 #define MS_UNUSED(x) ((void)(x))
51 
52 #define ms_malloc	ortp_malloc
53 #define ms_malloc0	ortp_malloc0
54 #define ms_realloc	ortp_realloc
55 #define ms_new		ortp_new
56 #define ms_new0		ortp_new0
57 #define ms_free		ortp_free
58 #define ms_strdup	ortp_strdup
59 #define ms_strndup	ortp_strndup
60 #define ms_strdup_printf	ortp_strdup_printf
61 #define ms_strcat_printf	ortp_strcat_printf
62 
63 #define ms_mutex_t		ortp_mutex_t
64 #define ms_mutex_init		ortp_mutex_init
65 #define ms_mutex_destroy	ortp_mutex_destroy
66 #define ms_mutex_lock		ortp_mutex_lock
67 #define ms_mutex_unlock		ortp_mutex_unlock
68 
69 #define ms_cond_t		ortp_cond_t
70 #define ms_cond_init		ortp_cond_init
71 #define ms_cond_wait		ortp_cond_wait
72 #define ms_cond_signal		ortp_cond_signal
73 #define ms_cond_broadcast	ortp_cond_broadcast
74 #define ms_cond_destroy		ortp_cond_destroy
75 
76 #define MS_DEFAULT_MAX_PAYLOAD_SIZE 1440
77 
78 #define MS2_INLINE ORTP_INLINE
79 
80 #ifdef _WIN32
81 #if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP)
82 #define MS2_WINDOWS_DESKTOP 1
83 #elif defined(WINAPI_FAMILY_PARTITION)
84 #if defined(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
85 #define MS2_WINDOWS_DESKTOP 1
86 #elif defined(WINAPI_PARTITION_PHONE_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
87 #define MS2_WINDOWS_PHONE 1
88 #elif defined(WINAPI_PARTITION_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
89 #define MS2_WINDOWS_UNIVERSAL 1
90 #endif
91 #endif
92 #endif
93 
94 #if defined(_MSC_VER)
95 #ifdef MS2_STATIC
96 #define MS2_PUBLIC
97 #define MS2_VAR_PUBLIC extern
98 #else
99 #ifdef MS2_EXPORTS
100 #define MS2_PUBLIC	__declspec(dllexport)
101 #define MS2_VAR_PUBLIC extern __declspec(dllexport)
102 #else
103 #define MS2_PUBLIC	__declspec(dllimport)
104 #define MS2_VAR_PUBLIC extern __declspec(dllimport)
105 #endif
106 #endif
107 #else
108 #define MS2_PUBLIC
109 #define MS2_VAR_PUBLIC extern
110 #endif
111 
112 #if defined(_WIN32_WCE)
113 time_t ms_time (time_t *t);
114 #else
115 #define ms_time time
116 #endif
117 
118 #ifdef DEBUG
ms_debug(const char * fmt,...)119 static MS2_INLINE void ms_debug(const char *fmt,...)
120 {
121   va_list args;
122   va_start (args, fmt);
123   ortp_logv(ORTP_LOG_DOMAIN, ORTP_DEBUG, fmt, args);
124   va_end (args);
125 }
126 #else
127 #define ms_debug(fmt, ...)
128 #endif
129 
130 #define ms_message	ortp_message
131 #define ms_warning	ortp_warning
132 #define ms_error	ortp_error
133 #define ms_fatal	ortp_fatal
134 
135 #define ms_return_val_if_fail(_expr_,_ret_)\
136 	if (!(_expr_)) { ms_fatal("assert "#_expr_ "failed"); return (_ret_);}
137 
138 #define ms_return_if_fail(_expr_) \
139 	if (!(_expr_)){ ms_fatal("assert "#_expr_ "failed"); return ;}
140 
141 #define ms_thread_t		ortp_thread_t
142 #define ms_thread_create 	ortp_thread_create
143 #define ms_thread_join		ortp_thread_join
144 #define ms_thread_self		ortp_thread_self
145 
146 typedef ortpTimeSpec MSTimeSpec;
147 
148 #define ms_get_cur_time ortp_get_cur_time
149 #define ms_get_cur_time_ms ortp_get_cur_time_ms
150 
151 typedef bctbx_compare_func MSCompareFunc;
152 typedef void (*MSIterateFunc)(void *a);
153 typedef void (*MSIterate2Func)(void *a, void *b);
154 typedef void (*MSIterate3Func)(void *a, void *b, void *c);
155 
156 #ifdef __cplusplus
157 extern "C"{
158 #endif
159 /*for stun*/
160 typedef struct { unsigned char octet[12]; } UInt96;
161 typedef struct { unsigned char octet[16]; } UInt128;
162 
163 MS2_PUBLIC void ms_thread_exit(void* ret_val);
164 
165 
166 #define MSList bctbx_list_t
167 
168 /**
169  * @addtogroup ms_list
170  * @{
171 **/
172 
173 /** Inserts a new element containing data to the end of a given list
174  * @param list list where data should be added. If NULL, a new list will be created.
175  * @param data data to insert into the list
176  * @return first element of the list
177  * @deprecated Use bctbx_list_append() instead
178 **/
179 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_append(MSList *list, void * data);
180 
181 /** Inserts given element to the end of a given list
182  * @param list list where data should be added. If NULL, a new list will be created.
183  * @param new_elem element to append
184  * @return first element of the list
185  * @deprecated Use bctbx_list_append_link() instead
186 **/
187 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_append_link(MSList *list, MSList *new_elem);
188 
189 /** Inserts a new element containing data to the start of a given list
190  * @param list list where data should be added. If NULL, a new list will be created.
191  * @param data data to insert into the list
192  * @return first element of the list - the one which was just created.
193  * @deprecated Use bctbx_list_prepend() instead
194 **/
195 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_prepend(MSList *list, void * data);
196 
197 /** Frees all elements of a given list
198  * Note that data contained in each element will not be freed. If you need to clean
199  * them, consider using @ms_list_free_with_data
200  * @param list object to free.
201  * @return NULL
202  * @deprecated Use bctbx_list_free() instead
203 **/
204 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_free(MSList *list);
205 
206 /** Frees all elements of a given list after having called freefunc on each element
207  * @param list object to free.
208  * @param freefunc function to invoke on each element data before destroying the element
209  * @return NULL
210  * @deprecated Use bctbx_list_free_with_data() instead
211 **/
212 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_free_with_data(MSList *list, void (*freefunc)(void*));
213 
214 /** Concatenates second list to the end of first list
215  * @param first First list
216  * @param second Second list to append at the end of first list.
217  * @return first element of the merged list
218  * @deprecated Use bctbx_list_concat() instead
219 **/
220 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_concat(MSList *first, MSList *second);
221 
222 /** Finds and remove the first element containing the given data. Nothing is done if element is not found.
223  * @param list List in which data must be removed
224  * @param data Data to remove
225  * @return first element of the modified list
226  * @deprecated Use bctbx_list_remove() instead
227 **/
228 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_remove(MSList *list, void *data);
229 
230 /** Finds and remove any elements according to the given predicate function
231  * @param list List in which data must be removed
232  * @param compare_func Function to invoke on each element. If it returns TRUE, the given element will be deleted.
233  * @param user_data User data to pass to compare_func function
234  * @return first element of the modified list
235  * @deprecated Use bctbx_list_remove_custom() instead
236 **/
237 MS2_PUBLIC MS2_DEPRECATED MSList * ms_list_remove_custom(MSList *list, MSCompareFunc compare_func, const void *user_data);
238 
239 /** Returns size of a given list
240  * @param list List to measure
241  * @return Size of list
242  * @deprecated Use bctbx_list_size() instead
243 **/
244 MS2_PUBLIC MS2_DEPRECATED int ms_list_size(const MSList *list);
245 
246 /** Invoke function on each element of the list
247  * @param list List object
248  * @param iterate_func Function to invoke on each element.
249  * @deprecated Use bctbx_list_for_each() instead
250 **/
251 MS2_PUBLIC MS2_DEPRECATED void ms_list_for_each(const MSList *list, MSIterateFunc iterate_func);
252 
253 /** Invoke function on each element of the list
254  * @param list List object
255  * @param iterate_func Function to invoke on each element.
256  * @param user_data User data to pass to iterate_func function.
257  * @deprecated Use bctbx_list_for_each2() instead
258 **/
259 MS2_PUBLIC MS2_DEPRECATED void ms_list_for_each2(const MSList *list, MSIterate2Func iterate_func, void *user_data);
260 
261 MS2_PUBLIC MS2_DEPRECATED void ms_list_for_each3(const MSList *list, MSIterate3Func iterate_func, void *user_data, void *factory);
262 
263 /** Finds and remove given element in list.
264  * @param list List in which element must be removed
265  * @param element element to remove
266  * @return first element of the modified list
267  * @deprecated Use bctbx_list_remove_link() instead
268 **/
269 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_remove_link(MSList *list, MSList *elem);
270 
271 /** Finds first element containing data in the given list.
272  * @param list List in which element must be found
273  * @param data data to find
274  * @return element containing data, or NULL if not found
275  * @deprecated Use bctbx_list_find() instead
276 **/
277 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_find(MSList *list, void *data);
278 
279 /** Finds first element according to the given predicate function
280  * @param list List in which element must be found
281  * @param compare_func Function to invoke on each element. If it returns TRUE, the given element will be returned.
282  * @param user_data User data to pass to compare_func function
283  * @return Element matching the predicate, or NULL if none is found.
284  * @deprecated Use bctbx_list_find_custom() instead
285 **/
286 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_find_custom(MSList *list, MSCompareFunc compare_func, const void *user_data);
287 
288 /** Returns the nth element data of the list
289  * @param list List object
290  * @param index data index which must be returned.
291  * @return Element at the given index. NULL if index is invalid (negative or greater or equal to ms_list_size).
292  * @deprecated Use bctbx_list_nth_data() instead
293 **/
294 MS2_PUBLIC MS2_DEPRECATED void * ms_list_nth_data(const MSList *list, int index);
295 
296 /** Returns the index of the given element
297  * @param list List object
298  * @param elem Element to search for.
299  * @return Index of the given element. -1 if not found.
300  * @deprecated Use bctbx_list_position() instead
301 **/
302 MS2_PUBLIC MS2_DEPRECATED int ms_list_position(const MSList *list, MSList *elem);
303 
304 /** Returns the index of the first element containing data
305  * @param list List object
306  * @param data Data to search for.
307  * @return Index of the element containing data. -1 if not found.
308  * @deprecated Use bctbx_list_index() instead
309 **/
310 MS2_PUBLIC MS2_DEPRECATED int ms_list_index(const MSList *list, void *data);
311 
312 /** Inserts a new element containing data at the place given by compare_func
313  * @param list list where data should be added. If NULL, a new list will be created.
314  * @param data data to insert into the list
315  * @param compare_func function determining where should the new element be placed
316  * @return first element of the list.
317  * @deprecated Use bctbx_list_insert_sorted() instead
318 **/
319 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_insert_sorted(MSList *list, void *data, MSCompareFunc compare_func);
320 
321 /** Inserts a new element containing data before the given element
322  * @param list list where data should be added. If NULL, a new list will be created.
323  * @param before element parent to the one we will insert.
324  * @param data data to insert into the list
325  * @return first element of the modified list.
326  * @deprecated Use bctbx_list_insert() instead
327 **/
328 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_insert(MSList *list, MSList *before, void *data);
329 
330 /** Copies a list in another one, duplicating elements but not data
331  * @param list list to copy
332  * @return Newly created list
333  * @deprecated Use bctbx_list_copy() instead
334 **/
335 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_copy(const MSList *list);
336 
337 /** Copies a list in another one, duplicating elements according to the given function
338  * @param list list to copy
339  * @param copyfunc function to invoke on each element which will return the new list data value
340  * @return Newly created list
341  * @deprecated Use bctbx_list_copy_with_data() instead
342 **/
343 MS2_PUBLIC MS2_DEPRECATED MSList *ms_list_copy_with_data(const MSList *list, void *(*copyfunc)(void *));
344 
345 /**
346  * @deprecated @deprecated Use bctbx_list_next() instead
347  */
348 MS2_PUBLIC MS2_DEPRECATED MSList* ms_list_next(const MSList *list);
349 
350 /** @} */
351 
352 MS2_PUBLIC char * ms_tags_list_as_string(const MSList *list);
353 MS2_PUBLIC bool_t ms_tags_list_contains_tag(const MSList *list, const char *tag);
354 
355 #undef MIN
356 #define MIN(a,b)	((a)>(b) ? (b) : (a))
357 #undef MAX
358 #define MAX(a,b)	((a)>(b) ? (a) : (b))
359 
360 /**
361  * @file mscommon.h
362  * @brief mediastreamer2 mscommon.h include file
363  *
364  * This file provide the API needed to initialize
365  * and reset the mediastreamer2 library.
366  *
367  */
368 
369 /**
370  * @addtogroup mediastreamer2_init
371  * @{
372  */
373 
374 
375 /**
376  * Helper macro for backward compatibility.
377  * Use ms_base_init() and ms_voip_init() instead.
378  */
379 #define ms_init()	ms_base_init(), ms_voip_init(), ms_plugins_init()
380 
381 /**
382  * Helper macro for backward compatibility.
383  * Use ms_base_exit() and ms_voip_exit() instead.
384  */
385 #define ms_exit()	ms_voip_exit(), ms_plugins_exit(), ms_base_exit()
386 
387 /**
388  * Initialize the mediastreamer2 base library.
389  *
390  * This must be called once before calling any other API.
391  * @deprecated use ms_factory_new()
392  */
393 MS2_PUBLIC MS2_DEPRECATED void ms_base_init(void);
394 
395 /**
396  * Initialize the mediastreamer2 VoIP library.
397  *
398  * This must be called one before calling any other API.
399  * @deprecated use ms_factory_new_with_voip().
400  */
401 MS2_PUBLIC MS2_DEPRECATED void ms_voip_init(void);
402 
403 /**
404  * Load the plugins from the default plugin directory.
405  *
406  * This is just a wrapper around ms_load_plugins().
407  * This must be called after ms_base_init() and after ms_voip_init().
408  * @deprecated use ms_factory_init_plugins(), or ms_factory_new_with_voip() that does it automatically.
409  */
410 MS2_PUBLIC MS2_DEPRECATED void ms_plugins_init(void);
411 
412 /**
413  * Set the directory from where the plugins are to be loaded when calling ms_plugins_init().
414  * @param[in] path The path to the plugins directory.
415  * @deprecated use ms_factory_set_plugins_dir().
416  */
417 MS2_PUBLIC MS2_DEPRECATED void ms_set_plugins_dir(const char *path);
418 
419 /**
420  * Load plugins from a specific directory.
421  * This method basically loads all libraries in the specified directory and attempts to call a C function called
422  * \<libraryname\>_init. For example if a library 'libdummy.so' or 'libdummy.dll' is found, then the loader tries to locate
423  * a C function called 'libdummy_init()' and calls it if it exists.
424  * ms_load_plugins() can be used to load non-mediastreamer2 plugins as it does not expect mediastreamer2 specific entry points.
425  *
426  * @param directory   A directory where plugins library are available.
427  *
428  * @return >0 if successfull, 0 if not plugins loaded, -1 otherwise.
429  * @deprecated use ms_factory_load_plugins().
430  */
431 MS2_PUBLIC MS2_DEPRECATED int ms_load_plugins(const char *directory);
432 
433 /**
434  * Release resource allocated in the mediastreamer2 base library.
435  *
436  * This must be called once before closing program.
437  * @deprecated use ms_factory_destroy().
438  */
439 MS2_PUBLIC MS2_DEPRECATED void  ms_base_exit(void);
440 
441 /**
442  * Release resource allocated in the mediastreamer2 VoIP library.
443  *
444  * This must be called once before closing program.
445  * @deprecated use ms_factory_destroy().
446  */
447 MS2_PUBLIC MS2_DEPRECATED void ms_voip_exit(void);
448 
449 /**
450  * Unload the plugins loaded by ms_plugins_init().
451  * @deprecated use ms_factory_destroy().
452  */
453 MS2_PUBLIC MS2_DEPRECATED void ms_plugins_exit(void);
454 
455 struct _MSSndCardDesc;
456 
457 MS2_PUBLIC void ms_sleep(int seconds);
458 
459 MS2_PUBLIC void ms_usleep(uint64_t usec);
460 
461 /**
462  * The max payload size allowed.
463  * Filters that generate data that can be sent through RTP should make packets
464  * whose size is below ms_get_payload_max_size().
465  * The default value is 1440 computed as the standard internet MTU minus IPv6 header,
466  * UDP header and RTP header. As IPV4 header is smaller than IPv6 header, this
467  * value works for both.
468  * @deprecated use ms_factory_get_payload_max_size().
469 **/
470 MS2_PUBLIC MS2_DEPRECATED int ms_get_payload_max_size(void);
471 
472 /**
473  * Set the maximum payload size allowed.
474  * @deprecated use ms_factory_set_payload_max_size().
475 **/
476 MS2_PUBLIC MS2_DEPRECATED void ms_set_payload_max_size(int size);
477 
478 /**
479  * Returns the network Max Transmission Unit to reach destination_host.
480  * This will attempt to send one or more big packets to destination_host, to a random port.
481  * Those packets are filled with zeroes.
482 **/
483 MS2_PUBLIC int ms_discover_mtu(const char *destination_host);
484 
485 /**
486  * Set mediastreamer default mtu, used to compute the default RTP max payload size.
487  * This function will call ms_set_payload_max_size(mtu-[ipv6 header size]).
488  * @deprecated use ms_factory_set_mtu()
489 **/
490 MS2_PUBLIC MS2_DEPRECATED void ms_set_mtu(int mtu);
491 
492 /**
493  * Get mediastreamer default mtu, used to compute the default RTP max payload size.
494  * @deprecated use ms_factory_get_mtu().
495 **/
496 MS2_PUBLIC MS2_DEPRECATED int ms_get_mtu(void);
497 
498 /**
499  * Declare how many cpu (cores) are available on the platform
500  * @deprecated use ms_factory_set_cpu_count().
501  */
502 MS2_PUBLIC MS2_DEPRECATED void ms_set_cpu_count(unsigned int c);
503 
504 /**
505  * @deprecated use ms_factory_get_cpu_count().
506 **/
507 MS2_PUBLIC MS2_DEPRECATED unsigned int ms_get_cpu_count(void);
508 
509 /**
510  * Adds a new entry in the SoundDeviceDescription table
511  */
512 MS2_PUBLIC void ms_sound_device_description_add(const char *manufacturer, const char *model, const char *platform, unsigned int flags, int delay, int recommended_rate);
513 
514 /**
515  * @return TRUE if address is ipv6
516  */
517 MS2_PUBLIC bool_t ms_is_ipv6(const char *address);
518 
519 /**
520  * @return TRUE if address is multicast
521  */
522 bool_t ms_is_multicast_addr(const struct sockaddr *address);
523 /**
524  * @return TRUE if address is multicast
525  */
526 MS2_PUBLIC bool_t ms_is_multicast(const char *address);
527 
528 /**
529  * Utility function to load a file into memory.
530  * @param file a FILE handle
531  * @param nbytes (optional) number of bytes read
532 **/
533 MS2_PUBLIC char *ms_load_file_content(FILE *file, size_t *nbytes);
534 
535 /**
536  * Utility function to load a file into memory.
537  * @param path a FILE handle
538  * @param nbytes (optional) number of bytes read
539 **/
540 MS2_PUBLIC char *ms_load_path_content(const char *path, size_t *nbytes);
541 /** @} */
542 
543 #ifdef __cplusplus
544 }
545 #endif
546 
547 #ifdef MS2_INTERNAL
548 #  ifdef HAVE_CONFIG_H
549 #  include "mediastreamer-config.h" /*necessary to know if ENABLE_NLS is there*/
550 #  endif
551 
552 #ifdef _WIN32
553 #include <malloc.h> //for alloca
554 #ifdef _MSC_VER
555 #define alloca _alloca
556 #endif
557 #endif
558 
559 #  if defined(ENABLE_NLS)
560 
561 #ifdef _MSC_VER
562 // prevent libintl.h from re-defining fprintf and vfprintf
563 #ifndef fprintf
564 #define fprintf fprintf
565 #endif
566 #ifndef vfprintf
567 #define vfprintf vfprintf
568 #endif
569 #define _GL_STDIO_H
570 #endif
571 
572 #    include <libintl.h>
573 #    define _(String) dgettext (GETTEXT_PACKAGE, String)
574 #  else
575 #    define _(String) (String)
576 #  endif // ENABLE_NLS
577 #define N_(String) (String)
578 #endif // MS2_INTERNAL
579 
580 #ifdef __ANDROID__
581 #include "mediastreamer2/msjava.h"
582 #endif
583 #endif
584 
585