diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | bcb704366cb5e333a626c18c308c7e0448a8e69f (patch) | |
tree | f0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c | |
download | tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c')
-rw-r--r-- | kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c new file mode 100644 index 00000000..cfcafa33 --- /dev/null +++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/ms.c @@ -0,0 +1,342 @@ +/* + The mediastreamer library aims at providing modular media processing and I/O + for linphone, but also for any telephony application. + Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ms.h" +#include "sndcard.h" +#include "mscodec.h" + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef VIDEO_ENABLED +extern void ms_video_source_register_all(); +#endif +#ifdef HAVE_ILBC +extern void ms_ilbc_codec_init(); +#endif + +/** + * ms_init: + * + * + * Initialize the mediastreamer. This must be the first function called in a program + * using the mediastreamer library. + * + * + */ +void ms_init() +{ + if (!g_thread_supported()) g_thread_init (NULL); +#ifdef HAVE_GLIB + if (!g_module_supported()){ + g_error("GModule is not supported."); + } +#endif + /* initialize the oss subsystem */ + snd_card_manager_init(snd_card_manager); + /* register the statically linked codecs */ + ms_codec_register_all(); +#ifdef VIDEO_ENABLED + ms_video_source_register_all(); +#endif +#ifdef HAVE_ILBC + ms_ilbc_codec_init(); +#endif +} + + +static gint compare(gconstpointer a, gconstpointer b) +{ + MSFilter *f1=(MSFilter*)a,*f2=(MSFilter*)b; + if (f1->klass<f2->klass) return -1; + if (f1->klass==f2->klass) return 0; + /* if f1->klass>f2->klass ....*/ + return 1; +} + +static GList *g_list_append_if_new(GList *l,gpointer data) +{ + GList *res=l; + if (g_list_find(res,data)==NULL) + res=g_list_append(res,data); + return(res); +} + +static GList *get_nexts(MSFilter *f,GList *l) +{ + int i; + MSFifo *fifo; + MSQueue *q; + GList *res=l; + + /* check fifos*/ + for (i=0;i <f->klass->max_foutputs;i++) + { + fifo=f->outfifos[i]; + if (fifo!=NULL) res=g_list_append_if_new(res,(gpointer)fifo->next_data); + } + /* check queues*/ + for (i=0;i <f->klass->max_qoutputs;i++) + { + q=f->outqueues[i]; + if (q!=NULL) res=g_list_append_if_new(res,(gpointer)q->next_data); + } + return(res); +} + +/* compile graphs attached to a sync source*/ +int ms_compile(MSSync *sync) +{ + int i; + GList *list1=NULL,*list2=NULL,*elem; + GList *proc_chain=NULL; + MSFilter *f; + + /* first free the old list if we are just updating*/ + if (sync->execution_list!=NULL) g_list_free(sync->execution_list); + /* get the list of filters attached to this sync*/ + for (i=0;i<sync->filters;i++) + { + /* //printf("found filter !\n"); */ + list1=g_list_append(list1,sync->attached_filters[i]); + } + /* find the processing chain */ + while (list1!=NULL) + { + list2=NULL; + /* sort the list by types of filter*/ + list1=g_list_sort(list1,compare); + /* save into the processing chain list*/ + /* //printf("list1 :%i elements\n",g_list_length(list1)); */ + proc_chain=g_list_concat(proc_chain,list1); + /* get all following filters. They are appended to list2*/ + elem=list1; + while (elem!=NULL) + { + f=(MSFilter*)(elem->data); + /* check if filter 's status */ + if (f->klass->attributes & FILTER_CAN_SYNC) + { + sync->samples_per_tick=0; + } + list2=get_nexts(f,list2); + elem=g_list_next(elem); + } + list1=list2; + } + sync->execution_list=proc_chain; + sync->flags&=~MS_SYNC_NEED_UPDATE; + ms_trace("%i filters successfully compiled in a processing chain.",g_list_length(sync->execution_list)); + return 0; +} + +/*execute the processing chain attached to a sync source. It is called as a thread by ms_main()*/ +void *ms_thread_run(void *sync_ptr) +{ + MSSync *sync=(MSSync*) sync_ptr; + GList *filter; + MSFilter *f; + + + ms_sync_lock(sync); + while(sync->run) + { + /* //g_message("sync->run=%i",sync->run); */ + if (sync->samples_per_tick==0) ms_sync_suspend(sync); + if (sync->flags & MS_SYNC_NEED_UPDATE){ + ms_compile(sync); + ms_sync_setup(sync); + } + filter=sync->execution_list; + ms_sync_unlock(sync); + /* //ms_trace("Calling synchronisation"); */ + ms_sync_synchronize(sync); + while(filter!=NULL) + { + f=(MSFilter*)filter->data; + if (MS_FILTER_GET_CLASS(f)->attributes & FILTER_IS_SOURCE) + { + /* execute it once */ + ms_trace("Running source filter %s.",f->klass->name); + ms_filter_process(f); + } + else + { + /* make the filter process its input data until it has no more */ + while ( ms_filter_fifos_have_data(f) || ms_filter_queues_have_data(f) ) + { + ms_trace("Running filter %s.",f->klass->name); + ms_filter_process(f); + } + } + filter=g_list_next(filter); + } + ms_sync_lock(sync); + } + g_cond_signal(sync->stop_cond); /* signal that the sync thread has finished */ + ms_sync_unlock(sync); + g_message("Mediastreamer processing thread is exiting."); + return NULL; +} + +/* stop the processing chain attached to a sync source.*/ +void ms_thread_stop(MSSync *sync) +{ + if (sync->thread!=NULL) + { + if (sync->samples_per_tick==0) + { + /* to wakeup the thread */ + /* //g_cond_signal(sync->thread_cond); */ + } + g_mutex_lock(sync->lock); + sync->run=0; + sync->thread=NULL; + g_cond_wait(sync->stop_cond,sync->lock); + g_mutex_unlock(sync->lock); + } + /* //g_message("ms_thread_stop() finished."); */ +} + +/** + * ms_start: + * @sync: A synchronisation source to be started. + * + * Starts a thread that will shedule all processing chains attached to the synchronisation source @sync. + * + * + */ +void ms_start(MSSync *sync) +{ + if (sync->run==1) return; /*already running*/ + ms_compile(sync); + ms_sync_setup(sync); + /* this is to avoid race conditions, for example: + ms_start(sync); + ms_oss_write_start(ossw); + here tge ossw filter need to be compiled to run ms_oss_write_start() + */ + ms_trace("ms_start: creating new thread."); + sync->run=1; + sync->thread=g_thread_create((GThreadFunc)ms_thread_run,(gpointer)sync,TRUE,NULL); + if (sync->thread==NULL){ + g_warning("Could not create thread !"); + } +} + +/** + * ms_stop: + * @sync: A synchronisation source to be stopped. + * + * Stop the thread that was sheduling the processing chains attached to the synchronisation source @sync. + * The processing chains are kept unchanged, no object is freed. The synchronisation source can be restarted using ms_start(). + * + * + */ +void ms_stop(MSSync *sync) +{ + ms_thread_stop(sync); + ms_sync_unsetup(sync); +} + + +gint ms_load_plugin(gchar *path) +{ +#ifdef HAVE_GLIB + g_module_open(path,0); +#endif + return 0; +} + +gchar * ms_proc_get_param(gchar *parameter) +{ + gchar *file; + int fd; + int err,len; + gchar *p,*begin,*end; + gchar *ret; + fd=open("/proc/cpuinfo",O_RDONLY); + if (fd<0){ + g_warning("Could not open /proc/cpuinfo."); + return NULL; + } + file=g_malloc(1024); + err=read(fd,file,1024); + file[err-1]='\0'; + /* find the parameter */ + p=strstr(file,parameter); + if (p==NULL){ + /* parameter not found */ + g_free(file); + return NULL; + } + /* find the following ':' */ + p=strchr(p,':'); + if (p==NULL){ + g_free(file); + return NULL; + } + /* find the value*/ + begin=p+2; + end=strchr(begin,'\n'); + if (end==NULL) end=strchr(begin,'\0'); + len=end-begin+1; + ret=g_malloc(len+1); + snprintf(ret,len,"%s",begin); + /* //printf("%s=%s\n",parameter,ret); */ + g_free(file); + return ret; +} + +gint ms_proc_get_type() +{ + static int proc_type=0; + gchar *value; + if (proc_type==0){ + value=ms_proc_get_param("cpu family"); + if (value!=NULL) { + proc_type=atoi(value); + g_free(value); + }else return -1; + } + return proc_type; +} + +gint ms_proc_get_speed() +{ + char *value; + static int proc_speed=0; + if (proc_speed==0){ + value=ms_proc_get_param("cpu MHz"); + if (value!=NULL){ + proc_speed=atoi(value); + g_free(value); + }else return -1; + } + /* //printf("proc_speed=%i\n",proc_speed); */ + return proc_speed; +} |