📄 sdpchunk.cpp
字号:
/* ***** 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 = '\0';
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -