⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdpchunk.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** 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 + -