📄 rtspclnt.cpp
字号:
(void**) &m_pInterruptState);
if (HXR_OK != m_pContext->QueryInterface(IID_IHXNetworkServices, (void**)&m_pNetworkServices) ||
HXR_OK != m_pContext->QueryInterface(IID_IHXPreferences, (void**)&m_pPreferences))
{
hresult = HXR_FAILED;
goto cleanup;
}
if (NULL == pHostName &&
NULL != pInfo &&
HXR_OK == pInfo->GetPropertyCString("helix-sdp", pSrcBuffer))
{
m_bSDPInitiated = TRUE;
if (HXR_OK != ParseSDP("application/sdp", pSrcBuffer))
{
hresult = HXR_FAILED;
goto cleanup;
}
if (!m_sessionHost.IsEmpty())
{
UINT32 addr = HXinet_addr((const char*)m_sessionHost);
UINT32 ulHostAddr = DwToHost(addr);
if (ulHostAddr >= MULTICAST_ADDRESS_RANGE_LOW &&
ulHostAddr <= MULTICAST_ADDRESS_RANGE_HIGH)
{
m_bMulticast = TRUE;
m_ulMulticastAddress = ulHostAddr;
pHostName = (const char*)m_sessionHost;
pInfo->SetPropertyULONG32("MulticastOnly", 1);
m_pSDPFileHeader->SetPropertyULONG32("LiveStream", 1);
}
}
if (!m_bMulticast)
{
pURL = new CHXURL(m_headerControl);
if (!(pURLProps = pURL->GetProperties()))
{
hresult = HXR_FAILED;
goto cleanup;
}
pURLProps->GetPropertyULONG32(PROPERTY_PORT, (UINT32&)foreignPort);
if (HXR_OK != pURLProps->GetPropertyBuffer(PROPERTY_HOST, pBuffer))
{
hresult = HXR_FAILED;
goto cleanup;
}
pHostName = (char*)pBuffer->GetBuffer();
}
HX_RELEASE(pBuffer);
}
ReadPrefINT32(m_pPreferences, "ConnectionTimeOut", m_uConnectionTimeout);
ReadPrefINT32(m_pPreferences, "ServerTimeOut", m_ulServerTimeOut);
if (m_ulServerTimeOut < MINIMUM_TIMEOUT)
{
m_ulServerTimeOut = MINIMUM_TIMEOUT;
}
m_ulServerTimeOut *= MILLISECS_PER_SECOND;
if (bHTTPCloak && m_bUseProxy)
{
m_bUseHTTPProxy = TRUE;
}
ReadPrefBOOL(m_pPreferences, "RTSPMessageDebug", m_bMessageDebug);
if (m_bMessageDebug)
{
if (HXR_OK == m_pPreferences->ReadPref("RTSPMessageDebugFile", pBuffer))
{
if (pBuffer->GetSize() <= 0)
{
// no file name, no log
m_bMessageDebug = FALSE;
}
else
{
m_messageDebugFileName = (const char*)pBuffer->GetBuffer();
}
}
HX_RELEASE(pBuffer);
}
// XXXGo - Interop workaround
ReadPrefBOOL(m_pPreferences, "NonRS", m_bNonRSRTP);
if (m_bNonRSRTP)
{
m_pIsMethodSupported[SET_PARAM] = FALSE;
m_pIsMethodSupported[GET_PARAM] = FALSE;
m_pIsMethodSupported[RECORD] = FALSE;
m_pIsMethodSupported[ANNOUNCE] = FALSE;
}
ReadPrefBOOL(m_pPreferences, "RTSPNoReuseConnection", bNoReuseConnection);
ReadPrefBOOL(m_pPreferences, "LoadTest", m_bLoadTest);
if (!m_pTransportStreamMap)
{
m_pTransportStreamMap = new CHXMapLongToObj;
if(!m_pTransportStreamMap)
{
hresult = HXR_OUTOFMEMORY;
goto cleanup;
}
}
if (!m_pTransportPortMap)
{
m_pTransportPortMap = new CHXMapLongToObj;
if(!m_pTransportPortMap)
{
hresult = HXR_OUTOFMEMORY;
goto cleanup;
}
}
if (!m_pTransportMPortMap)
{
m_pTransportMPortMap = new CHXMapLongToObj;
if(!m_pTransportMPortMap)
{
hresult = HXR_OUTOFMEMORY;
goto cleanup;
}
}
m_hostName = pHostName;
m_foreignPort = foreignPort;
m_bHTTPOnly = bHTTPCloak;
m_uCloakPort = uCloakPort;
m_bNoReuseConnection = bNoReuseConnection;
if (m_bHTTPOnly)
{
m_currentTransport = HTTPCloakMode;
}
if(pSessionHeaders && !m_pSessionHeaders)
{
m_pSessionHeaders = pSessionHeaders;
m_pSessionHeaders->AddRef();
}
HX_RELEASE(m_pResponseHeaders);
if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXKeyValueList, (void**)&pUnknown))
{
hresult = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != pUnknown->QueryInterface(IID_IHXKeyValueList, (void**)&m_pResponseHeaders))
{
hresult = HXR_FAILED;
goto cleanup;
}
if(!m_pRegistry)
{
#if defined(HELIX_FEATURE_REGISTRY)
// get registry ptr
IHXRegistry* pRegistry = 0;
hresult = m_pContext->QueryInterface(IID_IHXRegistry,
(void**)&pRegistry);
HX_VERIFY(HXR_OK == hresult);
if(hresult == HXR_OK)
{
m_pRegistry = pRegistry;
}
#endif /* HELIX_FEATURE_REGISTRY */
}
if(!m_pResolver)
{
m_pNetworkServices->CreateResolver(&pResolver);
if(!pResolver)
{
hresult = HXR_OUTOFMEMORY;
goto cleanup;
}
HX_RELEASE(m_pResolver);
m_pResolver = pResolver;
m_pResolver->Init(this);
CHXString pHost;
if (m_bUseHTTPProxy || m_bUseProxy)
{
pHost = m_proxyHost;
}
else
{
pHost = m_hostName;
}
if(IsNumericAddr(pHost, pHost.GetLength()))
{
UINT32 addr = HXinet_addr((const char*)pHost);
UINT32 ulHostAddr = DwToHost(addr);
hresult = GetHostByNameDone(HXR_OK, ulHostAddr);
}
else
{
hresult = m_pResolver->GetHostByName(pHost);
}
}
HX_RELEASE(m_pScheduler);
if (HXR_OK != m_pContext->QueryInterface(IID_IHXScheduler,
(void**)&m_pScheduler))
{
hresult = HXR_OUTOFMEMORY;
goto cleanup;
}
// check for UAProf headers
if (m_pPreferences)
{
HX_RELEASE(m_pUAProfURI);
HX_RELEASE(m_pUAProfDiff);
m_pPreferences->ReadPref("XWapProfileURI", m_pUAProfURI);
m_pPreferences->ReadPref("XWapProfileDiff", m_pUAProfDiff);
}
#if defined(_MACINTOSH)
if (m_pCallback &&
m_pCallback->m_bIsCallbackPending &&
m_pScheduler)
{
m_pCallback->m_bIsCallbackPending = FALSE;
m_pScheduler->Remove(m_pCallback->m_Handle);
}
#endif /* _MACINTOSH */
cleanup:
HX_RELEASE(pSrcBuffer);
HX_RELEASE(pURLProps);
HX_RELEASE(pUnknown);
HX_DELETE(pURL);
return hresult;
}
STDMETHODIMP
RTSPClientProtocol::SetProxy(const char* pProxyHost, UINT16 uProxyPort)
{
m_bUseProxy = TRUE;
m_proxyHost = pProxyHost;
m_proxyPort = uProxyPort;
return HXR_OK;
}
STDMETHODIMP
RTSPClientProtocol::SetResponse(IHXRTSPClientProtocolResponse* pResp)
{
HX_RELEASE(m_pResp);
m_pResp = pResp;
m_pResp->AddRef();
return HXR_OK;
}
STDMETHODIMP
RTSPClientProtocol::SetBuildVersion(const char* pVersionString)
{
m_versionString = pVersionString;
return HXR_OK;
}
STDMETHODIMP
RTSPClientProtocol::Done()
{
m_bClientDone = TRUE;
if (m_pMutex)
{
m_pMutex->Lock();
}
#if defined(_MACINTOSH)
if (m_pCallback &&
m_pCallback->m_bIsCallbackPending &&
m_pScheduler)
{
m_pCallback->m_bIsCallbackPending = FALSE;
m_pScheduler->Remove(m_pCallback->m_Handle);
}
HX_RELEASE(m_pCallback);
#endif /* _MACINTOSH */
while (!m_sessionList.IsEmpty())
{
RTSPClientSession* pTempSession = (RTSPClientSession*)m_sessionList.RemoveHead();
m_pSessionManager->removeFromSession(this, pTempSession);
}
HX_ASSERT(m_pSessionManager && m_pSessionManager->isValid());
if (m_pSession)
{
m_pSessionManager->removeFromSession(this, m_pSession);
m_pSession = NULL;
}
HX_RELEASE(m_pSessionManager);
clearSocketStreamMap(m_pUDPSocketStreamMap);
clearSocketStreamMap(m_pRTCPSocketStreamMap);
reset();
if (m_pMutex)
{
m_pMutex->Unlock();
}
return HXR_OK;
}
STDMETHODIMP
RTSPClientProtocol::SendStreamDescriptionRequest(const char* pURL,
IHXValues* pRequestHeaders)
{
#ifdef _MACINTOSH
if (m_pInterruptState && m_pInterruptState->AtInterruptTime())
{
/*
* We cannot load DLLs (Stream Desc Plugins) at deferred time.
* Also, encodeURL calls HXIsLeadByte->CharType->...internally
* calls GetPort. Mac does not like that either at deferred time.
* Schedule a callback and do this operation at system time
*/
if (!m_pCallback)
{
m_pCallback = new RTSPClientProtocolCallback(this);
if(!m_pCallback)
{
return HXR_OUTOFMEMORY;
}
m_pCallback->AddRef();
}
HX_ASSERT(m_pScheduler);
if (!m_pCallback->m_bIsCallbackPending)
{
m_pCallback->m_bIsCallbackPending = TRUE;
m_pCallback->m_Handle =
m_pScheduler->RelativeEnter(m_pCallback, 0);
}
/*
* If we receive a SendStreamDescriptionRequest when
* one is already pending, we do not queue them up.
* The last one wins
*/
m_pCallback->m_PendingDescURL = pURL;
HX_RELEASE(m_pCallback->m_pPendingRequestHeaders);
m_pCallback->m_pPendingRequestHeaders = pRequestHeaders;
m_pCallback->m_pPendingRequestHeaders->AddRef();
return HXR_OK;
}
HX_ASSERT(m_pScheduler);
/* remove any previously scheduled callback */
if (m_pCallback &&
m_pCallback->m_bIsCallbackPending)
{
m_pCallback->m_bIsCallbackPending = FALSE;
m_pScheduler->Remove(m_pCallback->m_Handle);
}
#endif
return sendPendingStreamDescription(pURL, pRequestHeaders);
}
HX_RESULT
RTSPClientProtocol::sendPendingStreamDescription(const char* pURL,
IHXValues* pRequestHeaders)
{
m_pMutex->Lock();
HX_RESULT rc = HXR_OK;
if (HXR_OUTOFMEMORY == extractExistingAuthorizationInformation(pRequestHeaders))
{
m_pMutex->Unlock();
return HXR_OUTOFMEMORY;
}
RTSPDescribeMessage* pMsg = new RTSPDescribeMessage;
if(!pMsg)
{
m_pMutex->Unlock();
return HXR_OUTOFMEMORY;
}
CHXString encodedURL;
CHXURL::encodeURL(pURL, encodedURL);
UINT32 stringSize = 7 + m_hostName.GetLength() + 1 + 5 + 1 + encodedURL.GetLength() + 1;
char* pURLBuffer = new char[ stringSize ];
if(!pURLBuffer)
{
HX_DELETE(pMsg);
m_pMutex->Unlock();
return HXR_OUTOFMEMORY;
}
SafeSprintf( pURLBuffer, stringSize, "rtsp://%s:%u/%s", (const char*)m_hostName, m_foreignPort, (const char*)encodedURL ); /* Flawfinder: ignore */
m_url = pURLBuffer;
delete [] pURLBuffer;
pMsg->setURL(m_url);
IHXValues* pValuesRequestHeaders = NULL;
pValuesRequestHeaders = new CHXHeader();
if(!pValuesRequestHeaders)
{
HX_DELETE(pMsg);
m_pMutex->Unlock();
return HXR_OUTOFMEMORY;
}
pValuesRequestHeaders->AddRef();
if (m_bEntityRequired)
{
CHXString CHXStringRequireValue
(
RTSPClientProtocol::RTSPRequireOptionsTable
[
RTSPClientProtocol::RTSP_REQUIRE_ENTITY
].pcharOption
);
IHXBuffer* pBufferRequireValue = NULL;
CHXBuffer::FromCharArray
(
CHXStringRequireValue.GetBuffer(0),
&pBufferRequireValue
);
// Set require header
pValuesRequestHeaders->SetPropertyCString
(
"Require",
pBufferRequireValue
);
HX_RELEASE(pBufferRequireValue);
}
addUAProfHeaders(pValuesRequestHeaders);
CHXHeader::mergeHeaders
(
pValuesRequestHeaders,
pRequestHeaders
);
// get all StreamDescription plugin mime types
CHXString mimeTypes;
IHXCommonClassFactory* pClassFactory = NULL;
IHXPluginGroupEnumerator* pPluginGroupEnum = NULL;
// ok we are going to get an IRMA PluginGroupEnumerator from the core.
if
(
SUCCEEDED
(
m_pContext->QueryInterface
(
IID_IHXCommonClassFactory,
(void**) &pClassFactory
)
)
)
{
pClassFactory->CreateInstance
(
CLSID_IHXPluginGroupEnumerator,
(void**)&pPluginGroupEnum
);
HX_RELEASE(pClassFactory);
}
if(pPluginGroupEnum &&
(HXR_OK == pPluginGroupEnum->Init(IID_IHXStreamDescription)))
{
IUnknown* pUnknown = NULL;
ULONG32 ulNumPlugins = pPluginGroupEnum->GetNumOfPlugins();
for(ULONG32 i=0;i<ulNumPlugins;++i)
{
if (SUCCEEDED(pPluginGroupEnum->GetPlugin(i, pUnknown)))
{
GetStreamDescriptionInfo(pUnknown, mimeTypes);
HX_RELEASE(pUnknown);
}
}
}
else
{
// if we don't have a CCF or we don't have a pluginGroupEnumerator
// then we will have to use a plugin Enumerator.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -