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); //从接口获取信息结构体 //信息存在rtsp://59.46.115.84:8554/h264/ch1/sub/av_stream RTSPRelaySession* clientSes = NULL; //首先查找Map里面是否已经有了对应的流 StrPtrLen streamName(theUriStr); OSRef* clientSesRef = sRelaySessionMap->Resolve(&streamName); if(clientSesRef != NULL) { clientSes = (RTSPRelaySession*)clientSesRef->GetObject(); } else { clientSes = NEW RTSPRelaySession("rtsp://*****:*****@192.168.66.189/", RTSPRelaySession::kRTSPTCPClientType, theUriStr); QTSS_Error theErr = clientSes->SendDescribe(); if(theErr == QTSS_NoErr) { OS_Error theErr = sRelaySessionMap->Register(clientSes->GetRef()); Assert(theErr == QTSS_NoErr); } else { clientSes->Signal(Task::kKillEvent); return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientNotFound, 0); } //增加一次对RelaySession的无效引用,后面会统一释放 OSRef* debug = sRelaySessionMap->Resolve(&streamName); Assert(debug == clientSes->GetRef()); } return QTSS_NoErr; }
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); //从接口获取信息结构体 //TODO: DeviceInfo* pDeviceInfo = parseDevice->GetDeviceInfoByIdName(theUriStr); if(pDeviceInfo == NULL) { qtss_printf("ID:%s Not Found\n",theUriStr); return QTSS_RequestFailed; } //信息存在rtsp://59.46.115.84:8554/h264/ch1/sub/av_stream RTSPRelaySession* clientSes = NULL; //首先查找Map里面是否已经有了对应的流 StrPtrLen streamName(theUriStr); OSRef* clientSesRef = sClientSessionMap->Resolve(&streamName); if(clientSesRef != NULL) { clientSes = (RTSPRelaySession*)clientSesRef->GetObject(); } else { clientSes = NEW RTSPRelaySession( 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); OS_Error theErr = clientSes->SendDescribe(); if(theErr == QTSS_NoErr) { OS_Error theErr = sClientSessionMap->Register(clientSes->GetRef()); Assert(theErr == QTSS_NoErr); } else { clientSes->Signal(Task::kKillEvent); return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientNotFound, 0); } //增加一次对RelaySession的无效引用,后面会统一释放 OSRef* debug = sClientSessionMap->Resolve(&streamName); Assert(debug == clientSes->GetRef()); } ReflectorSession* theSession = SetupProxySession(inParams, clientSes); if (theSession == NULL) { sClientSessionMap->Release(clientSes->GetRef()); return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssServerNotImplemented, 0); } QTSS_Error Err = QTSS_SetValue(inParams->inRTSPSession, sRTSPBroadcastSessionAttr, 0, &theSession, sizeof(theSession)); Assert(Err == QTSS_NoErr); clientSes->SetReflectorSession(theSession); theSession->SetRTSPRelaySession((void*)clientSes); sClientSessionMap->Release(clientSes->GetRef()); iovec theDescribeVec[3] = { {0 }}; Assert(theSession->GetLocalSDP()->Ptr != NULL); StrPtrLen theFileData; QTSS_TimeVal outModDate = 0; QTSS_TimeVal inModDate = -1; theFileData.Ptr = theSession->GetLocalSDP()->Ptr; theFileData.Len = theSession->GetLocalSDP()->Len; // -------------- process SDP to remove connection info and add track IDs, port info, and default c= line StrPtrLen theSDPData; SDPSourceInfo tempSDPSourceInfo(theFileData.Ptr, theFileData.Len); // will make a copy and delete in destructor theSDPData.Ptr = tempSDPSourceInfo.GetLocalSDP(&theSDPData.Len); // returns a new buffer with processed sdp OSCharArrayDeleter sdpDeleter(theSDPData.Ptr); // delete the temp sdp source info buffer returned by GetLocalSDP if (theSDPData.Len <= 0) // can't find it on disk or it failed to parse just use the one in the session. { theSDPData.Ptr = theSession->GetLocalSDP()->Ptr; // this sdp isn't ours it must not be deleted theSDPData.Len = theSession->GetLocalSDP()->Len; } // ------------ Clean up missing required SDP lines ResizeableStringFormatter editedSDP(NULL,0); DoDescribeAddRequiredSDPLines2(inParams, theSession, outModDate, &editedSDP, &theSDPData); StrPtrLen editedSDPSPL(editedSDP.GetBufPtr(),editedSDP.GetBytesWritten()); // ------------ Check the headers SDPContainer checkedSDPContainer; checkedSDPContainer.SetSDPBuffer( &editedSDPSPL ); if (!checkedSDPContainer.IsSDPBufferValid()) { return QTSSModuleUtils::SendErrorResponseWithMessage(inParams->inRTSPRequest, qtssUnsupportedMediaType, &sSDPNotValidMessage); } // ------------ Put SDP header lines in correct order Float32 adjustMediaBandwidthPercent = 1.0; Bool16 adjustMediaBandwidth = false; SDPLineSorter sortedSDP(&checkedSDPContainer,adjustMediaBandwidthPercent); // ------------ Write the SDP UInt32 sessLen = sortedSDP.GetSessionHeaders()->Len; UInt32 mediaLen = sortedSDP.GetMediaHeaders()->Len; theDescribeVec[1].iov_base = sortedSDP.GetSessionHeaders()->Ptr; theDescribeVec[1].iov_len = sortedSDP.GetSessionHeaders()->Len; theDescribeVec[2].iov_base = sortedSDP.GetMediaHeaders()->Ptr; theDescribeVec[2].iov_len = sortedSDP.GetMediaHeaders()->Len; (void)QTSS_AppendRTSPHeader(inParams->inRTSPRequest, qtssCacheControlHeader, kCacheControlHeader.Ptr, kCacheControlHeader.Len); QTSSModuleUtils::SendDescribeResponse(inParams->inRTSPRequest, inParams->inClientSession, &theDescribeVec[0], 3, sessLen + mediaLen ); return QTSS_NoErr; }