📄 rtspprotocol.cpp
字号:
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleAlertRequest
(
HX_RESULT status,
INT32 lAlertNumber,
const char* pAlertText
)
{
HX_RESULT theErr = HXR_OK;
m_idleState = ALERT_STATE;
m_ulLastAlert = (UINT32)lAlertNumber;
HX_VECTOR_DELETE(m_pTextBuf);
if (pAlertText)
{
m_pTextBuf = new char[::strlen(pAlertText) + 1];
if(!m_pTextBuf)
{
theErr = HXR_OUTOFMEMORY;
goto cleanup;
}
strcpy(m_pTextBuf, pAlertText); /* Flawfinder: ignore */
}
cleanup:
// Clear the authentication cache
if (m_pRegistry)
{
m_pRegistry->DeleteByName("CredCache");
}
return theErr;
}
STDMETHODIMP
RTSPProtocol::HandleUseProxyRequest
(
const char* pProxyURL
)
{
HX_RESULT rc = HXR_OK;
if(!pProxyURL)
{
mOwner->ReportError(HXR_DNR);
}
else
{
char* pProxyHost = NULL;
UINT32 ulProxyPort = 0;
// parse host name, port
CHXURL proxyURL(pProxyURL);
IHXValues* pProxyURLProps = proxyURL.GetProperties();
IHXBuffer* pBuffer = NULL;
if(HXR_OK == pProxyURLProps->GetPropertyBuffer(PROPERTY_HOST, pBuffer))
{
pProxyHost = new char[pBuffer->GetSize()+1];
strcpy(pProxyHost, (char*)pBuffer->GetBuffer()); /* Flawfinder: ignore */
HX_RELEASE(pBuffer);
}
pProxyURLProps->GetPropertyULONG32(PROPERTY_PORT, ulProxyPort);
HX_RELEASE(pProxyURLProps);
if(pProxyHost)
{
initialize_members();
set_proxy(pProxyHost, (UINT16)ulProxyPort);
// copy host/path so setup doesn't override
char* pHost = new_string(mHost);
char* pPath = new_string(mPath);
rc = setup(pHost, pPath, mPort, mLossCorrection,
m_bHTTPOnly, m_bSDPInitiated, mCloakPort);
delete[] pHost;
delete[] pPath;
}
delete[] pProxyHost;
}
return rc;
}
STDMETHODIMP
RTSPProtocol::HandleRedirectRequest
(
const char* pURL,
UINT32 msFromNow
)
{
HX_RESULT rc = HXR_OK;
char* pHostStr = NULL;
char* pResource = NULL;
UINT32 ulPort = 0;
IHXValues* pHeader = NULL;
if(pURL)
{
CHXURL urlObj(pURL);
pHeader = urlObj.GetProperties();
IHXBuffer* pBuffer = 0;
if (HXR_OK != pHeader->GetPropertyBuffer(PROPERTY_HOST, pBuffer))
{
rc = HXR_FAILED;
goto cleanup;
}
pHostStr = new char[pBuffer->GetSize()+1];
strcpy(pHostStr, (char*)pBuffer->GetBuffer()); /* Flawfinder: ignore */
pBuffer->Release();
if (HXR_OK != pHeader->GetPropertyBuffer(PROPERTY_RESOURCE, pBuffer))
{
rc = HXR_FAILED;
goto cleanup;
}
pResource = (char*)pBuffer->GetBuffer();
ulPort = 0;
pHeader->GetPropertyULONG32(PROPERTY_PORT, ulPort);
mOwner->SetRedirectURL(pHostStr, (UINT16)ulPort, pResource, &urlObj);
m_LastError = HXR_REDIRECTION;
pBuffer->Release();
delete[] pHostStr;
}
else
{
mOwner->ReportError(HXR_DNR);
}
cleanup:
HX_RELEASE(pHeader);
return rc;
}
STDMETHODIMP
RTSPProtocol::HandlePacket
(
HX_RESULT status,
const char* pSessionID,
IHXPacket* pPacket
)
{
/*
* These are flushed pre-seek packets
*/
if (HXR_OK == status)
{
CHXEvent* pEvent = new CHXEvent(pPacket);
pEvent->SetPreSeekEvent();
mOwner->EventReady(pEvent);
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandleProtocolError
(
HX_RESULT status
)
{
/*
* XXX...Need to get proper errors from protocol library
*/
mOwner->ReportError(status);//ConvertHResultToHXError(status));
m_bPlaying = FALSE;
return status;
}
STDMETHODIMP
RTSPProtocol::HandleRTTResponse
(
HX_RESULT status,
const char* pSessionID,
UINT32 ulSecs,
UINT32 ulUSecs
)
{
// we handle RTT response in order to detect
// whether the UDP channel is still alive during PAUSE/RESUME
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandleCongestion
(
HX_RESULT status,
const char* pSessionID,
INT32 xmitMultiplier,
INT32 recvMultiplier
)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
RTSPProtocol::HandleSourceDone(void)
{
mSourceEnd = TRUE;
if (mOwner)
{
mOwner->SetEndOfClip();
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandlePrerollChange(THIS_
RTSPPrerollTypeEnum prerollType,
UINT32 ulPreroll)
{
if (RTSP_PREROLL_PREDECBUFPERIOD == prerollType)
{
// Handle 3GPP 26.234 Annex G x-initpredecbufperiod field
// This field only updates the preroll for video streams
// Look through all the streams
for (UINT16 uStrmNum = 0; uStrmNum < m_uStreamCount; uStrmNum++)
{
STREAM_INFO* pStreamInfo = NULL;
IHXBuffer* pMimeType = NULL;
// Look for video streams
if ((HXR_OK == mOwner->GetStreamInfo(uStrmNum, pStreamInfo)) &&
(pStreamInfo->m_pHeader) &&
(HXR_OK == pStreamInfo->m_pHeader->GetPropertyCString("Mimetype",
pMimeType)) &&
(!strncasecmp("video/", (char*)pMimeType->GetBuffer(), 6)))
{
// Update the preroll value
pStreamInfo->BufferingState().UpdatePreroll(ulPreroll);
}
HX_RELEASE(pMimeType);
}
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::HandleStreamDone
(
HX_RESULT status,
UINT16 uStreamNumber
)
{
STREAM_INFO* pStreamInfo;
if (HXR_OK != mOwner->GetStreamInfo(uStreamNumber, pStreamInfo))
{
return HXR_FAIL;
}
HX_ASSERT(!pStreamInfo->m_bSrcStreamDone);
if (!pStreamInfo->m_bSrcStreamDone)
{
pStreamInfo->m_bSrcStreamDone = TRUE;
m_uCurrentStreamCount--;
if (!m_uCurrentStreamCount)
{
mOwner->SetEndOfClip();
}
}
return HXR_OK;
}
STDMETHODIMP
RTSPProtocol::GetStatus
(
REF(UINT16) uStatusCode,
REF(IHXBuffer*) pStatusDesc,
REF(UINT16) ulPercentDone
)
{
// XXX HP
// we no longer care about the buffering at the transport layer
// playback starts as soon as we get enough data at BufferManager
#if 0
/*
* XXX...This needs to be properly implemented
*/
CHXBuffer* pStatus = NULL;
IUnknown* pContext = NULL;
IHXClientEngine* pEngine = NULL;
uStatusCode = HX_STATUS_READY;
ulPercentDone = 100;
pStatusDesc = NULL;
if (!m_bConnectDone)
{
uStatusCode = HX_STATUS_CONTACTING;
ulPercentDone = 0;
mOwner->GetContext(pContext);
#if defined(HELIX_FEATURE_RESOURCEMGR)
if (pContext &&
HXR_OK == pContext->QueryInterface(IID_IHXClientEngine, (void**)&pEngine))
{
pStatus = ((HXClientEngine *)pEngine)->GetResMgr()->GetMiscString(IDS_STATUS_CONTACTING);
}
pStatusDesc = new CHXBuffer;
if (!pStatusDesc)
{
return HXR_OUTOFMEMORY;
}
pStatusDesc->AddRef();
CHXString statusDesc = "";
if (pStatus)
{
statusDesc += (const char*) pStatus->GetBuffer();
statusDesc += " ";
}
statusDesc += mHost;
statusDesc += "...";
pStatusDesc->Set((UCHAR*)(const char*) statusDesc,
strlen((const char*)statusDesc)+1);
HX_RELEASE(pStatus);
HX_RELEASE(pEngine);
#endif /* HELIX_FEATURE_RESOURCEMGR */
HX_RELEASE(pContext);
return HXR_OK;
}
else if (m_pPendingStatus)
{
return m_pPendingStatus->GetStatus(uStatusCode,
pStatusDesc,
ulPercentDone);
}
else
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = 0;
}
return HXR_OK;
#else
return HXR_NOTIMPL;
#endif
}
#if defined(HELIX_FEATURE_STATS)
/************************************************************************
* Method:
* IHXStatistics::InitializeStatistics
* Purpose:
* Pass registry ID to the caller
*/
STDMETHODIMP
RTSPProtocol::InitializeStatistics
(
UINT32 /*IN*/ ulRegistryID
)
{
m_ulRegistryID = ulRegistryID;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXStatistics::UpdateStatistics
* Purpose:
* Notify the user to updates its statistics registry
*/
STDMETHODIMP
RTSPProtocol::UpdateStatistics()
{
if (!m_pStatistics)
{
return HXR_FAIL;
}
return m_pStatistics->UpdateStatistics();
}
#endif /* HELIX_FEATURE_STATS */
HX_RESULT
RTSPProtocol::GetStreamStatistics
(
ULONG32 ulStreamNumber,
STREAM_STATS** ppStreamStats
)
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
RTSP_STREAM_INFO* pStreamInfo;
if (!m_pStreamInfoList->Lookup(ulStreamNumber, (void*&)pStreamInfo))
{
*ppStreamStats = NULL;
return HXR_FAIL;
}
*ppStreamStats = pStreamInfo->m_pStreamStats;
return HXR_OK;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
HX_RESULT
RTSPProtocol::UpdateRegistry(UINT32 ulStreamNumber,
UINT32 ulRegistryID)
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
HX_RESULT result = HXR_OK;
if (!m_pRegistry)
{
return HXR_FAIL;
}
CHXMapLongToObj::Iterator i;
for (i = m_pStreamInfoList->Begin(); i != m_pStreamInfoList->End(); ++i)
{
RTSP_STREAM_INFO* pStreamInfo = (RTSP_STREAM_INFO*)(*i);
if (pStreamInfo->m_uStreamNumber == (UINT16)ulStreamNumber)
{
STREAM_STATS* pTmpStreamStats = new STREAM_STATS(m_pRegistry, ulRegistryID);
*pTmpStreamStats = *pStreamInfo->m_pStreamStats;
HX_DELETE(pStreamInfo->m_pStreamStats);
pStreamInfo->m_pStreamStats = pTmpStreamStats;
if (m_pProtocolLib)
{
((RTSPClientProtocol*)m_pProtocolLib)->SetStatistics(pStreamInfo->m_uStreamNumber,
pStreamInfo->m_pStreamStats);
}
break;
}
}
return result;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
STDMETHODIMP
RTSPProtocol::RuleChange(REF(CHXSimpleList) pList)
{
return m_pProtocolLib->RuleChange(&pList);
}
/*
* IHXASMSource methods
*/
/************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -