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

📄 sdpmdparse.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    LISTPOSITION pos = m_streams.GetHeadPosition();
    while(pos)
    {
        IHXValues* pStream = (IHXValues*)m_streams.GetNext(pos);
        HX_RELEASE(pStream);
    }
    m_streams.RemoveAll();
}

IHXValues* SDPMediaDescParser::CreateHeader()
{
    IHXValues* pRet = 0;

    if (m_pCCF)
        m_pCCF->CreateInstance(IID_IHXValues, (void**)&pRet);

    return pRet;
}

void SDPMediaDescParser::AddULONG32(IHXValues* pHeader, 
                                    const char* pKey, ULONG32 ulValue)
{
    pHeader->SetPropertyULONG32(pKey, ulValue);
}

void SDPMediaDescParser::AddString(IHXValues* pHeader, 
                                   const char* pKey,
                                   const char* pValue)
{
    if ((pKey == NULL) || (pValue == NULL))
    {
        return;
    }

    IHXBuffer* pBuf = CopyBuffer((const UINT8*)pValue, strlen(pValue) + 1);

    if (pBuf)
        pHeader->SetPropertyCString(pKey, pBuf);

    HX_RELEASE(pBuf);
}

void SDPMediaDescParser::AddBuffer(IHXValues* pHeader, 
                                   const char* pKey,
                                   const UINT8* pValue,
                                   ULONG32 ulLength)
{
    IHXBuffer* pBuf = CopyBuffer(pValue, ulLength);

    if (pBuf)
        pHeader->SetPropertyBuffer(pKey, pBuf);

    HX_RELEASE(pBuf);
}

IHXBuffer* SDPMediaDescParser::CopyBuffer(const UINT8* pBuf, ULONG32 ulLength)
{
    IHXBuffer* pRet = 0;
    if (SUCCEEDED(m_pCCF->CreateInstance(IID_IHXBuffer, (void**)&pRet)))
        pRet->Set(pBuf, ulLength);

    return pRet;
}

HX_RESULT SDPMediaDescParser::GetLine(const char*& pData,
                                      const char* pEnd,
                                      IHXBuffer*& pLine) const
{
    HX_RESULT res = HXR_OK;

    CHXCharStack tok(m_pCCF);
    BOOL bInQuote = FALSE;
    BOOL bLastWasEscape = FALSE;

    for (; (HXR_OK == res) && *pData && (pData < pEnd) && (bInQuote || !strchr("\r\n", *pData)); pData++)
    {
        if (bLastWasEscape)
        {
            bLastWasEscape = FALSE;
        }
        else
        {
            if (*pData == '"')
            {
                bInQuote = !bInQuote;
            }
            else if (*pData == '\\')
            {
                bLastWasEscape = TRUE;
            }
        }

        res = tok.AddChar(*pData);
    }

    if (HXR_OK == res)
    {
        res = tok.Finish(pLine);
    }

    return res;
}

void SDPMediaDescParser::SkipSpaces(char*& pData) const
{
    for (; *pData && *pData == ' '; pData++)
        ;
}

BOOL SDPMediaDescParser::ScanForDelim(char*& pData, char delim) const
{
    BOOL bRet = FALSE;

    while(*pData && !bRet)
    {
        if (*pData == delim)
        {
            bRet = TRUE;
        }
        else
        {
            pData++;
        }
    }

    return bRet;
}

HX_RESULT SDPMediaDescParser::HandleVLine(char* pLine)
{
    HX_RESULT res = HXR_FAILED;
    
    char* pEnd = 0;

    unsigned long version = strtoul(pLine, &pEnd, 10);

    if (*pLine && !*pEnd && (version == 0))
    {
        
        res = HXR_OK;
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandleMLine(char* pLine, IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;

    if (*pLine)
    {
        int state = 0;
        const char* pMediaType = pLine;
        ULONG32 ulPort = 0;
        ULONG32 ulPayloadType = 0;
        

        if (ScanForDelim(pLine, ' '))
        {
            // Null terminate mimetype
            *pLine++ = '\0';

            // Save media type for later
            m_mediaType = pMediaType;

            res = HXR_OK;
        }

        while(*pLine && (HXR_OK == res))
        {
            char* pEnd = 0;

            SkipSpaces(pLine);
            
            if (*pLine)
            {
                switch(state) {
                case 0:
                    // Grab port number
                    ulPort = strtoul(pLine, &pEnd, 10);
                    if (*pEnd == ' ')
                    {
                        pLine = pEnd;
                        state = 1;
                    }
                    else
                    {
                        // No transport field or
                        // invalid port character
                        res = HXR_FAILED;
                    }
                    break;
                case 1:
                    // Skip transport. Usually RTP/AVP
                    if (ScanForDelim(pLine, ' '))
                    {
                        state = 2;
                    }
                    break;
                case 2:
                    // Grab the first payload type
                    ulPayloadType = strtoul(pLine, &pEnd, 10);
                    if ((*pEnd == ' ') || !*pEnd )
                    {
                        state = 3;
                    }
                    else
                    {
                        // There was an unexpected character
                        // the the payload type
                        res = HXR_FAILED;
                    }

                case 3:
                    // Consume the rest of the payload types
                    for (; *pLine; pLine++)
                        ;
                    break;
                }
            }
        }

        if (state == 3)
        {
            AddULONG32(pHdr, "RTPPayloadType", ulPayloadType);
            
            if (ulPort)
            {
                AddULONG32(pHdr, "Port", ulPort);
            }

            if (SDPIsStaticPayload(ulPayloadType))
            {
                if (IsPayloadTableValid(ulPayloadType))
                {
                    if (!SDPIsTimestampDeliverable(ulPayloadType))
                    {
                        ULONG32 ulBitrate = 
                            SDPMapPayloadToBitrate(ulPayloadType);

                        HX_ASSERT(ulBitrate);
                        // we have a bandwidth info in a table...
                        AddULONG32(pHdr, "AvgBitRate", ulBitrate);
                    }

                    // static payload type
                    AddString(pHdr, "MimeType", 
                              SDPMapPayloadToMimeType(ulPayloadType));
                    AddULONG32(pHdr,
                               "RTPTimestampConversionFactor", 
                               SDPMapPayloadToRTPFactor(ulPayloadType));
                    AddULONG32(pHdr,
                               "HXTimestampConversionFactor", 
                               SDPMapPayloadToRMAFactor(ulPayloadType));
                    AddULONG32(pHdr,
                               "SamplesPerSecond", 
                               SDPMapPayloadToSamplesPerSecond(ulPayloadType));
                    AddULONG32(pHdr,
                               "Channels", 
                               (ULONG32)SDPMapPayloadToChannels(ulPayloadType));

                    // deal with opaque hack...
                    const BYTE* pOpaqueData = NULL;
                    ULONG32 ulOpaqueDataSize = 0;
                    switch(ulPayloadType)
                    {
                    case RTP_PAYLOAD_GSM:
                        pOpaqueData = 
                            SDPMapPayloadToHeaderData(RTP_PAYLOAD_GSM,
                                                      ulOpaqueDataSize);
                        break;
                    }   
                    
                    if (pOpaqueData)
                    {
                        AddBuffer(pHdr, "OpaqueData",
                                  pOpaqueData, ulOpaqueDataSize);
                    }           
                }
                else
                {
                    res = HXR_REQUEST_UPGRADE;
                }
            }
        }
        else if (HXR_OK == res)
        {
            res = HXR_FAILED;
        }
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandleALine(char* pLine, IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;
    
    const char* pFieldName = pLine;
    char* pFieldValue = 0;
    FieldType fieldType = ftUnknown;
    
    if (*pLine)
    {
        // Collect the field name
        if (ScanForDelim(pLine, ':'))
        {
            char* pColon = pLine;

            // Must be the key/value form 
            // a=foo:bar
            
            // Null terminate field name by replacing ':' with '\0'
            *pLine++ = '\0';
                    
            pFieldValue = pLine;

            if ((HXR_OK == (res = ParseFieldValue(pFieldValue, fieldType))))
            {
                switch (fieldType) {
                case ftUnknown:
                    res = HandleSpecialFields(pFieldName, pFieldValue, pHdr);
                    break;
                case ftULONG32:
                {
                    char* pEnd = 0;
                    ULONG32 ulValue = strtoul(pFieldValue, &pEnd, 10);
                    
                    if (*pFieldValue && !*pEnd)
                    {
                        res = pHdr->SetPropertyULONG32(pFieldName, ulValue);
                    }
                } break;
                case ftString:
                    AddString(pHdr, pFieldName, pFieldValue);
                    res = HXR_OK;
                    break;
                case ftBuffer:
                {
                    int length = strlen(pFieldValue);
                    BYTE* pDecodeBuf = new BYTE[length];
                    INT32 decodeLen = BinFrom64(pFieldValue, length, 
                                                pDecodeBuf);
                    if( decodeLen != -1 )
                    {
                        AddBuffer(pHdr, pFieldName, pDecodeBuf, decodeLen);
                    }

                    res = HXR_OK;

                    delete [] pDecodeBuf;
                }break;
                }
            }
            
            if (HXR_OK != res)
            {
                // Put back the ':'
                *pColon = ':';
            }
        }
        else
        {
            // Must be the key only form
            // a=foo
            res = HXR_NOT_SUPPORTED;
        }
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandleCLine(char* pLine, IHXValues* pHdr)
{
    // Handles the following forms
    // c=IN IP4 xxx.xxx.xxx.xxx
    // c=IN IP4 xxx.xxx.xxx.xxx/xxx
    // c=IN IP4 xxx.xxx.xxx.xxx/xxx/xx
    HX_RESULT res = HXR_FAILED;
    
    char* pCur = pLine;

    if (ScanForDelim(pCur, ' '))
    {
        *pCur++ = '\0';
        
        SkipSpaces(pCur);

        char* pAddrType = pCur;

        if (!strcasecmp(pLine, "IN") && ScanForDelim(pCur, ' '))
        {
            *pCur++ = '\0';

            SkipSpaces(pCur);

            if (!strcasecmp(pAddrType, "IP4") && *pCur)
            {
                char* pAddr = pCur;

                if (ScanForDelim(pCur, '/'))
                {
                    *pCur++ = '\0';

                    if (*pCur)
                    {
                        char* pEnd = 0;
                        ULONG32 ulTTL = strtoul(pCur, &pEnd, 10);

                        if (*pCur && ((*pEnd == '/') || (!*pEnd)))
                        {
                            AddULONG32(pHdr, "MulticastTTL", ulTTL);
                            res = HXR_OK;

                            pCur = pEnd;
                            if (*pCur)
                            {
                                pCur++; // skip '/'
                                ULONG32 ulRange = strtoul(pCur, &pEnd, 10);
                                
                                if (*pCur && !*pEnd)
                                {
                                    // c=IN IP4 xxx.xxx.xxx.xxx/xxx/xx
                                    AddULONG32(pHdr, "MulticastRange", ulRange);
                                    res = HXR_OK;
                                }
                            }
                        }
                    }
                }
                else
                {
                    // c=IN IP4 xxx.xxx.xxx.xxx
                    res = HXR_OK;
                }

                if (HXR_OK == res)
                {
                    AddString(pHdr, "MulticastAddress", pAddr);
                }
            }
        }
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandleBLine(char* pLine, IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -