📄 sdpmdparse.cpp
字号:
} else { return HXR_OK; }}void SDPMediaDescParser::clearStreamList(){ LISTPOSITION pos = m_streams.GetHeadPosition(); while(pos) { IHXValues* pStream = (IHXValues*)m_streams.GetNext(pos); HX_RELEASE(pStream); } m_streams.RemoveAll();}IHXValues* SDPMediaDescParser::CreateHeader(){ IHXValues* pRet = 0; if (m_pCCF) m_pCCF->CreateInstance(IID_IHXValues, (void**)&pRet); return pRet;}void SDPMediaDescParser::AddULONG32(IHXValues* pHeader, const char* pKey, ULONG32 ulValue){ pHeader->SetPropertyULONG32(pKey, ulValue);}void SDPMediaDescParser::AddString(IHXValues* pHeader, const char* pKey, const char* pValue){ if ((pKey == NULL) || (pValue == NULL)) { return; } IHXBuffer* pBuf = CopyBuffer((const UINT8*)pValue, strlen(pValue) + 1); if (pBuf) pHeader->SetPropertyCString(pKey, pBuf); HX_RELEASE(pBuf);}void SDPMediaDescParser::AddBuffer(IHXValues* pHeader, const char* pKey, const UINT8* pValue, ULONG32 ulLength){ IHXBuffer* pBuf = CopyBuffer(pValue, ulLength); if (pBuf) pHeader->SetPropertyBuffer(pKey, pBuf); HX_RELEASE(pBuf);}IHXBuffer* SDPMediaDescParser::CopyBuffer(const UINT8* pBuf, ULONG32 ulLength){ IHXBuffer* pRet = 0; if (SUCCEEDED(m_pCCF->CreateInstance(IID_IHXBuffer, (void**)&pRet))) pRet->Set(pBuf, ulLength); return pRet;}HX_RESULT SDPMediaDescParser::GetLine(const char*& pData, const char* pEnd, IHXBuffer*& pLine) const{ HX_RESULT res = HXR_OK; CHXCharStack tok(m_pCCF); BOOL bInQuote = FALSE; BOOL bLastWasEscape = FALSE; for (; (HXR_OK == res) && *pData && (pData < pEnd) && (bInQuote || !strchr("\r\n", *pData)); pData++) { if (bLastWasEscape) { bLastWasEscape = FALSE; } else { if (*pData == '"') { bInQuote = !bInQuote; } else if (*pData == '\\') { bLastWasEscape = TRUE; } } res = tok.AddChar(*pData); } if (HXR_OK == res) { res = tok.Finish(pLine); } return res;}void SDPMediaDescParser::SkipSpaces(char*& pData) const{ for (; *pData && *pData == ' '; pData++) ;}BOOL SDPMediaDescParser::ScanForDelim(char*& pData, char delim) const{ BOOL bRet = FALSE; while(*pData && !bRet) { if (*pData == delim) { bRet = TRUE; } else { pData++; } } return bRet;}HX_RESULT SDPMediaDescParser::HandleVLine(char* pLine){ HX_RESULT res = HXR_FAILED; char* pEnd = 0; unsigned long version = strtoul(pLine, &pEnd, 10); if (*pLine && !*pEnd && (version == 0)) { res = HXR_OK; } return res;}HX_RESULT SDPMediaDescParser::HandleMLine(char* pLine, IHXValues* pHdr){ HX_RESULT res = HXR_FAILED; if (*pLine) { int state = 0; const char* pMediaType = pLine; ULONG32 ulPort = 0; ULONG32 ulPayloadType = 0; if (ScanForDelim(pLine, ' ')) { // Null terminate mimetype *pLine++ = '\0'; // Save media type for later m_mediaType = pMediaType; res = HXR_OK; } while(*pLine && (HXR_OK == res)) { char* pEnd = 0; SkipSpaces(pLine); if (*pLine) { switch(state) { case 0: // Grab port number ulPort = strtoul(pLine, &pEnd, 10); if (*pEnd == ' ') { pLine = pEnd; state = 1; } else { // No transport field or // invalid port character res = HXR_FAILED; } break; case 1: // Skip transport. Usually RTP/AVP if (ScanForDelim(pLine, ' ')) { state = 2; } break; case 2: // Grab the first payload type ulPayloadType = strtoul(pLine, &pEnd, 10); if ((*pEnd == ' ') || !*pEnd ) { state = 3; } else { // There was an unexpected character // the the payload type res = HXR_FAILED; } case 3: // Consume the rest of the payload types for (; *pLine; pLine++) ; break; } } } if (state == 3) { AddULONG32(pHdr, "RTPPayloadType", ulPayloadType); if (ulPort) { AddULONG32(pHdr, "Port", ulPort); } if (SDPIsStaticPayload(ulPayloadType)) { if (IsPayloadTableValid(ulPayloadType)) { if (!SDPIsTimestampDeliverable(ulPayloadType)) { ULONG32 ulBitrate = SDPMapPayloadToBitrate(ulPayloadType); HX_ASSERT(ulBitrate); // we have a bandwidth info in a table... AddULONG32(pHdr, "AvgBitRate", ulBitrate); } // static payload type AddString(pHdr, "MimeType", SDPMapPayloadToMimeType(ulPayloadType)); AddULONG32(pHdr, "RTPTimestampConversionFactor", SDPMapPayloadToRTPFactor(ulPayloadType)); AddULONG32(pHdr, "HXTimestampConversionFactor", SDPMapPayloadToRMAFactor(ulPayloadType)); AddULONG32(pHdr, "SamplesPerSecond", SDPMapPayloadToSamplesPerSecond(ulPayloadType)); AddULONG32(pHdr, "Channels", (ULONG32)SDPMapPayloadToChannels(ulPayloadType)); // deal with opaque hack... const BYTE* pOpaqueData = NULL; ULONG32 ulOpaqueDataSize = 0; switch(ulPayloadType) { case RTP_PAYLOAD_GSM: pOpaqueData = SDPMapPayloadToHeaderData(RTP_PAYLOAD_GSM, ulOpaqueDataSize); break; } if (pOpaqueData) { AddBuffer(pHdr, "OpaqueData", pOpaqueData, ulOpaqueDataSize); } } else { res = HXR_REQUEST_UPGRADE; } } } else if (HXR_OK == res) { res = HXR_FAILED; } } return res;}HX_RESULT SDPMediaDescParser::HandleALine(char* pLine, IHXValues* pHdr){ HX_RESULT res = HXR_FAILED; const char* pFieldName = pLine; char* pFieldValue = 0; FieldType fieldType = ftUnknown; if (*pLine) { // Collect the field name if (ScanForDelim(pLine, ':')) { char* pColon = pLine; // Must be the key/value form // a=foo:bar // Null terminate field name by replacing ':' with '\0' *pLine++ = '\0'; pFieldValue = pLine; if ((HXR_OK == (res = ParseFieldValue(pFieldValue, fieldType)))) { switch (fieldType) { case ftUnknown: res = HandleSpecialFields(pFieldName, pFieldValue, pHdr); break; case ftULONG32: { char* pEnd = 0; ULONG32 ulValue = strtoul(pFieldValue, &pEnd, 10); if (*pFieldValue && !*pEnd) { res = pHdr->SetPropertyULONG32(pFieldName, ulValue); } } break; case ftString: AddString(pHdr, pFieldName, pFieldValue); res = HXR_OK; break; case ftBuffer: { int length = strlen(pFieldValue); BYTE* pDecodeBuf = new BYTE[length]; INT32 decodeLen = BinFrom64(pFieldValue, length, pDecodeBuf); if( decodeLen != -1 ) { AddBuffer(pHdr, pFieldName, pDecodeBuf, decodeLen); } res = HXR_OK; delete [] pDecodeBuf; }break; } } if (HXR_OK != res) { // Put back the ':' *pColon = ':'; } } else { // Must be the key only form // a=foo res = HXR_NOT_SUPPORTED; } } return res;}HX_RESULT SDPMediaDescParser::HandleCLine(char* pLine, IHXValues* pHdr){ // Handles the following forms // c=IN IP4 xxx.xxx.xxx.xxx // c=IN IP4 xxx.xxx.xxx.xxx/xxx // c=IN IP4 xxx.xxx.xxx.xxx/xxx/xx HX_RESULT res = HXR_FAILED; char* pCur = pLine; if (ScanForDelim(pCur, ' ')) { *pCur++ = '\0'; SkipSpaces(pCur); char* pAddrType = pCur; if (!strcasecmp(pLine, "IN") && ScanForDelim(pCur, ' ')) { *pCur++ = '\0'; SkipSpaces(pCur); if (!strcasecmp(pAddrType, "IP4") && *pCur) { char* pAddr = pCur; if (ScanForDelim(pCur, '/')) { *pCur++ = '\0'; if (*pCur) { char* pEnd = 0; ULONG32 ulTTL = strtoul(pCur, &pEnd, 10); if (*pCur && ((*pEnd == '/') || (!*pEnd))) { AddULONG32(pHdr, "MulticastTTL", ulTTL); res = HXR_OK; pCur = pEnd; if (*pCur) { pCur++; // skip '/' ULONG32 ulRange = strtoul(pCur, &pEnd, 10); if (*pCur && !*pEnd) { // c=IN IP4 xxx.xxx.xxx.xxx/xxx/xx AddULONG32(pHdr, "MulticastRange", ulRange); res = HXR_OK; } } } } } else { // c=IN IP4 xxx.xxx.xxx.xxx res = HXR_OK; } if (HXR_OK == res) { AddString(pHdr, "MulticastAddress", pAddr); } } } } return res;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -