一个RTP会话中多个H.264视频流

11
我想在流媒体视频应用中动态切换视频源。但是,不同的视频源具有独特的图像尺寸。我可以为每个视频源生成单独的SDP文件,但我希望将它们合并到一个单独的SDP文件中,以便查看客户端在视频源更改时自动调整显示窗口大小。以下是两个示例SDP文件:
640x480.sdp:
v = 0 o = VideoServer 305419896 9876543210 IN IP4 192.168.0.2 s = VideoStream640x480 t = 0 0 c = IN IP4 192.168.0.2 m = video 8000/2 RTP/AVP 96 a = rtpmap:96 H264/90000 a = fmtp:96 packetization-mode = 0; profile-level-id = 4D4033; sprop-parameter-sets = Z01AM5ZkBQHtCAAAAwAIAAADAYR4wZU =, aO48gJ == a = control:trackID = 1
960x480.sdp:
v = 0 o = VideoServer 305419896 9876543210 IN IP4 192.168.0.2 s = VideoStream960x480 t = 0 0 c = IN IP4 192.168.0.2 m = video 8000/2 RTP/AVP 96 a = rtpmap:96 H264/90000 a = fmtp:96 packetization-mode = 0; profile-level-id = 4D4033; sprop-parameter-sets = J01AM5WwPA9sBAIA, KO4G8gA = a = control:trackID = 1
如何将这些单独的文件合并成一个SDP文件?
4个回答

9
你两个sdp示例中的参数非常接近,流名称和sprop-parameter-sets不同。我假设你不在意流名称。如果您需要单独的sprop-parameter-sets,并且客户端支持标准,则可以为每个分辨率使用单独的动态有效载荷类型,并具有以下单个SDP:
    v = 0
    o = VideoServer 305419896 9876543210 IN IP4 192.168.0.2
    s = VideoStream640x480
    t = 0 0
    c = IN IP4 192.168.0.2
    m = video 8000/2 RTP / AVP 96 97
    a = rtpmap:96 H264 / 90000
    a = fmtp:96 packetization-mode = 0; profile-level-id = 4D4033; sprop-parameter-sets = Z01AM5ZkBQHtCAAAAwAIAAADAYR4wZU =,aO48gJ==
    a = rtpmap:97 H264 / 90000
    a = fmtp:97 packetization-mode = 0; profile-level-id = 4D4033; sprop-parameter-sets = J01AM5WwPA9sBAIA,KO4G8gA =
    a = control:trackID = 1
与其他答案类似,如果您实际上不需要不同的流名称或不同的sprop-parameter-sets,则应该能够使用您的第一个SDP并在流中间切换格式。我不知道H.264的实际负载或您特定的解码器是否足够了解,以确保这将在您的应用程序中工作,但在视频会议应用程序中允许动态切换分辨率而不需要信令更改或要求单独的动态有效载荷类型是非常常见的。
尽管您可以像另一个答案中提到的那样连接两个SDP文档,但我认为这在这种情况下不会有所帮助。我认为H.264解码器一次只能处理单个sprop-parameter-sets参数。由于两个SDP都具有相同的负载类型、源端口等,接收方将不知道何时使用哪个sprop-parameter-sets参数。更新:请注意,某些实现会从SDP中获取其sprops(或仅最初从SDP中获取)。如果在您的环境中适用,则可以通过inband更新SDP sprop-parameter-sets
参考资料:
  1. RFC 3984 RTP H.264视频负载格式
  2. 新的建议的H.264 RTP负载格式RFC 6184
  3. RFC 4566 SDP:会话描述协议

【抱歉没有给出完整的引用-请随意更正】


我还会放弃sprop-parameter-sets,并将它们嵌入视频流中,只有一条视频媒体线路。所有h264编码器都会将它们嵌入到流中。然后,如果您希望客户端控制发送的视频大小并实时切换摄像头,则需要某种反向通道。客户端可以“检测”分辨率何时发生变化,并更改其显示大小。这对我来说很有效。唯一的问题是,如果您的尺寸(比特率)大于指定的配置级别,则需要更新SDP参数(他们在5.1中使用的可能性不大)。 - Shane Powell

2
我已经阅读了RFC(RFC2327 - SDP:会话描述协议),看起来您只需将两个SDP文档连接起来即可。该文档明确指出:

当通过SAP传输SDP时,每个数据包只允许一个会话描述。当通过其他方式传输SDP时,可以将多个SDP会话描述连接在一起(“v =”行表示会话描述的开始,终止前一个描述)。


0

你可以通过动态负载更改或流内参数设置更改,或SIP重新邀请来实现。

负载更改的问题在于,如果你无法控制编码器和解码器,你需要确保另一端接受两种负载,并且它们将正确地切换负载(并且足够快 - 没有要求)。

流内更改的问题在于,如果参数集数据包丢失,你可以使用不同的参数集(在更改时从参数集1切换到2)以避免错误解码 - 如果参数集丢失,你应该只会得到一个冻结或空白的画面。我建议多次重传它们(不要太快)。

SIP重新邀请是带外握手的,因此安全,但会增加任何切换的延迟,并且可能会出现故障,具体取决于接收方,并且可能会被拒绝。

(注意:我是RFC 3984bis的作者,这是RFC 3984的更新版本)


0

我认为这取决于您的解码器。如果它支持流内参数更改,那么如果您可以告诉编码器在更改分辨率时放置相应的标头,您的解码器应该会自动切换。

您的问题到底是什么? 是:如何在不停止/重新启动流的情况下更改分辨率?

我不认为您可以事先告诉解码器,以下是一些 SDP 魔法中可能遇到的分辨率。要么您的解码器能够理解 H264 参数更改,那么您就没问题了,要么您必须停止重新启动整个流程,然后动态 SDP 就足够了。

例如,我知道 VLC 能够检测 MP4 编码更改(例如从可变比特率到恒定比特率),但更改分辨率将导致崩溃。您可以使用 sdp 做的唯一一件事就是组合不同的媒体描述,例如使用不同的动态负载类型和不同的控制 ID 属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接