sdpchunk.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,471 行 · 第 1/3 页
CPP
1,471 行
/* ***** 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 + =
减小字号Ctrl + -
显示快捷键?