📄 rtspclnt.cpp
字号:
HX_DELETE(pHeader); return HXR_OUTOFMEMORY; } pTrans->AddRef(); if (m_bPrefetch) { pTrans->EnterPrefetch(); } if (HXR_OK != ((RTPTCPTransport*)pTrans)->init( m_pContext, m_pSocket, (IHXRTSPTransportResponse*)this)) { status = HXR_BAD_TRANSPORT; } // create an RTCP transport for this stream RTCPTCPTransport* pRTCPTran = new RTCPTCPTransport(m_bSetupRecord); if(!pRTCPTran) { HX_DELETE(pHeader); HX_DELETE(pTrans); return HXR_OUTOFMEMORY; } pRTCPTran->AddRef(); pRTCPTran->init(m_pContext, m_pSocket, (RTPTCPTransport*)pTrans, (IHXRTSPTransportResponse*)this, streamNumber); ((RTPTCPTransport*)pTrans)->setRTCPTransport((RTCPBaseTransport*)pRTCPTran); status = pRequest->addTransportInfo(pTrans, (RTCPBaseTransport*)pRTCPTran, streamNumber, nUDPPort); if (m_bIPTV && m_pSetupRequestHeader) { addRFC822Headers(pMsg, m_pSetupRequestHeader); // don't add it twice... pIHXValuesRequestHeaders = NULL; } } break; default: { } break; }#endif /* HELIX_FEATURE_RTP */ char* pModifiedMimeType = NULL; const char* pMimeType = RTSPTransportMimeMapper::getTransportMimeType ( pRequest->m_lTransportType ); // Accomodate incompliant servers that understand only upper case // transport mime-types if (m_bForceUCaseTransportMimeType) { ULONG32 ulMimeTypeLength = strlen(pMimeType); if (ulMimeTypeLength != 0) { pModifiedMimeType = new char [ulMimeTypeLength + 1]; if(!pModifiedMimeType) { HX_DELETE(pHeader); return HXR_OUTOFMEMORY; } } if (pModifiedMimeType) { strcpy(pModifiedMimeType, pMimeType); /* Flawfinder: ignore */ StrToUpper(pModifiedMimeType); pMimeType = pModifiedMimeType; } }#if defined(HELIX_FEATURE_RTP) switch(pRequest->m_lTransportType) { case RTSP_TR_RTP_UDP: case RTSP_TR_RTP_TCP: { char portValue[32]; /* Flawfinder: ignore */ MIMEHeaderValue* pHeaderValue = new MIMEHeaderValue(pMimeType); if(!pHeaderValue) { HX_DELETE(pHeader); HX_DELETE(pModifiedMimeType); return HXR_OUTOFMEMORY; } if (RTSP_TR_RTP_UDP == pRequest->m_lTransportType) { SafeSprintf(portValue, 32, "%u-%u", nUDPPort, nUDPPort+1); pHeaderValue->addParameter("client_port", (const char*)portValue);#ifdef XXXtbradleyTEST_RTSP_DESTINATION pHeaderValue->addParameter("destination", "127.0.0.1");#endif /* XXXtbradleyTEST_RTSP_DESTINATION */ } if(m_bSetupRecord) { pHeaderValue->addParameter("mode", "record"); } else { pHeaderValue->addParameter("mode", "play"); } pHeader->addHeaderValue(pHeaderValue); } break; case RTSP_TR_RTP_MCAST: default: { } break; }#endif /* HELIX_FEATURE_RTP */ HX_VECTOR_DELETE(pModifiedMimeType); } pMsg->addHeader(pHeader); return status;}STDMETHODIMPRTSPClientProtocol::SendPlayRequest(UINT32 lFrom, UINT32 lTo, CHXSimpleList* pASMRules){ /* * Flush the data packets out of the transport buffers */ m_pMutex->Lock(); m_bPaused = FALSE;#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST) if (m_bSDPInitiated && m_bMulticast) { m_pMutex->Unlock(); return m_pResp->HandlePlayResponse(HXR_OK); }#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */ /* * XXXGH...I believe we should be iterating through m_transportRequestList * here and for SendPauseRequest, SendResumeRequest, etc. */ // only used when m_bNonRSRTP is TRUE m_bPlayJustSent = TRUE; if (!m_transportRequestList.IsEmpty()) { RTSPTransportRequest* pRequest = (RTSPTransportRequest*)m_transportRequestList.GetHead(); RTSPTransportInfo* pTransInfo = pRequest->getFirstTransportInfo(); while(pTransInfo) { pTransInfo->m_pTransport->playReset(); // set the range in transport...only for RTP pTransInfo->m_pTransport->setPlayRange(lFrom, lTo); pTransInfo->m_pTransport->SetPlayRequestSent(TRUE); pTransInfo->m_pTransport->resumeBuffers(); pTransInfo = pRequest->getNextTransportInfo(); } } HX_RESULT rc = HXR_OK; RTSPPlayMessage* pMsg = new RTSPPlayMessage; if(pMsg) { RTSPRange range(lFrom, lTo, RTSPRange::TR_NPT); pMsg->setURL(m_url); AddCommonHeaderToMsg(pMsg); pMsg->addHeader("Range", (const char*)range.asString()); UINT32 seqNo = m_pSession->getNextSeqNo(this); rc = sendRequest(pMsg, seqNo); } else { rc = HXR_OUTOFMEMORY; } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendRecordRequest(){ if (!m_pIsMethodSupported[RECORD] || !m_pSession) { return HXR_OK; } HX_RESULT rc = HXR_OK; m_pMutex->Lock(); // Declaring these here so I can use a goto below! CHXString streamSequenceNumbers; BOOL bIsFirst = TRUE; CHXMapLongToObj::Iterator i; RTSPRecordMessage* pMsg = new RTSPRecordMessage; if(!pMsg) { rc = HXR_OUTOFMEMORY; goto overandout; } pMsg->setURL(m_url); AddCommonHeaderToMsg(pMsg); /* * Add header for sequence numbers */ for(i=m_pTransportStreamMap->Begin(); i!=m_pTransportStreamMap->End(); ++i) { int lenTmpBuf = 100 + strlen(m_url); char* tmpBuf = new char[lenTmpBuf]; if(!tmpBuf) { HX_DELETE(pMsg); rc = HXR_OUTOFMEMORY; goto overandout; } RTSPTransport* pTransport = (RTSPTransport*)(*i); pTransport->m_bHackedRecordFlag = TRUE; UINT16 streamNumber = (UINT16)i.get_key(); UINT16 seqNum = pTransport->getSeqNum(streamNumber); UINT32 ulTimestamp = pTransport->getTimestamp(streamNumber); SafeSprintf(tmpBuf, lenTmpBuf, "url=" + m_url + "/streamid=%d;seq=%d;rtptime=%ld", streamNumber, seqNum, ulTimestamp); if(!bIsFirst) { streamSequenceNumbers += ", " + CHXString(tmpBuf); } else { bIsFirst = FALSE; streamSequenceNumbers = tmpBuf; } delete[] tmpBuf; } pMsg->addHeader("RTP-Info", streamSequenceNumbers); if( m_pSession ) { UINT32 seqNo = m_pSession->getNextSeqNo(this); rc = sendRequest(pMsg, seqNo); }overandout: m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendPauseRequest(){ m_bPaused = TRUE; /* * Stop the internal buffer timers */ if (!m_pIsMethodSupported[PAUSE] || m_transportRequestList.IsEmpty() || !m_pSession) { return HXR_OK; } m_pMutex->Lock(); // only used when m_bNonRSRTP is TRUE m_bPlayJustSent = FALSE; SendMsgToTransport(PAUSE_BUFFER); HX_RESULT rc = SendMsgToServer(RTSP_PAUSE); m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendResumeRequest(){ m_bPaused = FALSE; if (!m_pSession) { return HXR_OK; } /* * Restart the internal buffer timers */ m_pMutex->Lock(); SendMsgToTransport(RESUME_BUFFER); /* * Man, iptv, teracast, and darwin server don't like this even though * this is perfetly legal... */ if (m_bNonRSRTP && m_bPlayJustSent) { m_pResp->HandlePlayResponse(HXR_OK); m_pMutex->Unlock(); return HXR_OK; } HX_RESULT rc = SendMsgToServer(RTSP_PLAY); m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendTeardownRequest(){ // make sure not to send a TEARDOWN unless SETUP succeeded if (m_setupResponseCount <= 0 || !m_pSession) { // no successful SETUP response received... return HXR_OK; } // it's ok if there is no session by spec. m_pMutex->Lock(); HX_RESULT rc = SendMsgToServer(RTSP_TEARDOWN); m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendPlayerStats(const char* pStats){#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY) if (!m_pIsMethodSupported[SET_PARAM]) { return HXR_OK; } if(m_pSession && !m_sessionID.IsEmpty()) { HX_RESULT rc = HXR_OK; m_pMutex->Lock(); RTSPSetParamMessage* pMsg = new RTSPSetParamMessage; if(pMsg) { pMsg->setURL(m_url); pMsg->addHeader("Session", m_sessionID); pMsg->addHeader("PlayerStats", pStats); UINT32 seqNo = m_pSession->getNextSeqNo(this); rc = sendRequest(pMsg, seqNo); } else { rc = HXR_OUTOFMEMORY; } m_pMutex->Unlock(); return rc; }#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */ return HXR_OK;}STDMETHODIMPRTSPClientProtocol::SendKeepAlive(){ HX_RESULT rc = HXR_OK; // XXXSMP - Not right! :-) m_pMutex->Lock(); if (!m_pSession) { // just say alive! m_pMutex->Unlock(); return HXR_OK; } // If using session timeout code, send an Options message, // otherwise, send a SetParam. The SetParam approach is // is for servers that do not specify a session timeout value. if (!m_bUseLegacyTimeOutMsg || !m_pIsMethodSupported[SET_PARAM] || m_bNoKeepAlive) { m_bKeepAlivePending = TRUE; rc = SendMsgToServer(RTSP_OPTIONS); } else { RTSPSetParamMessage* pMsg = new RTSPSetParamMessage; if(pMsg) { pMsg->setURL("*"); MIMEHeader* pAlertHeader = new MIMEHeader("Ping"); if(pAlertHeader) { pAlertHeader->addHeaderValue("Pong"); pMsg->addHeader(pAlertHeader); AddCommonHeaderToMsg(pMsg); UINT32 seqNo = m_pSession->getNextSeqNo(this); sendRequest(pMsg, seqNo); } else { rc = HXR_OUTOFMEMORY; } } else { rc = HXR_OUTOFMEMORY; } } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendPacket(BasePacket* pPacket){ m_pMutex->Lock(); HX_RESULT rc = HXR_UNEXPECTED; RTSPTransport* pTrans = (RTSPTransport*)(*m_pTransportStreamMap)[pPacket->GetStreamNumber()]; if(pTrans) { rc = pTrans->sendPacket(pPacket); } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::SendStreamDone(UINT16 streamNumber){ m_pMutex->Lock(); HX_RESULT rc = HXR_UNEXPECTED; RTSPTransport* pTrans = (RTSPTransport*)(*m_pTransportStreamMap)[streamNumber]; if(pTrans) { rc = pTrans->streamDone(streamNumber); } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::GetPacket(UINT16 uStreamNumber, REF(IHXPacket*) pPacket){ m_pMutex->Lock(); /* * Must not return HXR_FAIL because player may request a packet * before the transport is set up */ HX_RESULT rc = HXR_NO_DATA; RTSPTransport* pTrans = (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber]; if (pTrans) { rc = pTrans->getPacket(uStreamNumber, pPacket); } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::StartPackets(UINT16 uStreamNumber){ m_pMutex->Lock(); HX_RESULT rc = HXR_FAIL; RTSPTransport* pTrans = (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber]; if (pTrans) { rc = pTrans->startPackets(uStreamNumber); } m_pMutex->Unlock(); return rc;}STDMETHODIMPRTSPClientProtocol::StopPackets(UINT16 uStreamNumber){ m_pMutex->Lock(); HX_RESULT rc = HXR_FAIL; RTSPTransport* pTrans = (RTSPTransport*)(*m_pTransportStreamMap)[uStreamNumber]; if (pTrans) { /* * Must not return HXR_FAIL because player may request a packet * before the transport is set up */ rc = pTrans->stopPackets(uStreamNumber); } m_pMutex->Unlock(); return rc;}/* * XXX...This had BETTER GET FIXED when we go to full IRMA */STDMETHODIMP_(IHXPendingStatus*)RTSPClientProtocol::GetPendingStatus(){ AddRef(); return (IHXPendingStatus*)this;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -