darwin之流处理(ReflectorStream)
负责一路流的处理:如果一个rtsp流有音视频2路流,那么每一路都需要一个ReflectorStream(在ReflectorSession通过SDPSourceInfo创建)。
ReflectorStream能接收数据,能发送数据,能管理客户端列表。
ReflectorStream通过UDPSocketPair* fSockets来接收rtp,rtcp包,通过ReflectorSender来发送rtp,rtcp数据包,
通过Bucket* fOutputArray维护所有的rtp发送客户端。
2.ReflectorStream负责维护所有rtp客户端。
对一路流的转发:因为同时可能有多个客户端请求这路流,通过一个二维数组(Bucket*fOutputArray)来管理所有的客户端。每一个客户端代表一个ReflectorOutput对象。
3.rtp客户端(RtpSessionOutput)何时被添加到ReflectorStream?
在rtsp客户端发送setup时,进行处理。ReflectorSession::AddOutput在客户端发送多次setup时,只会被处理一次。
因此AddOutput需要把所有的RelectStream都加入RtpSessionOutput。
4.ReflectorStream如何维护所有客户端(RTPSessionOutput) ?
通过二维数组以水桶的方式来维护所有RTP客户端
初始化的时候维护了一个16*16的二维数组,在分配客户端时调用AddOutput从头查找空缺位置占用即可。
5.RTPSessionOutput作用 ?
因为RTPSessionOutput内部维护了RTPSession的指针,所以能够实现发送rtp流到客户端的功能 。
6.ReflectorStream通过水桶来维护rtp客户端,那么如何维护数据流源的呢?
拿到数据流源是进行reflector的前提 。
因ReflectorStream只管理rtsp流中的一路流,而实际上每一路流又包含了rtp和rtcp两种类型的数据包,
因此通过UDPSocketPair* fSockets来管理rtp和rtcp两种类型数据。
通过UDPSocketPair的fSocketA来管理rtp包 ,fSocketB来管里rtcp包 。
UDPSocketPair实质上是维护UDP的数据源包,而针对rtsp客户端推送上去的tcp数据包,如何处理呢?
仍然是用UDPSocketPair,ReflectorStream::PushPacket来接收推送来的rtp,rtcp数据包 ,将不同的数据包 分别存储到UDPSocketPair::fSocketA和 UDPSocketPair::fSocketB中 ,存储的方式为 : ReflectorSocket::ProcessPacket。
7.ReflectorStream如何将输入的数据关联到ReflectOutput,进而发送给客户端呢?
在ReflectorStream中通过UDPSocketPair接收数据流,通过ReflectorSender将其发送出去(内部会遍历所有客户端 ,依次发送)。
在BindSockets函数中,将ReflectSocket与 ReflectorSender关联 。
ReflectorSender内部维护OSQueue fPacketQueue队列,用来存放待发送的数据包 。
在ProcessPacket函数中,将 ReflectSocket接收到的数据放到ReflectorSender队列fPacketQueue中 。
通过调用ReflectorSender::ReflectPackets方法 将队列中的一个数据包发送到rtp客户端 。
ReflectPackets何时被调用?
ReflectorSocket可以关联一组ReflectorSender。
在其接收到数据后,放到OSQueue fPacketQueue队列中。在run函数中被调用。
run中会遍历所有ReflectorSender,调用ReflectPackets发送数据。