📄 rtspbase.cpp
字号:
MIMEHeader* pMimeHeader;
const char* pName = NULL;
IHXBuffer* pValue = NULL;
IHXKeyValueList* pKeyedHdrs;
if (!pRFC822Headers)
{
return;
}
// Find out if the IHXValues supports IHXKeyValueList
// XXX showell - eventually, we should just make all callers
// give us an IHXKeyValueList, since it's more efficient,
// and so we don't overwrite duplicate headers.
res = pRFC822Headers->QueryInterface(IID_IHXKeyValueList,
(void**) &pKeyedHdrs);
if (res == HXR_OK)
{
IHXKeyValueListIter* pListIter = NULL;
pKeyedHdrs->GetIter(pListIter);
HX_ASSERT(pListIter);
while (pListIter->GetNextPair(pName, pValue) == HXR_OK)
{
pMimeHeader = new MIMEHeader(pName);
pMimeHeader->addHeaderValue((char*)pValue->GetBuffer());
pMsg->addHeader(pMimeHeader);
HX_RELEASE(pValue);
}
HX_RELEASE(pListIter);
}
else
{
res = pRFC822Headers->GetFirstPropertyCString(pName, pValue);
while (res == HXR_OK)
{
pMimeHeader = new MIMEHeader(pName);
pMimeHeader->addHeaderValue((char*)pValue->GetBuffer());
pMsg->addHeader(pMimeHeader);
pValue->Release();
res = pRFC822Headers->GetNextPropertyCString(pName, pValue);
}
}
HX_RELEASE(pKeyedHdrs);
}
void
RTSPBaseProtocol::getRFC822Headers(RTSPMessage* pMsg,
REF(IHXValues*) pRFC822Headers)
{
MIMEHeader* pHeader = NULL;
IUnknown* pUnknown = NULL;
IHXKeyValueList* pList = NULL;
pRFC822Headers = NULL;
if (!m_pCommonClassFactory)
{
goto cleanup;
}
if (HXR_OK != m_pCommonClassFactory->CreateInstance(CLSID_IHXKeyValueList,
(void**) &pUnknown))
{
goto cleanup;
}
if (HXR_OK != pUnknown->QueryInterface(IID_IHXKeyValueList,
(void**) &pList))
{
goto cleanup;
}
pHeader = pMsg->getFirstHeader();
while (pHeader)
{
MIMEHeaderValue* pHeaderValue;
/*
* XXX...There is way too much memcpy() going on here
*/
pHeaderValue = pHeader->getFirstHeaderValue();
CHXString HeaderString;
while (pHeaderValue)
{
CHXString TempString;
pHeaderValue->asString(TempString);
HeaderString += TempString;
pHeaderValue = pHeader->getNextHeaderValue();
if (pHeaderValue)
{
HeaderString += ", ";
}
}
IHXBuffer *pBuffer = NULL;
CHXBuffer::FromCharArray((const char*) HeaderString, &pBuffer);
pList->AddKeyValue(pHeader->name(), pBuffer);
HX_RELEASE(pBuffer);
pHeader = pMsg->getNextHeader();
}
// XXX showell - Yet another item for rnvalues cleanup phase II. We should
// just change this function so its callers don't expect IHXValues, since
// the IHXKeyValueList interface is better for header data.
if (HXR_OK != pList->QueryInterface(IID_IHXValues,
(void**) &pRFC822Headers))
{
pRFC822Headers = NULL;
}
cleanup:
HX_RELEASE(pList);
HX_RELEASE(pUnknown);
}
HX_RESULT
RTSPBaseProtocol::sendControlMessage(IHXBuffer* pBuffer)
{
HX_RESULT hxr = HXR_OK;
handleDebug(pBuffer, FALSE);
handleTiming(pBuffer, FALSE);
if (!m_pSocket)
{
m_pControlBuffer = pBuffer;
m_pControlBuffer->AddRef();
hxr = reopenSocket();
}
else
{
m_uControlBytesSent += pBuffer->GetSize();
if (m_pFastSocket)
{
hxr = m_pFastSocket->BufferedWrite(pBuffer);
m_pFastSocket->FlushWrite();
}
else
{
hxr = m_pSocket->Write(pBuffer);
}
}
return hxr;
}
HX_RESULT
RTSPBaseProtocol::handleACK(IHXPacketResend* pPacketResend,
RTSPResendBuffer* pResendBuffer,
UINT16 uStreamNumber,
UINT16* pAckList,
UINT32 uAckListCount,
UINT16* pNakList,
UINT32 uNakListCount,
BOOL bIgnoreACK)
{
if (!pResendBuffer)
{
return HXR_UNEXPECTED;
}
/*
* ACKs and NAKs only have meaning for resend buffers
*
* NOTE: keep the ACKing/NAKing in order by starting at the back of
* the lists
*/
INT32 i;
if (!bIgnoreACK)
{
for (i = uAckListCount - 1; i >= 0; i--)
{
pResendBuffer->Remove(pAckList[i]);
}
}
if (uNakListCount)
{
//XXXGH...must be BasePacket
BasePacket** ppPacket = new BasePacket*[uNakListCount + 1];
/*
* Only allow 10 packets to be resent
*/
UINT16 j = 0;
for (i = uNakListCount - 1; i >= 0 && j < 10; i--)
{
BasePacket* pPacket;
pPacket = pResendBuffer->Find(pNakList[i], TRUE);
if (pPacket)
{
ppPacket[j++] = pPacket;
pPacket->AddRef();
}
}
ppPacket[j] = 0;
//XXX..will the BasePacket have the stream number in it?
pPacketResend->OnPacket(uStreamNumber, ppPacket);
BasePacket* pReleasePacket = NULL;
BasePacket** ppReleasePacket = ppPacket;
for (; (pReleasePacket = *ppReleasePacket); ppReleasePacket++)
{
HX_RELEASE(pReleasePacket);
}
HX_VECTOR_DELETE(ppPacket);
}
return HXR_OK;
}
/*
* The grammer in RFC2326, I think, is wrong....But in any case, there is no
* gurantee seq_no and rtptime are present in RTP-Info.
*/
RTPInfoEnum
RTSPBaseProtocol::parseRTPInfoHeader(
MIMEHeaderValue* pSeqValue, UINT16& streamID, UINT16& seqNum,
UINT32& ulTimestamp, const char*& pControl)
{
BOOL bFoundSeqNo = FALSE;
BOOL bFoundRTPTime = FALSE;
MIMEParameter* pParam = pSeqValue->getFirstParameter();
while (pParam != NULL)
{
if(pParam->m_attribute == "url")
{
// Note: We don't currently do anything with the first section
// of the "url" attribute (the actual player-requested URL). If
// we ever do, please note that all ';' characters were escaped
// by the server when this message was created, because ';' has
// special meaning as a delimiter in this message. Remember to
// unescape all instances of "%3b" to ";" before using the URL.
const char* pUrl = (const char*) pParam->m_value;
const char* pEq = strrchr(pUrl, '=');
if (pEq != NULL)
{
streamID = (UINT16)strtol(pEq + 1, 0, 10);
}
// take the control string...
pControl = pUrl;
}
else if(pParam->m_attribute == "seq")
{
bFoundSeqNo = TRUE;
seqNum = (UINT16)strtol((const char*)pParam->m_value,0,10);
}
else if(pParam->m_attribute == "rtptime")
{
bFoundRTPTime = TRUE;
ulTimestamp = (UINT32)strtoul((const char*)pParam->m_value, 0, 10);
}
pParam = pSeqValue->getNextParameter();
}
if (bFoundSeqNo)
{
if (bFoundRTPTime)
{
return RTPINFO_SEQ_RTPTIME;
}
return RTPINFO_SEQ;
}
if (bFoundRTPTime)
{
return RTPINFO_RTPTIME;
}
return RTPINFO_EMPTY;
}
BOOL
RTSPBaseProtocol::isRequired(RTSPMessage* pRTSPMessageToSearch,
UINT32 ulOptionToFind)
{
BOOL bRetainState = FALSE;
MIMEHeader* pMIMEHeaderRequire;
pMIMEHeaderRequire = pRTSPMessageToSearch->getHeader("Require");
// If a require header was found
if (pMIMEHeaderRequire != NULL)
{
MIMEHeaderValue* pMIMEHeaderValueRequire =
pMIMEHeaderRequire->getFirstHeaderValue();
while (pMIMEHeaderValueRequire != NULL)
{
if (!strcasecmp(RTSPRequireOptionsTable[ulOptionToFind].pcharOption,
pMIMEHeaderValueRequire->value()))
{
bRetainState = TRUE;
}
pMIMEHeaderValueRequire = pMIMEHeaderRequire->getNextHeaderValue();
}
}
return bRetainState;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -