收藏 分销(赏)

Darwin在转发流过程中对推送端断开的处理问题 ..docx

上传人:xrp****65 文档编号:6865748 上传时间:2024-12-22 格式:DOCX 页数:4 大小:22.75KB 下载积分:10 金币
下载 相关 举报
Darwin在转发流过程中对推送端断开的处理问题 ..docx_第1页
第1页 / 共4页
Darwin在转发流过程中对推送端断开的处理问题 ..docx_第2页
第2页 / 共4页


点击查看更多>>
资源描述
    最近在做项目的过程中遇到一个问题,在用Darwin Streaming Server中的QTSSReflectorModule模块做为流转发和分发服务,用live555的DarwinInjector类做为模拟设备 进行流推送时,如果按照正常RTSP推送流程:Announce、Setup、Play…、Teardown,Darwin能较好地完成流的转发,但是假如设备在不正常工作,例如网络异常断开,设备断电等中断了数据流的推送,而缺少了<设备->服务器>的Teardown过程,这样与此路推送相关的RTSPSession、RTPSession以及ReflectorSession等都需要等到配置的“rtp_timeout”时间后、RTPSession超时才能析构所有相关转发对象。先分析下原因:       RTSPSession在创建RTPSession时 [cpp] view plaincopyprint? 1. // Set the current RTSP session for this RTP session.    2. // We do this here because we need to make sure the SessionMutex    3. // is grabbed while we do this. Only do this if the RTSP session    4. // is still alive, of course.    5. if (this->IsLiveSession())   6.     fRTPSession->UpdateRTSPSession(this);   // Set the current RTSP session for this RTP session. // We do this here because we need to make sure the SessionMutex // is grabbed while we do this. Only do this if the RTSP session // is still alive, of course. if (this->IsLiveSession()) fRTPSession->UpdateRTSPSession(this); [cpp] view plaincopyprint? 1. void RTPSessionInterface::UpdateRTSPSession(RTSPSessionInterface* inNewRTSPSession)   2. {      3.     if (inNewRTSPSession != fRTSPSession)   4.     {   5.         // If there was an old session, let it know that we are done    6.         if (fRTSPSession != NULL)   7.             fRTSPSession->DecrementObjectHolderCount();   8.            9.         // Increment this count to prevent the RTSP session from being deleted    10.         fRTSPSession = inNewRTSPSession;   11.         fRTSPSession->IncrementObjectHolderCount();   12.     }   13. }   void RTPSessionInterface::UpdateRTSPSession(RTSPSessionInterface* inNewRTSPSession) { if (inNewRTSPSession != fRTSPSession) { // If there was an old session, let it know that we are done if (fRTSPSession != NULL) fRTSPSession->DecrementObjectHolderCount(); // Increment this count to prevent the RTSP session from being deleted fRTSPSession = inNewRTSPSession; fRTSPSession->IncrementObjectHolderCount(); } } IncrementObjectHolderCount()增加了fRTPSession对RTSPSession的引用,而对应的DecrementObjectHolderCount()在RTPSession::Teardown()中执行,由于RTSPSession拥有很好的对象保护机制,只有当对当前RTSPSession的引用数为0时 [cpp] view plaincopyprint? 1. // Only delete if it is ok to delete!    2. if (fObjectHolders == 0)   3.     return -1;   // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; RTSPSession自身才能调用Task::Run(){return -1;} delete,所以在RTSPSession注销之前,必须等待RTPSession注销,而且RTPSession没有等到Teardown命令,就只能等超时,而这个超时时间不能定,及时几秒钟对于转发实时流来说也是不合理的。 解决办法: 在RTSPSession:Run()函数中的 [cpp] view plaincopyprint? 1. while(IsLiveSession())   2. {   3.       switch(){case:}   4. }   while(IsLiveSession()) { switch(){case:} } 状态机外加入代码及时析构RTPSession [cpp] view plaincopyprint? 1. // Make absolutely sure there are no resources being occupied by the session    2. // at this point.    3. this->CleanupRequest();   4.    5.    6. //Kill与RTSPSession相关的RTPSession    7. if(!IsLiveSession()){   8. OSRefTable* theMap = QTSServerInterface::GetServer()->GetRTPSessionMap();   9. OSRef* theRef = theMap->Resolve(&fLastRTPSessionIDPtr);   10. if (theRef != NULL){   11.     fRTPSession = (RTPSession*)theRef->GetObject();   12.     if(fRTPSession) fRTPSession->Teardown();   13.     theMap->Release(fRTPSession->GetRef());   14.     fRTPSession = NULL;   15.     }    16. }      17. // Only delete if it is ok to delete!        18. if (fObjectHolders == 0)        return -1;      19. // If we are here because of a timeout, but we can't delete because someone        20. // is holding onto a reference to this session, just reschedule the timeout.       21. // At this point, however, the session is DEAD.       22. return 0;   // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); //Kill与RTSPSession相关的RTPSession if(!IsLiveSession()){ OSRefTable* theMap = QTSServerInterface::GetServer()->GetRTPSessionMap(); OSRef* theRef = theMap->Resolve(&fLastRTPSessionIDPtr); if (theRef != NULL){ fRTPSession = (RTPSession*)theRef->GetObject(); if(fRTPSession) fRTPSession->Teardown(); theMap->Release(fRTPSession->GetRef()); fRTPSession = NULL; } } // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // At this point, however, the session is DEAD. return 0; 注意 this->CleanupRequest();在前, 这样就能在RTSPSession判断fObjectHolders之前将附属的RTPSession析构,进而析构RTSPSession. 由于工作比较忙,写的可能在思路上不是很清楚,欢迎指正! /--------------------------------------割了------------------------------------/ 在上段代码中可以加入一个补充条件进行代码的优化,并且CleanupRequest()必须在此之后! [cpp] view plaincopyprint? 1. //fObjectHolders--      2. if(!IsLiveSession()&& fObjectHolders > 0){     3. OSRefTable* theMap = QTSServerInterface::GetServer()->GetRTPSessionMap();     4. OSRef* theRef = theMap->Resolve(&fLastRTPSessionIDPtr);     5. if (theRef != NULL){     6.     fRTPSession = (RTPSession*)theRef->GetObject();     7.     if(fRTPSession) fRTPSession->Teardown();     8.     theMap->Release(fRTPSession->GetRef());     9.     fRTPSession = NULL;     10.     }      11. }       12.    13.    // Make absolutely sure there are no resources being occupied by the session    14.    // at this point.    15.    this->CleanupRequest();   16.    17.    // Only delete if it is ok to delete!    18.    if (fObjectHolders == 0)   19.        return -1;  
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 环境建筑 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服