webrtc發(fā)送端-編碼到發(fā)送pipeline

github:https://github.com/bigonelby/webrtcUml/tree/master/latest

webrtc-發(fā)送端-編碼到發(fā)送pipeline.drawio.png
  1. 這張圖介紹了數(shù)據(jù)從編碼器中輸出挖炬,最終流入pacing的過程

  2. 首先看看CorePipeline褪秀,編碼后的幀通過EncodedImageCallback返回启上,那么數(shù)據(jù)從VideoStreamEncoder出發(fā)矿微,將會(huì)如何流到下游呢?VideoStreamEncoderInterface提供了一個(gè)關(guān)鍵的方法:SetSink念搬,給出了下一步數(shù)據(jù)流的重要指示抑堡。持有這個(gè)接口的是VideoSendStreamImpl,其在RegisterProcessThread的時(shí)候朗徊,會(huì)調(diào)用該接口的SetSink方法首妖,為編碼器設(shè)置下游。這個(gè)sink爷恳,即為EncoderSink有缆,這個(gè)EncoderSink本身也是繼承自EncodedImageCallback,因此他也具有接收EncodedImage的能力温亲。而實(shí)現(xiàn)EncoderSink接口的棚壁,是VideoSendStreamImpl。因此編碼器在產(chǎn)生編碼數(shù)據(jù)后铸豁,通過EncoderSink這個(gè)設(shè)置的sink灌曙,就將EncodedImage成功的送到了VideoSendStreamImpl中

  3. 后面的重點(diǎn)操作菊碟,當(dāng)然就是將EncodedImage打包成rtp节芥,然后發(fā)送出去。處理這個(gè)工作的,可不是VideoSendStreamImpl头镊。因此VideoSendStreamImpl會(huì)將數(shù)據(jù)繼續(xù)送給負(fù)責(zé)的模塊蚣驼。誰(shuí)來負(fù)責(zé)這個(gè)事情呢?就是RtpVideoSenderInterface這個(gè)接口相艇,這個(gè)接口本身也是繼承了EncodedImageCallback這個(gè)接口颖杏,因此顯然,他也具備處理EncodedImage的能力坛芽!這個(gè)接口的實(shí)現(xiàn)類為RtpVideoSender留储,這個(gè)類是由RtpTransportControllerSendInterface這個(gè)接口的CreateRtpVideoSender方法創(chuàng)建的。這個(gè)過程前面的圖里有過介紹

  4. 由此數(shù)據(jù)到達(dá)了RtpVideoSender這個(gè)重要的模塊咙轩,RtpVideoSender的處理單元為Stream获讳,因?yàn)閷?duì)于video而言,也許含有多個(gè)stream活喊,simulcast等丐膝。那么負(fù)責(zé)每個(gè)模塊的發(fā)送的,即為RtpVideoSender的助手钾菊,RtpStreamSender帅矗。從名字就可以看出來,這個(gè)類是負(fù)責(zé)stream的發(fā)送的煞烫。RtpStreamSender是一個(gè)組長(zhǎng)浑此,其有兩個(gè)組員,ModuleRtpRtcpImpl2红竭,RtpSenderVideo尤勋。ModuleRtpRtcpImpl2本身掌握很多關(guān)于rtprtcp發(fā)送的重要信息,他的創(chuàng)建依賴于Configuration茵宪;而RtpSenderVideo是真正的發(fā)送視頻數(shù)據(jù)的類

  5. RtpSenderVideo主要做了三件事最冰,通過RtpSender的AllocatePacket方法,創(chuàng)建了RtpPacketToSend對(duì)象稀火;通過RtpPacketizer進(jìn)行打包暖哨,最終填充RtpPacketToSend對(duì)象;然后通過RtpSender的EnqueuePackets方法凰狞,將打包好的RtpPacketToSend對(duì)象送給RtpPacketSender

  6. 接著篇裁,我們看看RtpPacket對(duì)象。首先先看看RTPVideoHeader赡若。這個(gè)對(duì)象是由RtpPayloadParams的GetRtpVideoHeader方法創(chuàng)建的达布。其主要內(nèi)容是從EncodedImage中來。再來看看RtpPacketToSend逾冬,其本身就是RtpPacket黍聂,對(duì)于Rtp包而言躺苦,除了基本頭信息,重要的就是擴(kuò)展頭了产还,即extension匹厘,因此這是Rtp包的一個(gè)重點(diǎn)。這些Extension由ExtensionManager管理脐区,每個(gè)Extension必須提供kId愈诚,kUri,kValueSizeBytes牛隅,以及Write炕柔,ValueSize,Parse方法媒佣。這些Extension本身并沒有共同的基類汗唱,但是由于都遵守這樣的規(guī)則,可以通過模板函數(shù)的方法操作丈攒。每個(gè)Extension的關(guān)鍵信息由ExtensionInfo這個(gè)類來記錄哩罪,包括了id,length和offset巡验。其中offset是相對(duì)于packet的buffer_的偏移量际插。可以通過RtpPacket的ReserverExtension显设,HasExtension框弛,AllocateExtension,等方法操作Extension捕捂。如果需要自定義的Extension瑟枫,也需要按照Extension的固定格式開發(fā)

  7. 我們繼續(xù)看看Packetizer,這個(gè)模塊由RtpSenderVideo模塊在發(fā)送每個(gè)EncodedImage時(shí)創(chuàng)建指攒,通過RtpPacketizer的Create靜態(tài)方法創(chuàng)建慷妙,對(duì)于h264而言,其實(shí)現(xiàn)類為RtpPacketizerH264允悦。打包的過程是這樣的膝擂,通過工具方法FindNaluIndices找到EncodedImage中的所有Nalu單元,即結(jié)構(gòu)體NaluIndex隙弛,這個(gè)結(jié)構(gòu)體里記錄了每個(gè)Nalu單元中的起始偏移架馋,payload偏移,以及payload大小全闷。根據(jù)這些找到的NaluIndex就可以構(gòu)建相對(duì)應(yīng)的ArrayView了叉寂,每個(gè)ArrayView包含了一個(gè)NaluIndex所對(duì)應(yīng)的buffer。RtpPacketizerH264总珠,通過GeneratePackets方法屏鳍,將這些ArrayView進(jìn)一步封裝為PacketUnit伊约,根據(jù)實(shí)際情況,通過PacketizeSingeNalu或PacketizeFuA或PacketizeStapA進(jìn)行打包孕蝉。這個(gè)結(jié)構(gòu)體里記錄了first_fragment,last_fragment腌逢,aggregated降淮,header,以及source_fragment搏讶。每次調(diào)用Packetizer的NextPacket方法時(shí)佳鳖,就會(huì)通過PacketUnit生成對(duì)應(yīng)的RtpPacketToSend對(duì)象

  8. 準(zhǔn)備好了一切,有了RtpPacketToSend這個(gè)發(fā)送對(duì)象媒惕,最后RtpSenderVideo將準(zhǔn)備好的RtpPacketToSend系吩,通過RtpSender的EnqueuePackets入隊(duì)列,準(zhǔn)備發(fā)送妒蔚。RtpSender進(jìn)一步調(diào)用了RtpPacketSender的EnqeuuePackets方法穿挨,這個(gè)RtpPacketSender是一個(gè)接口類,其實(shí)現(xiàn)類為PacedSender肴盏,最終PacedSender將這個(gè)RtpPacket交由PacingController發(fā)送科盛,PacingController將其放入了自己的隊(duì)列packet_queue_中

  9. 至于PacingController后續(xù)如何將RtpPacket發(fā)送出去,下次再繼續(xù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菜皂,一起剝皮案震驚了整個(gè)濱河市贞绵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恍飘,老刑警劉巖榨崩,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異章母,居然都是意外死亡母蛛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門乳怎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溯祸,“玉大人,你說我怎么就攤上這事舞肆〗垢ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵椿胯,是天一觀的道長(zhǎng)筷登。 經(jīng)常有香客問我,道長(zhǎng)哩盲,這世上最難降的妖魔是什么前方? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任狈醉,我火速辦了婚禮,結(jié)果婚禮上惠险,老公的妹妹穿的比我還像新娘苗傅。我一直安慰自己,他們只是感情好班巩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布渣慕。 她就那樣靜靜地躺著,像睡著了一般抱慌。 火紅的嫁衣襯著肌膚如雪逊桦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天抑进,我揣著相機(jī)與錄音强经,去河邊找鬼。 笑死寺渗,一個(gè)胖子當(dāng)著我的面吹牛匿情,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播信殊,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼码秉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鸡号?” 一聲冷哼從身側(cè)響起转砖,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鲸伴,沒想到半個(gè)月后府蔗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汞窗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年姓赤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仲吏。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡不铆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出裹唆,到底是詐尸還是另有隱情誓斥,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布许帐,位于F島的核電站劳坑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏成畦。R本人自食惡果不足惜距芬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一涝开、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧框仔,春花似錦舀武、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捐腿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間柿顶,已是汗流浹背茄袖。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘁锯,地道東北人宪祥。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像家乘,于是被迫代替她去往敵國(guó)和親蝗羊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容