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

📄 rtspprotocol.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"
#include "hlxclib/stdio.h"
#include "hlxclib/stdlib.h"
#include "hxver.h"

#include "hxtypes.h"
#include "hxresult.h"
#include "hxstrutl.h"
#include "hxcomm.h"
#include "ihxpckts.h"
#include "hxfiles.h"
#include "hxengin.h"
#include "hxasm.h"
#include "hxsdesc.h"
#include "chxpckts.h"
#include "hxcore.h"
#include "hxprefs.h" 
#include "hxpref.h"
#include "hxsdesc.h"
#include "hxpends.h"
#include "hxrsdbf.h"
#include "hxengin.h"

#include "hxstring.h"
#include "hxslist.h"
#include "hxstat.h"
#include "hxtick.h"
#include "chxeven.h"

#include "hxcleng.h"
//#include "rtmlpars.h"
#include "rtspclnt.h"
#include "rtspclntext.h"
#include "rtsputil.h"
#include "mimehead.h"
#include "rtspmsg.h"
#include "rtsppars.h"
#include "rtspmdsc.h"

#include "statinfo.h"
#include "hxntsrc.h"
#include "hxprotocol.h"

#include "hxauthn.h"
#include "hxplgns.h"

#include "hxauth.h"
#include "hxdate.h"
#include "hxurl.h"
#include "platform.h"
#include "clntcore.ver"

#include "hxplugn.h"
#include "dtrvtcon.h"
#include "rmfftype.h"
#include "rtspprotocol.h"

#include "hxcomsp.h"
#include "hxpktsp.h"
#include "hxplnsp.h"
#include "miscsp.h"
#include "hxxrsmg.h"
#include "hxresmgr.h"
#include "dcoreres.h"
#ifdef _MACINTOSH
#include "hxmm.h"
#endif

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


#define PRAGMA  "initiate-session"
#define MINIMUM_STATS_INTERVAL      15000 // 15 seconds
#define MAX_DEFAULT_STATS_SIZE      512
#define MAX_TRANSPORT               10

RTSPProtocol::RTSPProtocol(HXNetSource* owner, ULONG32 ulPlatformSpecific)
: HXProtocol (owner, ulPlatformSpecific)
, m_lRefCount(0)
, m_uSecurityKey(0)
, m_uStreamCount(0)
, m_uCurrentStreamCount(0)
, m_pProtocolLib(0)
, m_pPendingStatus(0)
, m_pStatistics(0)
, m_bPlaying(FALSE)
, m_bIsASMSource(FALSE)
, m_bUseRTP(FALSE)
, m_bReceivedData(FALSE)
, m_bMulticastOnly(FALSE)
, m_idleState(NULL_STATE)
, m_pIDInfo(NULL)
, m_pRequest(NULL)
, m_bFirstAuthAttempt(TRUE)
, mReceivedControl(FALSE)
, m_bPendingSeek(FALSE)
, m_ulSeekPos1(0)
, m_ulSeekPos2(0)
, m_bHandleWWWAuthentication(FALSE)
, m_WWWResult(HXR_OK)
, m_pWWWValues(NULL)

#if defined(HELIX_FEATURE_REVERTER)
, m_pDataRevert(0)
#endif /* HELIX_FEATURE_REVERTER */
{
    m_pStreamInfoList = new CHXMapLongToObj;
    
    if (owner)
    {
        IHXPlayer* pPlayer = NULL;
        IUnknown*   pUnknown = NULL;

        owner->GetPlayer(pPlayer);

        if (pPlayer)
        {
            pUnknown = (IUnknown*)pPlayer;
        }
        // auto. config doesn't have the player object
        // use IHXClientEngine instead
        else
        {
            owner->GetContext(pUnknown);
        }

#if defined(HELIX_FEATURE_REVERTER)
        m_pDataRevert = new DataRevertController(pUnknown);
        m_pDataRevert->AddRef();
        m_pDataRevert->SetControlResponse(this);
#endif /* HELIX_FEATURE_REVERTER */

        HX_RELEASE(pUnknown);
    }

    /* Always allowed in RTSP - till we add some code to file format
     * plugins to set this value in file header - XXXRA
     */
    m_bPerfectPlayAllowed = TRUE;
    //
    // get proxy info for RTSP protocol
    //
    initialize_members();

    ReadPrefBOOL(m_pPreferences, "NonRS", m_bUseRTP);    
    if (!m_bUseRTP)
    {
        ReadPrefBOOL(m_pPreferences, "UseRTP", m_bUseRTP);
    }
}

RTSPProtocol::~RTSPProtocol ()
{
    if (m_pProtocolLib)
    {
        m_pProtocolLib->Done();
        HX_RELEASE(m_pProtocolLib);
    }

    HX_RELEASE(m_pRequest);
    HX_RELEASE(m_pPendingStatus);
    HX_RELEASE(m_pStatistics);
    HX_RELEASE(m_pIDInfo);
    HX_RELEASE(m_pWWWValues);
#if defined(HELIX_FEATURE_REVERTER)
    HX_RELEASE(m_pDataRevert);
#endif /* HELIX_FEATURE_REVERTER */
    
    HX_DELETE(m_pStreamInfoList);

}

/* IUnknown methods */

STDMETHODIMP
RTSPProtocol::QueryInterface(REFIID riid, void** ppvObj)
{
    QInterfaceList qiList[] =
        {
            { GET_IIDHANDLE(IID_IHXPendingStatus), (IHXPendingStatus*)this },
            { GET_IIDHANDLE(IID_IHXStatistics), (IHXStatistics*)this },
            { GET_IIDHANDLE(IID_IHXBackChannel), (IHXBackChannel*)this },
            { GET_IIDHANDLE(IID_IHXAtomicRuleChange), (IHXAtomicRuleChange*)this },
            { GET_IIDHANDLE(IID_IHXPreferredTransportSink), (IHXPreferredTransportSink*)this },
            { GET_IIDHANDLE(IID_IUnknown), this },
        };
    
    if (HXR_OK == ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj))
    {
        return HXR_OK;
    }    
    else if (IsEqualIID(riid, IID_IHXASMSource) && m_bIsASMSource)
    {
        AddRef();
        *ppvObj = (IHXASMSource*)this;
        return HXR_OK;
    }
    else if (m_pProtocolLib &&
            (HXR_OK == m_pProtocolLib->QueryInterface(riid, ppvObj)))
    {
        return HXR_OK;
    }

    *ppvObj = NULL;
    return HXR_NOINTERFACE;
}


/////////////////////////////////////////////////////////////////////////
//  Method:
//      IUnknown::AddRef
//  Purpose:
//      Everyone usually implements this the same... feel free to use
//      this implementation.
//
STDMETHODIMP_(ULONG32) RTSPProtocol::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//      IUnknown::Release
//  Purpose:
//      Everyone usually implements this the same... feel free to use
//      this implementation.
//
STDMETHODIMP_(ULONG32) RTSPProtocol::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}


/* IHXRTSPClientProtocolResponse methods */

STDMETHODIMP
RTSPProtocol::InitDone
(
    HX_RESULT status
)
{
    if (status != HXR_OK)
    {
        /*
         * XXX...Need to get proper errors from protocol library
         */

        mOwner->ReportError(status); //ConvertHResultToHXError(status));
    }

    if (m_pProtocolLib->HttpOnly())
    {
        mCurrentTransport = TCPMode;
    }

    return HXR_OK;
}

STDMETHODIMP
RTSPProtocol::HandleWWWAuthentication
(
    HX_RESULT HX_RESULTStatus,
    IHXValues* pIHXValuesHeaders
)
{
#if defined(HELIX_FEATURE_AUTHENTICATION)
#ifdef _MACINTOSH
    /*
     * We load a plugin for authetication. Can't do this at interrupt
     * time on Mac
     */
    if (HXMM_ATINTERRUPT())
    {
        m_bHandleWWWAuthentication  = TRUE;
        m_WWWResult                 = HX_RESULTStatus;

        HX_RELEASE(m_pWWWValues);

        m_pWWWValues                = pIHXValuesHeaders;
        if (m_pWWWValues)
        {
            m_pWWWValues->AddRef();
        }

        if (mOwner)
        {
            mOwner->ScheduleProcessCallback();
        }

        return HXR_OK;
    }
#endif

    return (handlePendingWWWAuthentication(HX_RESULTStatus, pIHXValuesHeaders));
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_AUTHENTICATION */
}

#if defined(HELIX_FEATURE_AUTHENTICATION)
// IHXClientAuthResponse
STDMETHODIMP
RTSPProtocol::ResponseReady
(
    HX_RESULT   HX_RESULTStatus,
    IHXRequest* pIHXRequestResponse
)
{
    HX_RESULT HX_RESULTErr;
    IHXValues* pIHXValuesRequestHeaders = NULL;

    if(SUCCEEDED(HX_RESULTStatus))
    {
        if (!m_pProtocolLib)
        {
            return HXR_OUTOFMEMORY;
        }

        pIHXRequestResponse->GetRequestHeaders
        (
            pIHXValuesRequestHeaders
        );

        if(!m_uStreamCount)
        {
            // We haven't received a successful Describe..
            //
            CHXHeader::mergeHeaders
            (
                pIHXValuesRequestHeaders,
                m_spIHXValuesStoredHeaders
            );

            HX_RESULTErr = m_pProtocolLib->SendStreamDescriptionRequest
            (
                mPath,
                pIHXValuesRequestHeaders
            );
        }
        else if (m_uCurrentStreamCount == m_uStreamCount)
        {
            // We haven't received a successful Setup..
            //
            HX_RESULTErr = m_pProtocolLib->SendSetupRequest
            (
                NULL,
                0,
                pIHXValuesRequestHeaders
            );
        }

        HX_RELEASE(pIHXValuesRequestHeaders);
    }
    else
    {
        if (HXR_FAIL == HX_RESULTStatus)
        {
            HX_RESULTStatus = HXR_NOT_AUTHORIZED;
        }
        mOwner->ReportError(HX_RESULTStatus);
    }

    return HXR_OK;
}

HX_RESULT
RTSPProtocol::handlePendingWWWAuthentication
(
    HX_RESULT HX_RESULTStatus,
    IHXValues* pIHXValuesHeaders
)
{
    HX_RESULT HX_RESULTRet = HXR_FAIL;

    if(HXR_NOT_AUTHORIZED == HX_RESULTStatus)
    {
        IUnknown*   pIUnknownContext = NULL;
        IHXPlayer* pIHXPlayerPlayer = NULL;
        IHXAuthenticationManager* pIHXAuthenticationManager = NULL;

        // Don't transport switch while we are waiting for authentication
        mOwner->StopDataWait();

        if
        (
            m_spIHXClientAuthConversationAuthenticator.IsValid()
            &&
            m_spIHXClientAuthConversationAuthenticator->IsDone()
        )
        {
            // Well we tried to authenticate already,
            // so it must have failed

            m_spIHXClientAuthConversationAuthenticator->Authenticated(FALSE);

            // Cleanup so that we can re-auth
            m_spIHXClientAuthConversationAuthenticator.Release();
        }

        mOwner->GetPlayer(pIHXPlayerPlayer);

        if (NULL == pIHXPlayerPlayer)
        {
            // in case of the Auto. Config
            mOwner->GetContext(pIUnknownContext);
        }
        else
        {
            pIUnknownContext = (IUnknown*)pIHXPlayerPlayer;
        }

        if (!m_spIHXClientAuthConversationAuthenticator.IsValid())
        {
            DECLARE_SMART_POINTER_UNKNOWN spIUnknownAuthenticator;
            DECLARE_SMART_POINTER
            (
                IHXObjectConfiguration
            ) spIHXObjectConfigurationAuthenticator;
            DECLARE_SMART_POINTER
            (
                IHXCommonClassFactory
            ) spIHXCommonClassFactoryHXCore;

            spIHXCommonClassFactoryHXCore = pIUnknownContext;

            // Starting conversation
            HX_RESULTRet = spIHXCommonClassFactoryHXCore->CreateInstance
            (
                CLSID_CHXClientAuthenticator,
                (void**)&spIUnknownAuthenticator
            );

            if
            (
                SUCCEEDED(HX_RESULTRet)
                &&
                spIUnknownAuthenticator.IsValid()
            )

⌨️ 快捷键说明

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