首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Live555 RTSP 客戶端開發:MediaSession 與 MediaSubsession 區別詳解

     編輯:程式設計疑難解答

問題背景

使用 Live555 開發 RTSP 客戶端時,收到 SDP 信息後創建 MediaSession,隨後仍需遍歷創建 MediaSubsession 並對每個發送 SETUP,不理解兩者關係與必要性。

核心概念區別

概念對應實體作用SDP 中體現
MediaSession一個完整的媒體會話/演示聚合多個媒體流的控制入口,管理整體會話狀態整個 SDP 文本(v=0 到末尾)
MediaSubsession單一媒體軌道代表具體的音視頻軌道,處理獨立的 SETUP/PLAY/TEARDOWN每個 m= 行及其屬性(a=rtpmap 等)

為什麼需要 Subsession?

一個 RTSP 會話通常包含多個媒體流:

  • 視頻軌道(H.264/H.265)
  • 音頻軌道(AAC/G.711/OPUS)
  • 可能的字幕、數據軌道

每個軌道需要獨立的傳輸參數協商:

  • 不同的 RTP/RTCP 端口對
  • 不同的編解碼參數(fmtp)
  • 不同的傳輸模式(單播/組播、UDP/TCP)

因此 每個軌道 = 一個 Subsession = 一次獨立的 SETUP 交互。

典型 RTSP 交互流程

客戶端                    服務端
  |                         |
  |---- DESCRIBE --------->|
  |<--- 200 OK (SDP) ------|  ← 解析 SDP 創建 MediaSession
  |                         |
  |---- SETUP (video) ---->|  ← 為視頻 Subsession 發送 SETUP
  |<--- 200 OK (ports) ----|
  |                         |
  |---- SETUP (audio) ---->|  ← 為音頻 Subsession 發送 SETUP
  |<--- 200 OK (ports) ----|
  |                         |
  |---- PLAY (aggregate) -->|  ← 聚合播放整個 Session
  |<--- 200 OK ------------|
  |                         |
  |==== RTP/RTP 流數據 ====>|  ← 多路流並行傳輸
  |                         |

代碼邏輯對應

// 1. 解析 SDP 創建會話
MediaSession* session = MediaSession::createNew(env, sdpDescription);

// 2. 遍歷每個 Subsession(即每個 m= 行)
MediaSubsessionIterator iter(*session);
MediaSubsession* subsession;
while ((subsession = iter.next()) != NULL) {
    // 3. 為每個 Subsession 創建源/接收器
    subsession->initiate();  // 內部會發送 SETUP
    
    // 4. 可選:設置接收回調、緩衝區等
    // subsession->sink = MySink::createNew(...);
}

// 5. 聚合播放整個會話
session->startPlaying();  // 發送 PLAY (aggregate)

關鍵數據結構關係

MediaSession
├── sessionName (SDP s=)
├── sessionDescription (SDP i=)
├── subsessions (MediaSubsession 列表)
│   ├── MediaSubsession (視頻)
│   │   ├── mediumName = "video"
│   │   ├── codecName = "H264"
│   │   ├── rtpPayloadFormat = 96
│   │   ├── rtpTimestampFrequency = 90000
│   │   ├── controlPath = "track1"  ← SETUP URL 相對路徑
│   │   ├── rtpChannel, rtcpChannel  ← SETUP 協商得到的端口
│   │   └── sink (MediaSink)         ← 數據接收器
│   │
│   └── MediaSubsession (音頻)
│       ├── mediumName = "audio"
│       ├── codecName = "AAC"
│       ├── controlPath = "track2"
│       └── sink ...
│
└── aggregateControl (PLAY 聚合控制 URL)

常見誤區澄清

  1. 誤區:「Session 建立後直接 PLAY 即可」
    正確:必須先對每個 Subsession 完成 SETUP 協商傳輸參數,才能 PLAY。
  2. 誤區:「Subsession 就是視頻幀」
    正確:Subsession 是邏輯軌道,包含該軌道的所有幀數據流。
  3. 引用原文解釋:「ServerMediaSession 代表媒體名稱,ServerMediaSubsession 代表一個 Track,流是指有數據流動的組合」——完全正確。

參考資源

總結

MediaSession = 整個會話容器,MediaSubsession = 單一媒體軌道。SDP 中每個 m= 行對應一個 Subsession,客戶端必須遍歷所有 Subsession 逐個發送 SETUP 協商傳輸參數,最後對 Session 發送聚合 PLAY 開始接收多路流數據。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved