sdpchunk.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:42k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /****************************************************************************
- * Defines
- */
- #define DFLT_PAYLOAD_MIME_TYPE "data/x-unknown"
- #define CHAR_LF 0x0a
- #define CHAR_CR 0x0d
- #define BAD_PULL_TABLE_IDX 0xFFFFFFFF
- #define MAX_INT_TEXT_LENGTH 10
- #define N_CLIPRECT_COORDS 4
- #define FMPT_PREFIX "FMTP"
- #define FMPT_PREFIX_SIZE (sizeof(FMPT_PREFIX) - 1)
- /****************************************************************************
- * Includes
- */
- //#include "hlxclib/stdlib.h"
- #include "hxstrutl.h"
- #include "hxassert.h"
- #include "sdpchunk.h"
- #include "hxstring.h"
- #include "hxslist.h"
- #include "sdppyldinfo.h"
- /****************************************************************************
- * Locals
- */
- /****************************************************************************
- * Pull Functions
- */
- static HX_RESULT PullSessionName(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullMediaDesc (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullRTPMap (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullControl (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullClipRect (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullBufferDelay(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullFormatParams(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullGroupID (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullGroupBitrate(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- static HX_RESULT PullBandwidth (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory);
- /****************************************************************************
- * Local Utilities
- */
- inline static ULONG32 GetPullTableIdx(const SDPRecordPuller* pTable,
- char* pData,
- ULONG32 ulRecordSize);
- inline static char* FindSDPFieldByIdx(char* pData,
- ULONG32 ulLength,
- ULONG32 ulIdx);
- inline static char* FindSDPFieldEnd(char* pData,
- ULONG32 ulLength);
- inline static char* FindCRLF(char* pData,
- ULONG32 ulLength);
- inline static HX_RESULT PullLine(char* pData,
- ULONG32 ulLength,
- REF(IHXBuffer*) pLine,
- IHXCommonClassFactory* pClassFactory);
- inline static char* SkipSDPFieldEnd(char* pData,
- ULONG32 ulLength);
- inline static void OrderUp(LONG32 &l1, LONG32 &l2);
- /****************************************************************************
- * Pull Tables - must be NULL terminated
- */
- const SDPRecordPuller SessionPullTable[] =
- {
- {"s=", sizeof("s=") - 1, PullSessionName},
- {"b=", sizeof("b=") - 1, PullBandwidth},
- {NULL, 0, NULL}
- };
- const SDPRecordPuller MediaPullTable[] =
- {
- {"m=", sizeof("m=") - 1, PullMediaDesc},
- {"a=rtpmap:", sizeof("a=rtpmap:") - 1, PullRTPMap},
- {"a=control:", sizeof("a=control:") - 1, NULL},
- {"b=", sizeof("b=") - 1, PullBandwidth},
- {NULL, 0, NULL}
- };
- const SDPRecordPuller TimePullTable[] =
- {
- {NULL, 0, NULL}
- };
- const SDPRecordPuller GenericPullTable[] =
- {
- {NULL, 0, NULL}
- };
- const SDPRecordPuller RendererPullTable[] =
- {
- {"a=cliprect:", sizeof("a=cliprect:") - 1, PullClipRect},
- {"a=x-bufferdelay:", sizeof("a=x-bufferdelay:") - 1, PullBufferDelay},
- {"a=fmtp:", sizeof("a=fmtp:") - 1, PullFormatParams},
- {NULL, 0, NULL}
- };
- const SDPRecordPuller GroupPullTable[] =
- {
- {"a=x-alternate:group=", sizeof("a=x-alternate:group=") - 1, PullGroupID},
- {"a=x-alternate:datarate=", sizeof("a=x-alternate:datarate=") - 1, PullGroupBitrate},
- {NULL, 0, NULL}
- };
- /****************************************************************************
- * Global Utility fuinctions
- */
- /****************************************************************************
- * SDPParseChunk - use context
- */
- HX_RESULT SDPParseChunk(char* pData,
- ULONG32 ulDataLen,
- IHXValues* &pSDPValues,
- IHXCommonClassFactory *pClassFactory,
- SDPChunkContext SDPContext,
- BOOL bPullRecords)
- {
- HX_RESULT retVal = HXR_OK;
- const SDPRecordPuller* pPullTable = NULL;
- switch (SDPContext)
- {
- case SDPCTX_Media:
- pPullTable = MediaPullTable;
- break;
- case SDPCTX_Session:
- pPullTable = SessionPullTable;
- break;
- case SDPCTX_Group:
- pPullTable = GroupPullTable;
- break;
- case SDPCTX_Time:
- pPullTable = TimePullTable;
- break;
- case SDPCTX_Generic:
- pPullTable = GenericPullTable;
- break;
- case SDPCTX_Renderer:
- pPullTable = RendererPullTable;
- break;
- default:
- retVal = HXR_INVALID_PARAMETER;
- break;
- }
- if (SUCCEEDED(retVal))
- {
- retVal = SDPParseChunk(pData,
- ulDataLen,
- pSDPValues,
- pClassFactory,
- pPullTable,
- bPullRecords);
- }
- return retVal;
- }
- /****************************************************************************
- * SDPParseChunk - use custom pull table
- */
- HX_RESULT SDPParseChunk(char* pData,
- ULONG32 ulDataLen,
- IHXValues* &pSDPValues,
- IHXCommonClassFactory *pClassFactory,
- const SDPRecordPuller* pPullTable,
- BOOL bPullRecords)
- {
- HX_RESULT retVal = HXR_OK;
- IHXBuffer* pSDPBuffer = NULL;
- char* pSDPData = NULL;
- char* pPattern;
- ULONG32 ulRecordSize;
- ULONG32 ulPullTableIdx;
- BOOL bSDPValuesMadeHere = FALSE;
-
- if ((pData == NULL) || (ulDataLen == 0))
- {
- if (pSDPValues == NULL)
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- if (!pSDPValues)
- {
- bSDPValuesMadeHere = TRUE;
- retVal = pClassFactory->CreateInstance(CLSID_IHXValues,
- (void**) &pSDPValues);
- }
- if (bPullRecords)
- {
- if (SUCCEEDED(retVal))
- {
- retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
- (void**) &pSDPBuffer);
- }
-
- if (SUCCEEDED(retVal))
- {
- retVal = pSDPBuffer->SetSize(ulDataLen + 1);
- }
- }
- if (SUCCEEDED(retVal))
- {
- if (pPullTable == NULL)
- {
- retVal = HXR_INVALID_PARAMETER;
- }
- }
- if (SUCCEEDED(retVal))
- {
- if (pSDPBuffer)
- {
- pSDPData = (char*) pSDPBuffer->GetBuffer();
- }
-
- do
- {
- pPattern = StrNChr(pData, CHAR_LF, ulDataLen);
- if (pPattern == NULL)
- {
- ulRecordSize = ulDataLen;
- }
- else
- {
- ulRecordSize = pPattern - pData;
- pPattern = SkipSDPFieldEnd(pPattern,
- ulDataLen - ulRecordSize);
- ulRecordSize = pPattern - pData;
- }
-
- ulPullTableIdx = GetPullTableIdx(pPullTable,
- pData,
- ulRecordSize);
- if (ulPullTableIdx == BAD_PULL_TABLE_IDX)
- {
- if (pSDPData)
- {
- // keep this entry as SDP data
- memcpy(pSDPData, pData, ulRecordSize); /* Flawfinder: ignore */
- pSDPData += ulRecordSize;
- }
- }
- else
- {
- // pull this record out of SDP data
- if (pPullTable[ulPullTableIdx].pPullFunc)
- {
- retVal = (*(pPullTable[ulPullTableIdx].pPullFunc))(
- pData,
- ulRecordSize,
- pSDPValues,
- pClassFactory);
- }
- }
- pData += ulRecordSize;
- ulDataLen -= ulRecordSize;
- } while ((ulDataLen != 0) && SUCCEEDED(retVal));
- }
-
- if (SUCCEEDED(retVal) && pSDPData)
- {
- HX_ASSERT(((ULONG32) (pSDPData - ((char *) pSDPBuffer->GetBuffer())) )
- < pSDPBuffer->GetSize());
- if (((char *) pSDPBuffer->GetBuffer()) != pSDPData)
- {
- *pSDPData = ' ';
- pSDPValues->SetPropertyCString("SDPData", pSDPBuffer);
- }
- }
- HX_RELEASE(pSDPBuffer);
- if (FAILED(retVal) && bSDPValuesMadeHere)
- {
- HX_RELEASE(pSDPValues);
- }
- return retVal;
- }
- /****************************************************************************
- * SDPMapPayloadToMime
- */
- HX_RESULT SDPMapPayloadToMime(ULONG32 ulPayloadType,
- IHXBuffer* &pMimeType,
- IHXCommonClassFactory *pClassFactory)
- {
- HX_RESULT retVal = HXR_OK;
- HX_ASSERT(pClassFactory);
- if (!pMimeType)
- {
- retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
- (void**) &pMimeType);
- }
- if (SUCCEEDED(retVal))
- {
- const char* pPayloadMime = DFLT_PAYLOAD_MIME_TYPE;
- if (SDPIsKnownPayload(ulPayloadType))
- {
- pPayloadMime = SDPMapPayloadToMimeType(ulPayloadType);
- }
- retVal = pMimeType->Set((UCHAR*) pPayloadMime,
- strlen(pPayloadMime) + 1);
- }
- return retVal;
- }
- /****************************************************************************
- * SDPIsFixedRatePayload
- */
- BOOL SDPIsFixedRatePayload(ULONG32 ulPayloadType)
- {
- if (SDPIsStaticPayload(ulPayloadType))
- {
- return !SDPIsTimestampDeliverable(ulPayloadType);
- }
- return FALSE;
- }
- /****************************************************************************
- * SDPMapMimeToSamplesPerSecond
- */
- ULONG32 SDPMapMimeToSamplesPerSecond(IHXBuffer* pMimeTypeBuffer)
- {
- ULONG32 ulPayload = 0;
- ULONG32 ulSamplesPerSecond = 0;
- if (SUCCEEDED(SDPMapMimeToPayload(pMimeTypeBuffer, ulPayload)))
- {
- ulSamplesPerSecond = SDPMapPayloadToSamplesPerSecond(ulPayload);
- }
- else
- {
- const char* pTargetMimeType = (const char*)pMimeTypeBuffer->GetBuffer();
- ulSamplesPerSecond = SDPMapMimeTypeToSampleRate(pTargetMimeType);
- }
- return ulSamplesPerSecond;
- }
- /****************************************************************************
- * SDPIsKnownPayload
- */
- BOOL SDPIsKnownPayload(ULONG32 ulPayloadType)
- {
- return (SDPIsStaticPayload(ulPayloadType) &&
- (SDPMapPayloadToMimeType(ulPayloadType) != NULL));
- }
- /****************************************************************************
- * SDPMapMimeToPayloadID
- */
- HX_RESULT SDPMapMimeToPayload(IHXBuffer* pMimeTypeBuffer, ULONG32 &ulPayload)
- {
- ULONG32 ulId;
- HX_RESULT retVal = HXR_FAIL;
- char* pMimeType = NULL;
- char* pEncodingName;
- if (pMimeTypeBuffer)
- {
- pMimeType = (char *) pMimeTypeBuffer->GetBuffer();
- }
- if (pMimeType &&
- (pEncodingName = strchr((char*) pMimeType, '/')))
- {
- pEncodingName++;
-
- for (ulId = 0; SDPIsStaticPayload(ulId); ulId++)
- {
- if (SDPMapPayloadToEncodingName(ulId) &&
- !strcasecmp(SDPMapPayloadToEncodingName(ulId),
- pEncodingName))
- {
- ulPayload = ulId;
- retVal = HXR_OK;
- break;
- }
- }
- }
- return retVal;
- }
- /****************************************************************************
- * Pull Functions
- */
- /****************************************************************************
- * Pull Functions
- */
- /*
- * "s=" text CRLF
- */
- static HX_RESULT PullSessionName(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- HX_ASSERT(pData && !strncmp(pData, "s=", 2));
- HX_RESULT retVal = HXR_FAIL;
- IHXBuffer* pSessionName = NULL;
- retVal = PullLine(pData + 2, ulLength - 2, pSessionName, pClassFactory);
- if (SUCCEEDED(retVal))
- {
- retVal = pSDPValues->SetPropertyCString("Title", pSessionName);
- }
- HX_RELEASE(pSessionName);
- return retVal;
- }
- static HX_RESULT PullMediaDesc (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPayloadType = 0;
- IHXBuffer* pMimeType = NULL;
- HX_RESULT retVal = HXR_FAIL;
- // Extract Payload Type
- pPattern = FindSDPFieldByIdx(pData, ulLength, 3);
- if (pPattern != NULL)
- {
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- ULONG32 ulNumTextLength = (ulLength - (pPattern - pData));
- if (ulNumTextLength > MAX_INT_TEXT_LENGTH)
- {
- ulNumTextLength = MAX_INT_TEXT_LENGTH;
- }
- memcpy(pNumBuffer, pPattern, ulNumTextLength); /* Flawfinder: ignore */
- pNumBuffer[ulNumTextLength] = ' ';
- ulPayloadType = strtol(pNumBuffer, &pNumEnd, 10);
- if (pNumEnd > pNumBuffer)
- {
- retVal = HXR_OK;
- }
- }
- // Prepare Mime Type
- if (SUCCEEDED(retVal))
- {
- const char* pPayloadMime = NULL;
- ULONG32 ulPayloadMimeLength = 0;
- char* pMimeStart = NULL;
- ULONG32 ulMimeLength = 0;
- if (SDPIsStaticPayload(ulPayloadType))
- {
- pPayloadMime = SDPMapPayloadToEncodingName(ulPayloadType);
- retVal = HXR_FAIL;
- if (pPayloadMime != NULL)
- {
- ulPayloadMimeLength = strlen(pPayloadMime) + 1;
- pSDPValues->SetPropertyULONG32(
- "SamplesPerSecond",
- SDPMapPayloadToSamplesPerSecond(ulPayloadType));
- UINT16 uChannels =
- SDPMapPayloadToChannels(ulPayloadType);
- if (uChannels > 0)
- {
- pSDPValues->SetPropertyULONG32(
- "Channels",
- uChannels);
- }
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- // extract portion of mime type
- // - will be completed when rtp map encountered
- // if this is not a static payload
- pPattern = StrNChr((char *) pData, ' ', ulLength);
- pMimeStart = pData + 2;
-
- retVal = HXR_FAIL;
-
- if ((pPattern != NULL) &&
- ((pPattern - pData) > 2))
- {
- ulMimeLength = pPattern - pData - 2;
-
- retVal = pClassFactory->CreateInstance(
- CLSID_IHXBuffer,
- (void**) &pMimeType);
- }
-
- if (SUCCEEDED(retVal))
- {
- retVal = pMimeType->SetSize(ulMimeLength +
- ulPayloadMimeLength +
- 1);
- }
-
- if (SUCCEEDED(retVal))
- {
- memcpy(pMimeType->GetBuffer(), /* Flawfinder: ignore */
- pMimeStart,
- ulMimeLength);
- if (ulPayloadMimeLength > 0)
- {
- memcpy(pMimeType->GetBuffer() + ulMimeLength + 1, /* Flawfinder: ignore */
- pPayloadMime,
- ulPayloadMimeLength - 1);
- pMimeType->GetBuffer()[ulMimeLength] = '/';
- }
-
- pMimeType->GetBuffer()[ulMimeLength +
- ulPayloadMimeLength] = ' ';
- }
- }
- }
- if (SUCCEEDED(retVal))
- {
- pSDPValues->SetPropertyULONG32("RTPPayloadType", ulPayloadType);
- pSDPValues->SetPropertyCString("MimeType", pMimeType);
- }
- HX_RELEASE(pMimeType);
- return retVal;
- }
- static HX_RESULT PullRTPMap(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern = NULL;
- char* pPatternEnd = NULL;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd = NULL;
- ULONG32 ulPatternLength = 0;
- ULONG32 ulPayloadType = 0;
- ULONG32 ulMediaPayloadType = 0;
- HX_RESULT retVal = HXR_FAIL;
- // Extract the Payload Type
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
- ulPayloadType = strtol(pNumBuffer, &pNumEnd, 10);
-
- if (pNumEnd > pNumBuffer)
- {
- retVal = pSDPValues->GetPropertyULONG32(
- "RTPPayloadType", ulMediaPayloadType);
- }
- }
- // Check if this is the payload type entry we are looking for
- if (SUCCEEDED(retVal) &&
- (ulMediaPayloadType == ulPayloadType))
- {
- IHXBuffer* pMimeType = NULL;
- ULONG32 ulOldMimeTextLength;
- BOOL bHasParams = TRUE;
- // Locate New and Old Mime Name Section
- pPattern = StrNChr((char *) pData, ' ', ulLength);
- retVal = HXR_FAIL;
- if (pPattern)
- {
- pPattern++;
-
- pPatternEnd = StrNChr(pPattern,
- '/',
- ulLength - (pPattern - pData));
- if (pPatternEnd == NULL)
- {
- bHasParams = FALSE;
- pPatternEnd = FindSDPFieldEnd(pPattern,
- ulLength - (pPattern - pData));
- }
-
- ulPatternLength = pPatternEnd - pPattern;
-
- if (ulPatternLength != 0)
- {
- retVal = pSDPValues->GetPropertyCString(
- "MimeType", pMimeType);
- }
- }
- // Realocate memory for combined name
- if (SUCCEEDED(retVal))
- {
- pMimeType->Release(); // OK since pSDPValues has ref.
- ulOldMimeTextLength = pMimeType->GetSize() - 1;
- retVal = pMimeType->SetSize(
- ulOldMimeTextLength + ulPatternLength + 2);
- }
- // Copy in new Mime Name section
- if (SUCCEEDED(retVal))
- {
- char *pMimeData = (char*) pMimeType->GetBuffer();
- memcpy(pMimeData + ulOldMimeTextLength + 1, /* Flawfinder: ignore */
- pPattern,
- ulPatternLength);
- pMimeData[ulOldMimeTextLength] = '/';
- pMimeData[pMimeType->GetSize() - 1] = ' ';
- }
- // Check for parameters following mime type
- if (SUCCEEDED(retVal))
- {
- ULONG32 ulParamIdx = 0;
- while (bHasParams)
- {
- pPattern += ulPatternLength + 1;
-
- pPatternEnd = StrNChr(pPattern,
- '/',
- ulLength - (pPattern - pData));
- if (pPatternEnd == NULL)
- {
- bHasParams = FALSE;
- pPatternEnd = FindSDPFieldEnd(
- pPattern,
- ulLength - (pPattern - pData));
- }
- ulPatternLength = pPatternEnd - pPattern;
-
- if (ulPatternLength != 0)
- {
- LONG32 lValue;
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- lValue = strtol(pNumBuffer, &pNumEnd, 10);
- if (pNumEnd > pNumBuffer)
- {
- switch (ulParamIdx)
- {
- case 0:
- pSDPValues->SetPropertyULONG32(
- "SamplesPerSecond", (ULONG32) lValue);
- break;
- case 1:
- pSDPValues->SetPropertyULONG32(
- "Channels", (ULONG32) lValue);
- break;
- default:
- // do nothing
- break;
- }
- }
- }
- ulParamIdx++;
- }
- }
- }
- return retVal;
- }
- static HX_RESULT PullControl(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern = NULL;
- char* pPatternEnd = NULL;
- ULONG32 ulPatternLength = 0;
- IHXBuffer* pControl = NULL;
- HX_RESULT retVal = HXR_FAIL;
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- pPattern++;
- pPatternEnd = FindSDPFieldEnd(
- pPattern, ulLength - (pPattern - pData));
- ulPatternLength = pPatternEnd - pPattern;
- if (ulPatternLength > 0)
- {
- retVal = pClassFactory->CreateInstance(
- CLSID_IHXBuffer,
- (void**) &pControl);
- }
- }
- if (SUCCEEDED(retVal))
- {
- retVal = pControl->SetSize(ulPatternLength + 1);
- memcpy(pControl->GetBuffer(), /* Flawfinder: ignore */
- pPattern,
- ulPatternLength);
- (pControl->GetBuffer())[ulPatternLength] = ' ';
- pSDPValues->SetPropertyCString("Control", pControl);
- HX_RELEASE(pControl);
- }
- return retVal;
- }
- static HX_RESULT PullClipRect(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPatternLength;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- ULONG32 ulIdx = 0;
- LONG32 lCoord[N_CLIPRECT_COORDS];
- HX_RESULT retVal = HXR_FAIL;
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- do
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- lCoord[ulIdx] = strtol(pNumBuffer, &pNumEnd, 10);
- if (pNumEnd == pNumBuffer)
- {
- break;
- }
- } while (((++ulIdx) < N_CLIPRECT_COORDS) &&
- (pPattern = StrNChr((char *) pPattern, ',', ulLength)));
- if (ulIdx == N_CLIPRECT_COORDS)
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- OrderUp(lCoord[0], lCoord[2]);
- OrderUp(lCoord[1], lCoord[3]);
- pSDPValues->SetPropertyULONG32("ClipFrameLeft", lCoord[1]);
- pSDPValues->SetPropertyULONG32("ClipFrameRight", lCoord[3]);
- pSDPValues->SetPropertyULONG32("ClipFrameTop", lCoord[0]);
- pSDPValues->SetPropertyULONG32("ClipFrameBottom", lCoord[2]);
- }
- return retVal;
- }
- static HX_RESULT PullFormatParams(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern = NULL;
- char* pPatternEnd = NULL;
- BOOL bParmNumeric = FALSE;
- ULONG32 ulParmValue = 0;
- ULONG32 ulPatternLength = 0;
- char* pParmName = NULL;
- IHXBuffer* pParmValue = NULL;
- HX_RESULT retVal = HXR_FAIL;
- // Find the start of name-value tuple
- pPattern = FindSDPFieldEnd((char*) pData, ulLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - (pPattern - pData));
- retVal = HXR_OK;
- }
- do
- {
- // Find the start of name-value tuple
- if (SUCCEEDED(retVal))
- {
- retVal = HXR_FAIL;
-
- pPattern = SkipSDPFieldEnd(pPattern, ulPatternLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - (pPattern - pData));
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- if (ulPatternLength == 0)
- {
- // Done: no more tuples
- break;
- }
- }
- // Parse the tuple name
- if (SUCCEEDED(retVal))
- {
- retVal = HXR_FAIL;
- pPatternEnd = StrNChr((char*) pPattern, '=', ulPatternLength);
- if (pPatternEnd)
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- retVal = HXR_FAIL;
- ulPatternLength = pPatternEnd - pPattern;
- if (ulPatternLength > 0)
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- retVal = HXR_OUTOFMEMORY;
- pParmName = new char [ulPatternLength + FMPT_PREFIX_SIZE + 1];
- if (pParmName)
- {
- retVal = HXR_OK;
- }
- }
- if (SUCCEEDED(retVal))
- {
- memcpy(pParmName, /* Flawfinder: ignore */
- FMPT_PREFIX,
- FMPT_PREFIX_SIZE);
- memcpy(pParmName + FMPT_PREFIX_SIZE, /* Flawfinder: ignore */
- pPattern,
- ulPatternLength);
- pParmName[ulPatternLength + FMPT_PREFIX_SIZE] = ' ';
- pPattern = pPatternEnd;
- ulPatternLength = (ulLength - ((++pPattern) - pData));
- }
- // Parse the tuple value
- if (SUCCEEDED(retVal))
- {
- retVal = HXR_FAIL;
- pPatternEnd = StrNChr(pPattern, ';', ulPatternLength);
- if (!pPatternEnd)
- {
- pPatternEnd = FindSDPFieldEnd(pPattern, ulPatternLength);
- }
- if (pPatternEnd)
- {
- ulPatternLength = pPatternEnd - pPattern;
- }
- if (ulPatternLength > 0)
- {
- retVal = HXR_OK;
- }
- }
- bParmNumeric = FALSE;
- if (SUCCEEDED(retVal) && (ulPatternLength <= (MAX_INT_TEXT_LENGTH - 1)))
- {
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd = NULL;
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
- ulParmValue = strtol(pNumBuffer, &pNumEnd, 10);
- if (pNumEnd && (pNumEnd == (pNumBuffer + ulPatternLength)))
- {
- bParmNumeric = TRUE;
- }
- }
- if (bParmNumeric)
- {
- if (SUCCEEDED(retVal))
- {
- retVal = pSDPValues->SetPropertyULONG32(pParmName,
- ulParmValue);
- }
- }
- else
- {
- if (SUCCEEDED(retVal))
- {
- retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
- (void**) &pParmValue);
- }
-
- if (SUCCEEDED(retVal))
- {
- retVal = pParmValue->SetSize(ulPatternLength + 1);
- }
-
- if (SUCCEEDED(retVal))
- {
- UINT8* pBufferData = pParmValue->GetBuffer();
- memcpy(pBufferData, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pBufferData[ulPatternLength] = ' ';
-
- retVal = pSDPValues->SetPropertyCString(pParmName, pParmValue);
- }
- }
- if (SUCCEEDED(retVal))
- {
- ulPatternLength = 0;
- pPattern = pPatternEnd;
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
- }
- }
- HX_VECTOR_DELETE(pParmName);
- HX_RELEASE(pParmValue);
- } while (SUCCEEDED(retVal) && (ulPatternLength != 0));
- return retVal;
- }
- static HX_RESULT PullBufferDelay(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPatternLength;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- ULONG32 ulPreroll;
- double fPreroll;
- HX_RESULT retVal = HXR_FAIL;
- if (pSDPValues->GetPropertyULONG32("Preroll", ulPreroll) != HXR_OK)
- {
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- fPreroll = strtod(pNumBuffer, &pNumEnd);
-
- if (pNumEnd > pNumBuffer)
- {
- retVal = pSDPValues->SetPropertyULONG32(
- "Preroll",
- (ULONG32) (fPreroll * 1000.0 + 0.5));
- }
- }
- }
- return retVal;
- }
- static HX_RESULT PullGroupID(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPatternLength;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- ULONG32 ulGroupID;
- HX_RESULT retVal = HXR_FAIL;
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
- pPattern = StrNChr((char *) pPattern, '=', ulPatternLength);
- }
-
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- ulGroupID = strtol(pNumBuffer, &pNumEnd, 10);
-
- if (pNumEnd > pNumBuffer)
- {
- retVal = pSDPValues->SetPropertyULONG32(
- "AlternateGroupID",
- ulGroupID);
- }
- }
- return retVal;
- }
- static HX_RESULT PullGroupBitrate(char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPatternLength;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- ULONG32 ulGroupBitrate;
- HX_RESULT retVal = HXR_FAIL;
- pPattern = StrNChr((char *) pData, ':', ulLength);
-
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- pPattern = StrNChr((char *) pPattern, '=', ulPatternLength);
- }
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- ulGroupBitrate = strtol(pNumBuffer, &pNumEnd, 10);
-
- if (pNumEnd > pNumBuffer)
- {
- retVal = pSDPValues->SetPropertyULONG32(
- "AlternateGroupBitrate",
- ulGroupBitrate);
- }
- }
- return retVal;
- }
- static HX_RESULT PullBandwidth (char* pData,
- ULONG32 ulLength,
- IHXValues* pSDPValues,
- IHXCommonClassFactory* pClassFactory)
- {
- char* pPattern;
- ULONG32 ulPatternLength;
- char pNumBuffer[MAX_INT_TEXT_LENGTH + 1]; /* Flawfinder: ignore */
- char* pNumEnd;
- HX_RESULT retVal = HXR_FAIL;
- char* pPropName = NULL;
- ULONG32 ulBandwidth = 0;
-
- pPattern = StrNChr((char *) pData, ':', ulLength);
- if (pPattern)
- {
- ulPatternLength = (ulLength - ((++pPattern) - pData));
-
- if (ulPatternLength > MAX_INT_TEXT_LENGTH)
- {
- ulPatternLength = MAX_INT_TEXT_LENGTH;
- }
-
- memcpy(pNumBuffer, pPattern, ulPatternLength); /* Flawfinder: ignore */
- pNumBuffer[ulPatternLength] = ' ';
-
- ulBandwidth = strtol(pNumBuffer, &pNumEnd, 10);
- if (pNumEnd > pNumBuffer)
- {
- // skip b=
- pData += 2;
- ulLength -= 2;
- if (StrNStr((char*)pData, "AS:", ulLength, 3))
- {
- pPropName = "AvgBitRate";
- ulBandwidth *= 1000;
- }
- else if (StrNStr((char*)pData, "RR:", ulLength, 3))
- {
- pPropName = "RtcpRRRate";
- }
- else if (StrNStr((char*)pData, "RS:", ulLength, 3))
- {
- pPropName = "RtcpRSRate";
- }
- else
- {
- // fine, ignore
- retVal = HXR_OK;
- }
- }
- if (pPropName)
- {
- retVal = pSDPValues->SetPropertyULONG32(pPropName, ulBandwidth);
- }
- }
- return retVal;
- }
- /****************************************************************************
- * Local Utilities
- */
- inline static ULONG32 GetPullTableIdx(const SDPRecordPuller* pTable,
- char* pData,
- ULONG32 ulRecordSize)
- {
- ULONG32 ulIdx = 0;
- HX_ASSERT(pTable);
- while (pTable->pSDPMatch != NULL)
- {
- if (pTable->ulSDPMatchSize <= ulRecordSize)
- {
- if (!strncmp(pTable->pSDPMatch,
- pData,
- pTable->ulSDPMatchSize))
- {
- return ulIdx;
- }
- }
- pTable++;
- ulIdx++;
- }
- return BAD_PULL_TABLE_IDX;
- }
- inline static char* FindSDPFieldByIdx(char* pData,
- ULONG32 ulLength,
- ULONG32 ulIdx)
- {
- char* pField;
- while((ulIdx != 0) && (pData != NULL))
- {
- pField = StrNChr((char *) pData, ' ', ulLength);
- if (pField)
- {
- ulLength -= ((++pField) - pData);
- ulIdx--;
- }
- pData = pField;
- }
- if (ulLength == 0)
- {
- pData = NULL;
- }
- return pData;
- }
- inline static char* FindSDPFieldEnd(char* pData,
- ULONG32 ulLength)
- {
- while((ulLength != 0) &&
- (*pData != ' ') &&
- (*pData != CHAR_CR) &&
- (*pData != CHAR_LF))
- {
- pData++;
- ulLength--;
- }
- return pData;
- }
- inline static char* FindCRLF(char* pData,
- ULONG32 ulLength)
- {
- HX_ASSERT(pData && ulLength);
-
- while((0 != ulLength) &&
- (CHAR_CR != *pData))
- {
- pData++;
- ulLength--;
- }
- if (ulLength)
- {
- if (*(pData+1) == CHAR_LF)
- {
- // found it
- return pData;
- }
- else
- {
- pData++;
- ulLength--;
- return FindCRLF(pData, ulLength);
- }
- }
- return NULL;
- }
- /*
- * saves what pData points to upto CRLF sequence in pLine (' ' terminated)
- */
- inline static HX_RESULT PullLine(char* pData,
- ULONG32 ulLength,
- REF(IHXBuffer*) pLine,
- IHXCommonClassFactory* pClassFactory)
- {
- HX_ASSERT(pData && ulLength);
-
- char* pc = NULL;
- HX_RESULT retVal = HXR_FAIL;
- pc = FindCRLF((char*)pData, ulLength);
- if (pc)
- {
- HX_ASSERT((pc > pData) && (ulLength > (ULONG32)(pc - pData)));
- ulLength = pc - pData;
- retVal = HXR_OK;
- }
- if (SUCCEEDED(retVal))
- {
- retVal = pClassFactory->CreateInstance
- (CLSID_IHXBuffer, (void**) &pLine);
- }
- if (SUCCEEDED(retVal))
- {
- retVal = pLine->SetSize(ulLength + 1);
- BYTE* pcLine = pLine->GetBuffer();
- memcpy(pcLine, pData, ulLength); /* Flawfinder: ignore */
- pcLine[ulLength] = ' ';
- }
- return retVal;
- }
- inline static char* SkipSDPFieldEnd(char* pData, ULONG32 ulSize)
- {
- while((ulSize > 0) &&
- ((*pData == CHAR_CR) ||
- (*pData == CHAR_LF) ||
- (*pData == ' ')))
- {
- pData++;
- ulSize--;
- }
- return pData;
- }
- inline static void OrderUp(LONG32 &l1, LONG32 &l2)
- {
- LONG32 temp;
- if (l1 > l2)
- {
- temp = l1;
- l1 = l2;
- l2 = temp;
- }
- }