rfc3264: An Offer/Answer Model with the SDP

answer/offer

  • agent:一个 agent 是 offer/answer 交换中的一个协议实现。offer/answer 交换包括两种代理:offerer 和 answerer
  • offerer:会话一方,创建或者修改一个会话。发送的 SDP 消息包含了 offerer 希望使用的媒体流和编解码器的集合,以及 offerer 接收媒体流希望使用的地址和端口
  • offer:offerer 发送的 SDP 消息
  • answerer:会话的另一方参与者。answerer 为接收到的 offer 生成一个回复的 SDP 消息。消息对应 offer 每个流有一个媒体流,指出这个流是否被接收,以及使用的编解码器和 answerer 接收媒体流希望使用的地址和端口
  • answer:answerer 发送的用于回复 offer 的 SDP 消息

协议操作

  • 在任何时候,代理可以生成一个新的 offer 来更新会话。但是
    • answerer 不能在收到一个 offer 之后,回复或者拒绝之前生成一个新的 offer
    • offerer 不能发送一个 offer 之后,在收到回复或拒绝之前生成一个新的 offer
  • “glare”:一个代理在发送一个 offer 之后,还没有回复这个 offer 就收到一个新的 offer
    • 上层协议应该解决这种冲突

生成初始 offer

  • 忽视 e 和 p 字段
  • 没有 m 字段表示 offerer 希望通讯,但是通过后续的修改 offer 来增加会话的流信息
  • 单播流
    • sendonly:offerer 只想发送媒体流
    • inactive:offerer 希望通讯,但是不希望发送或接收媒体流
    • sendrecv:offerer 想发送和接收媒体流,这个是默认选项
    • recvonly:offerer 只想接收媒体流
    • RTCP 仍然会在 sendonly/inactive/recvonly 流中发送。媒体流的方向性不影响 RTCP 的使用
    • sendrecv/recvonly:offer 中的地址和端口表示 offerer 想要接收媒体流的信息
    • sendonly:offer 中的地址和端口表示 offerer 想要接收 RTCP 包的信息
      • 如果没有明确说明 RTCP 的地址和端口,RTCP 包将会发送到比指定的端口大 1 的端口
    • offer 中的地址和端口和 offerer 发送媒体流的地址和端口无关
    • offer 中的端口为 0 表示提供流但是不会使用流,比如回复中的端口为 0 表示拒绝流,或者设置端口为 0 终止已存在的流
    • 如果 SDP 中包含多个媒体格式(应当按照倾向顺序排列),表示 answerer 在会话中间可能会修改格式为媒体格式列表中的任一一个,同时不会发送一个新的 offer
    • 带宽为 0 不被建议,表示不应当发送任何媒体流,包括 RTP 的 RTCP 信息
    • offer 中不同类型的媒体流信息表示 offerer 同时希望使用的流;相同类型的媒体流信息表示 offerer 希望同时发送和/或接收指定类型的多个媒体流
  • 多播流
    • sendonly:只想发送媒体流
    • recvonly:只想接收媒体流

生成 answer

  • 对于 offer 中的每一个 “m=”,answer 中必须有对应的 “m=”。这便于基于顺序匹配流
  • answer 的 “t=” 必须和 offer 的相等
  • 如果拒绝一个流,可以将对应的流的端口设置为 0,其他的格式信息被忽略
  • 单播流
    • offer 的流为 sendonly,对应的流必须是 recvonly/sendrecv
    • offer 的流为 recvonly,对应的流必须是 sendonly/sendrecv
    • offer 的流为 sendrecv(没有的话默认为 sendrecv),对应的流必须是 sendonly/recvonly/sendrecv/inactive
    • offer 的流为 inactive,对应的流必须是 inactive
    • answer 中标记流为 recvonly,“m=” 中必须包含 offer 中至少一个媒体格式
    • answer 中标记流为 sendonly,“m=” 中必须包含 offer 中至少一个媒体格式
    • answer 中标记流为 sendrecv,“m=” 中必须包含 offer 中至少一个媒体格式
    • answer 中标记流为 inactive
    • offer 的流为 sendonly,媒体格式按照 recvonly 构造
    • offer 的流为 recvonly,媒体格式按照 sendonly 构造
    • offer 的流为 sendrecv,媒体格式按照 sendrecv 构造
    • offer 的流为 inactive,媒体格式按照 sendrecv 构造
    • 尽量按照 offer 的优先顺序排列媒体格式
    • 如果对于提供的媒体没有通用的媒体格式,answer 将设置端口为 0 来拒绝该媒体流
    • 如果对于所有的流都没有通用的格式,整个会话被拒绝
    • answerer 发送媒体流的格式应该是 offer 中最优先且在 answer 中列举的媒体格式。对于 RTP,即使和 answer 不同,也必须使用 offer 中指定的负载类型
  • 多播流
    • 多播 offer 的 answer 通常涉及修改一个流的某些方面
    • 如果接受多播流,answer 的地址和端口信息必须和 offer 中的对应,且流的方向信息必须和 offer 的一致
    • answer 中的媒体格式必须和 offer 中的相同或者是 offer 的一个子集。移除一个格式表示 answerer 不支持该格式
    • 如果 offer 中有 ptime 和带宽属性,answer 必须和其一样。否则,answer 可以添加一个非 0 的 ptime 属性

offerer 处理 answer

  • 如果 answer 是 sendrecv/recvonly,offerer 收到 answer 时可以发送媒体流
    • offerer 必须使用 answer 中列举的媒体格式发送,且应该(不是必须)使用 answer 中第一个媒体格式
    • offerer 应该根据 answer 中的 ptime 和带宽来发送媒体
    • offerer 可以立即停止监听 offer 中列举但是 answer 中未显示的媒体格式

修改会话

  • 在会话期间,任意一方可以发起一个新的 offer 来修改会话属性
  • 先前的 SDP:包括 offer 或 answer 中提供的 SDP
  • 新 offer 的 SDP 的 “o=” 必须和先前的 SDP 一样,版本号加 1
    • 新 offer 的 SDP 和先前的 SDP 一致的话,answerer 必须可以处理,可以返回和之前处理过程相同的 SDP
  • 新 offer 的 SDP 的媒体属性必须和之前的 SDP 的每个媒体对应,即 offer 中的媒体数目不会减少。之前的 SDP 删除的媒体流不能在新的 SDP 中移除,可以不显示流的属性
  • 添加一个媒体流
    • 可以复用之前拒绝的媒体流的位置,即端口设置为 0 的媒体
    • 在已有的媒体下面添加新的媒体描述
  • 移除一个媒体流
    • 将媒体所在位置的端口设置为 0,可以忽视之前的其他属性,只留下媒体格式
    • 可以释放与其相关的资源
  • 修改一个媒体流
    • 修改地址,端口或协议
    • offerer 一发送 offer,就必须为接收旧的和新的端口做准备。直到收到 answer 和媒体到达新的端口,offerer 才可以停止监听旧端口。此举避免在传送过程中丢掉媒体数据
    • answerer 对端口修改的处理和 offerer
    • 如果提供的流被拒绝,收到拒绝的时候就可以停止监听
    • 修改地址类比修改端口,不过更新的是连接,而不是端口
    • 修改协议和修改端口一样处理
    • 修改媒体格式集
    • 修改媒体类型:比起添加新媒体,建议修改媒体类型
    • 修改属性
  • 暂停一个单播流
    • 之前标记为 sendrecv 的流,应改成 sendonly
    • 之前标记为 recvonly 的流,应改成 inactive

表明能力

  • 代理构造一个用于表明媒体能力的 SDP
    • 必须是有效的,忽视 e 和 p 字段
    • 关于时间属性t= 0 0
    • 代理支持的每个媒体类型必须有对应的媒体描述
    • o 字段的会话 ID 必须是唯一的
    • 端口是 0(确保不会建立媒体流),连接地址是任意的
    • “m=” 的传输表明媒体类型的传输

相关