当前位置: 首页 > news >正文

WebRTC 发送端 SSRC 生成流程总结

前言:

总结发送端 SSRC(Synchronization Source Identifier)的设置流程。
SSRC 是 RTP/RTCP 包的关键标识,通常在 SDP 协商或配置阶段生成或设置,如果未指定则随机生成(非零 32 位值)。流程从 SDP 内容更新开始,到 RTP 发送模块初始化结束。报告具体到每个接口,包括调用关系、代码分析。

看不懂的朋友也可以跟着了解下发送Stream创建流程,特别懂的朋友也可以跟着看我有没有胡说八道,咱们都吃不了亏,上不了当,闲言少叙,走起!!!

1. 流程概述

发送端 SSRC 设置主要发生在 SDP 协商阶段(本地 offer/answer 处理)和 RTP 模块初始化阶段。核心逻辑:

  • 如果 SDP 中 StreamParams (sp) 已指定 SSRC,则直接使用。
  • 如果未指定(e.g., 使用 RIDs 而非 SSRCs),则在 UpdateLocalStreams_w 中调用 GenerateSsrcs 生成随机 SSRC。
  • 生成的 SSRC 传递到下层(如 RtpVideoSender、VideoSendStreamImpl),最终设置到 RTPSender 和 RTCPSender 中。
  • 数据流向:SDP 更新 → 通道配置 → 流添加 → RTP 配置 → 发送模块初始化。
  • 设计原则:确保 SSRC 唯一、非零,支持 simulcast(多 SSRC)和 RID(无 SSRC 协商)。

2. 详细接口流程

以下按调用顺序描述每个接口,包括输入/输出、代码片段和分析。流程从 SDP 处理开始。

2.1 接口:VideoChannel::SetLocalContent_w

  • 描述:处理本地 SDP 视频内容描述,更新接收/发送参数,并调用 UpdateLocalStreams_w 设置本地流(包括 SSRC)。
  • 调用关系:上层 SDP 协商(如 PeerConnection)调用此接口处理本地 offer/answer。
  • 输入:MediaContentDescription* content(SDP 视频描述,包括 streams),SdpType type(offer/answer),error_desc。
  • 输出:bool(成功/失败)。
  • SSRC 设置逻辑:不直接生成 SSRC,但调用 UpdateLocalStreams_w 处理 streams。如果 streams 无 SSRC,则在下层生成。
  • 核心代码分析
    bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content, SdpType type, std::string* error_desc) {// ... 提取 video 描述,更新 recv/send paramsif (!UpdateLocalStreams_w(video->streams(), type, error_desc)) {  // 调用 UpdateLocalStreams_wSafeSetError("Failed to set local video description streams.", error_desc);return false;}// ... 更新方向和状态return true;
    }
    
    • 分析:如果 streams (video->streams()) 无 SSRC 或 RIDs,则 UpdateLocalStreams_w 会生成。type=answer 时,检查 codec 兼容性,但不影响 SSRC 生成。

2.2 接口:BaseChannel::UpdateLocalStreams_w

  • 描述:更新本地发送流列表,包括添加/移除流。如果流无 SSRC,则调用 GenerateSsrcs 生成。
  • 调用关系:由 SetLocalContent_w 调用。
  • 输入:std::vector streams(SDP 中的流参数,可能无 SSRC),SdpType type,error_desc。
  • 输出:bool(成功/失败)。
  • SSRC 设置逻辑:遍历 streams,如果新流无 SSRC/RIDs,则跳过;否则调用 GenerateSsrcs 生成 SSRC(基于 RIDs 数量,支持 RTX/FEC)。然后调用 media_channel()->AddSendStream 添加流。
  • 核心代码分析
    bool BaseChannel::UpdateLocalStreams_w(const std::vector<StreamParams>& streams,SdpType type,std::string* error_desc) {// ... 检查移除旧流std::vector<StreamParams> all_streams;for (const StreamParams& stream : streams) {StreamParams* existing = GetStream(local_streams_, StreamFinder(&stream));if (existing) {all_streams.push_back(*existing);continue;}all_streams.push_back(stream);StreamParams& new_stream = all_streams.back();if (!new_stream.has_ssrcs() && !new_stream.has_rids()) continue;  // 无 SSRC/RIDs 跳过RTC_DCHECK(new_stream.has_ssrcs() || new_stream.has_rids());if (new_stream.has_ssrcs() && new_stream.has_rids()) {  // 不能同时有// ... 错误处理}// 生成 SSRCif (!new_stream.has_ssrcs()) {new_stream.GenerateSsrcs(new_stream.rids().size(), /* rtx = */ true,/* flex_fec = */ false, ssrc_generator_);  // 调用 GenerateSsrcs}// 添加流if (media_channel()->AddSendStream(new_stream)) {RTC_LOG(LS_INFO) << "Add send stream ssrc: " << new_stream.ssrcs[0];} else {// ... 错误处理}}local_streams_ = all_streams;return true;
    }
    
    • 分析:GenerateSsrcs(rids.size(), true, false, ssrc_generator_) 生成主 SSRC + RTX SSRC(如果启用)。ssrc_generator_ 是 SsrcGenerator 实例,确保唯一随机 SSRC。如果 SDP 已指定 SSRC,则直接使用。

2.3 接口:WebRtcVideoChannel::AddSendStream

  • 描述:添加发送流,创建 WebRtcVideoSendStream,并调用 Call::CreateVideoSendStream 生成 VideoSendStream。
  • 调用关系:由 UpdateLocalStreams_w 调用 media_channel()->AddSendStream(new_stream)。
  • 输入:StreamParams& sp(包含 SSRCs)。
  • 输出:bool(成功/失败)。
  • SSRC 设置逻辑:使用 sp 中的 SSRC 创建 config.rtp.ssrcs,然后调用 CreateVideoSendStream。
  • 核心代码分析
    bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) {// ... 验证 spWebRtcVideoSendStream* stream = new WebRtcVideoSendStream(call_, sp, std::move(config), default_send_options_, video_config_.enable_cpu_adaptation,bitrate_config_.max_bitrate_bps, send_codec_, send_rtp_extensions_, send_params_);uint32_t ssrc = sp.first_ssrc();  // 使用 sp.first_ssrc()send_streams_[ssrc] = stream;  // 存储到 send_streams_if (sending_) stream->SetSend(true);  // 如果已发送,启用return true;
    }
    
    • 分析:sp.ssrcs 来自上层生成。stream 持有 SSRC,用于 RTP/RTCP。

2.4 接口:Call::CreateVideoSendStream

  • 描述:创建 VideoSendStream,设置 config.rtp.ssrcs,并调用 RtpVideoSender 构造函数。
  • 调用关系:由 AddSendStream 调用。
  • 输入:VideoSendStream::Config config(包含 rtp.ssrcs),VideoEncoderConfig 等。
  • 输出:VideoSendStream*。
  • SSRC 设置逻辑:直接使用 config.rtp.ssrcs(来自 sp.ssrcs)。
  • 核心代码分析
    VideoSendStream* Call::CreateVideoSendStream(webrtc::VideoSendStream::Config config,VideoEncoderConfig encoder_config,std::unique_ptr<FecController> fec_controller) {// ... 记录 SSRCsfor (size_t ssrc_index = 0; ssrc_index < config.rtp.ssrcs.size(); ++ssrc_index) {// ... 事件日志}// 创建 VideoSendStreamVideoSendStream* send_stream = new VideoSendStream(/*...*/, config.rtp.ssrcs, std::move(config),std::move(encoder_config), /*...*/);// ... 添加到 video_send_ssrcs_ 和 video_send_streams_return send_stream;
    }
    
    • 分析:config.rtp.ssrcs 来自上层传入,已生成。send_stream 持有 SSRC,用于内部模块。

2.5 接口:VideoSendStream::VideoSendStream

  • 描述:创建 VideoSendStreamImpl,并调用 RtpVideoSender::RtpVideoSender。
  • 调用关系:由 CreateVideoSendStream 调用。
  • 输入:Config config(包含 rtp.ssrcs),EncoderConfig 等。
  • 输出:无(构造函数)。
  • SSRC 设置逻辑:使用 config.rtp.ssrcs 传入 RtpVideoSender。
  • 核心代码分析
    VideoSendStream::VideoSendStream(/*...*/, VideoSendStream::Config config, /*...*/) : // ... 初始化rtp_video_sender_(transport_->CreateRtpVideoSender(suspended_ssrcs, suspended_payload_states, config.rtp, /*...*/)) {  // 传入 config.rtp// ... 配置
    }
    
    • 分析:rtp_video_sender_ 持有 SSRC,用于 RTP 发送。

2.6 接口:RtpVideoSender::RtpVideoSender

  • 描述:创建 RtpStreamSenders,并调用 RtpRtcp::Configuration 设置 ssrc。
  • 调用关系:由 VideoSendStream 构造函数调用。
  • 输入:Config rtp_config(包含 rtp.ssrcs)。
  • 输出:无(构造函数)。
  • SSRC 设置逻辑:使用 rtp_config.ssrcs 设置 configuration.local_media_ssrc。
  • 核心代码分析
    RtpVideoSender::RtpVideoSender(/*...*/, const RtpConfig& rtp_config, /*...*/) : // ... 初始化rtp_streams_(CreateRtpStreamSenders(clock, rtp_config, /*...*/)) {  // 传入 rtp_config// ... 配置
    }
    
    • 分析:CreateRtpStreamSenders 遍历 rtp_config.ssrcs,创建 RtpRtcp 模块,每个模块的 configuration.local_media_ssrc = ssrc。

2.7 接口:CreateRtpStreamSenders (RtpVideoSender 内)

  • 描述:创建多个 RtpStreamSender,每个对应一个 SSRC。
  • 调用关系:由 RtpVideoSender 构造函数调用。
  • 输入:RtpConfig& rtp_config(包含 ssrcs)。
  • 输出:std::vector。
  • SSRC 设置逻辑:为每个 ssrc 创建 RtpRtcp 模块,设置 configuration.local_media_ssrc = ssrc。
  • 核心代码分析
    // 推断代码(基于片段)
    std::vector<RtpStreamSender> CreateRtpStreamSenders(/*...*/, const RtpConfig& rtp_config, /*...*/) {std::vector<RtpStreamSender> streams;for (uint32_t ssrc : rtp_config.ssrcs) {RtpRtcp::Configuration configuration;configuration.local_media_ssrc = ssrc;  // 设置本地 SSRC// ... 创建 RtpRtcp 模块streams.emplace_back(std::make_unique<RtpRtcp>(configuration), /*...*/);}return streams;
    }
    
    • 分析:这是最终设置点。SSRC 传入 RtpRtcp 模块,用于 RTP/RTCP 包头。

3. 总结

  • 问题:如果 SDP 无 SSRC/RIDs,GenerateSsrcs 使用 ssrc_generator_ 生成随机值,确保唯一。
  • 建议:在 SDP 协商中优先使用协商 SSRC;测试时检查 config.rtp.ssrcs 非零。
  • 参考:WebRTC 官方 SsrcGeneratorImpl 使用 rtc::CreateRandomNonZeroId() 生成。
http://www.dtcms.com/a/418637.html

相关文章:

  • 客户标签自动管理:标签自动化运营,画像持久保鲜
  • 云原生架构与GitOps技术栈介绍
  • 智能外呼产品架构组成
  • 【深度学习新浪潮】如何提升agent的专业性?
  • AI排名查询工具如何助力GEO优化?生成引擎优化中的关键词竞争力分析
  • 福州有网站建设的公司网站都需要什么类别
  • Nginx 反向代理与负载均衡核心内容总结
  • JavaWeb 课堂笔记 —— 20 SpringBootWeb案例 配置文件
  • 算法练习题
  • 9.数组介绍和静态初始化
  • 无重复字符的最长子串_优选算法(C++)滑动窗口
  • 提升雾化片性能,关键是精密测量盲孔尺寸
  • Flannel工作原理-Flannel故障案例-镜像拉取策略-secret对接harbor及ServiceAccount实战
  • GitLab高危漏洞可致实例崩溃(CVE-2025-10858 和 CVE-2025-8014)
  • 中铁建设投资集团有限公司网站自己公司怎样做免费的网站
  • 安卓13_ROM修改定制化-----修改rom 实现支持原生安装器 破除厂商定制限制
  • android 字符串工具类(兼容 Android 16+ / API 16,无报错版)
  • 9.28 深度学习10
  • 数据安全合规行业实战解析:金融、医疗与智能网联汽车的破局之道
  • 汽车全景天窗生产线解决方案 - SNK施努卡
  • 汽车地带AutoZone EDI需求分析及对接指南
  • 如何给自己网站做反链家在深圳罗湖
  • 云手机在电商行业中的优势都有哪些
  • 微信小程序入门学习教程,从入门到精通,微信小程序页面制作(2)
  • 漳州本地网站宝安网站开发
  • Pytest框架速成
  • C++设计模式之结构型模式:代理模式(Proxy)
  • 八股已死、场景当立(分布式ID篇)
  • C++指针笔试题1
  • 中英双语 网站 模板网站建设项目验收单