RTSP服务器开发二:关键帧提取技术

1. 前情提要

这篇文章中,我着重阐述了,如何使用GO语言,从零开发一个RTSP服务器。今天,我们继续对它进行改造。

2. 关键帧

通俗来讲,播放端在开始播放时,会持续不断接受到视频帧,但是只有关键帧到来时,它才会出画面,也就是说,关键帧什么时候到来,决定了什么时候出现画面。那么,既然RTSP服务器是我们手写的,能不能服务器提前缓存好最后一个关键帧,当播放端连接时,立马把缓存的最后一个关键帧发送给播放端。

实测证明,这样做是可行的,点击播放按钮的下一刻,画面就出来了,完全不需要任何等待。

3. RTSP中的RTP协议

我翻阅了大量资料,终于找到了RTSP一个完整的数据包中,如何解析出来关键帧,首先看下面一段报文:

00000348  24 01 00 1c 80 c8 00 06  17 dc a1 1a e4 12 6a 05   $....... ......j.
00000358  50 a3 d7 0a 65 d0 0c a5  00 00 00 00 00 00 00 00   P...e... ........

00000368  24 00 05 c0 80 60 08 ae  65 cf b5 76 17 dc a1 1a   $....`.. e..v....
00000378  7c 81 e0 08 af b9 d6 bf  a1 63 79 bc 16 a8 3a b8   |....... .cy...:.
00000388  86 a6 16 0b f2 2b f8 f3  f3 83 c9 cb de 06 d3 46   .....+.. .......F
00000398  a4 23 08 37 d9 16 dd 1f  ae eb 73 bb 69 e6 e6 a6   .#.7.... ..s.i...
000003A8  e5 b8 62 64 5e 83 81 eb  85 32 be c6 26 38 44 83   ..bd^... .2..&8D.
000003B8  c3 91 53 a6 5d e5 23 26  29 f5 06 a8 3e b6 54 21   ..S.].#& )...>.T!
000003C8  86 fa 16 59 5d 5e 34 c3  2a 1b 09 09 d7 75 25 d8   ...Y]^4. *....u%.

上面的报文是RTSP推流端发给RTSP服务器的,很显然,它是RTSP包装的RTP报文

在RTSP协议中,关于对这个包装,是如下描述的:

第一个字节是0X24,这是固定不变的,第二个字节是0x00或者0x01,第三和第四个字节是RTP报文的长度,从第五个字节开始,就是RTP报文。

当第二个字节是0x01时,第五个字节往后是RTCP报文。

当第二个字节是0x00时,第五个字节往后是RTP报文。

很显然,在报文中,从 第三行开始才是RTP报文,第一行和第二行都是RTCP报文。

也就是说,RTP报文是如下开始的:

00000368  24 00 05 c0 80 60 08 ae  65 cf b5 76 17 dc a1 1a   $....`.. e..v....
00000378  7c 81 e0 08 af b9 d6 bf  a1 63 79 bc 16 a8 3a b8   |....... .cy...:.
00000388  86 a6 16 0b f2 2b f8 f3  f3 83 c9 cb de 06 d3 46   .....+.. .......F
00000398  a4 23 08 37 d9 16 dd 1f  ae eb 73 bb 69 e6 e6 a6   .#.7.... ..s.i...
000003A8  e5 b8 62 64 5e 83 81 eb  85 32 be c6 26 38 44 83   ..bd^... .2..&8D.
000003B8  c3 91 53 a6 5d e5 23 26  29 f5 06 a8 3e b6 54 21   ..S.].#& )...>.T!
000003C8  86 fa 16 59 5d 5e 34 c3  2a 1b 09 09 d7 75 25 d8   ...Y]^4. *....u%.

 

从第五个字节0x80开始,就是正经的RTP报文,RTP报文头是这样的:

0X80 拆解成二进制是:1000 0000

我们从左往右看:第一位和第二位,是 1 0,也就是V,代表RTSP版本号,好像是固定的2

第三位和第四位,分别是P和X。

第五位到第八位,是0000,也就是0,这代表着CSRC数量是0。

也就是说,这段RTP报文,头部长12个字节。

PT:也就是 0X60,也就是96,意味着,RTP中的视频编码协议是H264。,也就是说,从第十三个字节开始,是H264编码方案。

H264报文如下:

00000378  7c 81 e0 08 af b9 d6 bf  a1 63 79 bc 16 a8 3a b8   |....... .cy...:.
00000388  86 a6 16 0b f2 2b f8 f3  f3 83 c9 cb de 06 d3 46   .....+.. .......F
00000398  a4 23 08 37 d9 16 dd 1f  ae eb 73 bb 69 e6 e6 a6   .#.7.... ..s.i...
000003A8  e5 b8 62 64 5e 83 81 eb  85 32 be c6 26 38 44 83   ..bd^... .2..&8D.
000003B8  c3 91 53 a6 5d e5 23 26  29 f5 06 a8 3e b6 54 21   ..S.].#& )...>.T!
000003C8  86 fa 16 59 5d 5e 34 c3  2a 1b 09 09 d7 75 25 d8   ...Y]^4. *....u%.

H264协议就不贴了,我们这里只分析前两个字节,也就是7c和81

7c (0111 1100)  ,从左往右开始数:

F:第一位,0必须是0

NRI:11   ,第二和第三位,

Type:28(0001 1100)代表这是FU-A的分组方案

 


        81  :100 0 0001,从左向右看
                S  第1位,1代表 NAL载荷开始
                E  第2位,1代表NAL载荷的结束
                R  第3位,必须位0
                Type 剩余5位,表示这是什么类型的帧,注意如果是0 0101,就是关键帧。

 

也就是说,对于H264编码来说,7c 85,就意味着一个新的关键帧已经开始了,就需要开始缓存了。

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值