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

📄 robpktparse.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        }
        
        // We don't have a time stamp, but there are no more packets coming
        dPresTime = m_dNextPts;
    }

    // If this is the first frame, set the time accordingly
    if(m_bFirstFrame)
    {
#if defined(WIN32) && defined(_DEBUG)
        char str[256]; /* Flawfinder: ignore */
        SafeSprintf(str, 256, "First decode, setting time to %lf\n", dPresTime);
        OutputDebugString(OS_STRING(str));
#endif // defined(WIN32) && defined(_DEBUG)
        m_dNextPts = dPresTime;
    }

    if(!m_bFirstFrame && dPresTime - m_dNextPts >= m_dFrameTime)
    {
        // We have frames lost before this one
#if defined(WIN32) && defined(_DEBUG)
        char str[256]; /* Flawfinder: ignore */
        SafeSprintf(str, 256, "Apparent packet loss: Index: %d, Cycle: %d, "
                "PresTime: %lf, NextPts: %lf, FrameTime: %lf\n", 
                ulIndex, pCycle->nCycleIndex, dPresTime, m_dNextPts, 
                m_dFrameTime);
        OutputDebugString(OS_STRING(str));
#endif // defined(WIN32) && defined(_DEBUG)
        bLost = TRUE;
    }

    if(pFrameInfo && pFrameInfo->ulADUSize < 2)
    {
        // this frame is too small. skip it and do loss recovery
        HX_DELETE(pCycle->pFrames[ulIndex]);
        m_ulIndex = ulIndex + 1;
        bLost = TRUE;
    }

    // If the frame was lost, we reuse the one already in the buffer,
    // so don't need to copy or anything
    if(!bLost)
    {
        IHXBuffer* pPacketBuf;
        SFrameData* pFrameData;
        UINT32 ulSize;        
        UCHAR* pBuf;
        UCHAR* pDecBuf = m_pDecBuffer;
        m_ulDecBufBytes = 0;

        // Copy the frame into the decode buffer
        for(pFrameData= pFrameInfo->pFrameData; pFrameData != NULL;
            pFrameData = pFrameData->pNext)
        {
            pPacketBuf = pFrameData->pPacketBuf;
            if(pPacketBuf)
            {
                pPacketBuf->Get(pBuf, ulSize);
                if(pBuf && ulSize >= pFrameData->ulOffset + 2)
                {
                    // seek to the frame offset
                    ulSize -= pFrameData->ulOffset;
                    pBuf += pFrameData->ulOffset;
            
                    if(pFrameInfo->ulADUSize < ulSize)
                    {
                        ulSize = pFrameInfo->ulADUSize;
                    }
                    // Make sure it will actually fit
                    if(ulSize > DEC_BUFFER_SIZE - m_ulDecBufBytes)
                    {
                        ulSize = DEC_BUFFER_SIZE - m_ulDecBufBytes;
                    }
            
                    memcpy(pDecBuf, pBuf, ulSize); /* Flawfinder: ignore */
                    m_ulDecBufBytes += ulSize;
                    pDecBuf += ulSize;
                }
            }
        }

        HX_DELETE(pCycle->pFrames[ulIndex]);
        m_ulIndex = ulIndex + 1;
    
        // Clear the main_data_begin (since we're reformatted)
        m_pFmt->ClearMainDataBegin(m_pDecBuffer);
    }

    pFrameBuffer = m_pDecBuffer;
    dTime = dPresTime;

    m_dNextPts = dPresTime + m_dFrameTime;
    m_bFirstFrame = FALSE;   

    return m_ulDecBufBytes;
}

UINT32 CRobustPacketParser::GetFrameInfo(IHXBuffer* pPacket, UINT32 ulOffset,
                                         double dTime)
{   
    if(pPacket->GetSize() <= ulOffset)
    {
        return pPacket->GetSize();
    }

    UCHAR*  pBuf = pPacket->GetBuffer() + ulOffset;

    // bit 0: continuation bit
    BOOL    bCont = (pBuf[0] & 0x80) == 0 ? FALSE : TRUE; 
    // bit 1: Descriptor type flag
    int nDescSize = (pBuf[0] & 0x40) == 0 ? 1 : 2; 
    
    if(pPacket->GetSize() - ulOffset < (UINT32)nDescSize + 2)
    {
        return pPacket->GetSize();
    }

    UINT32 ulADUSize;
    int nIndex;
    int nCycle;

    // in a one byte descriptor, bits 2-7 are the ADU size
    // in a two byte descriptor, bits 2-15 are the size
    ulADUSize = nDescSize == 1 ? (pBuf[0] & 0x3F) :
                ((UINT32)(pBuf[0] & 0x3F) << 8) + pBuf[1];
    
    pBuf += nDescSize;    
    
    // MPEG audio sync word is the first 12 bits, first 11 always set.
    // if the sync word is in tact, we are not reordered
    if(pBuf[0] == 0xFF && (pBuf[1] & 0xE0) == 0xE0)
    {
        nIndex = 0;
        nCycle = -1;
    }
    // otherwise, the first 11 bits of the sync word are re-used to 
    // identify the frame order    
    else
    {
        // bits 0-7: frame index
        nIndex = pBuf[0];
        // bits 8-10: cycle
        nCycle = (pBuf[1] & 0xE0) >> 5;
    }
    
    SCycle* pCycle = m_Cycles.IsEmpty() ? NULL : (SCycle*)m_Cycles.GetTail();
    if(!pCycle || nCycle != pCycle->nCycleIndex || nCycle < 0)
    {
        // This is a new cycle
        pCycle = new SCycle(nCycle);
        if(pCycle == NULL)
        {
            return pPacket->GetSize();
        }
        pCycle->nMaxIndex = nIndex;
        m_Cycles.AddTail(pCycle);                   
    }
    else if(nIndex > pCycle->nMaxIndex)
    {
        pCycle->nMaxIndex = nIndex;
    }

    SFrameData* pFrameData = new SFrameData();
    SFrameData* pIterator;

    pPacket->AddRef();
    pFrameData->pPacketBuf = pPacket;
    pFrameData->ulOffset = ulOffset + nDescSize;
    pFrameData->bCont = bCont;
    
    SFrameInfo* pInfo = pCycle->pFrames[nIndex];
    if(pInfo != NULL)
    {
        // We have a frag. Note that the spec only accounts for a frame being 
        // split accross two packets when reordered. If one is split across 
        // more than two packets, we will assume the cont frags are in order
        if(bCont || (pCycle->pFrames[nIndex]->pFrameData && 
            !pCycle->pFrames[nIndex]->pFrameData->bCont))
        {
            pIterator = pCycle->pFrames[nIndex]->pFrameData;
            if(pIterator)
            {
                while(pIterator->pNext != NULL)
                    pIterator = pIterator->pNext;

                pFrameData->pNext = NULL;
                pIterator->pNext = pFrameData;
            }
            else
            {
                pFrameData->pNext = pCycle->pFrames[nIndex]->pFrameData;
                pCycle->pFrames[nIndex]->pFrameData = pFrameData;
            }
        }
        // If this is not a continuation frame, it is the first frag
        else
        {
            pFrameData->pNext = pCycle->pFrames[nIndex]->pFrameData;
            pCycle->pFrames[nIndex]->pFrameData = pFrameData;
        }    
    }
    else
    {
        pFrameData->pNext = NULL;
        pInfo = new SFrameInfo();
        pInfo->nIndex = nIndex;
        pInfo->ulADUSize = ulADUSize;
        pInfo->pFrameData = pFrameData;
        pInfo->dTime = dTime;
        pCycle->pFrames[nIndex] = pInfo;
    }

    UINT32 ulSize = 0;
    for(pIterator = pCycle->pFrames[nIndex]->pFrameData; pIterator!= NULL;
        pIterator = pIterator->pNext)
    {        
        HX_ASSERT(pIterator->pPacketBuf);
        ulSize += pIterator->pPacketBuf->GetSize() - pIterator->ulOffset;
    }
    
    pInfo->bComplete = ulSize >= pInfo->ulADUSize ? TRUE : FALSE;

    // Set first 11 bits
    pBuf[0]  = 0xFF;
    pBuf[1] |= 0xE0;

    // Init our decoder if needed
    if(m_pDecoder || InitDecoder(pBuf, pPacket->GetSize() - ulOffset, FALSE))
    {
        // set the first frame's presentation time
        if(dTime >= 0)
        {
            if(pCycle->dStartTime < 0)
            {
                pCycle->dStartTime = dTime - m_dFrameTime*(nIndex);    
            }
        }   
    }    

    return min(pFrameData->ulOffset + ulADUSize, pPacket->GetSize());
}

HX_RESULT
CRobustPacketParser::RenderAll()
{
    if(!m_pRenderer || !m_pFmt)
    {
        return HXR_FAIL;
    }

    UCHAR* pFrameBuf;
    UINT32 ulSize;
    BOOL bPacketLoss;
    double dTime;

    for(;;)
    {
        ulSize = GetFrame(pFrameBuf, dTime, bPacketLoss);
        if(!pFrameBuf || !ulSize)
        {
            return HXR_OK;
        }

        if(!m_pDecoder && !InitDecoder(pFrameBuf, ulSize, TRUE))
        {
            return HXR_FAIL;
        }

        DecodeAndRender(pFrameBuf, ulSize, dTime, bPacketLoss);
    }
}

void
CRobustPacketParser::PreSeek()
{ 
    m_Cycles.DeleteAll();
    m_ulIndex = 0;
    m_bFirstFrame = TRUE;
    CPacketParser::PreSeek();
}

void
CRobustPacketParser::PostSeek(UINT32 time)
{ 
    m_Cycles.DeleteAll();
    m_ulIndex = 0;
    m_bFirstFrame = TRUE;
    CPacketParser::PostSeek(time);
    HX_DELETE(m_pTsConvert);
}

void
CRobustPacketParser::EndOfPackets()
{
    m_bEndOfPackets = TRUE;

    // Decode and render any frames left queued.
    RenderAll();
}

⌨️ 快捷键说明

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