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

📄 robpktparse.cpp

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

#include "hxtypes.h"
#include "hlxclib/stdio.h"
#include "hlxosstr.h"
#include "hxcom.h"              // IUnknown
#include "hxcomm.h"            // IHXCommonClassFactory
#include "ihxpckts.h"           // IHXBuffer, IHXPacket, IHXValues
#include "hxplugn.h"           // IHXPlugin
#include "hxrendr.h"           // IHXRenderer
#include "hxengin.h"           // IHXInterruptSafe
#include "hxcore.h"            // IHXStream
#include "hxausvc.h"           // Audio Services
#include "hxmon.h"             // IHXStatistics
#include "hxupgrd.h"           // IHXUpgradeCollection
#include "hxslist.h"            // CHXSimpleList
#include "carray.h"             // CHXPtrArray
#include "tconverter.h"		// CHXTimestampConverter
#include "hxstrutl.h"

#include "mpadecobj.h"          // MPEG Audio Decoder (selects fixed-pt or floating-pt based on HELIX_CONFIG_FIXEDPOINT)
#include "mp3format.h"          // MP3 formatter

#ifdef DEMUXER
#include "xmddemuxer.h"         // Demuxer
#include "xmdtypes.h"
#endif

#include "mp3rend.h"            // CRnMp3Ren
#include "pktparse.h"           // CPacketParser
#include "robpktparse.h"        // CRobustPacketParser


CRobustPacketParser::CRobustPacketParser() :
    CPacketParser(),    
    m_ulIndex(0),
    m_bFirstFrame(TRUE),
    m_pTsConvert(NULL)
//    m_dNextFrameTime(0.0),
//    m_dFrameTime(0.0)
{
    m_bReformatted = TRUE;
}

CRobustPacketParser::~CRobustPacketParser()
{
    m_Cycles.DeleteAll();
    HX_DELETE(m_pTsConvert);
}

HX_RESULT
CRobustPacketParser::AddPacket(IHXPacket* pPacket, INT32 streamOffsetTime)
{
    if(pPacket == NULL)
        return HXR_INVALID_PARAMETER;

    // Get the buffer.
    IHXBuffer* pPacketBuf = pPacket->GetBuffer();
    if(pPacketBuf == NULL || pPacketBuf->GetSize() == 0)
    {
        HX_RELEASE(pPacketBuf);
        return HXR_INVALID_PARAMETER;
    }
    double dTime;

    // Get the packet time
    IHXRTPPacket *pRtpPacket = NULL;
    pPacket->QueryInterface(IID_IHXRTPPacket, (void**)&pRtpPacket);

    if (pRtpPacket)
    {
	if (!m_pTsConvert)
	{
	    m_pTsConvert = new CHXTimestampConverter(CHXTimestampConverter::FACTORS,
						     1,
						     90);
	    if (m_pTsConvert)
	    {
		m_pTsConvert->setHXAnchor(pPacket->GetTime());
	    }
	}
	if (m_pTsConvert)
	{
	    dTime = m_pTsConvert->rtp2hxa(pRtpPacket->GetRTPTime());
	}
	else
	{
	    dTime = pRtpPacket->GetRTPTime() / 90.0;
	}
        pRtpPacket->Release();
    }
    else
    {
        //dTime = pPacket->GetTime();
        dTime = pPacket->GetTime();
    }

    if(streamOffsetTime > dTime)
    {
        dTime =  0;
    }
    else
    {
        dTime -= streamOffsetTime;
    }

    // Set the time for the first frame in the packet
    UINT32 ulOffset = GetFrameInfo(pPacketBuf, 0, dTime);
    
    while(ulOffset < pPacketBuf->GetSize())
    {
        ulOffset = GetFrameInfo(pPacketBuf, ulOffset, -1);
    }

    return HXR_OK;
}

UINT32
CRobustPacketParser::GetFrame(UCHAR*& pFrameBuffer, double& dTime, BOOL& bLost)                              
{    
    pFrameBuffer = NULL;
    dTime = 0.0;
    bLost = FALSE;

    // If we don't have any frames yet
    if(m_Cycles.IsEmpty())
    {
        return 0;
    }

    SCycle* pCycle = NULL;
    BOOL bNextCycle = TRUE;
    BOOL bCheckLoss = FALSE;
    SFrameInfo* pFrameInfo = NULL;
    UINT32 ulIndex = m_ulIndex;

    pCycle = (SCycle*)m_Cycles.GetHead();

    while(bNextCycle)
    {
        // This will never be NULL since we never add NULL
        HX_ASSERT(pCycle != NULL);  

        pFrameInfo = pCycle->pFrames[ulIndex];

        if(pFrameInfo && pFrameInfo->bComplete)
        {
            // we have a frame ready!            
            bNextCycle = FALSE;
        }
        else
        {
            // we haven't got to the next cycle yet, keep waiting
            if(m_Cycles.GetCount() <= 1 && !m_bEndOfPackets)
            {
                m_ulIndex = ulIndex;
                return 0;
            }

            // this frame is lost (we still have more this cycle)
            if(ulIndex < (UINT32)pCycle->nMaxIndex)
            {
                #if defined(WIN32) && defined(_DEBUG)
                char str[256]; /* Flawfinder: ignore */
                SafeSprintf(str, 256, "Known packet loss: Index: %d, Cycle: %d, "
                        "Frag: %c\n", ulIndex, pCycle->nCycleIndex, 
                        pFrameInfo ? 'y' : 'n');
                OutputDebugString(OS_STRING(str));
                #endif // defined(WIN32) && defined(_DEBUG)

                // If we have a partial frame, release it
                HX_DELETE(pCycle->pFrames[ulIndex]);

                if(m_bFirstFrame)
                {
                    #if defined(WIN32) && defined(_DEBUG)
                    OutputDebugString(OS_STRING("First frame missing. Ignoring.\n"));
                    #endif // defined(WIN32) && defined(_DEBUG)                    
   
                    // If this was the first frame, ignore it and keep looking                    
                    while(++ulIndex <= (UINT32)pCycle->nMaxIndex && bNextCycle)
                    {                        
                        pFrameInfo = pCycle->pFrames[ulIndex];
                        if(pFrameInfo && pFrameInfo->bComplete)
                        {
                            // we have a frame ready!                       
                            bNextCycle = FALSE;                            
                            break;
                        }
                        HX_DELETE(pCycle->pFrames[ulIndex]);
                    }                    
                }
                else
                {
                    m_ulIndex++;
                    bLost = TRUE;
                    bNextCycle = FALSE;
                }
            }

            if(bNextCycle)
            {
                // We're done with this cycle, so get rid of it and 
                // go to the next    
                m_Cycles.RemoveHead();
                delete pCycle;

                ulIndex = 0;                
                if(m_Cycles.GetCount() > 0)
                {
                    pCycle = (SCycle*)(m_Cycles.GetHead());
                }
                else if (m_bEndOfPackets)
                {
                    m_ulIndex = 0;
                    return 0;
                }                
            }
        }
    }
    
    // Try to get the frame presentation time
    double dPresTime;

    // If it's lost, go with the default time
    if(bLost)
    {
        dPresTime = m_dNextPts;
    }
    // Else if this frame has a time stamp, use it
    else if(pFrameInfo->dTime >= 0)
    {
        dPresTime = pFrameInfo->dTime;
    }
    // Else if we have calculated the start time of this cycle
    // (based on another frame with a timestamp) calculate this one
    else if(pCycle->dStartTime >= 0)
    {
        dPresTime = pCycle->dStartTime + m_dFrameTime*ulIndex;
    }
    // Else we have no time stamps for any frames in this cycle yet.
    // Check if we have later cycles with timestamps
    else
    {
        dPresTime = -1.0;
        SCycle* pTmpCycle = pCycle;        
        while((pTmpCycle = m_Cycles.GetNext(pTmpCycle)) != 0)
        {
            if(pTmpCycle->dStartTime >= 0)
            {
                // uh-oh, we got a full cycle without any time stamps!
                // either massive packet loss or a really crappy
                // interleaving algorithm. assume it's supposed to go now
                // and any unaccounted for loss is at the end of the cycle
                dPresTime = m_dNextPts;
                pCycle->dStartTime = dPresTime - m_dFrameTime*ulIndex;
            }
        }
    }

    // If we haven't gotten any timestamps yet this cycle, wait for
    // the next packet.
    if(dPresTime < 0)
    {
        if(!m_bEndOfPackets)
        {
            m_ulIndex = ulIndex;
            return 0;

⌨️ 快捷键说明

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