Linphone的编译与代码分析
- 格式:pdf
- 大小:299.71 KB
- 文档页数:10
Linphone的编译与代码分析2008-12-14updatedb@gmail.com目录1LINPHONE的编译31.1LINPHONE在ARM上的编译环境说明31.2LINPHONE依赖的库31.3LINPHONE编译脚本31.4编译过程中的问题4
2LINPHONE代码分析42.1LINPHONE的初始化分析42.1.1LINPHONEC的初始化52.1.2LINPHONE_CORE的初始化52.1.3ORTP的初始化52.1.4MEDIASTREAM2的初始化62.1.5EXOSIP的初始化62.2LINPHONE的通话过程分析62.2.1LINPHONE的命令处理分析72.2.2LINPHONE的呼叫过程分析72.2.3LINPHONE的通话过程分析82.2.4LINPHONE的响应过程分析82.3LINPHONE中创建以及应用自定义过滤器92.3.1过滤器的基本功能92.3.2过滤器的通用接口102.3.3自定义过滤器10Linphone的编译与代码分析1Linphone的编译1.1Linphone在arm上的编译环境说明Linphone在arm上编译的时候,时常会碰到一些问题,有时候想办法解决了相关的问题,但编译出来的Linphone在板子上的运行仍然不稳定,或者不能通话。如果条件允许的话,当碰到这些问题之后,可以换其它的工具链进行编译。我最初编译Linphone的时候采用的是xscale270板子自带的工具链,GCC3.4.3以及uclibc。经过很痛苦的一番折腾之后,所以的代码最终都编译通过,但是编译出来的linphonec在板子上运行在通话开始之后总是崩溃。通过GDB调试,发现是多线程的问题引起的,于是编译了一个线程结构相当的程序,但是测试没有发现问题。最后,我改用GCC4.0.0以及Glibc-2.3.5基本上没有碰到什么问题,直接编译通过,并且在板子上正常运行。
1.2Linphone依赖的库除了上面所提到的Gcc,Glibc以及系统的基本库外我主要编译了下面的程序包。序号库名称说明1ReadLine一个终端显示库,Linphone会用到它时里面的事件循环机制来读取会话事件。
2ffmpeg音视频编解码库3Speex专为通话过程设计的音频编码库4libtheora视频压缩编码库
5libfaacmpeg4的音频编码器6libfaad2AAC音频解码器7SDL简单的视频支持层
8libosip2SIP的简单实现
9libeXosip2对libosip2的调用进行封装,隐藏了多媒体会话建立过程中SIP的细节10linphone-3.0linphone的主程序,包括mediastream,oRtp,coreapi以及console四个部分
1.3Linphone编译脚本见附件。1.4编译过程中的问题1、ffmpeg的编译问题在编译ffmpeg的时候会发现有不少编解码码器不能编译能过,在configure的时候禁用的就行了。2、linphone的编译linphone的编译过程中可能会出现mediastream2下面的test不能编译能过的问题,在mediastream2下面找到Makefile文件,找到SUBDIRS将tests删掉即可。linphone下面的所有的库编译完成之后,linphonec的编译可能不能能过,原因是几个库不能找到,这时候其它那几个库用不着,重新修改Makefile即可(详见附件)。
2Linphone代码分析
Linphone代码的分析主要分为三个部分。在整个分析过程主要是对音频通话相关的内容进行分析,视频的流程类似,但有细节有很大的区别,请自行分析。如果在看代码的过程中碰到一些问题不能理解,推荐先看看SIP/RTP/RTCP等协议的基本内容,或者通过抓数据包对整个会话过程进行分析。
2.1Linphone的初始化分析首先主要的流程在流程图里面都有表现,图是边看代码,边画出来的,不是很好。下面的分析主要是对图中的内容进行讲述。先对图里面的标识解释一下:实心箭头表示流程走向;空心箭头表示调用关系;指向出发点箭头表示循环调用;黄色的框表示代相对独立的码块,红色表示关键函数,绿色表示成功;虚线指向表示有相关性,但并非调用关系;虚线框表示主要数据结构。对Linphone的整个初始化过程进行分析可以分为下面的个部分。2.1.1linphonec的初始化在linphonec的初始化过程中,一共做了两件事。首先初始化linphone_core,如果成功,则进入linphonec的主循环,等待用户输入,如果有用户输入就会调用相应的命令处理函数。处理函数被注册在静态的数组LPC_COMMANDcommands中。如果你想增加linphone处理其它的命令,最好在这儿添加。
2.1.2linphone_core的初始化Linphone_core的初始化概括的讲的就产生一个唯一的linphone实例,该实例包括了显示,配置,数据流等内容。在配置linphone_core的实例的过程中,linphone会读取并分析配置文件,并调用相关的初始化函数。Linphone_core初始化完成之后,会调用linphonec_initalize_readline,该函数将linphonec_idel_call注册到readline的事件循环中,并且每隔1秒调用一次,检查是否有等待处理的osip事件(比如有人发送INVITE消息)。
2.1.3Ortp的初始化Ortp的初始化除了对数据结构的初始化外,主要的工作就是加载相关的PayloadType.2.1.4mediastream2的初始化主要是对filter以及声卡,网卡的初始化。详细解释见函数调用图,以及函数解释。2.1.5eXosip的初始化eXosip的核心是初始化osip,打开相关的网络接口,进入监听状态。下面列出流程中主要的函数调用的用途:1LinphonecoreVtable用于初始化屏幕相关,以及输出相关
2ortp_init初始华ortp,并加载默认的PayloadType(在avprofile.c定义)。如果要定义新的过滤
器,在这儿也要注册相应的PayloadType,当然,自定义的PayloadType可以只在需要的时候再即用。3ms_initmediastreamer2的初始化,首先注册所有的filter,这些filter在alldescs.h中被表态保存在ms_filter_desc数组中。注册新的过滤器时,过滤器的描述结构应该被注册到该数组中。同时也注册了声卡与摄像头,并且初始化每个设备,放到全局静态变量MSSndCardManager和MSWebCamManager中。4lp_config_new读取并分析配置文件
5XXX_config读取配置文件中XXX相关的配置到linphone_core中,包括读取网络配置,RTP配
置,解码器配置以及sip/view/ui的配置。6linphone_core_set_sip_port用于打开sip端口,等待并接收sip信息。
7exosip_init这个函数在libeXosip中,而不是在linphone中。用于寢化eXosip变量,在初始化时eXosip和osip互相指向,用于后面的访问。eXosip_call_t和void*j_thread没有被初始化。接着对四种extl_protocol进行初始化,为osip数据包传输做好准备。8osip_init这个函数初始化了osip_t数据结构,被启动了四个用于osip数据处理的状态机。
每个新状态机都是一个transition列表,每一个transition时面包括state,type,处理函数method.四个状机代表四个不同的会话事务。每个会话事务,根据状态机不同的状态,调用相应事务中eXosip_set_callbacks中注册的处理函数,并改变事务状态。9eXosip_set_callbacks调用osip_set_cb_send_message和osip_set_XXX_callback为osip注册处理各种状态数据包的回调函数。初始化了osip中msg_callbacks,kill_callbacks,tp_error_callbacks,cb_send_message几个最重要的数据。cb_send_message这个函数最终会根据协议的不同,调用不同的eXtl_protocol对像发送数据。10eXosip_listen_addr打开一个监听端口,用于接收连接,并启动一个线程专门牏sip数据包。根据不同的数据传输类型打开不同的数据接收端口。11osip_thread_create创建一个线程,循环执行osip_execute直至接收到退出或者异常信息。12osip_execute这个函数会读取eXtl_XXX打开的socket,然后遍历所有的状态机,看是否有事件
需要处理。13eXosip_read_message如果可以读取数据,那么将得到的数据交给数据处理函数,数据处理函数对数据进
行格式化,构造成为osip数据结构及以osip_event,然后再通过osip_evnet_t的类型查找是那个transaction及对应的状态机。并且将事件加到transation所对应的osip_fifo_t*transactionff中。14osip_timers_XiXt_execute依次检查四个状态机的所有transaction,判断是否需要注册一个TIMEOUT_I/
TIMEOUT_H/TIMEOUT_G事件,如果需要则注册相应的事件。15osip_XiXst_execute依次检查四个状态机的所有的transaction,看是否有需要执行的事件,如果有事件要执行,则在状态机中调用相应的在set_callbacks中注册的函数。
2.2Linphone的通话过程分析在分析Linphone的通话过程之前,我们首先分析看看当前的状态:linphonec_main_loop在等待用户输入。从而用户可以在自己的控制端进行操作,比如发起呼叫。eXosip_listen_addr在监听端口,等远程连接。如果有数据,即可以接收,并解析数据,