linPhone 源碼分析

http://www.360doc.com/content/13/1125/17/2306903_332089963.shtml




這幾天比較輕鬆,所以打算好好來看看linphone的代碼,源碼版本爲3.5.2。從linphone初始化的過程開始,首先來看linphone_core_new函數。 

Cpp代碼  收藏代碼
  1. LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,  
  2.                         const char *config_path, const char *factory_config_path, void * userdata)  
  3. {  
  4.     LinphoneCore *core=ms_new(LinphoneCore,1);  
  5.     linphone_core_init(core,vtable,config_path, factory_config_path, userdata);  
  6.     return core;  
  7. }  

主要工作基本上在函數linphone_core_init中實現
Plain代碼  收藏代碼
  1. static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path,  
  2.     const char *factory_config_path, void * userdata)  
  3. {  
  4.     memset (lc, 0, sizeof (LinphoneCore));  
  5.     lc->data=userdata;  
  6.     lc->ringstream_autorelease=TRUE;  
  7.   
  8.   
  9.     memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable));  //保存了回調函數表  
  10.   
  11.   
  12.     linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");  //設置linphone內部狀態  
  13.     ortp_init();  //ortp模塊初始化  
  14.     lc->dyn_pt=96;  //負載類型從96開始都是動態負載類型  
  15.     linphone_core_assign_payload_type(lc,&payload_type_pcmu8000,0,NULL);  
  16.     linphone_core_assign_payload_type(lc,&payload_type_gsm,3,NULL);  
  17.     linphone_core_assign_payload_type(lc,&payload_type_pcma8000,8,NULL);  
  18.     linphone_core_assign_payload_type(lc,&payload_type_speex_nb,110,"vbr=on");  
  19.     linphone_core_assign_payload_type(lc,&payload_type_speex_wb,111,"vbr=on");  
  20.     linphone_core_assign_payload_type(lc,&payload_type_speex_uwb,112,"vbr=on");  
  21.     linphone_core_assign_payload_type(lc,&payload_type_telephone_event,101,"0-11");  
  22.     linphone_core_assign_payload_type(lc,&payload_type_g722,9,NULL);  
  23.   
  24.   
  25. #if defined(ANDROID) || defined (__IPHONE_OS_VERSION_MIN_REQUIRED)  
  26.     /*shorten the DNS lookup time and send more retransmissions on mobiles:  
  27.      - to workaround potential packet losses  
  28.      - to avoid hanging for 30 seconds when the network doesn't work despite the phone thinks it does.  
  29.      */  
  30.     _linphone_core_configure_resolver();  
  31. #endif  
  32.   
  33.   
  34. #ifdef ENABLE_NONSTANDARD_GSM  
  35.     {  
  36.         PayloadType *pt;  
  37.         pt=payload_type_clone(&payload_type_gsm);  
  38.         pt->clock_rate=11025;  
  39.         linphone_core_assign_payload_type(lc,pt,-1,NULL);  
  40.         pt->clock_rate=22050;  
  41.         linphone_core_assign_payload_type(lc,pt,-1,NULL);  
  42.         payload_type_destroy(pt);  
  43.     }  
  44. #endif  
  45.   
  46.   
  47. #ifdef VIDEO_ENABLED  
  48.     linphone_core_assign_payload_type(lc,&payload_type_h263,34,NULL);  
  49.     linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL);  
  50.     linphone_core_assign_payload_type(lc,&payload_type_h263_1998,98,"CIF=1;QCIF=1");  
  51.     linphone_core_assign_payload_type(lc,&payload_type_mp4v,99,"profile-level-id=3");  
  52.     linphone_core_assign_payload_type(lc,&payload_type_h264,102,"profile-level-id=428014");  
  53.     linphone_core_assign_payload_type(lc,&payload_type_vp8,103,NULL);  
  54.     linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL);  
  55.     /* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */  
  56.     /* linphone_core_assign_payload_type(&payload_type_h264,-1,"packetization-mode=1;profile-level-id=428014");*/  
  57. #endif  
  58.   
  59.   
  60.     //下面的這些負載類型,沒有指定類型號  
  61.     /*add all payload type for which we don't care about the number */  
  62.     linphone_core_assign_payload_type(lc,&payload_type_ilbc,-1,"mode=30");  
  63.     linphone_core_assign_payload_type(lc,&payload_type_amr,-1,"octet-align=1");  
  64.         linphone_core_assign_payload_type(lc,&payload_type_amrwb,-1,"octet-align=1");  
  65.     linphone_core_assign_payload_type(lc,&payload_type_lpc1015,-1,NULL);  
  66.     linphone_core_assign_payload_type(lc,&payload_type_g726_16,-1,NULL);  
  67.     linphone_core_assign_payload_type(lc,&payload_type_g726_24,-1,NULL);  
  68.     linphone_core_assign_payload_type(lc,&payload_type_g726_32,-1,NULL);  
  69.     linphone_core_assign_payload_type(lc,&payload_type_g726_40,-1,NULL);  
  70.     linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_16,-1,NULL);  
  71.     linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_24,-1,NULL);  
  72.     linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_32,-1,NULL);  
  73.     linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_40,-1,NULL);  
  74.     linphone_core_assign_payload_type(lc,&payload_type_silk_nb,-1,NULL);  
  75.     linphone_core_assign_payload_type(lc,&payload_type_silk_mb,-1,NULL);  
  76.     linphone_core_assign_payload_type(lc,&payload_type_silk_wb,-1,NULL);  
  77.     linphone_core_assign_payload_type(lc,&payload_type_silk_swb,-1,NULL);  
  78.     linphone_core_assign_payload_type(lc,&payload_type_g729,18,"annexb=no");  
  79.       
  80.     ms_init();  //初始化mediastreamer模塊  
  81.     /* create a mediastreamer2 event queue and set it as global */  
  82.     /* This allows to run event's callback in linphone_core_iterate() */  
  83.     lc->msevq=ms_event_queue_new();  //事件隊列,linphone_core_iterate函數中取出事件並調用相應的回調函數  
  84.     ms_set_global_event_queue(lc->msevq);  //隊列指針保存到一個全局的變量ms_global_event_queue裏  
  85.   
  86.   
  87.     lc->config=lp_config_new(config_path);  //讀取配置文件,config保存的是一個ini文檔,類似xml文檔    
  88.     if (factory_config_path)  //出廠配置文件是隻讀的,用於恢復出廠配置  
  89.         lp_config_read_file(lc->config,factory_config_path);  
  90.   
  91.   
  92.     lc->sal=sal_init();  //初始化exosip模塊,sal是什麼的縮寫呢?  
  93.     sal_set_user_pointer(lc->sal,lc);  
  94.     sal_set_callbacks(lc->sal,&linphone_sal_callbacks);  //設置sal回調函數  
  95.   
  96.   
  97.     sip_setup_register_all();  //這裏將加載所有插件  
  98.     sound_config_read(lc);  //讀取音頻相關配置  
  99.     net_config_read(lc);  //讀取網絡相關配置  
  100.     rtp_config_read(lc);  //讀取rtp相關配置  
  101.     codecs_config_read(lc);  //讀取編碼器相關配置  
  102.     sip_config_read(lc);   //讀取sip協議相關配置,/* this will start eXosip*/  
  103.     video_config_read(lc); //視頻相關配置  
  104.     //autoreplier_config_init(&lc->autoreplier_conf);  
  105.     lc->presence_mode=LinphoneStatusOnline;  //在線、離線,還是其它  
  106.     misc_config_read(lc);  //配置最大歷史記錄條數等  
  107.     ui_config_read(lc);  //讀取聯繫人(朋友),讀取通話記錄  
  108. #ifdef TUNNEL_ENABLED  
  109.     lc->tunnel=linphone_core_tunnel_new(lc);  
  110.     if (lc->tunnel) linphone_tunnel_configure(lc->tunnel);  
  111. #endif  
  112.     if (lc->vtable.display_status)  
  113.         lc->vtable.display_status(lc,_("Ready"));  //更新狀態  
  114.     lc->auto_net_state_mon=lc->sip_conf.auto_net_state_mon;  
  115.     linphone_core_set_state(lc,LinphoneGlobalOn,"Ready");  //這裏將會調用狀態改變的回調函數  
  116. }  
上面的代碼做了大量的工作,分配負載類型,初始化了各子模塊,如ortp、sal(對exosip的封裝吧)、mediastream2,加載了所有的插件,最後讀取配置文件。

再來看看分配負載類型的函數linphone_core_assign_payload_type的實現
Plain代碼  收藏代碼
  1. static void linphone_core_assign_payload_type(LinphoneCore *lc, PayloadType *const_pt, int number, const char *recv_fmtp){  
  2.     PayloadType *pt;  
  3.     pt=payload_type_clone(const_pt);  
  4.   
  5.   
  6.     //找一個未分配的負載類型碼,分配給本負載類型  
  7.     if (number==-1){  
  8.         /*look for a free number */  
  9.         MSList *elem;  
  10.         int i;  
  11.         for(i=lc->dyn_pt;i<=127;++i){  
  12.             bool_t already_assigned=FALSE;  
  13.             for(elem=lc->payload_types;elem!=NULL;elem=elem->next){  
  14.                 PayloadType *it=(PayloadType*)elem->data;  
  15.                 if (payload_type_get_number(it)==i){  
  16.                     already_assigned=TRUE;  
  17.                     break;  
  18.                 }  
  19.             }  
  20.             if (!already_assigned){  
  21.                 number=i;  
  22.                 lc->dyn_pt=i+1;  
  23.                 break;  
  24.             }  
  25.         }  
  26.         if (number==-1){  
  27.             ms_fatal("FIXME: too many codecs, no more free numbers.");  
  28.         }  
  29.     }  
  30.     ms_message("assigning %s/%i payload type number %i",pt->mime_type,pt->clock_rate,number);  
  31.     payload_type_set_number(pt,number);  
  32.     if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp);  
  33.     rtp_profile_set_payload(&av_profile,number,pt);  //將負載類型的對應關係保存到全局的RtpProfile結構中  
  34.     lc->payload_types=ms_list_append(lc->payload_types,pt);  //將支持的負載類型添加到鏈表中  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章