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

📄 rtsptran.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** 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 "hxassert.h"
#include "debug.h"
#include "hxcom.h"
#include "hxmarsh.h"
#include "hxstrutl.h"
#include "netbyte.h"
#include "hxengin.h"
#include "ihxpckts.h"
#include "hxcomm.h"
#include "hxmon.h"
#include "netbyte.h"
#include "hxstring.h"
#include "chxpckts.h"
#include "hxslist.h"
#include "hxmap.h"
#include "hxdeque.h"
#include "hxbitset.h"
#include "timebuff.h"
#include "timeval.h"
#include "tconverter.h"
#include "rtptypes.h"
#include "rtspmsg.h"
#include "hxcorgui.h"

#include "ntptime.h"

#include "rtspif.h"
#include "rtsptran.h"
//#include "rtpwrap.h"	// Wrappers for PMC generated base classes
#include "basepkt.h"
#include "hxtbuf.h"
#include "transbuf.h"
#include "hxtick.h"
#include "random32.h"	// random32()
#include "pkthndlr.h"	// in rtpmisc for RTCP routine
#include "rtcputil.h"	// takes care of RTCP in RTP mode
#include "hxprefs.h"	// IHXPreferences
#include "hxmime.h"
#include "hxcore.h"

#include "hxheap.h"
#ifdef PAULM_IHXTCPSCAR
#include "objdbg.h"
#endif

#ifdef PAULM_TNGTCPTRANSTIMING
#include "classtimer.h"
ClassTimer g_TNGTCPTransTimer("TNGTCPTransport", 0, 3600);
#endif

#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif

#define STREAM_END_DELAY_BASE_TOLERANCE	3000

static const UINT32 TRANSPORT_BUF_GROWTH_RATE  = 1000;

void
dump(const char* pFile, const char* pc)
{
    FILE* fp = fopen(pFile, "a");
    if(!fp)
    {
	    return;
    }
    fprintf(fp, "%s", pc);
    fclose(fp);    
}


RTSPStreamData::RTSPStreamData(BOOL needReliable):
    m_seqNo(0),
    m_streamNumber(0),
    m_reliableSeqNo(0),
    m_lastTimestamp(0),
    m_pTransportBuffer(0),
    m_pResendBuffer(0),
    m_pStreamStats(0),
    m_bNeedReliable(needReliable),
    m_packetSent(FALSE),
    m_bReceivedAllPackets(FALSE),
    m_bNeedToACK(FALSE),
    m_bFirstPacket(TRUE),
    m_bUsesRTPPackets(FALSE),
    m_pTSConverter(NULL),
    m_pTSOrderHack(NULL),
    m_eMediaType(RTSPMEDIA_TYPE_UNKNOWN)
{
    ;
}

RTSPStreamData::~RTSPStreamData()
{
    if (m_pTransportBuffer)
    {
	delete m_pTransportBuffer;
    }

    if (m_pResendBuffer)
    {
	delete m_pResendBuffer;
    }

    HX_DELETE(m_pTSConverter);
    HX_DELETE(m_pTSOrderHack);
}

RTSPStreamHandler::RTSPStreamHandler(RTSPTransport* pOwner)
    : m_pOwner(pOwner)
    , m_lRefCount(0)
{
    m_pStreamDataMap = new CHXMapLongToObj;
}

RTSPStreamHandler::~RTSPStreamHandler()
{
    CHXMapLongToObj::Iterator i;
    RTSPStreamData* pStreamData;

    for(i=m_pStreamDataMap->Begin();i!=m_pStreamDataMap->End();++i)
    {
	pStreamData = (RTSPStreamData*)(*i);
	delete pStreamData;
    }
    delete m_pStreamDataMap;
}


HX_RESULT
RTSPStreamHandler::initStreamData(
    UINT16 streamNumber, BOOL needReliable, BOOL bIsSource, INT16 rtpPayloadType,
    BOOL bRecordFlag, UINT32 wrapSequenceNumber, UINT32 ulBufferDepth,
    BOOL bHasOutOfOrderTS, CHXTimestampConverter* pTSConverter,
    RTSPMediaType eMediaType)
{
    RTSPStreamData* pStreamData;

    if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
    {
	pStreamData = new RTSPStreamData(needReliable);
	pStreamData->m_streamNumber = streamNumber;
        pStreamData->m_pTSConverter = pTSConverter;
	pStreamData->m_eMediaType = eMediaType;
	pStreamData->m_lastSeqNo = 0;
	(*m_pStreamDataMap)[streamNumber] = pStreamData;

	if (!bIsSource)
	{
	    UINT32 ulSetMaximumBufferDepth;
	    UINT32 ulSetBufferDepth;

	    if (bRecordFlag && ulBufferDepth != TRANSPORT_BUF_DURATION_UNDEF)
	    {
	    	ulSetMaximumBufferDepth = ulBufferDepth;
	    	ulSetBufferDepth = ulBufferDepth;
	    }
	    else if (bRecordFlag)
	    {
	    	ulSetMaximumBufferDepth = MAX_TRANSPORT_BUF_DURATION;
	    	ulSetBufferDepth = MAX_TRANSPORT_BUF_DURATION;
	    }
	    else
	    {
	    	ulSetMaximumBufferDepth = MAX_TRANSPORT_BUF_DURATION;
	    	ulSetBufferDepth = TRANSPORT_BUF_DURATION;
	    }

	    RTSPTransportBuffer* pTransportBuffer = 
		new RTSPTransportBuffer(m_pOwner,
	                                streamNumber,
	                                ulSetBufferDepth,
	                                ulSetMaximumBufferDepth,
	                                TRANSPORT_BUF_GROWTH_RATE,
	                                wrapSequenceNumber);


	    pStreamData->m_pTransportBuffer = pTransportBuffer;
	    pStreamData->m_pStreamStats = NULL;
	    pStreamData->m_bUsesRTPPackets = bHasOutOfOrderTS;
	}

	return HXR_OK;
    }

    return HXR_FAIL;
}

RTSPStreamData*
RTSPStreamHandler::getStreamData(UINT16 streamNumber)
{
    RTSPStreamData* pStreamData = 0;

    if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
    {
	return 0;
    }

    return pStreamData;
}

RTSPStreamData*
RTSPStreamHandler::firstStreamData()
{
    streamIterator = m_pStreamDataMap->Begin();
    if(streamIterator == m_pStreamDataMap->End())
    {
	return 0;
    }
    return (RTSPStreamData*)(*streamIterator);
}

RTSPStreamData*
RTSPStreamHandler::nextStreamData()
{
    ++streamIterator;
    if(streamIterator == m_pStreamDataMap->End())
    {
	return 0;
    }
    return (RTSPStreamData*)(*streamIterator);
}

BOOL
RTSPStreamHandler::endStreamData()
{
    return (streamIterator == m_pStreamDataMap->End());
}

HX_RESULT
RTSPStreamHandler::createResendBuffer(UINT16 streamNumber,
				      UINT32 wrapSequenceNumber)
{
    RTSPStreamData* pStreamData;

    if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
    {
	return HXR_FAILED;
    }

    RTSPResendBuffer* pResendBuffer;

    pResendBuffer = new RTSPResendBuffer(RESEND_BUF_DURATION,
                                         MAX_RESEND_BUF_DURATION,
                                         RESEND_BUF_GROWTH_RATE,
                                         wrapSequenceNumber);

    pStreamData->m_pResendBuffer = pResendBuffer;
    return HXR_OK;
}

RTSPResendBuffer*
RTSPStreamHandler::getResendBuffer(UINT16 streamNumber)
{
    RTSPStreamData* pStreamData = 0;

    if(!m_pStreamDataMap->Lookup(streamNumber, (void*&)pStreamData))
    {
	return 0;
    }
    return pStreamData->m_pResendBuffer;
}

/*
 * RTSPTransport methods
 */

RTSPTransport::RTSPTransport(BOOL bIsSource):
    m_pContext(NULL),
    m_pCommonClassFactory(0),
    m_pScheduler(0),
    m_pResp(0),
    m_pStreamHandler(0),
    m_pRegistry(0),
    m_pInternalReset(0),
    m_pSrcBufferStats(0),
    m_bIsSource(bIsSource),
    m_bIsInitialized(FALSE),
    m_bIsUpdated(FALSE),
    m_ulPacketsSent(0),
    m_lBytesSent(0),
    m_bIsReceivedData(FALSE),
    m_bSourceDone(FALSE),
    m_bHackedRecordFlag(FALSE),
    m_wrapSequenceNumber(0),
    m_bMulticast(FALSE),
    m_pPlayerState(NULL),
    m_pPacketFilter(NULL),
    m_pClientPacketList(NULL),
    m_bPrefetch(FALSE),
    m_bFastStart(FALSE),
    m_ulPlayRangeFrom(RTSP_PLAY_RANGE_BLANK),
    m_ulPlayRangeTo(RTSP_PLAY_RANGE_BLANK),
    m_bPlayRequestSent(FALSE),
    m_packets_since_last_drop(0),
    m_ulTotalSuccessfulResends(0),
    m_ulTotalFailedResends(0),
    m_ulSendingTime(0),
    m_drop_packets(FALSE),
    m_bSkipTimeAdjustment(FALSE)
#ifdef RDT_MESSAGE_DEBUG
    ,m_bRDTMessageDebug(FALSE)
#endif    
{
    m_ulStartTime = HX_GET_TICKCOUNT();
}

RTSPTransport::~RTSPTransport()
{
    HX_RELEASE(m_pCommonClassFactory);
    HX_RELEASE(m_pScheduler);
    HX_RELEASE(m_pResp);
    HX_RELEASE(m_pRegistry);
    if (m_pStreamHandler)
    {
        m_pStreamHandler->Release();
        m_pStreamHandler = NULL;
    }
    HX_RELEASE(m_pInternalReset);
    HX_RELEASE(m_pSrcBufferStats);
    HX_RELEASE(m_pPlayerState);
    HX_RELEASE(m_pPacketFilter);
    HX_RELEASE(m_pContext);

    HX_DELETE(m_pClientPacketList);
}

void
RTSPTransport::addStreamInfo(RTSPStreamInfo* pStreamInfo, UINT32 ulBufferDepth)
{
    if(pStreamInfo)
    {
	if(!m_pStreamHandler)
	{
	    m_pStreamHandler = new RTSPStreamHandler(this);
	    m_pStreamHandler->AddRef();
	}

	CHXTimestampConverter*  pTSConverter = NULL;

	if (pStreamInfo->m_HXFactor && pStreamInfo->m_RTPFactor)
	{
	    pTSConverter = new CHXTimestampConverter(CHXTimestampConverter::FACTORS,
						     pStreamInfo->m_HXFactor,
						     pStreamInfo->m_RTPFactor);
	 }
	 else if (pStreamInfo->m_sampleRate)
	 {
	     
	     pTSConverter =  new CHXTimestampConverter(CHXTimestampConverter::SAMPLES,
						       pStreamInfo->m_sampleRate);
	 }	

	 m_pStreamHandler->initStreamData(
	     pStreamInfo->m_streamNumber,
	     pStreamInfo->m_bNeedReliablePackets,
	     m_bIsSource,
	     pStreamInfo->m_rtpPayloadType,
	     m_bHackedRecordFlag,
	     m_wrapSequenceNumber,
	     ulBufferDepth,
	     pStreamInfo->m_bHasOutOfOrderTS,
	     pTSConverter,
	     pStreamInfo->m_eMediaType);

        m_bSkipTimeAdjustment = pStreamInfo->m_bRealMedia;

	RTSPStreamData* pStreamData = NULL;
	pStreamData = m_pStreamHandler->getStreamData(pStreamInfo->m_streamNumber);
	if (pStreamData && pStreamData->m_pTransportBuffer && m_bPrefetch)
	{
	    pStreamData->m_pTransportBuffer->EnterPrefetch();
	}
    }
}

void
RTSPTransport::setFirstTimeStamp(UINT16 uStreamNumber, UINT32 ulTS, 
                                 BOOL bIsRaw)
{
    RTSPStreamData* pStreamData = 
	m_pStreamHandler->getStreamData(uStreamNumber);

    if (pStreamData)
    {
	if (pStreamData->m_pTSConverter)
	{
	    pStreamData->m_pTSConverter->setHXAnchor(ulTS);
	}
	    	    
	HX_DELETE(pStreamData->m_pTSOrderHack);
    }

    if (!m_bIsSource)
    {
	RTSPTransportBuffer* pTransportBuffer = pStreamData->m_pTransportBuffer;
		
	if (pTransportBuffer && pStreamData)
	{
	    if ((m_ulPlayRangeFrom != RTSP_PLAY_RANGE_BLANK) &&
		(m_ulPlayRangeTo != RTSP_PLAY_RANGE_BLANK))
	    {
		if ((pStreamData->m_eMediaType == RTSPMEDIA_TYPE_AUDIO) ||
		    (pStreamData->m_eMediaType == RTSPMEDIA_TYPE_VIDEO))
		{
		    // For audio & video media, we'll inform transport of
		    // the media duration to help determining stream termination
		    pStreamData->m_pTransportBuffer->InformTimestampRange(
			m_ulPlayRangeFrom,
			m_ulPlayRangeTo,
			STREAM_END_DELAY_BASE_TOLERANCE);
		}
	    }
	}
    }
}

void 
RTSPTransport::setPlayRange(UINT32 ulFrom, UINT32 ulTo)
{
    // this is the Range values in PLAY request in RMA time (ms) called on PLAY 
    // request
    m_ulPlayRangeFrom = ulFrom; 
    m_ulPlayRangeTo = ulTo;
}

void
RTSPTransport::setSessionID(const char* pSessionID)
{
    m_sessionID = pSessionID;
}

UINT16
RTSPTransport::getSeqNum(UINT16 streamNumber)
{
    RTSPStreamData* pStreamData;

    pStreamData = m_pStreamHandler->getStreamData(streamNumber);

    if(pStreamData)
    {
	return pStreamData->m_seqNo;
    }
    else
    {
	return 0;	//XXXBAB - 0xffff?
    }
}

UINT32
RTSPTransport::getTimestamp(UINT16 streamNumber)
{
    RTSPStreamData* pStreamData;

    pStreamData = m_pStreamHandler->getStreamData(streamNumber);

    if(pStreamData)
    {
	// XXXGo - this is RTP time w/ offset (NOT RMA time) if RTPUDPTransprot...
	return pStreamData->m_lastTimestamp;
    }
    else
    {
	return 0;
    }
}

HX_RESULT
RTSPTransport::getPacket(UINT16 uStreamNumber, IHXPacket*& pPacket)
{
    RTSPTransportBuffer* pTransportBuffer = getTransportBuffer(uStreamNumber);
    RTSPStreamData* pStreamData = m_pStreamHandler->getStreamData(uStreamNumber);

    if ((!pTransportBuffer) || (!pStreamData))
    {
	return HXR_FAIL;
    }

    ClientPacket* clientPacket;

    HX_RESULT result = pTransportBuffer->GetPacket(clientPacket);

    if (result != HXR_OK)
    {
	return result;
    }

    pPacket = clientPacket->GetPacket();

    if (!pPacket)
    {
	/*
	 * This is a lost packet
	 */

	result = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket,
	                                               (void**)&pPacket);

	if (result != HXR_OK)
	{
	    return result;
	}

	UINT8 unASMFlags = 0;
	UINT32 ulTime = 0;
	if (clientPacket->IsDroppedPacket())
	{
	    // Preserve dropped flag as an ASM flag.
	    // This allows other code along the packet
	    // path to differentiate this packet from a 
	    // true lost packet.
	    unASMFlags |= HX_ASM_DROPPED_PKT;

	    // We have a valid timestamp for a dropped
	    // packet so lets put it in the IHXPacket
	    ulTime = clientPacket->GetTime();
	}

	pPacket->Set(0, ulTime, uStreamNumber, unASMFlags, 0);
	pPacket->SetAsLost();
    }
    else if (pStreamData->m_bUsesRTPPackets)
    {
	if (!pStreamData->m_pTSOrderHack)
	{
	    pStreamData->m_pTSOrderHack = new RTSPStreamData::TSOrderHackInfo();
	    
	    if (pStreamData->m_pTSOrderHack)
	    {
		pStreamData->m_pTSOrderHack->m_ulLastSentTS = 
		    pPacket->GetTime();
		pStreamData->m_pTSOrderHack->m_ulLastRecvTS = 
		    pStreamData->m_pTSOrderHack->m_ulLastSentTS;

⌨️ 快捷键说明

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