📄 sdpchunk.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: sdpchunk.cpp,v 1.7.8.1 2004/07/09 02:05:16 hubbe Exp $ * * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (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. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * 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++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -