📄 rtspclnt.cpp
字号:
* 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;
}
STDMETHODIMP
RTSPClientProtocol::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;
}
STDMETHODIMP
RTSPClientProtocol::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;
}
STDMETHODIMP_(IHXStatistics*)
RTSPClientProtocol::GetStatistics()
{
AddRef();
return (IHXStatistics*)this;
}
STDMETHODIMP_(BOOL)
RTSPClientProtocol::HttpOnly()
{
if(m_pSession)
{
return m_pSession->HttpOnly();
}
return FALSE;
}
/*
* IHXResolverResponse methods
*/
STDMETHODIMP
RTSPClientProtocol::GetHostByNameDone(HX_RESULT status,
UINT32 ulAddr)
{
UINT16 uPort = 0;
BOOL bUseProxy = FALSE;
CHXString host;
HX_RELEASE(m_pResolver);
/* We may have been deleted by now */
if (!m_pResp)
{
return HXR_OK;
}
m_pMutex->Lock();
HX_RESULT rc = HXR_OK;
#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
if (m_bSDPInitiated && m_bMulticast)
{
m_ulConnectToAddr = ulAddr;
m_pResp->InitDone(HXR_OK);
IHXValues* pResponseHeaders = NULL;
if (HXR_OK == m_pResponseHeaders->QueryInterface(IID_IHXValues, (void**)&pResponseHeaders))
{
rc = m_pResp->HandleStreamDescriptionResponse
(
HXR_OK,
m_pSDPFileHeader,
m_pSDPStreamHeaders,
pResponseHeaders
);
}
HX_RELEASE(pResponseHeaders);
RemoveSDPHeaders();
goto exit;
}
#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */
if(status == HXR_OK)
{
if (!m_pSessionManager->isValid())
{
// just return, this puppy's going away...
goto exit;
}
if (!m_pSession && !m_pSocket)
{
RTSPClientSession* pSession = 0;
IUnknown* pContextToMatch = NULL;
/* Do not reuse connection for connections coming from the
* same player. Check for context (IHXPlayer) equality test
* Context check is needed to simulate real-world scenario
* for SMIL load testing
*/
if (m_bNoReuseConnection && m_bLoadTest)
{
pContextToMatch = m_pContext;
}
/* We share established connections if
* 1. m_bNoReuseConnection is FALSE OR
* 2. m_bLoadTest is set to TRUE (in which case we share
* connections ONLY for the same context (see above)
* AND
* 3. m_bHTTPOnly is FALSE OR
* 4. m_pCloakPorts == NULL which means we *not* gonna
* attempt cloakport scanning
*
* NOTE: Splitter Plugin uses m_bNoReuseConnection = TRUE
*/
if ((!m_bHTTPOnly || !m_pCloakPorts) &&
(!m_bNoReuseConnection || m_bLoadTest))
{
if(m_bUseProxy || m_bUseHTTPProxy)
{
uPort = m_proxyPort;
}
else if (m_bHTTPOnly)
{
uPort = m_uCloakPort;
}
else
{
uPort = m_foreignPort;
}
pSession = m_pSessionManager->findSession
(
ulAddr,
uPort,
(m_bUseProxy | m_bUseHTTPProxy),
(const char*)m_hostName,
(m_bUseHTTPProxy?m_uCloakPort:m_foreignPort),
pContextToMatch
);
}
if(pSession)
{
pSession->addProtocol(this);
m_bSessionSucceeded = TRUE;
m_pSession = pSession;
m_pSocket = pSession->getSocket();
sendInitialMessage(m_pSession, m_pSocket);
IHXPreferredTransportSink* pPreferredTransportSink = NULL;
if (m_pResp &&
HXR_OK == m_pResp->QueryInterface(IID_IHXPreferredTransportSink,
(void**)&pPreferredTransportSink))
{
pPreferredTransportSink->TransportSucceeded(m_currentTransport, m_uCloakPort);
}
HX_RELEASE(pPreferredTransportSink);
m_pResp->InitDone(HXR_OK);
}
else
{
if(m_bUseProxy || m_bUseHTTPProxy)
{
host = m_proxyHost;
uPort = m_proxyPort;
bUseProxy = TRUE;
}
else
{
host = m_hostName;
uPort = m_foreignPort;
}
// XXX HP: the new session is created based on
// the actual(foreign) host and port to
// fix SMIL containing diff. servers
// the better fix will be send a new
// Challenge but still sharing the same
//. session
if (m_pCloakPorts)
{
HX_ASSERT(m_bHTTPOnly);
// initiating cloakport scanning
for (int i = 0; i < m_nCloakPorts; i++)
{
rc = m_pSessionManager->newSession(m_pContext,
this,
host,
uPort,
ulAddr,
bUseProxy,
m_bHTTPOnly,
m_pCloakPorts[i]);
HX_ASSERT(HXR_OK == rc);
}
goto exit;
}
else
{
rc = m_pSessionManager->newSession
(
m_pContext,
this,
host,
uPort,
ulAddr,
bUseProxy,
m_bHTTPOnly,
m_uCloakPort
);
goto exit;
}
}
}
else
{
// being re-inited..
//sendInitialMessage();
m_pResp->InitDone(HXR_OK);
}
}
else
{
m_pResp->InitDone(status);
}
exit:
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::SendGetParameterRequest(UINT32 lParamType,
const char* pParamName)
{
if (!m_pIsMethodSupported[GET_PARAM])
{
return HXR_OK;
}
HX_RESULT rc = HXR_OK;
m_pMutex->Lock();
RTSPGetParamMessage* pMsg = new RTSPGetParamMessage;
if(pMsg)
{
pMsg->setURL("*");
AddCommonHeaderToMsg(pMsg);
UINT32 seqNo = m_pSession->getNextSeqNo(this);
rc = sendRequest(pMsg, pParamName, "text/rtsp-parameters", seqNo);
}
else
{
rc = HXR_OUTOFMEMORY;
}
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::SendSetParameterRequest(UINT32 lParamType,
const char* pParamName, IHXBuffer* pParamValue)
{
if (!m_pIsMethodSupported[SET_PARAM])
{
return HXR_OK;
}
m_pMutex->Lock();
RTSPSetParamMessage* pMsg = new RTSPSetParamMessage;
pMsg->setURL(m_url);
AddCommonHeaderToMsg(pMsg);
pMsg->addHeader(pParamName, (const char*)pParamValue->GetBuffer());
UINT32 seqNo = m_pSession->getNextSeqNo(this);
HX_RESULT rc = sendRequest(pMsg, seqNo);
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::SendSetParameterRequest(const char* pParamName,
const char* pParamValue, const char* pMimeType,
const char* pContent)
{
if (!m_pIsMethodSupported[SET_PARAM])
{
return HXR_OK;
}
m_pMutex->Lock();
RTSPSetParamMessage* pMsg = new RTSPSetParamMessage;
pMsg->setURL(m_url);
AddCommonHeaderToMsg(pMsg);
pMsg->addHeader(pParamName, pParamValue);
UINT32 seqNo = m_pSession->getNextSeqNo(this);
HX_RESULT rc = sendRequest(pMsg, pContent, pMimeType, seqNo);
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::PacketReady(HX_RESULT status, const char* pSessionID,
IHXPacket* pPacket)
{
m_pMutex->Lock();
HX_RESULT rc = m_pResp->HandlePacket(status, pSessionID, pPacket);
m_pMutex->Unlock();
return rc;
}
/*
* OnRTTRequest() and OnBWReport() are server-side functions
*/
STDMETHODIMP
RTSPClientProtocol::OnRTTRequest(HX_RESULT status, const char* pSessionID)
{
return HXR_UNEXPECTED;
}
STDMETHODIMP
RTSPClientProtocol::OnRTTResponse(HX_RESULT status, const char* pSessionID,
UINT32 ulSecs, UINT32 ulUSecs)
{
m_pMutex->Lock();
HX_RESULT rc = m_pResp->HandleRTTResponse(status, pSessionID,
ulSecs, ulUSecs);
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::OnBWReport(HX_RESULT status, const char* pSessionID,
INT32 aveBandwidth, INT32 packetLoss, INT32 bandwidthWanted)
{
return HXR_UNEXPECTED;
}
STDMETHODIMP
RTSPClientProtocol::OnCongestion(HX_RESULT status, const char* pSessionID,
INT32 xmitMultiplier, INT32 recvMultiplier)
{
m_pMutex->Lock();
HX_RESULT rc = m_pResp->HandleCongestion(status, pSessionID,
xmitMultiplier, recvMultiplier);
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::OnACK(HX_RESULT status, RTSPResendBuffer* pResendBuffer,
UINT16 uStreamNumber, const char* pSessionID,
UINT16* pAckList, UINT32 uAckListCount,
UINT16* pNakList, UINT32 uNakListCount)
{
/*
* While it's ACKing, remote client is alive
*/
m_bConnectionAlive = TRUE;
m_pMutex->Lock();
HX_RESULT rc = handleACK((IHXPacketResend*)this, pResendBuffer,
uStreamNumber,
pAckList, uAckListCount,
pNakList, uNakListCount,
FALSE);
m_pMutex->Unlock();
return rc;
};
STDMETHODIMP
RTSPClientProtocol::OnStreamDone(HX_RESULT status, UINT16 uStreamNumber)
{
m_pMutex->Lock();
HX_RESULT rc = m_pResp->HandleStreamDone(status, uStreamNumber);
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::OnSourceDone(void)
{
m_pMutex->Lock();
HX_RESULT rc = m_pResp->HandleSourceDone();
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::OnProtocolError(HX_RESULT status)
{
HX_RESULT rc = HXR_OK;
// called from transport layer
m_pMutex->Lock();
if (m_sessionList.IsEmpty() || m_bSessionSucceeded)
{
rc = m_pResp->HandleProtocolError(status);
}
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::GetStatus
(
REF(UINT16) uStatusCode,
REF(IHXBuffer*) pStatusDesc,
REF(UINT16) ulPercentDone
)
{
#if 0
m_pMutex->Lock();
HX_RESULT rc = HXR_OK;
CHXMapLongToObj::Iterator i = m_pTransportStreamMap->Begin();
if(i != m_pTransportStreamMap->End())
{
RTSPTransport* pTrans = (RTSPTransport*)(*i);
rc = pTrans ? pTrans->getStatus(uStatusCode, pStatusDesc, ulPercentDone) : HXR_OK;
}
else
{
uStatusCode = HX_STATUS_BUFFERING;
pStatusDesc = 0;
ulPercentDone = 0;
}
m_pMutex->Unlock();
return rc;
#else
return HXR_NOTIMPL;
#endif
}
STDMETHODIMP
RTSPClientProtocol::InitializeStatistics
(
UINT32 ulRegistryID
)
{
HX_RESULT rc = HXR_FAIL;
m_pMutex->Lock();
CHXMapLongToObj::Iterator i = m_pTransportStreamMap->Begin();
if(i != m_pTransportStreamMap->End())
{
RTSPTransport* pTrans = (RTSPTransport*)(*i);
rc = pTrans ? pTrans->initializeStatistics(ulRegistryID) : HXR_FAIL;
}
m_pMutex->Unlock();
return rc;
}
STDMETHODIMP
RTSPClientProtocol::UpdateStatistics()
{
HX_RESULT rc = HXR_FAIL;
m_pMutex->Lock();
CHXMapLongToObj::Iterator i = m_pTransportStreamMap->Begin();
if(i != m_pTransportStreamMap->End())
{
RTSPTransport* pTrans = (RTSPTransport*)(*i);
rc = pT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -