source: mediastreamer2/linphone/mediastreamer2/src/mscommon.c @ 197:a3a8b2ea9d63

Last change on this file since 197:a3a8b2ea9d63 was 197:a3a8b2ea9d63, checked in by aymeric <aymeric@…>, 5 years ago

Improve log

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@200 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 13.4 KB
Line 
1/*
2mediastreamer2 library - modular sound and video processing and streaming
3Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18*/
19
20#ifdef HAVE_CONFIG_H
21#include "mediastreamer-config.h"
22#endif
23
24#include "mediastreamer2/mscommon.h"
25#include "mediastreamer2/msfilter.h"
26
27#include "alldescs.h"
28#include "mediastreamer2/mssndcard.h"
29#include "mediastreamer2/mswebcam.h"
30
31#if !defined(_WIN32_WCE)
32#include <sys/types.h>
33#endif
34#ifndef WIN32
35#include <dirent.h>
36#else
37#ifndef PACKAGE_PLUGINS_DIR
38#if defined(WIN32) || defined(_WIN32_WCE)
39#define PACKAGE_PLUGINS_DIR "plugins\\"
40#else
41#define PACKAGE_PLUGINS_DIR "."
42#endif
43#endif
44#endif
45#ifdef HAVE_DLOPEN
46#include <dlfcn.h>
47#endif
48
49#ifdef __APPLE__
50#import <Cocoa/Cocoa.h>
51#include <Foundation/Foundation.h>
52#endif
53
54MSList *ms_list_new(void *data){
55        MSList *new_elem=(MSList *)ms_new(MSList,1);
56        new_elem->prev=new_elem->next=NULL;
57        new_elem->data=data;
58        return new_elem;
59}
60
61MSList * ms_list_append(MSList *elem, void * data){
62        MSList *new_elem=ms_list_new(data);
63        MSList *it=elem;
64        if (elem==NULL) return new_elem;
65        while (it->next!=NULL) it=ms_list_next(it);
66        it->next=new_elem;
67        new_elem->prev=it;
68        return elem;
69}
70
71MSList * ms_list_prepend(MSList *elem, void *data){
72        MSList *new_elem=ms_list_new(data);
73        if (elem!=NULL) {
74                new_elem->next=elem;
75                elem->prev=new_elem;
76        }
77        return new_elem;
78}
79
80
81MSList * ms_list_concat(MSList *first, MSList *second){
82        MSList *it=first;
83        if (it==NULL) return second;
84        while(it->next!=NULL) it=ms_list_next(it);
85        it->next=second;
86        second->prev=it;
87        return first;
88}
89
90MSList * ms_list_free(MSList *list){
91        MSList *elem = list;
92        MSList *tmp;
93        if (list==NULL) return NULL;
94        while(elem->next!=NULL) {
95                tmp = elem;
96                elem = elem->next;
97                ms_free(tmp);
98        }
99        ms_free(elem);
100        return NULL;
101}
102
103MSList * ms_list_remove(MSList *first, void *data){
104        MSList *it;
105        it=ms_list_find(first,data);
106        if (it) return ms_list_remove_link(first,it);
107        else {
108                ms_warning("ms_list_remove: no element with %p data was in the list", data);
109                return first;
110        }
111}
112
113int ms_list_size(const MSList *first){
114        int n=0;
115        while(first!=NULL){
116                ++n;
117                first=first->next;
118        }
119        return n;
120}
121
122void ms_list_for_each(const MSList *list, void (*func)(void *)){
123        for(;list!=NULL;list=list->next){
124                func(list->data);
125        }
126}
127
128void ms_list_for_each2(const MSList *list, void (*func)(void *, void *), void *user_data){
129        for(;list!=NULL;list=list->next){
130                func(list->data,user_data);
131        }
132}
133
134MSList *ms_list_remove_link(MSList *list, MSList *elem){
135        MSList *ret;
136        if (elem==list){
137                ret=elem->next;
138                elem->prev=NULL;
139                elem->next=NULL;
140                if (ret!=NULL) ret->prev=NULL;
141                ms_free(elem);
142                return ret;
143        }
144        elem->prev->next=elem->next;
145        if (elem->next!=NULL) elem->next->prev=elem->prev;
146        elem->next=NULL;
147        elem->prev=NULL;
148        ms_free(elem);
149        return list;
150}
151
152MSList *ms_list_find(MSList *list, void *data){
153        for(;list!=NULL;list=list->next){
154                if (list->data==data) return list;
155        }
156        return NULL;
157}
158
159MSList *ms_list_find_custom(MSList *list, int (*compare_func)(const void *, const void*), void *user_data){
160        for(;list!=NULL;list=list->next){
161                if (compare_func(list->data,user_data)==0) return list;
162        }
163        return NULL;
164}
165
166void * ms_list_nth_data(const MSList *list, int index){
167        int i;
168        for(i=0;list!=NULL;list=list->next,++i){
169                if (i==index) return list->data;
170        }
171        ms_error("ms_list_nth_data: no such index in list.");
172        return NULL;
173}
174
175int ms_list_position(const MSList *list, MSList *elem){
176        int i;
177        for(i=0;list!=NULL;list=list->next,++i){
178                if (elem==list) return i;
179        }
180        ms_error("ms_list_position: no such element in list.");
181        return -1;
182}
183
184int ms_list_index(const MSList *list, void *data){
185        int i;
186        for(i=0;list!=NULL;list=list->next,++i){
187                if (data==list->data) return i;
188        }
189        ms_error("ms_list_index: no such element in list.");
190        return -1;
191}
192
193MSList *ms_list_insert_sorted(MSList *list, void *data, int (*compare_func)(const void *, const void*)){
194        MSList *it,*previt=NULL;
195        MSList *nelem;
196        MSList *ret=list;
197        if (list==NULL) return ms_list_append(list,data);
198        else{
199                nelem=ms_list_new(data);
200                for(it=list;it!=NULL;it=it->next){
201                        previt=it;
202                        if (compare_func(data,it->data)<=0){
203                                nelem->prev=it->prev;
204                                nelem->next=it;
205                                if (it->prev!=NULL)
206                                        it->prev->next=nelem;
207                                else{
208                                        ret=nelem;
209                                }
210                                it->prev=nelem;
211                                return ret;
212                        }
213                }
214                previt->next=nelem;
215                nelem->prev=previt;
216        }
217        return ret;
218}
219
220MSList *ms_list_insert(MSList *list, MSList *before, void *data){
221        MSList *elem;
222        if (list==NULL || before==NULL) return ms_list_append(list,data);
223        for(elem=list;elem!=NULL;elem=ms_list_next(elem)){
224                if (elem==before){
225                        if (elem->prev==NULL)
226                                return ms_list_prepend(list,data);
227                        else{
228                                MSList *nelem=ms_list_new(data);
229                                nelem->prev=elem->prev;
230                                nelem->next=elem;
231                                elem->prev->next=nelem;
232                                elem->prev=nelem;
233                        }
234                }
235        }
236        return list;
237}
238
239MSList *ms_list_copy(const MSList *list){
240        MSList *copy=NULL;
241        const MSList *iter;
242        for(iter=list;iter!=NULL;iter=ms_list_next(iter)){
243                copy=ms_list_append(copy,iter->data);
244        }
245        return copy;
246}
247
248
249#ifdef __APPLE__
250#define PLUGINS_EXT ".dylib"
251#else
252#define PLUGINS_EXT ".so"
253#endif
254
255typedef void (*init_func_t)(void);
256
257int ms_load_plugins(const char *dir){
258    int num=0;
259#if defined(WIN32) && !defined(_WIN32_WCE)
260    WIN32_FIND_DATA FileData; 
261    HANDLE hSearch; 
262    char szDirPath[1024]; 
263    char szPluginFile[1024]; 
264    BOOL fFinished = FALSE;
265   
266        snprintf(szDirPath, sizeof(szDirPath), "%s", dir);
267    // Create a new directory.   
268#if 0
269    if (!CreateDirectory(szDirPath, NULL))
270    {
271        ms_message("plugins directory already exist (%s).", szDirPath);
272    }
273#endif
274   
275    // Start searching for .TXT files in the current directory.
276   
277        snprintf(szDirPath, sizeof(szDirPath), "%s\\*.dll", dir);
278    hSearch = FindFirstFile(szDirPath, &FileData);
279    if (hSearch == INVALID_HANDLE_VALUE)
280    {
281        ms_message("no plugin (*.dll) found in %s.", szDirPath);
282                return 0;
283    }
284        snprintf(szDirPath, sizeof(szDirPath), "%s", dir);
285
286    while (!fFinished) 
287    {
288        /* load library */
289        HINSTANCE os_handle;
290        UINT em;
291        em = SetErrorMode (SEM_FAILCRITICALERRORS);
292
293        snprintf(szPluginFile, sizeof(szPluginFile), "%s\\%s", szDirPath, FileData.cFileName);
294        os_handle = LoadLibraryEx (szPluginFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
295        if (os_handle==NULL)
296        {
297            os_handle = LoadLibraryEx (szPluginFile, NULL, 0);
298        }
299        SetErrorMode (em);
300        if (os_handle==NULL)
301            ms_warning("Fail to load plugin %s", szPluginFile); 
302        else
303        {
304            init_func_t initroutine;
305            char szPluginName[256]; 
306            char szMethodName[256]; 
307            snprintf(szPluginName, 256, "%s", FileData.cFileName);
308            szPluginName[strlen(szPluginName)-4]='\0';
309            snprintf(szMethodName, 256, "%s_init", szPluginName);
310            initroutine = (init_func_t) GetProcAddress (os_handle, szMethodName);
311                        if (initroutine!=NULL){
312                                initroutine();
313                                ms_message("Plugin loaded (%s)", szPluginFile);
314                                num++;
315                        }else{
316                                ms_warning("Could not locate init routine of plugin %s", szPluginFile);
317                        }
318        }
319
320
321        if (!FindNextFile(hSearch, &FileData)) 
322        {
323            if (GetLastError() == ERROR_NO_MORE_FILES) 
324            { 
325                fFinished = TRUE; 
326            } 
327            else 
328            { 
329                ms_error("couldn't find next plugin dll."); 
330                fFinished = TRUE; 
331            } 
332        }
333    } 
334     
335    // Close the search handle.
336     
337    FindClose(hSearch);
338
339#elif HAVE_DLOPEN
340        DIR *ds;
341        struct dirent *de;
342        char *fullpath;
343        ds=opendir(dir);       
344        if (ds==NULL){
345                ms_message("Cannot open directory %s: %s",dir,strerror(errno));
346                return -1;
347        }
348        while( (de=readdir(ds))!=NULL){
349                if ((de->d_type==DT_REG && strstr(de->d_name,PLUGINS_EXT)!=NULL)
350                    || (de->d_type==DT_UNKNOWN && strstr(de->d_name,PLUGINS_EXT)==de->d_name+strlen(de->d_name)-strlen(PLUGINS_EXT))) {
351                        void *handle;
352                        fullpath=ms_strdup_printf("%s/%s",dir,de->d_name);
353                        ms_message("Loading plugin %s...",fullpath);
354                       
355                        if ( (handle=dlopen(fullpath,RTLD_NOW))==NULL){
356                                ms_warning("Fail to load plugin %s : %s",fullpath,dlerror());
357                        }else {
358                                char *initroutine_name=ms_malloc0(strlen(de->d_name)+10);
359                                char *p;
360                                void *initroutine=NULL;
361                                strcpy(initroutine_name,de->d_name);
362                                p=strstr(initroutine_name,PLUGINS_EXT);
363                                if (p!=NULL)
364                                  {
365                                    strcpy(p,"_init");
366                                    initroutine=dlsym(handle,initroutine_name);
367                                  }
368
369#ifdef __APPLE__
370                                if (initroutine==NULL){
371                                  /* on macosx: library name are libxxxx.1.2.3.dylib */
372                                  /* -> MUST remove the .1.2.3 */
373                                  p=strstr(initroutine_name,".");
374                                  if (p!=NULL)
375                                    {
376                                      strcpy(p,"_init");
377                                      initroutine=dlsym(handle,initroutine_name);
378                                    }
379                                }
380#endif
381
382                                if (initroutine!=NULL){
383                                        init_func_t func=(init_func_t)initroutine;
384                                        func();
385                                        ms_message("Plugin loaded (%s)", fullpath);
386                                        num++;
387                                }else{
388                                        ms_warning("Could not locate init routine of plugin %s",de->d_name);
389                                }
390                                ms_free(initroutine_name);
391                        }
392                        ms_free(fullpath);
393                }
394        }
395        closedir(ds);
396#else
397        ms_warning("no loadable plugin support: plugins cannot be loaded.");
398        num=-1;
399#endif
400        return num;
401}
402
403
404#ifdef __ALSA_ENABLED__
405extern MSSndCardDesc alsa_card_desc;
406#endif
407
408#ifdef HAVE_SYS_SOUNDCARD_H
409extern MSSndCardDesc oss_card_desc;
410#endif
411
412#ifdef __ARTS_ENABLED__
413extern MSSndCardDesc arts_card_desc;
414#endif
415
416#ifdef WIN32
417extern MSSndCardDesc winsnd_card_desc;
418#endif
419
420#ifdef __DIRECTSOUND_ENABLED__
421extern MSSndCardDesc winsndds_card_desc;
422#endif
423
424#ifdef __MACSND_ENABLED__
425extern MSSndCardDesc ca_card_desc;
426#endif
427
428#ifdef __PORTAUDIO_ENABLED__
429extern MSSndCardDesc pasnd_card_desc;
430#endif
431
432#ifdef __MAC_AQ_ENABLED__
433extern MSSndCardDesc aq_card_desc;
434#endif
435
436static MSSndCardDesc * ms_snd_card_descs[]={
437#ifdef __ALSA_ENABLED__
438        &alsa_card_desc,
439#endif
440#ifdef HAVE_SYS_SOUNDCARD_H
441        &oss_card_desc,
442#endif
443#ifdef __ARTS_ENABLED__
444        &arts_card_desc,
445#endif
446#ifdef WIN32
447        &winsnd_card_desc,
448#endif
449#ifdef __DIRECTSOUND_ENABLED__
450        &winsndds_card_desc,
451#endif
452#ifdef __PORTAUDIO_ENABLED__
453        &pasnd_card_desc,
454#endif
455#ifdef __MACSND_ENABLED__
456        &ca_card_desc,
457#endif
458#ifdef __MAC_AQ_ENABLED__
459        &aq_card_desc,
460#endif
461        NULL
462};
463
464#ifdef VIDEO_ENABLED
465
466#ifdef __linux
467extern MSWebCamDesc v4l_desc;
468#endif
469
470#ifdef HAVE_LINUX_VIDEODEV2_H
471extern MSWebCamDesc v4l2_desc;
472#endif
473
474#ifdef WIN32
475extern MSWebCamDesc ms_vfw_cam_desc;
476#endif
477#if defined(WIN32) && defined(HAVE_DIRECTSHOW)
478extern MSWebCamDesc ms_directx_cam_desc;
479#endif
480
481extern MSWebCamDesc static_image_desc;
482extern MSWebCamDesc mire_desc;
483
484static MSWebCamDesc * ms_web_cam_descs[]={
485#ifdef HAVE_LINUX_VIDEODEV2_H
486        &v4l2_desc,
487#endif
488#ifdef __linux
489        &v4l_desc,
490#endif
491#if defined(WIN32) && defined(HAVE_DIRECTSHOW)
492        &ms_directx_cam_desc,
493#endif
494#if defined(WIN32) && !defined(HAVE_DIRECTSHOW)
495        &ms_vfw_cam_desc,
496#endif
497        &mire_desc,
498        &static_image_desc,
499        NULL
500};
501
502#endif
503
504void ms_init(){
505        int i;
506        MSSndCardManager *cm;
507#ifdef __APPLE__
508        NSApplicationLoad();
509#endif
510
511#if !defined(_WIN32_WCE)
512        if (getenv("MEDIASTREAMER_DEBUG")!=NULL){
513                ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
514        }
515#endif
516        ms_message("Registering all filters...");
517        /* register builtin MSFilter's */
518        for (i=0;ms_filter_descs[i]!=NULL;i++){
519                ms_filter_register(ms_filter_descs[i]);
520        }
521        ms_message("Registering all soundcard handlers");
522        cm=ms_snd_card_manager_get();
523        for (i=0;ms_snd_card_descs[i]!=NULL;i++){
524                ms_snd_card_manager_register_desc(cm,ms_snd_card_descs[i]);
525        }
526
527#ifdef VIDEO_ENABLED
528        ms_message("Registering all webcam handlers");
529        {
530                MSWebCamManager *wm;
531                wm=ms_web_cam_manager_get();
532                for (i=0;ms_web_cam_descs[i]!=NULL;i++){
533                        ms_web_cam_manager_register_desc(wm,ms_web_cam_descs[i]);
534                }
535        }
536#endif
537        ms_message("Loading plugins");
538        ms_load_plugins(PACKAGE_PLUGINS_DIR);
539        ms_message("ms_init() done");
540}
541
542void ms_exit(){
543        ms_filter_unregister_all();
544        ms_snd_card_manager_destroy();
545#ifdef VIDEO_ENABLED
546        ms_web_cam_manager_destroy();
547#endif
548}
549
550void ms_reload_snd_card(MSSndCardDesc *snd_desc){
551        MSSndCardManager *cm;
552        int i;
553
554        ms_snd_card_manager_destroy();
555
556        ms_message("Registering all soundcard handlers");
557        if (snd_desc!=NULL)
558        {
559                cm=ms_snd_card_manager_get();
560                if (cm!=NULL)
561                        ms_snd_card_manager_register_desc(cm,snd_desc);
562                return;
563        }
564
565        /*register SndCardDesc */
566        cm=ms_snd_card_manager_get();
567        for (i=0;ms_snd_card_descs[i]!=NULL;i++){
568                ms_snd_card_manager_register_desc(cm,ms_snd_card_descs[i]);
569        }
570
571        return;
572}
573
574void ms_sleep(int seconds){
575#ifdef WIN32
576        Sleep(seconds*1000);
577#else
578        struct timespec ts,rem;
579        int err;
580        ts.tv_sec=seconds;
581        ts.tv_nsec=0;
582        do {
583                err=nanosleep(&ts,&rem);
584                ts=rem;
585        }while(err==-1 && errno==EINTR);
586#endif
587}
588
589#define DEFAULT_MAX_PAYLOAD_SIZE 1440
590
591static int max_payload_size=DEFAULT_MAX_PAYLOAD_SIZE;
592
593int ms_get_payload_max_size(){
594        return max_payload_size;
595}
596
597void ms_set_payload_max_size(int size){
598        if (size<=0) size=DEFAULT_MAX_PAYLOAD_SIZE;
599        max_payload_size=size;
600}
Note: See TracBrowser for help on using the repository browser.