Darwin做直播时对ReflectorSession引用数的控制
来源:互联网 发布:python复制文件夹 编辑:程序博客网 时间:2024/06/05 01:51
在之前的博客中,我们提到了如何用Darwin&live555实现直播过程,那么更进一步,当直播结束时,我们需要关闭所有正在收看的客户端,并且delete转发会话ReflectorSession,这样才能够在下一次再有同样名称的流推送进来时,创建新的转发Session。
我们下面所做的修改都是基于Darwin 6.0.3进行,具体下载可到https://github.com/xiejiashu/EasyDarwin获取。我们首先来对原有的ReflectorSession控制进行分析:
首先对于推送端,主要经历DoAnnounce、DoSetup、DoPlay、ProcessRTPData四个流程,在DoAnnounce时,QTSSReflectorModule并不创建ReflectorSession,所以此步跳过;
在第一次DoSetup推送流程时,转发会话ReflectorSession还没有创建,所以必然会进入FindOrCreateSession函数中的
在此函数中,变量isPush为true,所以不会引用到
所以,对ReflectorSession的引用在执行第一次DoSetup推送的时候为 +0.并且此时,还会设置推送端RTPSession的sClientBroadcastSessionAttr属性
当第二次进入DoSetup推送流程时(如果有多个Track),同样进入到FindOrCreateSession时,ReflectorSession已经创建,所以直接 OSRef* theSessionRef = sSessionMap->Resolve(inPath);调用后,直接获取到第一次创建的ReflectorSession,引用数+1.
第N次调用DoSetup(有时候会有多个Track推送,如3D视频等),可以推算得到,引用数为 +(N-1).
在进入到DoPlay(QTSS_StandardRTSP_Params* inParams, ReflectorSession* inSession) 推送流程时,参数inSession为NULL,所以调用到过程
由上过程得知,DoPlay为ReflectorSession增加了一次引用,+1.ProcessRTPData()过程并未进行sSessionMap的Resolve过程,所以此函数也可以跳过。如此一来,可以统计得到,推送端全程对ReflectorSession的引用数目为:N-1 + 1 =N(N为媒体的Track数目,对应到ReflectorSession中,也就是ReflectorStream的数量)。
再来看客户端,客户端经历DoDescribe、DoSetup、DoPlay三个流程。
客户端进入DoDescribe流程时,假设ReflectorSession已经由推送端建立,如此一来,同样是在FindOrCreateSession中,增加了一次对ReflectorSession的引用,+1.
当客户端第一次进入到DoSetup流程时
同样,调用DoSessionSetup和FindOrCreateSession,会增加一次对ReflectorSession的引用,+1.当客户端第二次进入到DoSetup流程时,QTSS_GetValuePtr(inParams->inClientSession, sOutputAttr, 0, (void**)(void*)&theOutput, &theLen)函数已经能够获取到theOutput,直接进入
这样,并不会增加对ReflectorSession的引用,对后面客户端的第N次DoSetup流程调用,都不会增加对ReflectorSession的引用。当客户端进入DoPlay流程时,由于在DoPlay之前调用的ProcessRTSPRequest函数中
如此,在客户端流程中,一共对ReflectorSession引用了+2次,一次是在DoDescribe,一次是在DoSetup.
我们再分别看推送端和客户端离线时,对ReflectorSession的处理:
推送端,在我们之前的博客http://blog.csdn.net/xiejiashu/article/details/8065717,已经修改过,也就是,当推送端断开时,会调用到QTSSReflectorModule中的DestroySession函数
如果单就推送端而言,上面的方法足够了,因为我们在上面的分析中,得知,DoAnnounce、DoSetup、DoPlay、ProcessRTPData总共对ReflectorSession引用次数就是媒体Track的数目(ReflectorSession->GetNumStreams())。那么如果客户端也同样调用到RemoveOutput中来时,一路客户端是固定的2次引用ReflectorSession,只有当Track数目为2时(常见的音视频同时存在),正好达到收支平衡,如果只有视频进行推送的情况下,一路客户端会造成一次引用的堆积,做过测试的就会发现,每一次播放停止,都会对ReflectorSession的总引用数累积1个。如果有3路或者3路以上Track时,又会造成ReflectorSession被过早收回,当还有客户端在看的情况下,被动的关闭,导致错误的发生,那么我们如何来避免呢?
首先,我们对QTSSReflectorModule的DoDescribe函数进行修改,因为我们发现,当客户端进行DoDescribe创建ReflectorSession时,RTPSession并没有任何属性设置了ReflectorSession的指针,也就是说,客户端如果只获取一下媒体的sdp信息就回去了,ReflectorSession的引用岂不是一直都被白白占用着,如此,我们可以在DoDescribe函数的倒数第二行加入一句
如此一来,客户端在DoDescribe时不占用ReflectorSession引用数,DoSetup引用数在 RemoveOutput中被释放,推送端释放机制未改变,这样就完美解决了问题。
- Darwin做直播时对ReflectorSession引用数的控制
- Darwin做直播时对ReflectorSession引用数的控制
- darwin之发送数据流(ReflectorSession)
- 做视频直播时如何实现对观看直播的用户做登记?
- 用Darwin和live555实现的直播框架
- 基于Darwin实现的分布式流媒体直播服务器系统
- 用Darwin和live555实现的直播框架
- 用Darwin和live555实现的直播框架
- 基于Darwin实现的分布式流媒体直播服务器系统
- iOS的直播怎么做
- 做一款仿映客的直播
- 做教学直播时,如何做PPT课件直播?
- Java中引用类型vs值类型&对引用类型所做的GC操作简介
- java hibernate对数据库连接数访问的控制
- Java中对浮点数精度的控制
- 如何做电视节目的视频直播(电视台节目直播)
- 做移动视频直播应用的思路
- 在线教学直播中做ppt文档的在线直播(在线课常多画面直播)教程
- Android --- 简单实现三级缓存
- CMSIS-RTOS2 应用笔记 四 创建工程
- NBNS扫描工具nbtscan-unixwiz
- Socket抽象成信件的发送
- 干货分享!DevExpressv16.2最新版演示示例等你来收!(下)
- Darwin做直播时对ReflectorSession引用数的控制
- 控制台录音生成wav文件
- cocos 跳坑记录之Layer的锚点设置
- three.js加载obj模型 键盘控制模型局部动作
- Android学习--GeoQuiz项目
- 剑指offer 31. 连续子数组的最大和
- 浅析JS中的 map, filter, some, every, forEach, for in, for of 用法总结
- 使用AutoResetEvent信号实现生产者消费者队列
- TPLINK渗透