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

📄 servrsnd.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
字号:
/* ***** 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 "debug.h"
#include "hxcom.h"
#include "hxtypes.h"
#include "hxstring.h"
#include "hxslist.h"
#include "hxdeque.h"
#include "hxmap.h"
#include "hxengin.h"
#include "ihxpckts.h"
#include "basepkt.h"
#include "servrsnd.h"
#include "rtspif.h"
#include "rtsptran.h"

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif

RTSPResendBuffer::RTSPResendBuffer
(
    UINT32 bufferDuration,
    UINT32 maxBufferDuration,
    UINT32 growthRate,
    UINT32 wrapSequenceNumber
) : m_bufferDuration(bufferDuration),
    m_maxBufferDuration(bufferDuration), // XXXGo Is this right?
    m_growthRate(growthRate),
    m_uFirstSequenceNumber(0),
    m_uForceSequenceNumber(0),
    m_ulResendSuccess(0),
    m_ulResendFailure(0),
    m_wrapSequenceNumber(wrapSequenceNumber),
    m_bSetFirstSequenceNumber(FALSE)
{
    m_pPacketDeque = new HX_deque;
}

RTSPResendBuffer::~RTSPResendBuffer()
{
    Clear();
    delete m_pPacketDeque;
}

void
RTSPResendBuffer::Clear()
{
    HX_deque::Iterator i;
    BasePacket* pPacket;
    while(!m_pPacketDeque->empty())
    {
	pPacket = (BasePacket*)m_pPacketDeque->pop_front();

	if (pPacket)
	{
	    pPacket->Release();
	}

	m_uFirstSequenceNumber++;

	if (m_uFirstSequenceNumber == m_wrapSequenceNumber)
	{
	    m_uFirstSequenceNumber = 0;
	}
    }
}

void
RTSPResendBuffer::Add(BasePacket* pPacket)
{
    /* If this hasn't been set yet, set it (multicast) */
    if (m_bSetFirstSequenceNumber == FALSE)
    {
	SetFirstSequenceNumber(pPacket->m_uSequenceNumber);
    }

    /*
     * If the sequence number is already in the queue, then this is
     * a resend packet
     */

    if (Find(pPacket->m_uSequenceNumber, FALSE))
    {
        return;
    }

    pPacket->AddRef();

    UINT32 index = GetPacketIndex(pPacket->GetSequenceNumber());

    while (m_pPacketDeque->size() < index)
    {
	m_pPacketDeque->push_back(0);
    }

    m_pPacketDeque->push_back(pPacket);

#ifdef DEBUG
    UINT32 uTestIndex = GetPacketIndex(pPacket->GetSequenceNumber());
    BasePacket* pTestPacket = (BasePacket*)(*m_pPacketDeque)[uTestIndex];
    /* GoGoGadget Short-Circuit Boolean Eval! */
    HX_ASSERT(!pTestPacket ||
              pTestPacket->GetSequenceNumber() == pPacket->GetSequenceNumber());
#endif

}

BasePacket*
RTSPResendBuffer::Find(UINT16 uSeqNo, BOOL bIsNAK)
{
    BasePacket* pPacket;

    UINT32 index = GetPacketIndex(uSeqNo);

    /*
     * If the packet is not found, then the resend buffer is not big
     * enough, so grow it
     */

    if(((UINT32)index) >= m_pPacketDeque->size())
    {
	/*
	 * Only want to grow the buffer if a packet that has been NAKed
	 * was removed too soon
	 */

	if (bIsNAK)
	{
	    Grow();
	    m_ulResendFailure++;
	}

	return 0;
    }

    pPacket = (BasePacket*)(*m_pPacketDeque)[index];

    if (bIsNAK)
    {
	m_ulResendSuccess++;
    }
    return pPacket;
}

void
RTSPResendBuffer::Remove(UINT16 uSeqNo)
{
    BasePacket* pPacket = Find(uSeqNo, FALSE);

    if (pPacket)
    {
	(*m_pPacketDeque)[GetPacketIndex(uSeqNo)] = 0;
	pPacket->Release();
    }
}

void
RTSPResendBuffer::Grow()
{
    if (m_bufferDuration + m_growthRate <= m_maxBufferDuration)
    {
	m_bufferDuration += m_growthRate;
    }
}

void
RTSPResendBuffer::DiscardExpiredPackets(BOOL bForce, UINT32 uParameter)
{
    UINT32 uLastTimeStamp = 0;

    if (bForce)
    {
	m_uForceSequenceNumber = (UINT16)uParameter;
    }
    else
    {
	uLastTimeStamp = uParameter;
    }

    BasePacket* pPacket;

    while(!m_pPacketDeque->empty())
    {
	pPacket = (BasePacket*)m_pPacketDeque->front();

	/*
	 * The packet may already have been removed by an ACK or not
	 * even entered if it had been a lost packet
	 */

	if (!pPacket)
	{
	    m_pPacketDeque->pop_front();

	    m_uFirstSequenceNumber++;

	    if (m_uFirstSequenceNumber == m_wrapSequenceNumber)
	    {
		m_uFirstSequenceNumber = 0;
	    }

	    continue;
	}

	/*
	 * 1) If we are not forcing the discard, quit if the packet
	 *    A) has not been in the buffer long enough or
	 *    B) is reliable
	 * 2) If we are forcing the discard, quit when the loop reaches
	 *    the discard sequence number
	 */
	if ((!bForce &&
	     (uLastTimeStamp - pPacket->GetTime() <= m_bufferDuration ||
	      pPacket->m_uPriority == 10)) ||
	    (bForce && GetForceIndex(m_uFirstSequenceNumber) < MAX_DEQUE_SIZE))
	{
	    break;
	}

	pPacket = (BasePacket*)m_pPacketDeque->pop_front();
	pPacket->Release();

	m_uFirstSequenceNumber++;

	if (m_uFirstSequenceNumber == m_wrapSequenceNumber)
	{
	    m_uFirstSequenceNumber = 0;
	}
    }
}

void
RTSPResendBuffer::SetFirstSequenceNumber(UINT16 uSeqNo)
{
    /*
     * Only allow the first sequence number to be set once
     */
    if (!m_bSetFirstSequenceNumber)
    {
	m_bSetFirstSequenceNumber = TRUE;
	m_uFirstSequenceNumber = uSeqNo;
    }
}

UINT32
RTSPResendBuffer::GetIndex(UINT32 uBaseSequenceNumber, UINT16 uSeqNo)
{
    INT32 index = uSeqNo - uBaseSequenceNumber;

    if(index < 0)
    {
	index = m_wrapSequenceNumber - uBaseSequenceNumber + uSeqNo;
    }

    return (UINT32)index;
}

HX_RESULT
RTSPResendBuffer::UpdateStatistics(UINT32& ulResendSuccess,
                                   UINT32& ulResendFailure)
{
    ulResendSuccess = m_ulResendSuccess;
    ulResendFailure = m_ulResendFailure;

    return HXR_OK;
}

void
RTSPResendBuffer::SetBufferDepth(UINT32 uMilliseconds)
{
    m_bufferDuration = uMilliseconds;

    if (m_maxBufferDuration < uMilliseconds)
    {
	m_maxBufferDuration = uMilliseconds;
    }
}

void		
RTSPResendBuffer::SetMaxBufferDepth(UINT32 uMilliseconds)
{
    if (m_maxBufferDuration < uMilliseconds)
    {    
	m_maxBufferDuration = uMilliseconds;
    }
    else
    {
	HX_ASSERT(FALSE);
    }	
}

⌨️ 快捷键说明

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