📄 rtspprotocol.cpp
字号:
if (m_pProtocolLib)
{
((RTSPClientProtocol*)m_pProtocolLib)->LeavePrefetch();
}
return;
}
void
RTSPProtocol::EnterFastStart(void)
{
m_bFastStart = TRUE;
if (m_pProtocolLib)
{
((RTSPClientProtocol*)m_pProtocolLib)->EnterFastStart();
}
return;
}
void
RTSPProtocol::LeaveFastStart(void)
{
m_bFastStart = FALSE;
if (m_pProtocolLib)
{
((RTSPClientProtocol*)m_pProtocolLib)->LeaveFastStart();
}
return;
}
/*
* If this is multicast, make sure to send subscribe msg
*/
HX_RESULT
RTSPProtocol::handle_multicast(void)
{
#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
HX_ASSERT(mCurrentTransport == MulticastMode);
STREAM_INFO* pStreamInfo = NULL;
IHXBuffer* pRuleBook = NULL;
for (UINT16 uStrmNum = 0; uStrmNum < m_uStreamCount; uStrmNum++)
{
pStreamInfo = NULL;
if (FAILED(mOwner->GetStreamInfo(uStrmNum, pStreamInfo)))
{
return HXR_OK;
}
HX_ASSERT(pStreamInfo);
// If there is an ASMRuleBook, subscription will be done eventually
// through RTSPClientProtocol::RuleChange()...
pRuleBook = NULL;
if (FAILED(pStreamInfo->m_pHeader->GetPropertyCString("ASMRuleBook", pRuleBook)))
{
HX_ASSERT(!pRuleBook);
Subscribe(uStrmNum, 0);
}
HX_RELEASE(pRuleBook);
}
return HXR_OK;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */
}
HX_RESULT
RTSPProtocol::send_setup_request()
{
HX_RESULT rc = HXR_OK;
RTSPTransportType* pTransport = new RTSPTransportType[MAX_TRANSPORT];
int nTransports = 0;
switch (mCurrentTransport)
{
/*
* Port is omitted here, the transport layer will pick it.
*/
#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
case MulticastMode:
if (!m_bUseRTP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_MCAST;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_UDP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_TNG_UDP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_UDP;
pTransport[nTransports++].m_sPort = 0;
if (m_ulTransportPrefMask & ATTEMPT_TCP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_TNG_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
}
else
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_UDP;
pTransport[nTransports++].m_sPort = 0;
if (m_ulTransportPrefMask & ATTEMPT_TCP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
}
// tell the owner that we are using multicast...
// this is needed to display it on the stats dialog...
mOwner->TransportStarted(MulticastMode);
break;
#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */
case UDPMode:
if(!m_bUseRTP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_UDP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_TNG_UDP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_UDP;
pTransport[nTransports++].m_sPort = 0;
if (m_ulTransportPrefMask & ATTEMPT_TCP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_TNG_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
}
else
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_UDP;
pTransport[nTransports++].m_sPort = 0;
if (m_ulTransportPrefMask & ATTEMPT_TCP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
}
// tell the owner that we are using UDP...
// this is needed to display it on the stats dialog...
mOwner->TransportStarted(UDPMode);
break;
case TCPMode:
if(!m_bUseRTP)
{
pTransport[nTransports].m_lTransportType = RTSP_TR_TNG_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RDT_TCP;
pTransport[nTransports++].m_sPort = 0;
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
else
{
pTransport[nTransports].m_lTransportType = RTSP_TR_RTP_TCP;
pTransport[nTransports++].m_sPort = 0;
}
// tell the owner that we are using TCPt...
// this is needed to display it on the stats dialog...
if (m_bHTTPOnly)
{
mOwner->TransportStarted(HTTPCloakMode);
}
else
{
mOwner->TransportStarted(TCPMode);
}
break;
default:
HX_VECTOR_DELETE(pTransport);
#if defined(_DEBUG) && defined(DEBUG_LOG_INFO)
HXStaticStatLog::StatPrintf("SetTransport::wrong mode %d\n", mCurrentTransport);
#endif
return HXR_FAIL;
}
HX_ASSERT(nTransports <= MAX_TRANSPORT);
// look for a cookie...
// If we use pRequsetHeaders straight from m_pRequest, it will contain a
// whole bunch of stuff that we don't need. SO, just extract the "Cookie"
// and create a new header right here. If you need other headers, we might
// need to come up with a better loginc.
IHXValues* pRequestHeaders = NULL;
IHXBuffer* pCookie = NULL;
if (SUCCEEDED(m_pRequest->GetRequestHeaders(pRequestHeaders)))
{
pRequestHeaders->GetPropertyCString("Cookie", pCookie);
HX_RELEASE(pRequestHeaders);
if (pCookie)
{
pRequestHeaders = new CHXHeader();
pRequestHeaders->AddRef();
pRequestHeaders->SetPropertyCString("Cookie", pCookie);
HX_RELEASE(pCookie);
}
}
rc = m_pProtocolLib->SendSetupRequest(pTransport, nTransports, pRequestHeaders);
HX_RELEASE(pRequestHeaders);
HX_VECTOR_DELETE(pTransport);
return rc;
}
STDMETHODIMP
RTSPProtocol::HandleStreamRecordDescriptionResponse
(
HX_RESULT status,
IHXValues* pResponseHeaders
)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleSetupResponse
(
HX_RESULT status
)
{
if (status != HXR_OK)
{
/*
* XXX...Need to get proper errors from protocol library
*/
mOwner->ReportError(status);
return status;
}
switch(m_pProtocolLib->GetProtocolType())
{
case 1:
mOwner->TransportStarted(MulticastMode);
#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
// OK, this is multicast for sure...Make sure to send subscription.
handle_multicast();
#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */
break;
case 2:
mOwner->TransportStarted(UDPMode);
break;
case 3:
// notify that the server has selected TCP over UDP
// when the player supports both
if (!m_bHTTPOnly &&
mCurrentTransport != TCPMode &&
HXR_OK == mOwner->TransportStarted(TCPMode))
{
mOwner->TransportSucceeded(TCPMode, 0);
}
/* No need to report TCP success
* We may be in TCP/HTTP Cloaking mode
*/
break;
default:
HX_ASSERT(FALSE);
break;
}
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
/*
* Must wait until transport is established before initializing
* statistics
*/
CHXMapLongToObj::Iterator i;
for (i = m_pStreamInfoList->Begin(); i != m_pStreamInfoList->End(); ++i)
{
RTSP_STREAM_INFO* pStreamInfo = (RTSP_STREAM_INFO*)(*i);
if (m_pProtocolLib)
{
((RTSPClientProtocol*)m_pProtocolLib)->SetStatistics(pStreamInfo->m_uStreamNumber,
pStreamInfo->m_pStreamStats);
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
mOwner->Initialize();
// return m_pProtocolLib->SendPlayRequest(RTSP_PLAY_RANGE_BLANK, RTSP_PLAY_RANGE_BLANK, 0);
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandlePlayResponse
(
HX_RESULT status
)
{
if (status != HXR_OK)
{
/*
* XXX...Need to get proper errors from protocol library
*/
mOwner->ReportError(status); //ConvertHResultToHXError(status));
return status;
}
/* Mark the current state as Playing ONLY if we have called resume */
if (!m_bIsFirstResume)
{
m_bPlaying = TRUE;
// Start Waiting for data..
mOwner->StartDataWait();
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandleRecordResponse
(
HX_RESULT status
)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleTeardownResponse
(
HX_RESULT status
)
{
AddRef();
if (m_pProtocolLib)
{
m_pProtocolLib->Done();
m_pProtocolLib->Release();
m_pProtocolLib = 0;
}
Release();
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandleSetParameterRequest
(
UINT32 lParamType,
const char* pParamName,
IHXBuffer* pParamValue
)
{
IHXPlayer* pPlayer;
IHXBandwidthManager * pBWM;
if(!strcmp(pParamName,"MaximumASMBandwidth") &&
(HXR_OK == mOwner->GetPlayer(pPlayer)) &&
(HXR_OK == pPlayer->QueryInterface(IID_IHXBandwidthManager,
(void **)&pBWM)))
{
pBWM->ChangeBW((UINT32)atoi((const char *)pParamValue->GetBuffer()),
mOwner);
return HXR_OK;
}
#if defined(HELIX_FEATURE_REVERTER)
else if (!strcmp(pParamName, "DataConvertBuffer"))
{
m_pDataRevert->ControlBufferReady(pParamValue);
return HXR_OK;
}
#endif /* HELIX_FEATURE_REVERTER */
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleSetParameterRequest(const char* pParamName,
const char* pParamValue, const char* pContent)
{
#if defined(HELIX_FEATURE_REVERTER)
if (!strcmp(pParamName, "DataConvertBuffer"))
{
IHXBuffer* pBuffer = new CHXBuffer();
int contentLen = strlen(pContent);
pBuffer->SetSize(contentLen);
int offset = BinFrom64(pContent, contentLen,
(unsigned char*)pBuffer->GetBuffer());
pBuffer->SetSize(offset);
pBuffer->AddRef();
m_pDataRevert->ControlBufferReady(pBuffer);
pBuffer->Release();
return HXR_OK;
}
#endif /* HELIX_FEATURE_REVERTER */
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleSetParameterResponse
(
HX_RESULT status
)
{
return HXR_OK; // XXXSMP Just return OK for now.
}
STDMETHODIMP
RTSPProtocol::HandleSetParameterResponseWithValues
(
HX_RESULT status,
IHXValues* pValues
)
{
if (status == HXR_OK && pValues)
{
UINT32 ulStatsInterval = 0;
UINT32 ulValue = 0;
if (pValues->GetPropertyULONG32("UpdateStatsInterval", ulStatsInterval) == HXR_OK)
{
ulStatsInterval = ulStatsInterval * 1000;
// ulStatsInterval = 0 to disable the stats
if (ulStatsInterval && ulStatsInterval < MINIMUM_STATS_INTERVAL)
{
ulStatsInterval = MINIMUM_STATS_INTERVAL;
}
mOwner->SetOption(HX_STATS_INTERVAL, &ulStatsInterval);
}
if (pValues->GetPropertyULONG32("Reconnect", ulValue) == HXR_OK)
{
mOwner->SetReconnectInfo(pValues);
}
}
return HandleSetParameterResponse(status);
}
STDMETHODIMP
RTSPProtocol::HandleGetParameterRequest
(
UINT32 lParamType,
const char* pParamName,
IHXBuffer** pParamValue
)
{
/*
* XXX...Need to implement
*/
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleGetParameterResponse
(
HX_RESULT status,
IHXBuffer* pParamValue
)
{
/*
* XXX...Need to implement
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -