darwin之数据包管理

1.如何管理数据包?

在darwin中,包含了两种类型的包:rtp和rtcp,他们都是通过ReflectorPacket类来管理的 。

ReflectorPacket对象管理一个数据包,该数据包在堆栈中分配 ,大小为2060字节,所有的rtp,rtcp数据包最大大小都不能超过这个值。



2.如何管理数据包的?

ReflectorSocket负责分配数据包 ,回收垃圾数据包。ReflectorSender负责使用数据包,数据来源是从ReflectorSocekt分配的,使用完之后还给ReflectorSocket。

ReflectorSocket负责分配数据包,并管理垃圾数据包。

所有的数据包都是在堆中分配的,由ReflectorSocket分配数据包,通过OSQueue fFreeQueue来管理所有的垃圾数据包 。

当需要获取数据包时,调用ReflectorSocket::GetPacket获取,其内部首先会从fFreeQueue从获取,如果fFreeQueue没有,则new 一个 。

使用完的数据包时 ,通过ReflectorSocket::fFreeQueue将其归还。




ReflectorSender负责,接收新数据,维护等待发送的数据包。

数据包的来源是从ReflectorSocket::GetPacket拿到的 ,用完之后归还到 ReflectorSocket::fFreeQueue中 :数据包发送完之后就变成了垃圾数据包。



数据包的释放

数据包由 ReflectorSocket::GetPacket来分配,那么何时释放呢?

在析构函数中释放 ,只有当整个对象不再使用的时候,才会释放。

例如:如果在1s中客户端发送了1万个包到darwin,那么就要在堆上分配10000个包,运行过程中永远不会释放,直到整个对象析构时才会释放 。

可以看到 ,ReflectorSocekt释放fFreeQueue队列中的数据包 ,ReflectorSender释放fPacketQueue队列中的数据包。


3.如何读取客户端推送的数据包?

在RTSPSession::Run函数中,通过RTSPRequestStream::ReadRequest不停的读取数据包(读取rtsp协议命令不再此研究):

1..如果ReadRequest返回 QTSS_RequestArrived:读取一个数据包成功(此时状态为kReadingRequest)。经过一系列状态机改变后,会调用HandleIncomingDataPacket将数据包放到队列中,最终进入kCleaningUp状态,在此改变状态为kReadingRequest,如此循环反复(在run函数中多次调用HandleIncomingDataPacket).

2.如果ReadRequest返回 QTSS_NoErr:表示网络网络缓冲区中已经没有数据可以读了(不够一个完整的rtp包),退出run函数,返回值0,退出前再次请求RequestEvent。

3.其他情况,可能是客户端退出了,见后面分析。

ps:Run函数并不是只读取一个rtp包就退出,而是将网络缓冲区中所有的rtp包都读完才返回,因此在此过程中,HandleIncomingDataPacket函数一定不要做费时间的工作,否则taskthread将直接卡主,影响后面的任务执行。



4.如何检测rtsp推流客户端的退出?

当客户端断开时, fInputStream.ReadRequest()会返回异常,Run中的while循环会退出,回调用fRTPSession->Teardown()函数,进而会在RTPSession::Run函数中调用所有模块的kClientSessionClosingRole角色,在模块中释放资源。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaopengsun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值