主頁 >  其他 > 流媒體傳輸協議之 RTP (上篇)

流媒體傳輸協議之 RTP (上篇)

2021-02-10 07:10:22 其他

本系列文章將整理各個流媒體傳輸協議,包括 RTP/RTCP,RTMP,希望通過深入梳理協議的設計細節,能夠給流媒體領域的開發者帶來一定的啟發,

作者:逸殊
審核:泰一

介紹

RTP,即 real-time transport protocol(實時傳輸協議),為實時傳輸互動的音頻和視頻提供了端到端傳輸服務,其中包括載荷的型別確認,序列編碼,時間戳和傳輸監控功能,一般應用都是基于 UDP 協議,來使用 RTP 的多路技術以及驗和服務,然而,RTP 還可以與其它適合的協議并用,如果底層網路支持多路分發,RTP 還可以將資料傳輸給多個目標,

需要注意的是 RTP 不提供任何機制以保證資料的實時性和 QOS (quality-of-service),而是依賴底層的服務來提供這些功能,RTP 既不保證傳輸的可靠性也不保證無序傳輸,同時也不假定底層網路是可信任的和有序的,接收端可以利用 RTP 中的序列號排序收到的報文,

RTP 與 RTCP

  • 實時傳輸協議 (RTP),傳輸具有實時特性的資料

  • RTP 控制協議 (RTCP),監控 QOS 和傳遞會話中參與者的資訊,它沒有明確的成員控制功能和 Session 建立程序,但這些對一個相對寬松的 Session 控制來說已經足夠了,它沒有必要包含一個應用的所有控制功能,

RTP 代表了一種新型協議,它遵循 Application level framing 和 Integrated layer processing,即 RTP 可以比較容易的拓展以傳遞某些特定需要的內容,而且可以比較容易地集成進某個應用,而不是作為一個獨立的補充層,RTP 協議被故意地設計成不完整的協議框架,

RTP 的使用場景

下面的例子描述了 RTP 的部分特性,選擇的例子是用來闡明基于 RTP 的應用的基本操作,而不是說 RTP 僅能用于此類應用,

簡單的多播音頻會議

一個小組要通過網路開一個音頻會議,他們用了 IP 多播服務,基于某種分配機制,小組得到了一個多播組地址和一對埠,其中一個埠是用來傳輸音頻資料的,另一個是用來傳輸 RTCP 報文的,這個組播地址和埠發給了所有與會者,如果想要引入一些安全策略,可以對資料報文和控制報文加密,然后把加密時用到的密鑰分發給與會者,

這個音頻會議軟體,可能會一直發送時長為 20ms 的音頻資料包,每個實際音頻資料包,都以 RTP 頭資料開始,然后再以 UDP 協議封裝并發送,RTP 包的頭部標識了該包的資料型別,以便訊息發送器來改變資料的編碼,例如,針對低帶寬的與會者進行一些調節,或者對網路擁堵作出反應,

像 UDP 這類包型別的網路,偶爾會丟包,亂序,延遲不定長時間,為了解決這類意外情況,RTP 包中包含了時間資訊和序列號,這樣接收者就可以通過它們重排資料包的時序,在這個例子中,我們就可以按順序地播放每個 20ms 的音頻資料,在會議中對每個資料源的 RTP 報文時序重排都是獨立進行的,接收者也可以通過序列號來確定丟失了多少報文,

因為這個小組開會期間,會有一些人加入或退出這個網路會議,所以我們需要知道具體是誰加入了會議,以及他們有沒有正常地接收到音頻資料,出于這個目的,每個網路會議的客戶端都會周期性的通過 RTCP 埠報告使用者的名字以及自己接收資料的情況,如果有人接收資料不正常,可能就需要對應的改變編碼,而且,除了用戶的名字之外,還會有一些別的資訊,用來控制帶寬限制,當有人從視頻會議中退出時,還需要發送一個 RTCP BYE 報文,

音頻和視頻會議

如果這個會議既要傳輸音頻又要傳輸視頻的話,它們會以獨立的 RTP Session 傳輸,也就是說,負責音頻傳輸的部分和負責視頻傳輸的部分會通過不同的組播地址(和埠對)分別傳輸各自的 RTP 報文和 RTCP 報文,在 RTP 協議這一層,音頻和視頻 Session 并沒有被組合到一起,我們期望與會者用同一個名字來建立音頻和視頻 Session,這樣這兩個 Session 就能聯系起來了,

RTP 協議之所以這樣設計,一個原因是某些與會者可以選擇只接收某一種型別的資料(只接收 Audio),即便 Audio 資料和 Video 資料是獨立分發的,但是我們仍然可以通過參考 RTCP 協議中時間資訊來同步播放它們,

Mixers & Translators

到目前為止,我們都是假設所有的與會者想要接收同一格式的媒體資料,但是這顯然不太合適,考慮一下,可能某些與會者網速相對較慢,而其他人網速卻比較快,對于這種情況,我們不應該強迫所有人都用低帶寬并降低音頻編碼的質量,而是使用 RTP 級別的中繼節點(Mixer)來給周圍低帶寬用戶分發低帶寬消耗的資料,

這個 Mixer 將接收到的不同與會者的音頻資料同步,并將它們耦合到一個單一流中,然后將這個流用低帶寬消耗的編碼方案進行壓縮,最后發送給那些低帶寬的與會者,Mixer 可以在 RTP 頭部寫一些特殊內容,來表明該 Mixer 包具體耦合了哪些與會者,這樣,接收到該 Mixer 包的人就能確定當前說話的人是誰了,

此外,有些與會者可能處于應用級防火墻的后面,無法僅通過 IP 組播訪問,這種情況下 Mixer 就沒有什么意義了,他們需要另一類 RTP 級別的中繼(Translator),我們需要兩個 Translator,安裝在防火墻的兩面,外面的 Translator 將收到的所有組播報文,通過一個安全連接傳輸給防火墻里面的 Translator,然后,防火墻里的 Translator 再將這些報文分發給內網的與會者,

層編碼

多媒體應用可以根據接收者的能力或者網路擁堵的情況調整傳輸速率,許多實作將碼率控制的責任放在了發送端,這和組播模式不太兼容,因為各個不同的資料接收者會有不同的帶寬情況,這就會產生木桶效應,即帶寬最差的接收者會拖垮整個會議的通訊質量,

因此,帶寬自適應的作業應該放到接收者這里,發送者需要拆分出面向不同帶寬與會者的媒體流(500K,2M,5M),它們分別對應了不同的組播地址,資料的接收者根據自己的帶寬情況,選擇加入適合的組播,

定義

  • RTP payload:RTP 包中傳輸的資料,比如音頻采樣資料或者壓縮過的視頻資料,
  • RTP packet:由定長 RTP 頭部,資料來源者的串列,RTP payload 組成的資料包,一些下層協議可能會自己定義 RTP 的封裝格式,一般來說,一個下層協議包只包含一個 RTP 包,但是也有可能多個 RTP 包被合并到一起,
  • RTCP packet:RTP 控制報文,由定長的 RTC 頭部開始,之后會跟著一些結構化的元素,它們在 RTCP 發揮不同功能時,會有不同的結構,通常多個 RTCP 包會被合在一起,通過一個下層協議包一起發送,
  • Port:傳輸層協議中用來區分某一主機下不同應用的抽象,RTP 協議依賴更底層網路提供埠機制,繼而提供多播的 RTP 和 RTCP 報文,
  • Transport address:網路地址和埠的組合,用來定位傳輸層的節點,
  • RTC media type:一個 RTP Session 中所用到的所有 payload 型別的合集,
  • Multimedia Session:視頻會議組中同時作業的一組 RTP Session,例如,視頻會議中的 Audio Session 和 Video Session,
  • RTP Session:一組參與者利用 RTP 來通訊的組合,一個參與者可以同時加入到多個 RTP Session 中,在 Multimedia Session 中,除非特意將多媒體編碼進同一資料流,否則,每個資料流會通過不同的 RTP Session 傳輸,與會者通過 Transport address 來區分不同的 RTP Session,同一 RTP Session 的不同與會者會共享同一個 Transport address,也可能每個與會者都有自己的 Transport address,在單播的情況時,一個與會者可能用同一對埠(RTP&RTCP)來接收所有其他與會者的資料,也可能對不同的與會者采用不同的埠對(RTP&RTCP),
  • Synchronization source (SSRC):RTP 報文流的一個 Source,由 RTP 頭中定義的 32-bit 的 SSRC identifier 來標識,這樣做是為了不依賴網路地址,同一個 SSRC 中發送的所有包都具有同一時序和序列號間隔,因此接收者可以通過 SSRC 將收到的資料包分組并排序,一個信號源(麥克風,攝像頭,Mixer)的報文流會有由一個 SSRC 的發送器發送,一個 SSRC 可能會隨著時間的變化,改變其資料格式,例如音頻編碼,SSRC 的身份識別碼都是隨機生成的,但是必須保證整個 RTP Session 中該身份識別碼不會重復,這些作業是通過 RTCP 來完成的,如果一個與會者在一個 RTP Session 中發送不同的媒體資料流,那么每個流的 SSRC 必須不同,
  • Contributing source (CSRC):RTP Mixer 所混合的所有資料對應的 SSRC 的串列,Mixer 會將一個 SSRC 串列寫入 RTP 頭中,該串列包含了這個混合報文中包含的所有來源 SSRC,
  • End system:一個生成 RTP payload 和消費收到的 RTP payload 的應用,一個 End system 可以扮演一個或者多個 SSRC 角色,但是通常是一個,
  • Mixer:一個中介系統,它接收一個或多個 Source 的資料,隨后它可能會改變這些資料的格式,并將它們合并為一個新的 RTP packet,因為,多個輸入源的時序通常來說都不一致,所以 Mixer 通常會同步不同源的時間,并生成一個自己的時序來處理合并資料流,所有從 Mixer 輸出的資料包都會標記上該 Mixer 的 SSRC,
  • Translator:一個中介系統,它會轉發 RTP packet 但是不改變其原本的 SSRC,
  • Monitor:一個在 RTP Session 中接收 RTCP 報文的應用,它會總結資料被接收的報告,并為當前分發系統評估 QOS,診斷錯誤,長期統計,Monitor 可以集成進會議應用中,也可以是獨立的第三方應用,只接收 RTCP 報文,但是什么都不發送,
  • Non-RTP means:為了讓 RTP 提供可用服務而加入的協議或者機制,特別是在多媒體會議中,需要一種控制協議來分發組播地址和加密密鑰,協調加密演算法,定義 RTP payload 格式和 RTP payload 型別的動態映射,

位元組序,資料對齊,時間格式

所有的整數欄位都使用網路位元組序(大端序),除了特別宣告,數字常量由十進制表示,

所有頭部資料都會根據其資料的原始長度進行對齊,比如,16-bit 的資料會對齊到偶數偏移,32-bit 的資料會對齊到可被 4 整除的偏移,此外,用 0 來作為填充位元組,

Wallclock time(絕對日期和時間)是用網路時間協議(NTP)的時間格式來表示,即從 1900 年一月一日 0 點到現在的秒數,NTP 的時間戳使用了 64-bit 的無符號固定小數點的形式表示,其中頭 32-bit 用來表示整數部分,后 32-bit 用來表示小數部分,RTP 的時間格式采用了 NTP 的簡化版,他只用了 NTP 的 64-bit 資料的中間 32-bit,即前 16-bit 表示整數,后 16-bit 表示小數,

NTP 時間戳到 2036 年就會回圈回 0,但是因為 RTP 只會使用不同 NTP 時間的差值,所以這不會有什么影響,只要一對時間戳都在同一個回圈周期里,直接用模塊化的架構相級訓者比較就可以,NTP 的回圈問題就不重要了,

RTP 資料傳輸協議

RTP 的定長頭欄位

RTP 頭的格式如下:

上圖中前 96-bit 的資料是每個 RTP 包都有的部分,CSRC 部分只有 Mixer 發送的報文才會有,這些欄位的意義如下:

  • Version(V):2 bits,RTP 版本號,現在用的是 2,(第一個 RTP 草案用的 1)
  • Padding(P):1 bit,如果設定了該欄位,報文的末尾會包含一個或多個填充位元組,這些填充位元組不是 payload 的內容,最后一個填充位元組標識了總共需要忽略多少個填充位元組(包括自己),Padding 可能會被一些加密演算法使用,因為有些加密演算法需要定長的資料塊,Padding 也可能被一些更下層的協議使用,用來一次發送多個 RTP 包,
  • Extension(X):1 bit,如果設定了該欄位,那么頭資料后跟著一個拓展資料,
  • CSRC count(CC):4 bits,CSRC 串列的長度,
  • Marker(M):1 bit,Marker 會在預設中進行定義(預設和 RTP 的關系可以參考 rfc3551,我的理解是預設是對 RTP 的補充,以達到某一類實際使用場景的需要),在報文流中用它來劃分每一幀的邊界,預設中可能會定義附加的 marker,或者移除 Marker 來拓展 payload type 欄位的長度,
  • Payload type(PT): 7bits,該欄位定義 RTP payload 的格式和他在預設中的意義,上層應用可能會定義一個(靜態的型別碼 <->payload 格式)映射關系,也可以用 RTP 協議外的方式來動態地定義 payload 型別,在一個 RTP Session 中 payload 型別可能會改變,但是不應該用 payload 型別來區分不同的媒體流,正如之前所說,不同的媒體流應該通過不同 Session 分別傳輸,
  • Sequence number:16 bits,每發送一個 RTP 包該序列號 + 1,RTP 包的接收者可以通過它來確定丟包情況并且利用它來重排包的順序,這個欄位的初始值應該是隨機的,這會讓 known-plaintext 更加困難,
  • Timestamp:32 bits,時間戳反映了 RTP 資料包生成第一塊資料時的時刻,這個時間戳必須恒定地線性增長,因為它會被用來同步資料包和計算網路抖動,此外這個時鐘解決方案必須有足夠的精度,像是一個視頻幀只有一個時鐘嘀嗒這樣是肯定不夠的,如果 RTP 包是周期性的生成的話,通常會使用采樣時鐘而不是系統時鐘,例如音頻傳輸中每個 RTP 報文包含 20ms 的音頻資料,那么相鄰的下一個 RTP 報文的時間戳就是增加 20ms 而不是獲取系統時間,和序列號一樣時間戳的初始值也應該是隨機的,而且如果多個 RTP 包是一次性生成的,那它們就會有相同的時間戳,不同媒體流的時間戳可能以不同的步幅增長,它們通常都是獨立的,具有隨機的偏移,這些時間戳雖然足以重建單一媒體流的時序,但是直接比較多個媒體流的時間戳是沒辦法進行同步的,每一時間戳都會和參考時鐘(wallclock)組成時間對,而且需要同步的不同流會共用同一個參考時鐘,通過對比不同流的時間對,就能計算出不同流的時間戳偏移量,這個時間對并不是和每個 RTP 包一同發送,而是通過 RTCP 協議,以一個相對較低的頻率進行共享,
  • SSRC:32 bits,該欄位用來確定資料的發送源,這個身份標識應該隨機生成,并且要保證同一個 RTP Session 中沒有重復的 SSRC,雖然 SSRC 沖突的概率很小,但是每個 RTP 客戶端都應該時刻警惕,如果發現沖突就要去解決,
  • CSRC list:0 ~ 15 items, 32 bits each,CSRC list 表示對該 payload 資料做出貢獻的所有 SSRC,這個欄位包含的 SSRC 數量由 CC 欄位定義,如果有超過 15 個 SSRC,只有 15 個可以被記錄,

RTP Session 多路復用

在 RTP 中,多路復用由目標傳輸地址(address:port)提供,不同的 RTP Session 有不同的傳輸地址,

獨立的音頻和視頻流不應該包含在同一個 RTP Session 中,也不應該通過 payload 型別和 SSRC 來區分不同的流,如果用同一個 SSRC 發送了不同的資料流,會引入如下問題:

  1. 假設 2 個音頻流共享了一個 RTP Session,并且用了同一個 SSRC,如果其中一個要改變編碼,這就導致了 payload 型別的改變,但是協議中沒有提供方法來讓接收者知道具體是哪個音頻流改變了編碼,

  2. 一個 SSRC 只有一個對應的時序和序列號,如果多個流有不同的時鐘周期的話,就需要不同的時序,而且還不能用序列號來確認是哪個流丟包了,

  3. RTCP 發送者報告和接收者報告只描述了時序和序列號而不包含 payload 型別資料,

  4. Mixer 無法將不兼容的兩個流合并,

  5. 如果一個 RTP Session 中包含了多個媒體流后就會失去如下優勢:

  • 使用不同的網路路徑或者分配網路資源
  • 只接收某一種媒體資料(網路較差時只接收 audio)
  • 接收方對不同的媒體型別做不同的處理

不同的流使用不同的 SSRC 但是仍然用同一個 RTP Session 發送確實可以解決前三個問題,但是仍然無法解決后兩個問題,

預設可能對 RTP 頭的改動

現有的這些 RTP 報文頭對一般應用來說已經足夠了,如果有需要,頭欄位可以根據預設進行一些修改,但仍要保證檢測和統計功能的正常使用,

RTP 頭拓展

RTP 提供了一個拓展機制,讓上層應用可以將自定義的資訊存盤在 RTP 報文頭,如果上層應用收到了無法識別的頭部拓展資料,它們會忽略它,

值得一提的是,這個頭部拓展是有一些限制的,如果附加資訊只對某些 payload 格式才有意義,那么最好還是別把這些資訊放到頭部拓展中,而是放到 payload 部分,


如果 RTP Header 中的 X 位設定為 1,那么 Header 后必須跟著一個不定長度的拓展塊,緊跟著 CSRC list(如果有的話),拓展部分的頭部包含一個 16-bit 的資料來描述拓展塊包含多少個 32-bit 字(不包括拓展部分的頭部),因為 RTP 頭部后面只能連接一個拓展塊,考慮到有些應用可能會有多種型別的拓展塊,所以拓展塊的頭 16-bit 留給開發者去自定義一些引數,

RTP 控制協議

同一個 Session 所有參與者會周期性地發送控制報文,RTP 控制協議就是通過這種方式進行的,和 RTP 資料的傳播一樣采用了組播的機制,下層協議必須提供資料包和控制報文的多路復用功能,例如使用獨立的 UDP 埠分別傳輸資料和控制報文,RTCP 協議具有如下四大功能:

  1. 最主要的功能是反饋資料分發的質量,這也是 RTP 作為一個傳輸協議來說最關鍵的功能,而且它和流量控制,擁塞控制息息相關,反饋資訊可能會直接影響自適應編碼的控制,發送反饋報告給所有的參與者可以讓它們評估遇到的資料分發問題是個人問題還是全域問題,通過 IP 組播這樣的分發機制,像網路提供商這樣的機構即便不加入到這個 RTP Session 中也能收到反饋資訊,它們會扮演一個第三方監測者的角色去確認資料分發問題,這個反饋的功能無論是 RTCP 的發送者還是接收者都會進行報告,

  2. RTCP 還會給每個 RTP source 帶一個不變的傳輸層身份識別符(CNAME),因為 SSRC 可能會中途改變(程式重啟),所以接收者需要這個 CNAME 來持續追蹤每個與會者,而且,接收者可以通過 CNAME 來將同一個與會者的所有資料流聯系在一起,比如同步音頻和視頻,單個媒體內部的資料同步也需要 NTP 和 RTP 時間戳,這些資料都在資料發送者發送的 RTCP 報文中,

  3. 因為前兩個功能需要所有的與會者都發送 RTCP 報文,所以需要適當的控制報文發送的頻率以保證 RTP 協議可以在大量客戶端一同加入時也能正常作業,通過每個參與者都廣播控制報文的方式,每個人都能獨立地計算出參與者的總數,

  4. 還有一個可有可無的功能,RTCP 可以用來共享小量的 Session 控制資訊,例如辨認參與者的身份,通常來說,該功能會被那些管理比較松散的 Session 使用,RTCP 可以作為一個方便的與其他參與者溝通的通道,但是你也別期望 RTCP 可以滿足一個應用的所有傳輸控制需求,這類需求往往是通過一個更高層的 Session 控制協議來滿足,

這四個功能中,前三個應該會被所有應用場景使用(IP 組播機制下),RTP 應用的設計者應該避免自己的應用只能作業在單播模式,RTP 應用應該設計成可拓展的,要考慮大量使用者并發時的情況,此外,RTCP 的傳輸應該根據發送者和接收者角色的不同而分別進行控制,例如一些單項連接,接收者的反饋資訊就發不出來,

提醒:像是指定源組播路由(SSM),只有一個人可以發送資料,其他接收者不能用組播來和其他人直接通訊,對于這種情況,建議完全關閉接收者的原始 RTCP 功能,然后為這個 SSM 設定一個 RTCP 的配接器,來接收所有的反饋,

RTCP 包格式

RTCP 定義了許多包型別來傳輸不同的控制資訊:

  • SR:發送者報告,發送者資料發送和接收的統計,
  • RR:接收者報告,只接收資料的節點的接收統計,
  • SDES:Source 描述,包括 CNAME,
  • BYE:表示退出,
  • APP:上層應用自定義,

每個 RTCP 包都有一個和 RTP 類似的固定格式的頭,后面跟著長度不定的結構化資料,在不同 RTCP 型別時,這些結構化資料各不一樣,但是它們必須都要 32-bit 對齊,RTCP 的頭部是定長的,而且在頭部有一個欄位來描述這個 RTCP 資料的長度,因此 RTCP 可以被復合成一組一同發送,還不需要任何分隔符來分割出單個的 RTCP 包,下層協議可能會根據自己的情況決定將多少個 RTCP 報文復合在一起組成一個復合包,

復合包中的每個獨立的 RTCP 報文都是無序的,而且可能會被隨意復合,為了讓協議的功能正常運作,會有如下限制:

  • 接收統計(SR|RR)的發送頻率需要達到帶寬的最大限制,因此每個周期發送的 RTCP 復合包都需要包含一個這類報文,
  • 一個新來的接收者需要盡可能快地得到資料源的 CNAME,因為它要用 CNAME 來確定每個資料源分別對應哪個人,并將資料源聯系在一起進行同步,所以每個 RTCP 復合包必須包含 SDES CNAME(除非這個復合包被拆成兩半一半加密,一般明文,這部分后面會介紹),
  • 復合包中包型別的數量需要限制,這可以減少其他發錯的包或者不相關的包被識別成 RTCP 包的可能性,還能增加第一個字中固定位元的數量,

因此,一個復合包中至少需要含有 2 種型別的 RTCP 報文,它的格式如下:

  • Encryption prefix:當且僅當這個復合包需要加密的時,那復合包在頭部插入一個隨機的 32-bit 數,如果加密演算法需要填充資料的話,需要填充到復合包中的最后一個 RTCP 包后,
  • SS 或 RR:復合包中第一個 RTCP 包必須是一個報告報文,這可以加速報文頭部資料的校驗,即便沒有 RTP 資料的發送和接收也要有一個報告報文,這種情況下必須發送一個空的 RR 報文,并且即便是這個復合包中的其他 RTCP 報文是 BYE 也要這么做,
  • Additional RRs:如果接收的 RTP 資料來自超過 31 個不同的源,前 31 個接收報告會寫進 SR 或者 RR 報文中,多出來的接收報告應該緊跟著默認的報告報文(SR 或 RR),
  • SDES:SDES 包必須包含 CNAME,每個復合包必須包含一個 SDES 包,如果上層應用有需要,也可以加入一些別的 SDES 報文,這視帶寬限制而定,
  • BYE 或 APP:其他 RTCP 包型別(包括協議中還未定義的),可能以任意順序跟在 SDES 后面,但是希望 BYE 包寫在最后面(BYE 包需要和 SSRC/CSRC 一同發送),

一個單獨的 RTP 參與者應該在一個報告周期中只發送一個復合 RTCP 包,該周期每個參與者應該視帶寬情況來估算,除非一個復合包被拆分加密,如果資料發送者的數量太多,以至于除了增加 MTU 這個方法之外,沒辦法將所有 RR 報文塞進一個復合包時,那么一次只會將部分 RR 資料塞進這個復合包,其他的資料就不發送了,當然,為了讓所有源的接收情況都得到報告,會在多個周期內以環的形式回圈共享所有源的接收情況,

為了減少資料包的開銷,一般建議 Translator 和 Mixer 無論何時都能將多個源的 RTCP 報文復合成一個復合包,下圖展示的就是一個 Mixer 生成的復合包的例子:

如果一個復合包的長度超過了下層網路協議的 MTU 的話,這個復合包會被拆分成多個更小的復合包分別發送,這不會對 RTCP 的帶寬估計產生任何影響,因為即便 Mixer 的復合包被拆分成了多個更小的復合包,但是這個些更小的復合包也要滿足 "每個復合包都要包含 SS 或 RR" 這一條件,所以每個更小的復合包至少也對應了一個參與者,這樣 Mixer 生成的復合包就和它收到的 RTCP 包數量基本匹配,甚至更少,

如果某一客戶端收到了它無法決議的 RTCP 型別的包,那它應該忽略這個包,附加的 RTCP 包型別會通過 IANA 進行注冊,

RTCP 傳輸周期

RTP 的設計理念是它要能根據 Session 參與者的人數增加而進行自適應處理,例如,音頻會議中同一時刻說話的一般也就那么一兩個人(這就從內部限制了音頻資料的傳輸),那么可以認為組播資料分發所用到的帶寬資源和與會人數無關,控制資訊的發送和音頻資料的傳輸不同,每個人都會不停的發送 RTCP 報文,如果每個參與者的接收報告以同一個周期發送的話,RTCP 報文傳輸所消耗的資源會隨著與會人數的增加而線性增加,因此,當與會人數增加時,RTCP 報文的發送間隔應該相應的動態地增大,

對每個 Session 來說,會有一個總的帶寬限制(Session bandwidth),它會被分配給每個獨立的與會者,整個網路的帶寬可能會有所保留,并從網路層面強制限制 Session 的帶寬,如果網路的帶寬沒有保留的話,也可能會有一些別的限制,不過這些都跟網路環境有關,總之最后會得出一個靠譜的 Session 最大帶寬,Session 帶寬可能會通過實際會消耗的網路資源進行評估,或者中途根據 Session 的剩余可用帶寬來變化,

這些都和媒體資料的編碼無關,但是會根據帶寬的限制來選擇具體使用哪種編碼,通常來說,會預估 Session 中有多少參與者會同時發送資料,然后根據同時發送這類資料大概需要多少帶寬這種方式來評估 Session 的帶寬,在音頻會議中,通常來說就是一個音頻發送者所需要的帶寬(一般同一時間只會有一個人說話),對于分層編碼這種情況,每一層都在一個獨立的 RTP Session 中,這些 Session 都有自己獨立的帶寬限制,

在 RTP Session 中應該有一個管理應用來調整 Session 帶寬,但是那些音頻會議應用可能會基于 Session 中選用的編碼格式,假設只有一個發送者發送資料,給自己設定一個默認的帶寬限制,這個音頻會議應用可能也會受到組播網路(或其他因素)的帶寬限制,同一個 Session 的所有參與者必須使用統一的 Session 帶寬限制,因為只有這樣大家才是以一個相同的頻率發送 RTCP 包,

Session 帶寬評估程序需要考慮到下層的傳輸層和網路層是否有一些資源保留機制,而且上層應用也需要知道 RTP 下層使用了什么協議,但是不需要知道資料鏈路層及以下的協議,因為從資料鏈路層開始資料包的頭就各不相同了,

控制報文的傳輸應該只使用 Session 帶寬中很小的一部分,這樣媒體資料的傳輸才會不受影響,建議 RTCP 傳輸使用 Session 帶寬的 5%,媒體資料發送者至少要占用 1/4 的 RTCP 帶寬,因為這樣做的話,新加進來的人可以更快的收到媒體資料發送者的 CNAME,在某些預設中,如果發送者的數量超過 1/4 可能會完全關閉接收報告,雖然 RTP 協議標準并不推薦這樣做,但是那些只有單向鏈路的系統或者不需要接收者反饋的系統一般是這么做的,

RTCP 報文的傳輸間隔一般都會稍微長一點,這樣,當參與者的數量陡增時,報文的數量就不會超過帶寬限制太多,當一個應用啟動時,它應該等一段時間(一般是最小 RTCP 報文間隔的一半)再發送第一個 RTCP 報文,這樣這可讓發送間隔的計算更快的收斂,推薦 RTCP 報文發送的最小間隔是 5 秒,

RTP 的上層應用可能會使用更短的 RTCP 發送間隔,但是也會遵循如下原則:

  • 對于組播形式的 Session,只有資料發送者會使用更短的 RTCP 發送間隔,
  • 對于單播形式的 Session,無論是發送者還是接收者都有可能使用更短的 RTCP 間隔,并且它們發送初始 RTCP 前可能不會等待一段時間,
  • 所有的 Session 都應該根據最小 RTCP 發送間隔來確定參與者的超時時間,
  • 推薦的最小 RTCP 發送間隔時間使用 "360 kb/Session 帶寬(kb/s)" 這種方式計算,這樣當 Session 帶寬大于 72kb/s 時,RTCP 發送間隔會小于 5 秒,

此外,為了讓 RTCP 能在大型 Session 中正常運行,現有的演算法還具有如下特點:

  • RTCP 報文發送間隔隨著 Session 參與者的人數增加而線性地降低,
  • RTCP 發包間隔通常會隨機縮放 0.5~1.5 倍,這樣做是為了避免大量的參與者同時發送 RTCP 報文,
  • RTCP 復合包中包含的控制報文資料會根據收發包情況動態變化,
  • 因為 RTCP 報文間隔是根據已知的 Session 參與者情況計算的,所以當有新的人要加入到 Session 時,可能會錯估整個 Session 的規模,而是用了較短的 RTCP 間隔,尤其是當大批量的人一齊加入 Session 時這種現象更加明顯,所以,可能會有一個 "發送時機重整" 演算法,它實作了一個簡單的撤回機制,可以在 Session 規模持續增長時,適當的撤回一些 RTCP 報文,
  • 當有人通過發送 BYE 報文或者因為超時退出 Session 時,RTCP 的發送間隔應該縮短,
  • BYE 報文和其他 RTCP 報文相比,有一些特殊的地方,當有人想要退出,并發送 BYE 報文時,它可以在下一個發送周期到來之前就發送,當然,如果一大批人同時退出時,也會受到前面提到的 RTCP 報文撤回機制的影響,

維護 Session 成員的數量

我們已經知道了,計算 RTCP 發送間隔是需要清楚整個 Session 中成員數量的,當一個新的節點被監聽到時,它就會被加入到 Session 總數中,并且大家要把它加入到一個 SSRC(CSRC)身份識別表中然后持續追蹤,大家只有收到這個新節點的多個資料包,或者收到他的 SDES 包(CNAME)時才覺得這個新節點是靠譜的,當某個節點發了一個 BYE 之后,它的資訊可能就會被大家刪了,但是考慮到可能有丟包或者網路擁堵的情況,所以大家會先把它標記為 "收到 BYE",然后等一段時間,如果還沒收到它的別的報文,這時候才會把它刪了,

如果一個節點超過一個 RTCP 周期都沒收到另一個節點的報文,它可能就會將其標記為不活躍,或者刪了它,這就需要丟包的情況盡可能別發生,但是不丟包是不可能的,所以大家一般會將 RTCP 傳輸間隔乘以一個系數(大于 1 的數)作為超時時間,

對于那些參與者很超級多的 Session,可能沒法去維護一個 SSRC 表來存盤所有參與者的資訊,通常大家都會簡化這個 SSRC 表,但是需要注意的是無論怎么簡化這個表都不能低估了參與者的總數,可以允許高估參與者總數,

RTCP 報文的收發規則

首先,無論是組播還是多個節點的單播都必須遵循前面提到的 RTCP 間隔,為了正常完成 RTCP 報文的收發操作,Session 中的每個參與者都會維護如下資訊:

  • TP:最后 RTCP 報文的發送時間;
  • TC:當前時間;
  • TN:下一個要發送報文的時間點;
  • P-Members:計算上一個 TN 時參考的 Session 成員總數;
  • Members:當前的 Session 成員總是;
  • Senders:資料發送者總數;
  • RTCP_BW:RTCP 的目標帶寬;
  • WE_Sent:從倒數第二個 RTCP 報文發送后,到現在為止,是否發送過資料;
  • AVG_RTCP_Size:平均 RTCP 復合包大小,包括傳輸層和網路層的頭;
  • initial:是否一個 RTCP 報文都沒發過,

計算 RTCP 發送間隔

為了讓 RTP 協議具有可伸縮性,RTCP 的發送間隔需要隨著 Session 總人數的變化而適當的縮放,結合上述的部分狀態,我們按如下方式計算 RTCP 報文間隔:

  1. 如果媒體流發送者的數量小于總人數的 25% 時,這個間隔和當前節點是否是媒體流發送者有關(通過 WE_Sent 判斷),如果是媒體流發送者,計算公式為 Senders * AVG_RTCP_Size / (25% * RTCP_BW),如果是媒體流的接收者,計算公式為:(Members - Senders)* AVG_RTCP_Size / (75% * RTCP_BW),當媒體流發送者的數量超過 25% 時,發送者和接收者會被同等對待,即它們的 RTCP 周期公式為:Members * AVG_RTCP_Size / RTCP_BW,

  2. 如果某個參與者一個 RTCP 包都還沒發送,最小發送間隔間隔(Tmin)為 2.5 秒,否則為 5 秒,

  3. 決定的發送間隔(Td)會是第一步計算的值和 Tmin 中較大的那個,

  4. 發包時會在 Td 的基礎上隨機縮放 0.5~1.5 倍,

  5. 最終這個間隔還要除以 e-3/2=1.21828,這是為了彌補因為 "發送時機重整" 演算法帶來的影響(因為這個演算法會導致最終 RTCP 使用的實際帶寬比預計使用的帶寬低),

初始化

當一個人剛加入到 Session 中時,tp=0,tc=0,senders=0,p-members=0,members=1,we_sent=false,rtcp_bw = 5% * Session 帶寬,initial=true,avg_rtcp_size 被設定為之后會發送的首個 RTCP 包的大小,然后計算發送間隔 T 時,會根據上述初始狀態進行計算,并以此作為參考發送第一個包,最后將自己的 SSRC 加入到成員串列中,

接收 RTP 和 Non-BYE RTCP 包

當 RTP 或者 RTCP 包被另一個人(A)接收到了,如果對 A 來說這個包的 SSRC 他沒見過,那么他就會將其加入到 SSRC 表中,并更新 Session 總人數(Members),對每個 CSRC 也會做同樣的操作,

如果收到了一個 RTP 報文,并且其對應的 SSRC 沒在發送者 SSRC 表中,那他就會把它加進發送者 SSRC 表中,并更新發送者的總數(Senders),

當每個復合 RTCP 報文被接收到時,平均 RTCP 報文大小(AVG_RTCP_Size)的狀態就會更新,更新公式為:AVG_RTCP_Size = (1 / 16) * last_rtcp_package_size + (15 / 16) * previous_avg_rtcp_size,

接收 RTCP BYE 報文

如果接收到了 RTCP BYE 報文,會在成員串列中確認一下,如果有對應的 SSRC 項,就會把它移除并更新成員總數(Members),同時也會在發送者 SSRC 表中做類似的操作,如果找到了就洗掉它并更新發送者總數(Senders),

此外,為了讓 RTCP 的傳輸率跟隨 Session 中人數的變化而動態變化,如下演算法會在收到 BYE 報文時執行:

  1. TN 按照如下公式更新:TN = TC + (Members / P-Members) * (TN - TC) ,

  2. TP 按照如下公式更新:TP = TC - (Members / P-Members) * (TC - TP) ,

  3. 下一個 RTCP 報文按照新的 TN 指示發送(比原來發的更早了),

  4. 將 P-Members 設定成 Members 的值,

這個演算法沒有考慮到一個意外情況,那就是當一大波人(并不是所有人)同時退出 Session 時,會導致 RTCP 的周期降到一個非常小的值,這樣可能出現錯誤的 Timeout 判斷,最終它會導致整個 Session 的總人數降到 0,但是,這種情況一般來說很少發生,所以大家都覺得問題不是很大,

SSRC 的超時

我們需要偶爾確認一下是不是太久沒收到某個與會者的報文了,一般來說每個 RTCP 周期內都必須確認,如果發現了超時,就需要將這個 SSRC 從成員串列(Members & Senders)中移除,并更新當前人數,

Member 表:一般超過 5 個發送周期(不考慮隨機縮放因素)未收到某人的訊息,會被確定為超時,

Sender 表:一般是 2 個發送周期,

如果某個成員被確定為超時,上一步介紹的演算法就操作起來了,

發送倒計時

我們已經知道,每個 RTCP 都是周期性的發送的,當發送完一個 RTCP 報文時,就會根據 TN 新建一個倒計時,每次當倒計時歸零時就會重復如下操作:

  1. 計算傳輸周期 T,引入隨機縮放因素,

  2. 如果 TP + T <= TC,立即發送一個 RTCP 報文,并將 TP 設定為 TC,TN 設定為 TC + T,下一個倒計時會在 TN 時刻歸零,如果 TP + T> TC,就不發送了 RTCP 報文,計算 TN = TC + T 后,然后重設一個定時器在 TN 歸零,

  3. P-Members 設定為 Members,

如果發送了 RTCP 報文,initial 會被設定為 FALSE,AVG_RTCP_Size 會按如下方式更新:
AVG_RTCP_Size = (1 / 16) * last_rtcp_package_size + (15 / 16) * previous_avg_rtcp_size,

發送 BYE 報文

當某個人想要退出 Session 時,他就會發一個 BYE 報文給其他人,為了防止一大幫人同時退出 Session 時出現 BYE 報文井噴的情況,所以當 Session 人數超過 50 時,會按下述方式操作:

  1. 當一個參與者想要離開時,TP 會設定成 TC,Members 和 P-Members 會設定成 1,initial 設定成 1,we_send 設定成 false,senders 設定成 0,avg_rtcp_size 設定成復合 BYE 報文的大小,然后計算 RTCP 發送間隔 T,下個 BYE 報文會在 TN = TC + T 后發送,

  2. 每當這個要離開的人收到了別人的 BYE 報文時,Members 就會增加 1,無論這個人是否在成員串列中,Members 的數量只有收到 BYE 報文時才增加,其他報文都不管,同樣,avg_rtcp_size 也只管收到的 BYE 報文的大小,Senders 數量也不變,

  3. 對了 BYE 報文來說,除了狀態值的維護套路變了,發送邏輯和前面提到的都一樣,通過上述方案,即可以讓 BYE 報文正確地發送,還能控制整體帶寬,最差的情況下,也只會導致 RTCP 報文傳輸占用 10% 的 Session 總帶寬,

有些參與者可能不想按照上述的方式發送 BYE 報文,他們可能什么也不發就離開了,這類情況會被 Timeout 機制 hold 住,

如果一個參與者要離開時,Session 的總人數小于 50,他可能會直接發送一個 BYE 報文,也可能按照上述方案來進行,

此外還有一個無論如何都要遵循的規則,如果一個參與者一個 RTP 報文或者 RTCP 報文都沒發送過的話,那他離開 Session 時絕對不能發送 BYE 報文,

更新 WE_Sent

當某個參與者最近發送過一個 RTP 后,他就會將 WE_Sent 置為 true 并將自己加入到 Senders 表中,否則如果超過兩個 RTCP 發送周期的時間內都沒發送過 RTP 報文,那他就會將自己從 Sender 表中移除,并將 WE_Sent 置為 false,

SDES 類報文的帶寬分配

SDES 報文中除了必須要有的 CNAME 之外,還有一些別的資訊,比如 NAME(個人名稱),EMAIL(email 地址)等,上層應用也可以自定義的一些報文型別,但是要小心別付加了太多的自定義資訊以至于拖慢了整個 RTCP 協議的運轉,建議這些附加內容的帶寬占用不要超過整個 RTCP 協議帶寬的 20%,此外,也不要覺得每個上層應用都會包含所有的 SDES 內容,上層應用要根據實際使用的情況給這些內容分配一定的帶寬,一般來說他們會通過控制發送間隔來控制這部分的帶寬,

比如,一個應用的 SDES 可能只包含 CNAME,NAME,和 EMAIL,其中 NAME 可能就會比 EMAIL 分配更多的帶寬,因為 NAME 會一直顯示出來,而 EMAIL 可能只在點擊查看的時候才顯示,在每個 RTCP 發送周期里,SDES 中都會包含 CNAME,如果假設 RTCP 周期是 5 秒的話,可能每 15 秒 SDES 才會附帶一個除 CNAME 以外的資訊,以 2 分鐘為例,其中 7 次附帶的是 NAME 資訊,1 次附帶的是 EMAIL 資訊,

「視頻云技術」你最值得關注的音視頻技術公眾號,每周推送來自阿里云一線的實踐技術文章,在這里與音視頻領域一流工程師交流切磋,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258327.html

標籤:其他

上一篇:子母鐘系統(GPS授時系統)作業模式介紹

下一篇:大資料開發-Spark Join原理詳解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more