国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

live555學習筆記16-幾個重要對象的生命期

2019-11-08 03:17:59
字體:
供稿:網(wǎng)友
十六 幾個重要對象的生命期live555中很多類,類與類之間的關系復雜,從屬關系不明顯,層次上看起來也有些亂.所以源代碼讀起來比較困難,對于一些對象生命的來龍去脈也很難厘清.但這并不能說明live555的架構不好,最適合的才是最好的,對于流媒體的處理來說,live555架構已是相當精巧,當然,這是在你深入了解它的基礎上才會有的體會.live555作為服務器,大家都很關心對內(nèi)存的利用效率,是否過多的吃內(nèi)存?是否造成太多的內(nèi)存碎片?我個人認為不必太擔心這方面的事,live555對于內(nèi)存的使用效率還是比較高的,當然要求太高的可能要自己實現(xiàn)內(nèi)存池之類的東西.然而,我在使用它的過程中,還是發(fā)現(xiàn)了一點小小的問題,這個問題只在某些情況下起作用.在此不對內(nèi)存管理做全面的闡述,只是探討一下live555中一些重要類的對象實體是怎樣被銷毀的,同時說明那點小問題.首先說創(chuàng)世者:是RTSPServer:它需永存,其余對象都是由它創(chuàng)建或由它引起了它們的創(chuàng)建.RTSPServer直接掌管的是ServerMediasession和RTSPClientSession(只主其生,不掌其死).ServerMediaSession對應一個媒體文件,而RTSPClientSession對應一個RTSP客戶連接.RTSPClientSession在客戶發(fā)出RTSP的TCP連接時建立,而ServerMediaSession在客戶發(fā)出對一個新文件的DESCRIBE時建立.建立ServerMediaSession的同時也建立了ServerMediaSubsession們,被ServerMediaSession所管理,代表一個文件中的track們.ServerMediaSession的建立規(guī)則值得一說:RTSPClientSession在收到客戶的DESCRIBE請求時,跟據(jù)地址中的媒體名字,去查找ServerMediaSession的列表,如果已有對應此媒體名字的ServerMediaSession,則利用它獲取SDP信息.如果沒找到,則跟據(jù)媒體名字中的擴展名部分,建立對應此類媒體的新ServerMediaSession對象.所以可以明確一點:一個ServerMediaSubsession對應一個文件!但是,如果測試,你會發(fā)現(xiàn)當一個文件播放完畢之后,并沒有刪除對應的ServerMediaSession.同時,與ServerMediaSubsession相關的那一坨東西(Demux和ServerMediaSubsession)也沒有被銷毀.但是它們終究還是要面臨死亡的.什么時候死呢?RTSPServer銷毀的什候(或?qū)奈募淮嬖诹藭r)!哦,看到問題了吧?如果你做點播服務器,每打開一個文件就會創(chuàng)建一個ServerMediaSession以及相關的一坨東西們,如果文件太多,內(nèi)存終究有用完的時候.再說一下RTSPClientSession,RTSPClientSession有兩種結束生命的方式,一是在對應流(StreamState)接收不到RTCP數(shù)據(jù)了,還記得前面講過RTCPInstance的setSpecificRRHandler()嗎?RTSPClientSession就是通過它來監(jiān)視客戶端的心跳的.二種方式是收到客戶端的TEARDOWN請求時自殺.RTSPClientSession自殺的同時會把流對象StreamState以及流上的Source和sink全干掉.所以說,除了RTSPClientSession那一坨之外,其余的對象還是可以在適當?shù)臅r候銷毀的.基本上是代表靜態(tài)數(shù)據(jù)的對象不銷毀,而代表動態(tài)數(shù)據(jù)的對象銷毀.如果你做的是實時流媒體,那么這正是所需要的.而做點播服務呢?總不能文件關了,代表文件的對象還在內(nèi)存中吧?那我們?nèi)绾稳ジ哪兀科鋵嵑芎唵危覀冎灰跊]有任何對ServerMediaSession的引用時把它刪除不就行了.而且ServerMediaSession中已經(jīng)實現(xiàn)了引用計數(shù),見如下三個函數(shù):[cpp] view plaincopyunsigned referenceCount() const  {      return fReferenceCount;  }  void incrementReferenceCount()  {      ++fReferenceCount;  }  void decrementReferenceCount()  {      if (fReferenceCount > 0)          --fReferenceCount;  }  [cpp] view plain copyunsigned referenceCount() const  {      return fReferenceCount;  }  void incrementReferenceCount()  {      ++fReferenceCount;  }  void decrementReferenceCount()  {      if (fReferenceCount > 0)          --fReferenceCount;  }  現(xiàn)在的問題是何時減少這個引用計數(shù).可以想象,基本情況是在建立一個新的StreamState時或建立RTSPClientSession時,ServerMediaSession的引用就會增加1.那么理應在RTSPClientSession關閉時減去1.我們看看源碼,是否是這樣做了?經(jīng)查找,是在建立新的StreamState時.在函數(shù)void RTSPServer::RTSPClientSession::handleCmd_SETUP(char const* cseq,char const* urlPReSuffix, char const* urlSuffix,char const* fullRequestStr)中可以看到.再找一下減少引用的代碼:[cpp] view plaincopyRTSPServer::RTSPClientSession::~RTSPClientSession()  {      closeSockets();          if (fSessionCookie != NULL)      {          // We were being used for RTSP-over-HTTP tunneling.  Remove ourselves from the 'session cookie' hash table before we go:           fOurServer.fClientSessionsForHTTPTunneling->Remove(fSessionCookie);          delete[] fSessionCookie;      }          reclaimStreamStates();          if (fOurServerMediaSession != NULL)      {          fOurServerMediaSession->decrementReferenceCount();          if (fOurServerMediaSession->referenceCount() == 0                  && fOurServerMediaSession->deleteWhenUnreferenced())          {              fOurServer.removeServerMediaSession(fOurServerMediaSession);              fOurServerMediaSession = NULL;          }      }  }  [cpp] view plain copyRTSPServer::RTSPClientSession::~RTSPClientSession()  {      closeSockets();          if (fSessionCookie != NULL)      {          // We were being used for RTSP-over-HTTP tunneling.  Remove ourselves from the 'session cookie' hash table before we go:          fOurServer.fClientSessionsForHTTPTunneling->Remove(fSessionCookie);          delete[] fSessionCookie;      }          reclaimStreamStates();          if (fOurServerMediaSession != NULL)      {          fOurServerMediaSession->decrementReferenceCount();          if (fOurServerMediaSession->referenceCount() == 0                  && fOurServerMediaSession->deleteWhenUnreferenced())          {              fOurServer.removeServerMediaSession(fOurServerMediaSession);              fOurServerMediaSession = NULL;          }      }  }  是在RTSPClientSession銷毀時減少引用.同時我們還看到[cpp] view plaincopyif (fOurServerMediaSession->referenceCount() == 0          && fOurServerMediaSession->deleteWhenUnreferenced())  {      fOurServer.removeServerMediaSession(fOurServerMediaSession);      fOurServerMediaSession = NULL;  }  [cpp] view plain copyif (fOurServerMediaSession->referenceCount() == 0          && fOurServerMediaSession->deleteWhenUnreferenced())  {      fOurServer.removeServerMediaSession(fOurServerMediaSession);      fOurServerMediaSession = NULL;  }  這樣的語句,翻譯過來就是:當引用為0并且可以在引用為0時刪除,那么就刪除它!原來在這里!我們只要讓他deleteWhenUnreferenced()能返回True就解決上面所說的那個小問題了.等等,似乎還有問題,ServerMediaSession是RTSPClientSession在建立StreamState時增加引用,而在RTSPClientSession銷毀時減少引用,如果有多個Track,StreamState是要被創(chuàng)建多次的?好像引用增加與減少對不起來啊!真的是這樣嗎?我沒測試我不敢說,嘿嘿,那就先留個懸念吧.
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 靖宇县| 安徽省| 斗六市| 汤原县| 垣曲县| 多伦县| 台州市| 松江区| 泾阳县| 开化县| 平湖市| 罗江县| 明水县| 瑞丽市| 宜宾县| 吴桥县| 贵南县| 泗水县| 青冈县| 平湖市| 桦南县| 万州区| 洪雅县| 视频| 丹阳市| 巴林左旗| 嘉祥县| 喜德县| 黄山市| 虎林市| 措美县| 柏乡县| 砀山县| 华容县| 华宁县| 临澧县| 凯里市| 东山县| 酒泉市| 沧州市| 奉新县|