用Darwin開發RTSP級聯伺服器(拉模式轉發)(附原始碼)
阿新 • • 發佈:2018-12-30
QTSS_Error DoDescribe(QTSS_StandardRTSP_Params* inParams) { char* theUriStr = NULL; QTSS_Error err = QTSS_GetValueAsString(inParams->inRTSPRequest, qtssRTSPReqFileName, 0, &theUriStr); Assert(err == QTSS_NoErr); if(err != QTSS_NoErr) return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientBadRequest, 0); QTSSCharArrayDeleter theUriStrDeleter(theUriStr); // 查詢配置表,獲取攝像機資訊結構體 DeviceInfo* pDeviceInfo = parseDevice->GetDeviceInfoByIdName(theUriStr); if(pDeviceInfo == NULL) { // 對映表中沒有查到相關資訊,返回,RTSP請求交給其他模組處理 return QTSS_RequestFailed; } // 對映資訊存在rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp RTSPClientSession* clientSes = NULL; // 首先查詢RTSPClientSession Hash表是否已經建立了對應攝像機的RTSPClientSession StrPtrLen streamName(theUriStr); OSRef* clientSesRef = sClientSessionMap->Resolve(&streamName); if(clientSesRef != NULL) { clientSes = (RTSPClientSession*)clientSesRef->GetObject(); } else { // 初次建立伺服器與攝像機間的互動RTSPClientSession clientSes = NEW RTSPClientSession( SocketUtils::ConvertStringToAddr(pDeviceInfo->m_szIP), pDeviceInfo->m_nPort, pDeviceInfo->m_szSourceUrl, 1, rtcpInterval, 0, theReadInterval, sockRcvBuf, speed, packetPlayHeader, overbufferwindowInK, sendOptions, pDeviceInfo->m_szUser, pDeviceInfo->m_szPassword, theUriStr); // 向攝像機源端傳送Describe請求 OS_Error theErr = clientSes->SendDescribe(); if(theErr == QTSS_NoErr){ // 將成功建立的RTSPClientSession註冊到sClientSessionMap表中 OS_Error theErr = sClientSessionMap->Register(clientSes->GetRef()); Assert(theErr == QTSS_NoErr); } else{ clientSes->Signal(Task::kKillEvent); return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientNotFound, 0); } //增加一次對RTSPClientSession的無效引用,後面會統一釋放 OSRef* debug = sClientSessionMap->Resolve(&streamName); Assert(debug == clientSes->GetRef()); } // 建立轉發所用的ReflectorSession,後續流程與QTSSReflectorModule類似 ReflectorSession* theSession = SetupProxySession(inParams, clientSes); if (theSession == NULL) { sClientSessionMap->Release(clientSes->GetRef()); return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssServerNotImplemented, 0); } }
這裡我們用到了兩個Hash Map,一個是儲存RTSPClientSession的sClientSessionMap、一個儲存ReflectorSession的sSessionMap。