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

📄 rtspclnt.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* ***** 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 "hxcom.h"
#if defined _UNIX
#if defined _SOLARIS || defined _IRIX || defined _FREEBSD || defined _OPENBSD || defined _NETBSD
#include <sys/types.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef _BEOS
#include <arpa/inet.h>
#endif
#endif

#include <stdlib.h>
#include "hxtypes.h"
#include "timeval.h"
#include "hxstring.h"
#include "hxslist.h"
#include "hxmarsh.h"
#include "hxtick.h"
#include "netbyte.h"
#include "hxengin.h"
#include "hxcore.h"
#include "hxpnets.h"
#include "ihxpckts.h"
#include "hxcomm.h"
#include "hxprefs.h"
#include "hxpref.h"
#include "hxplugn.h"
#include "hxencod.h"
#include "hxrsdbf.h"
#include "plghand2.h"
#ifdef HELIX_FEATURE_SERVER
#include "plgnhand.h"
#endif
#include "hxplugn.h"
#include "hxsdesc.h"
#include "netbyte.h"
#include "chxpckts.h"
#include "asmrulep.h"
#include "growingq.h"
#include "mimehead.h"
#include "mimescan.h"
#include "timerep.h"
#include "hxthread.h"
#include "rtspmsg.h"
#include "rtsppars.h"
#include "rtspmdsc.h"
#include "basepkt.h"
#include "servrsnd.h"
#include "portaddr.h"
#include "chxkeepalive.h"
#include "rtspclnt.h"
#include "rtsputil.h"
#include "sdptools.h"
#include "hxurl.h"
#include "hxstrutl.h"
#include "trmimemp.h"
#include "rtptypes.h"
#include "stream_desc_hlpr.h"

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

#define RN_COMMON_MIME_TYPE_FRAGMENT	"x-pn-"

#ifndef BUFFER_DEPTH_UNDEFINED
#define BUFFER_DEPTH_UNDEFINED 0xffffffff
#endif

#define MULTICAST_ADDRESS_RANGE_LOW     3758096384  // 224.0.0.0
#define MULTICAST_ADDRESS_RANGE_HIGH    4026531839  // 239.255.255.255

#define DEFAULT_SERVER_TIMEOUT          90          // in seconds
#define MINIMUM_TIMEOUT                 5           // in seconds

const RTSPTableEntry RTSPClientProtocol::zm_pRTSPTable[RTSP_TABLE_SIZE] =
{
    { "SETUP",		SETUP	    },
    { "REDIRECT",	REDIRECT    },
    { "PLAY",		PLAY	    },
    { "PAUSE",		PAUSE	    },
    { "SET_PARAMETER",	SET_PARAM   },
    { "GET_PARAMETER",	GET_PARAM   },
    { "OPTIONS",	OPTIONS	    },
    { "DESCRIBE",	DESCRIBE    },
    { "TEARDOWN",	TEARDOWN    },
    { "RECORD",		RECORD	    },
    { "ANNOUNCE",	ANNOUNCE    }
};

/*
 * RTSPTransportInfo methods
 */

RTSPTransportInfo::RTSPTransportInfo():
    m_pTransport(0),
    m_pRTCPTransport(0)
{
}

RTSPTransportInfo::~RTSPTransportInfo()
{
    if(m_pTransport)
    {
	m_pTransport->Done();
    }

    if(m_pRTCPTransport)
    {
	m_pRTCPTransport->Done();
    }

    HX_RELEASE(m_pTransport);
    HX_RELEASE(m_pRTCPTransport);
}

void
RTSPTransportInfo::addStreamNumber(UINT16 streamNumber)
{
    m_streamNumberList.AddTail((void*)streamNumber);
}

BOOL
RTSPTransportInfo::containsStreamNumber(UINT16 streamNumber)
{
    CHXSimpleList::Iterator i;
    for(i=m_streamNumberList.Begin();i!=m_streamNumberList.End();++i)
    {
	UINT16 sNumber = (UINT16)(PTR_INT)(*i);
	if(sNumber == streamNumber)
	{
	    return TRUE;
	}
    }
    return FALSE;
}


/*
 * RTSPTransportRequest methods
 */

RTSPTransportRequest::RTSPTransportRequest(RTSPTransportTypeEnum tType,
    UINT16 sPort):
	m_lTransportType(tType),
	m_sPort(sPort),
	m_bDelete(FALSE)
{
}

RTSPTransportRequest::~RTSPTransportRequest()
{
    CHXSimpleList::Iterator i;
    for(i=m_transportInfoList.Begin();i!=m_transportInfoList.End();++i)
    {
	RTSPTransportInfo* pInfo = (RTSPTransportInfo*)(*i);
	delete pInfo;
    }
}

RTSPTransportInfo*
RTSPTransportRequest::getTransportInfo(UINT16 streamNumber)
{
    CHXSimpleList::Iterator i;
    for(i=m_transportInfoList.Begin();i!=m_transportInfoList.End();++i)
    {
	RTSPTransportInfo* pInfo = (RTSPTransportInfo*)(*i);
	if(pInfo->containsStreamNumber(streamNumber))
	{
	    return pInfo;
	}
    }
    return 0;
}

RTSPTransportInfo*
RTSPTransportRequest::getFirstTransportInfo()
{
    m_lListPos = m_transportInfoList.GetHeadPosition();
    if(m_lListPos)
    {
	return (RTSPTransportInfo*)m_transportInfoList.GetNext(m_lListPos);
    }
    return 0;
}

RTSPTransportInfo*
RTSPTransportRequest::getNextTransportInfo()
{
    if(m_lListPos)
    {
	return (RTSPTransportInfo*)m_transportInfoList.GetNext(m_lListPos);
    }
    return 0;
}

HX_RESULT
RTSPTransportRequest::addTransportInfo(RTSPTransport* pTrans,
    RTCPBaseTransport* pRTCPTrans, UINT16 streamNumber, UINT16 sPort)
{
    HX_RESULT retVal = HXR_OK;
    RTSPTransportInfo* pTransInfo = new RTSPTransportInfo;
    if(pTransInfo)
    {
        pTransInfo->m_pTransport = pTrans;	// already AddRef'd
        pTransInfo->m_pRTCPTransport = pRTCPTrans;
        pTransInfo->addStreamNumber(streamNumber);
        pTransInfo->m_sPort = sPort;

        LISTPOSITION listRet = m_transportInfoList.AddTail(pTransInfo);
        if( listRet == NULL )
        {
            HX_DELETE(pTransInfo);
            retVal = HXR_OUTOFMEMORY;
        }
    }
    else
    {
        retVal = HXR_OUTOFMEMORY;
    }
    return retVal;
}


// static initializations
RTSPClientSessionManagerType RTSPClientSessionManager::zm_pSessionManager = 0;

/*
 * RTSPClientProtocol methods
 */


/*
 * IUnknown methods
 */

STDMETHODIMP
RTSPClientProtocol::QueryInterface(REFIID riid, void** ppvObj)
{
    QInterfaceList qiList[] =
    {
	{ GET_IIDHANDLE(IID_IUnknown), this },
	{ GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*) this },
	{ GET_IIDHANDLE(IID_IHXStatistics), (IHXStatistics*) this },
	{ GET_IIDHANDLE(IID_IHXResolverResponse), (IHXResolverResponse*) this },
	{ GET_IIDHANDLE(IID_IHXInterruptSafe), (IHXInterruptSafe*) this },
	{ GET_IIDHANDLE(IID_IHXResendBufferControl), (IHXResendBufferControl*) this },
	{ GET_IIDHANDLE(IID_IHXThinnableSource), (IHXThinnableSource*) this },
	{ GET_IIDHANDLE(IID_IHXTransportSyncServer), (IHXTransportSyncServer*) this },
    };
    if(QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj) == HXR_OK)
    {
	return HXR_OK;
    }
    else if (m_pTransportStreamMap &&
	     !m_pTransportStreamMap->IsEmpty() &&
	     ((void *)((*m_pTransportStreamMap)[0])) &&
	     (HXR_OK == ((RTSPTransport*)(*m_pTransportStreamMap)[0])->
		QueryInterface(riid, ppvObj)))
    {
	return HXR_OK;
    }
    *ppvObj = NULL;
    return HXR_NOINTERFACE;
}

STDMETHODIMP_(UINT32)
RTSPClientProtocol::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

STDMETHODIMP_(UINT32)
RTSPClientProtocol::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}

/*
 * RTSPClientProtocol methods
 */

RTSPClientProtocol::RTSPClientProtocol():
    m_foreignPort(0),
    m_pTransportStreamMap(0),
    m_pTransportPortMap(0),
    m_pTransportMPortMap(0),
    m_pTransportChannelMap(0),
    m_pControlToStreamNoMap(0),
    m_foreignAddr(0),
    m_ulConnectToAddr(0),
    m_lRefCount(0),
    m_pResp(0),
    m_pFileHeader(0),
    m_bSetupRecord(FALSE),
    m_setupResponseCount(0),
    m_pSessionHeaders(0),
    m_pResponseHeaders(0),
    m_pCloakValues(NULL),
    m_pSession(0),
    m_pRegistry(0),
    m_bClientDone(FALSE),
    m_bMessageDebug(FALSE),
    m_bUseProxy(FALSE),
    m_bHTTPOnly(FALSE),
    m_pUDPSocketStreamMap(0),
    m_pRTCPSocketStreamMap(0),
    m_pResolver(0),
    m_bSeqValueReceived(FALSE),
    m_bNoReuseConnection(FALSE),
    m_bLoadTest(FALSE),
    m_bEntityRequired(TRUE),
    m_pMutex(NULL),
    m_uProtocolType(0),
    m_pConnectionlessControl(0),
    m_bConnectionlessControl(FALSE),
    m_pConnectionCheckCallback(0),
    m_uConnectionCheckCallbackHandle(0),
    m_bConnectionAlive(FALSE),
    m_uConnectionTimeout(DEFAULT_CONN_TIMEOUT),
    m_ulBufferDepth(BUFFER_DEPTH_UNDEFINED),
    m_pInterruptState(NULL),
    m_pScheduler(NULL),
    m_bUseHTTPProxy(FALSE),
    m_bKeepLiveResponsed(TRUE),    
    m_bSplitterConsumer(FALSE),
    m_pPacketFilter(NULL),
    // workaround...
    m_bNonRSRTP(FALSE),
    m_pSetupRequestHeader(NULL),
    m_bPlayJustSent(FALSE),
    m_bIPTV(FALSE),
    m_bColumbia(FALSE),
    m_bNoKeepAlive(FALSE),
    m_bForceUCaseTransportMimeType(FALSE),
    m_bPrefetch(FALSE),
    m_bFastStart(FALSE),
    m_pCloakPorts(NULL),
    m_nCloakPorts(0),
    m_currentTransport(TCPMode),
    m_bReportedSuccessfulTransport(FALSE),
    m_bSDPInitiated(FALSE),
    m_bMulticast(FALSE),
    m_ulMulticastAddress(0),
    m_pSDPFileHeader(NULL),
    m_pSDPStreamHeaders(NULL),
    m_bSessionSucceeded(FALSE),
    m_bHasSyncMasterStream(FALSE),
    m_pNetworkServices(NULL),
    m_pPreferences(NULL),
    m_pSessionTimeout(NULL),
    m_pTimeoutCallback(NULL),
    m_bUseLegacyTimeOutMsg(TRUE),
    m_bKeepAlivePending(FALSE),
    m_bPaused(FALSE),
    m_ulServerTimeOut(DEFAULT_SERVER_TIMEOUT),
    m_ulCurrentTimeOut(0),
    m_pUAProfURI(NULL),
    m_pUAProfDiff(NULL)
#if defined(_MACINTOSH)
    , m_pCallback(NULL)
#endif /* _MACINTOSH */
{
    /*
     * Byte queue must be as large as possible because messages may be
     * bigger than MAX_RTSP_MSG
     */

    m_state = RTSPClientProtocol::INIT;

    // all methods supported...
    memset(m_pIsMethodSupported, 1, sizeof(BOOL) * RTSP_TABLE_SIZE);

#ifdef THREADS_SUPPORTED
	HXMutex::MakeMutex(m_pMutex);
#else
	HXMutex::MakeStubMutex(m_pMutex);
#endif
}

RTSPClientProtocol::~RTSPClientProtocol()
{
    clearStreamInfoList();
    clearTransportRequestList();
    clearUDPResponseHelperList();

    reset();

    HX_DELETE(m_pMutex);

    HX_RELEASE(m_pUAProfDiff);
    HX_RELEASE(m_pUAProfURI);
    HX_RELEASE(m_pPreferences);
    HX_RELEASE(m_pNetworkServices);
    HX_RELEASE(m_pRegistry);
    HX_RELEASE(m_pFileHeader);
    HX_RELEASE(m_pSessionHeaders);
    HX_RELEASE(m_pResponseHeaders);
    HX_RELEASE(m_pCloakValues);
    HX_RELEASE(m_pInterruptState);
    HX_RELEASE(m_pScheduler);
}

/*
 * IHXRTSPClientProtocol methods
 */

void
RTSPClientProtocol::SetSplitterConsumer(BOOL b)
{
    m_bSplitterConsumer = b;
}

STDMETHODIMP
RTSPClientProtocol::Init(IUnknown* pContext,
			const char* pHostName,
			UINT16 foreignPort,
			IHXRTSPClientProtocolResponse* pClient,
			UINT32 initializationType,
			IHXValues* pSessionHeaders,
			IHXValues* pInfo,
			BOOL bHTTPCloak,
			UINT16 uCloakPort,
			BOOL bNoReuseConnection)
{
    m_pSessionManager = RTSPClientSessionManager::instance();

    return InitExt(pContext,
		   pHostName,
		   foreignPort,
		   pClient,
		   initializationType,
		   pSessionHeaders,
		   pInfo,
		   bHTTPCloak,
		   uCloakPort,
		   bNoReuseConnection);
}

HX_RESULT
RTSPClientProtocol::InitExt(IUnknown*   pContext,
			    const char* pHostName,
			    UINT16	foreignPort,
			    IHXRTSPClientProtocolResponse* pClient,
			    UINT32	initializationType,
			    IHXValues* pSessionHeaders,
			    IHXValues* pInfo,
			    BOOL	bHTTPCloak,
			    UINT16	uCloakPort,
			    BOOL	bNoReuseConnection)
{
    HX_RESULT       hresult = HXR_OK;
    IUnknown*	    pUnknown = NULL;
    IHXResolver*    pResolver = NULL;
    IHXBuffer*      pBuffer = NULL;
    IHXBuffer*      pSrcBuffer = NULL;
    IHXValues*      pURLProps = NULL;
    CHXURL*         pURL = NULL;

    if (!m_pContext)
    {
	m_pContext = pContext;
	m_pContext->AddRef();
    }

    if (!m_pResp)
    {
	m_pResp = pClient;
	m_pResp->AddRef();
    }

    HX_RELEASE(m_pCommonClassFactory);

    hresult = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
                                         (void**) &m_pCommonClassFactory);

    if (HXR_OK != hresult)
    {
        goto cleanup;
    }

    HX_RELEASE(m_pInterruptState);
    hresult = m_pContext->QueryInterface(IID_IHXInterruptState,

⌨️ 快捷键说明

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