mod_conference模塊源碼分析

一、分析一個(gè)模塊的源碼步驟

  • 1、首先應(yīng)該看SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load);也就是要從mod_conference_load函數(shù)中,看到這個(gè)模塊中寫了哪些可供外部調(diào)用的api或app。
    SWITCH_ADD_API(api_interface, "conference", "Conference module commands", conf_api_main, p);
    SWITCH_ADD_APP(app_interface, global_app_name, global_app_name, NULL, conference_function, NULL, SAF_NONE);
    SWITCH_ADD_APP(app_interface, "conference_set_auto_outcall", "conference_set_auto_outcall", NULL, conference_auto_function, NULL, SAF_NONE);
    SWITCH_ADD_CHAT(chat_interface, CONF_CHAT_PROTO, chat_send);
  • 2、再找到要詳細(xì)分析的api或app的函數(shù),根據(jù)調(diào)用參數(shù)和返回結(jié)果情況去尋找匹配的源碼。
  • 3、模塊中其他的函數(shù)基本上都是供api或app函數(shù)調(diào)用的,因此可以在看到被調(diào)用后再去詳細(xì)分析。

二、詳細(xì)分析conference api

  • SWITCH_STANDARD_API(conf_api_main);即為該api函數(shù)。
  • 每個(gè)api實(shí)際傳入的參數(shù)是輸入?yún)?shù)cmd,作用的會(huì)話session,輸出流stream。
  • 先將傳入的參數(shù)cmd通過strdup函數(shù)復(fù)制到lbuf字符串保存好,然后將該字符串用空格分割后存入字符串?dāng)?shù)組argv,并得到字符串統(tǒng)計(jì)數(shù)argc。
  • conference后接的第一個(gè)參數(shù)是argv[0],接下來就是根據(jù)這第一個(gè)參數(shù)去進(jìn)行字符串匹配,然后執(zhí)行相應(yīng)的動(dòng)作。
  • 若是argv[0]是一個(gè)會(huì)議室號(hào)碼,則表示要對(duì)特殊的會(huì)議室進(jìn)行操作;否則就是對(duì)所有的會(huì)議進(jìn)行操作或者普通的api命令使用。
  • conference_find函數(shù),傳入會(huì)議室name號(hào)碼,返回該會(huì)議室結(jié)構(gòu)體對(duì)象conference_obj_t,以便后續(xù)操作。
  • 找到對(duì)應(yīng)的會(huì)議室結(jié)構(gòu)體對(duì)象后,轉(zhuǎn)到實(shí)際的執(zhí)行api命令的函數(shù)conf_api_dispatch。該函數(shù)中,利用api_command_t conf_api_sub_commands[]這樣一個(gè)命令參數(shù)匹配結(jié)構(gòu)體數(shù)組,找到匹配的子命令以及回調(diào)函數(shù)。
  • 比如vid-floor子命令的結(jié)構(gòu)體數(shù)據(jù)為{"vid-floor", (void_fn_t) & conf_api_sub_vid_floor, CONF_API_SUB_MEMBER_TARGET, "vid-floor", "<member_id|last> [force]"}。要想了解這個(gè)子命令的詳細(xì)執(zhí)行過程,可以轉(zhuǎn)到回調(diào)函數(shù)conf_api_sub_vid_floor。force可強(qiáng)制設(shè)定某個(gè)成員一直獲取vid_floor,即一直顯示該成員的畫面。
  • conference_set_floor_holder函數(shù)將某成員設(shè)為臨時(shí)擁有vid_floor,然后還是自動(dòng)根據(jù)聲音大小切換。
  • conference_set_video_floor_holder函數(shù)強(qiáng)制使某成員一直擁有vid_floor。conference的一個(gè)狀態(tài)值CFLAG_VID_FLOOR_LOCK標(biāo)記該vid_floor擁有者鎖住不可自動(dòng)變。
  • 以上都是通過成員對(duì)象即member結(jié)構(gòu)體對(duì)象來操作,而成員對(duì)象是對(duì)應(yīng)于一個(gè)會(huì)議的加入順序設(shè)定的鏈表中的id值,通過該member對(duì)象獲取channel號(hào)碼的方式是使用函數(shù)switch_channel_get_name(member->channel);此外還可以通過member->session獲取到該會(huì)話。
  • member_update_status_field(member)函數(shù)將對(duì)應(yīng)member對(duì)象的狀態(tài)改為TALKING和VIDEO (FLOOR),即有權(quán)講話和展示視頻的狀態(tài)。
  • switch_core_session_refresh_video(member->session);函數(shù)更新該session的msg狀態(tài)SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ,然后調(diào)用switch_core_session_receive_message(session, &msg)更新會(huì)話接收消息的策略。(后面跟蹤不到對(duì)應(yīng)狀態(tài)會(huì)干什么了。。。)
  • conference_loop_fn_vid_floor_toggle函數(shù)切換(toggle)vid_floor,放在一個(gè)結(jié)構(gòu)體數(shù)組中struct _mapping control_mappings[19]

三、發(fā)起一個(gè)會(huì)議的流程

conference_app中通過參數(shù)或其他方式傳入一個(gè)會(huì)議室號(hào)碼,然后先檢查該會(huì)議室是否存在并返回一個(gè)會(huì)議室對(duì)象conference=conference_find(conf_name, NULL);,如果不存在的話則創(chuàng)建一個(gè)conference = conference_new(conf_name, xml_cfg, session, NULL);
1)然后為這個(gè)會(huì)議室開啟一個(gè)線程運(yùn)行launch_conference_thread(conference);。該線程調(diào)用一個(gè)執(zhí)行函數(shù)conference_thread_run,內(nèi)部有一個(gè)while循環(huán)去處理會(huì)議成員之間的通信數(shù)據(jù)包。
2)視頻會(huì)議會(huì)創(chuàng)建一個(gè)特別的視頻線程launch_conference_video_thread(conference_obj_t *conference);,然后調(diào)用執(zhí)行函數(shù)conference_video_thread_run,并修改會(huì)議對(duì)象視頻狀態(tài)conference->video_running = 1;。該函數(shù)內(nèi)部有一個(gè)while循環(huán),會(huì)一直通過switch_core_session_read_video_frame(session, &vid_frame, SWITCH_IO_FLAG_NONE, 0);函數(shù)讀取每個(gè)vid_floor_hold成員的視頻幀vid_frame,根據(jù)一個(gè)for循環(huán)遍歷所有的成員并通過switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0);函數(shù)將該vid_frame轉(zhuǎn)發(fā)給所有成員。
3)兩個(gè)會(huì)議成員之間的視頻轉(zhuǎn)發(fā)流程

  • launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b)函數(shù)傳入兩個(gè)會(huì)議成員對(duì)象,函數(shù)內(nèi)調(diào)用兩個(gè)線程,分別執(zhí)行a到b的視頻幀轉(zhuǎn)發(fā)launch_thread_detached(conference_video_bridge_thread_run, pool, &conference->vh[0]);,和b到a的視頻幀轉(zhuǎn)發(fā)launch_thread_detached(conference_video_bridge_thread_run, pool, &conference->vh[1]);。然后都轉(zhuǎn)到線程調(diào)用的函數(shù)conference_video_bridge_thread_run,該函數(shù)內(nèi)有個(gè)while循環(huán)并通過函數(shù)switch_core_session_read_video_frameswitch_core_session_write_video_frame來進(jìn)行視頻幀的轉(zhuǎn)發(fā)。

四、1.6版本通過relate api設(shè)置成員之間的聯(lián)系,使一個(gè)成員可以綁定看另一個(gè)成員的視頻

  • conference 3000 relate 1 2 sendvideo即將成員1視頻發(fā)給成員2,不管成員1是否已獲得vid_floor
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 全目錄為愛而生I生于夏天 上一回影院情迷 漪汾夜歌 出了電影院,天已經(jīng)黑了,閆松訕笑著問道“你想吃什么?我來請(qǐng)?!?..
    瘋巖瘋語sun閱讀 495評(píng)論 0 4
  • 快八點(diǎn)才起,沒吃飯沒換衣服洗澡,八點(diǎn)半跑完1km。
    arthur503閱讀 112評(píng)論 0 0
  • 在確定工作單位之后,我就對(duì)自己承諾每周都要寫一篇實(shí)習(xí)總結(jié),不是流水賬而是經(jīng)過深思的。所以你不用擔(dān)心我的實(shí)習(xí)總結(jié)就是...
    謝小迪閱讀 1,061評(píng)論 2 13
  • 被朋友圈的刷屏占據(jù)了生活主力的我們,每天都會(huì)收到各式各樣的“佳作美文”,其中不乏各種標(biāo)題黨和一鍋又一鍋的雞湯,不...
    尚武三寶閱讀 4,474評(píng)論 22 46
  • 上了大學(xué)才發(fā)現(xiàn)讀書真的非常重要,更多的是帶來精神上的財(cái)富。 今天剛把《如何有效閱讀一本書》讀完,就先寫一篇初步的讀...
    誰用了噫吁嚱閱讀 194評(píng)論 0 0

友情鏈接更多精彩內(nèi)容