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

📄 sdpmdparse.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    char* pCur = pLine;

    if (ScanForDelim(pCur, ':'))
    {
        char* pColon = pCur;
        *pCur++ = '\0';
        
        char* pEnd = 0;
        ULONG32 ulBwValue = strtoul(pCur, &pEnd, 10);

        if (*pCur && !*pEnd)
        {
            const char* pBwKey = 0;
            res = HXR_OK;

            if (!strcasecmp(pLine, "AS"))
            {
                // a=AvgBitRate has the higher precedence...
                ULONG32 ulTmp;
                if (!SUCCEEDED(pHdr->GetPropertyULONG32("AvgBitRate",
                                                        ulTmp)))
                {
                                // use this as a default.       
                                // it's kilobits per sec....
                    pBwKey = "AvgBitRate";
                    ulBwValue *= 1000;
                }
            }
            else if (!strcasecmp(pLine, "RR"))
            {
                pBwKey = "RtcpRRRate";
            }
            else if (!strcasecmp(pLine, "RS"))
            {
                pBwKey = "RtcpRSRate";
            }
            else
            {
                res = HXR_NOT_SUPPORTED;
            }

            if (pBwKey)
            {
                AddULONG32(pHdr, pBwKey, ulBwValue);
            }
        }
        
        *pColon = ':';
    }

    return res;
}

HX_RESULT SDPMediaDescParser::ParseFieldValue(char*& pValue, 
                                              FieldType& fieldType) const
{
    HX_RESULT res = HXR_OK;

    char* pCur = pValue;

    // Look for the following forms
    // a=anInt:integer;43
    // a=aString:string;"this is a string"
    // a=aBuffer:buffer;"TWFjIFRWAA=="

    // Assume we don't know the type.
    fieldType = ftUnknown;

    if (ScanForDelim(pCur, ';'))
    {
        // Replace the ';' with a '\0' so we
        // can check to see if it matches the known
        // types
        char* pSemiColon = pCur;

        *pCur++ = '\0';

        if (!strcmp(pValue, "integer"))
        {
            // Update the value pointer to the
            // start of the integer value
            pValue = pCur;
            fieldType = ftULONG32;
        }
        else if (!strcmp(pValue, "string"))
        {
            fieldType = ftString;
        }
        else if (!strcmp(pValue, "buffer"))
        {
            fieldType = ftBuffer;
        }

        if ((fieldType == ftString) || (fieldType == ftBuffer))
        {
            BOOL bFailed = TRUE;

            // Look for starting '"'
            if (*pCur == '"')
            {
                pCur++; // skip '"'

                if (*pCur)
                {
                    // Store start of the string
                    char* pStrStart = pCur;

                    // Create temporary buffer for unescaping
                    char* pTmpBuf = new char[strlen(pStrStart) + 1];

                    if (pTmpBuf)
                    {
                        char* pDest = pTmpBuf;

                        // Copy string into pTmpBuf and
                        // unescape any escape sequences
                        while (*pCur && *pCur != '"')
                        {
                            if (*pCur == '\\')
                            {
                                *pCur++; // skip '\\'
                            }
                            
                            *pDest++ = *pCur++;
                        }
                        
                        // Make sure the last character is a '"'
                        if (*pCur == '"')
                        {
                            // Replace ending '"' with '\0'
                            *pDest = '\0';

                            // Replace escaped string with
                            // unescaped string.
                            strcpy(pStrStart, pTmpBuf);

                            // Update the value pointer to the 
                            // start of the string value
                            pValue = pStrStart;
                            bFailed = FALSE;
                        }

                        delete [] pTmpBuf;
                    }
                }
            }
            
            if (bFailed)
            {
                fieldType = ftUnknown;
            }
        }
        

        if (fieldType == ftUnknown)
        {
            // This is not a type we recognize.
            // Replace the '\0' with a ';' so the
            // value is the way it was before.
            *pSemiColon = ';';
        }
    }
    
    return res;
}

HX_RESULT SDPMediaDescParser::HandleSpecialFields(const char* pFieldName, 
                                                  char* pFieldValue, 
                                                  IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;

    if (!strcasecmp("Range", pFieldName))
    {
        res = HandleRangeField(pFieldValue, pHdr);
    }
    else if (!strcasecmp("length", pFieldName))
    {
        res = HandleLengthField(pFieldValue, pHdr);
    }
    else if (!strcasecmp("rtpmap", pFieldName))
    {
        res = HandleRTPMapField(pFieldValue, pHdr);
    }
    else if (!strcasecmp("fmtp", pFieldName))
    {
        res = HandleFMTPField(pFieldValue, pHdr);
    }
    else if (!strcasecmp("ptime", pFieldName))
    {
        // a=ptime:43
        AddULONG32(pHdr, "Ptime", strtol(pFieldValue, 0, 10)); 
        res = HXR_OK;
    }
    else if (!strcasecmp("x-bufferdelay", pFieldName))
    {
        // a=x-bufferdelay:234
        // x-bufferdelay units are 1/1000 of a sec
        res = HandlePrerollField(pFieldValue, 1000, pHdr);
    }
    else if (!strcasecmp("x-initpredecbufperiod", pFieldName))
    {
        // 3GPP 26.234 Annex G field
        // a=x-initpredecbufperiod:45000
        // x-initpredecbufperiod units are 1/90000 of a sec
        res = HandlePrerollField(pFieldValue, 90000, pHdr);
    }
    else if (!strcasecmp("x-predecbufsize", pFieldName))
    {
        // 3GPP 26.234 Annex G field
        // a=x-predecbufsize:45000
        // x-predecbufsize units are bytes
        AddULONG32(pHdr, "x-predecbufsize", strtoul(pFieldValue, 0, 10)); 
        res = HXR_OK;
    }
    else if (!strcasecmp("SdpplinVersion", pFieldName))
    {
        res = checkVersion(strtol(pFieldValue, 0, 10));
        
        if (HXR_FAIL == res)
        {
            // need to update...
            // this flag causes to exit in "m=" case
            res = HXR_REQUEST_UPGRADE;
        }
    }
    else if (!strcasecmp("control", pFieldName))
    {
        AddString(pHdr, "Control", pFieldValue);
        res = HXR_OK;
    }
    else
    {
        res = HXR_NOT_SUPPORTED;
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandleRangeField(char* pFieldValue, 
                                               IHXValues* pHdr)
{
    char* pCur = pFieldValue;

    ULONG32 duration = 0;
    BOOL bIsLegal = TRUE;
    
    if (ScanForDelim(pCur, '='))
    {
        // replace '=' with '\0'
        *pCur++ = '\0';
        
        if (!strcasecmp(pFieldValue, "npt"))
        {
            // Look for the following npt forms
            // a=range:npt=-xxx
            // a=range:npt=xxx-
            // a=range:npt=xxx-xxx
            char* pLeftVal = pCur;
            
            if (ScanForDelim(pCur, '-'))
            {
                // replace '-' with '\0'
                
                *pCur++ = '\0';
                
                NPTime left(pLeftVal);
                NPTime right(pCur);
                
                if (*pCur)
                {
                    // a=range:npt=xxx-xxx
                    duration = (UINT32)(right - left);
                    m_bDefiniteDuration = TRUE;
                }
                else
                {
                    // a=range:npt=xxx-
                    // Treat open-ended play ranges as live streams 
                    // unless it is overridden by a media range.
                }
            }
            else
            {
                // This must be the following illegal form
                // a=range:npt=xxx 
                bIsLegal = FALSE;
            }
        }
    }
    else
    {
        duration = strtol(pFieldValue, 0, 10);
    }
    
    if (bIsLegal)
    {
        if (0 == m_ulDefaultDuration)
        {
            m_ulDefaultDuration = duration;
        }
        
        AddULONG32(pHdr, "Duration", duration);
    }

    return HXR_OK;
}

HX_RESULT SDPMediaDescParser::HandleLengthField(char* pFieldValue, 
                                                IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;

    char* pCur = pFieldValue;

    ULONG32 duration = 0;
    BOOL bIsLegal = TRUE;

    // Look for the following npt form
    // a=length:npt=xxx
    if (ScanForDelim(pCur, '='))
    {
        char* pEqual = pCur;

        // replace '=' with '\0'
        *pCur++ = '\0';
        
        if (!strcasecmp(pFieldValue, "npt") && *pCur)
        {
            NPTime dTime(pCur);
            
            duration = (UINT32)dTime;
            res = HXR_OK;
        }
        else
        {
            // Put back '=' character
            *pEqual = '=';
        }
    }
    else
    {
        duration = strtol(pFieldValue, 0, 10);
        res = HXR_OK;
    }
    
    if (duration)
    {
        m_bDefiniteDuration = TRUE;
    }

    if (0 == m_ulDefaultDuration)
    {
        m_ulDefaultDuration = duration;
    }
        
    AddULONG32(pHdr, "Duration", duration);

    return res;
}

HX_RESULT SDPMediaDescParser::HandleRTPMapField(char* pFieldValue, 
                                                IHXValues* pHdr)
{
    HX_RESULT res = HXR_FAILED;

    // e.g. a=rtpmap:101 xxx/90000/2

    char* pCur = 0;
    UINT32 payload = strtol(pFieldValue, &pCur, 10);
    ULONG32 rtpPayloadType = 0;

    res = pHdr->GetPropertyULONG32("RTPPayloadType", rtpPayloadType);
    if (*pFieldValue && (*pCur == ' '))
    {
        SkipSpaces(pCur);

        // there could be multiple of these...
        if (payload == rtpPayloadType)
        {    
            CHXString mimeType(m_mediaType);

            res = getRTPMapInfo(pCur, mimeType, pHdr);
            /* make sure there is no mime type set!
             *  MimeType from m= && a=rtpmap has the lowest precedence.
             *  a=mimetype -> mimetype table -> this mimetype
             */
            IHXBuffer* pMimeType = 0;
            if (!SUCCEEDED(pHdr->GetPropertyCString(
                "MimeType", pMimeType)))
            {
                AddString(pHdr, "MimeType", mimeType);
            }
            HX_RELEASE(pMimeType);
        }                
    }
                
    return res;
}

HX_RESULT SDPMediaDescParser::HandleFMTPField(char* pFieldValue, 
                                              IHXValues* pHdr)
{
    // e.g. a=fmtp:101 emphasis=50/15;foo=bar

    char* pCur = 0;
    UINT32 payload = strtol(pFieldValue, &pCur, 10);

    ULONG32 rtpPayloadType = 0;
    HX_RESULT res = pHdr->GetPropertyULONG32("RTPPayloadType", rtpPayloadType);

    if (*pFieldValue && *pCur == ' ')
    {
        SkipSpaces(pCur);

        // If the RTPPayloadType field is present, compare it
        // to the value in the fmtp field.
        // There could be multiple of these...
        if ((HXR_OK != res) || (payload == rtpPayloadType))
        {    
            AddString(pHdr, "PayloadParameters", pCur);
        
            CHXFMTPParser fmtp(m_pCCF);
            res = fmtp.Parse(pCur, pHdr);
        }
    }

    return res;
}

HX_RESULT SDPMediaDescParser::HandlePrerollField(char* pFieldValue, 
                                                 ULONG32 ulPrerollUnits,
                                                 IHXValues* pHdr)
{
    ULONG32 ulPreroll = 0;
    
    if (HXR_OK != pHdr->GetPropertyULONG32("Preroll", ulPreroll))
    {
        ULONG32 ulValue = strtoul(pFieldValue, 0, 10);

        // Convert Preroll value to milliseconds
        ulPreroll = (ulValue / ulPrerollUnits) * 1000;
        ulPreroll += ((ulValue % ulPrerollUnits) * 1000) / ulPrerollUnits;
        
        AddULONG32(pHdr, "Preroll", ulPreroll); 
    }
    
    return HXR_OK;
}

⌨️ 快捷键说明

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