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

📄 rtspclnt.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	IHXPluginEnumerator* pPluginEnumerator = NULL;
	m_pContext->QueryInterface
	(
	    IID_IHXPluginEnumerator,
	    (void**)&pPluginEnumerator
	);

	if(pPluginEnumerator)
	{
	    IUnknown* pUnknown = NULL;
            ULONG32 ulNumPlugins = pPluginEnumerator->GetNumOfPlugins();
	    for(ULONG32 i=0;i<ulNumPlugins;++i)
	    {
		if(SUCCEEDED(pPluginEnumerator->GetPlugin(i, pUnknown)))
		{
                    GetStreamDescriptionInfo(pUnknown, mimeTypes);
                    HX_RELEASE(pUnknown);
                }
	    }
	    pPluginEnumerator->Release();
	}
    }

    HX_RELEASE(pPluginGroupEnum);

    pMsg->addHeader("Accept", (const char*)mimeTypes);
    AddCommonHeaderToMsg(pMsg);

    addRFC822Headers(pMsg, pValuesRequestHeaders);

    appendAuthorizationHeaders(pMsg);

    HX_RELEASE(pValuesRequestHeaders);

    UINT32 seqNo = m_pSession->getNextSeqNo(this);
    rc = sendRequest(pMsg, seqNo);
    m_pMutex->Unlock();
    return rc;
}

STDMETHODIMP
RTSPClientProtocol::SendStreamRecordDescriptionRequest(
    const char* pURL,
    IHXValues* pFileHeader,
    CHXSimpleList* pStreams,
    IHXValues* pRequestHeaders)
{
    HX_RESULT rc = HXR_OK;
    IHXBuffer* pDescription = 0;

    if (!m_pIsMethodSupported[ANNOUNCE])
    {
	return HXR_OK;
    }

    // Let's make sure we have enough mem before we do the mutex lock.
    RTSPAnnounceMessage* pMsg = new RTSPAnnounceMessage;
    if(!pMsg)
    {
        return HXR_OUTOFMEMORY;
    }
    m_pMutex->Lock();
    pMsg->setURL(pURL);
    m_url = pURL;
    const char* pDesc = 0;

    addRFC822Headers(pMsg, pRequestHeaders);

    clearStreamInfoList();

    // use the first stream description plugin found...
    char* pMimeType = 0;
    if(HXR_OK == getStreamDescriptionMimeType(pMimeType))
    {
	IHXStreamDescription* pSD = 
	    getStreamDescriptionInstance(pMimeType);

	if(pSD)
	{
	    UINT32 streamNumber;
	    UINT32 needReliable;
	    UINT32 rtpPayloadType;
	    UINT32 ulIsLive;
	    IHXBuffer* pControlString;
	    UINT32 ulIsSessionLive = 0;

	    // if we are talking to a realserver, we will make an old sdpfile
	    // for now...We need to check version and send the spec complient
	    // sdp!
	    IHXValues* pResponseHeaders = NULL;
	    if (HXR_OK ==
		m_pResponseHeaders->QueryInterface(IID_IHXValues, (void**)&pResponseHeaders))
	    {
		pFileHeader->SetPropertyULONG32("SdpFileType",
		    GetSdpFileTypeWeNeed(pResponseHeaders));
	    }
	    HX_RELEASE(pResponseHeaders);

	    UINT16 nStreams = pStreams->GetCount();
	    IHXValues** ppValues = new IHXValues*[nStreams+2];
            if(!ppValues)
            {
                rc = HXR_OUTOFMEMORY;
                HX_DELETE(pMsg);
                goto overandout;
            }
	    ppValues[0] = pFileHeader;
	    ppValues[1] = 0;    // no options

	    pFileHeader->GetPropertyULONG32("LiveStream", ulIsSessionLive);

	    CHXSimpleList::Iterator i;
	    INT16 j=2;
	    for(i=pStreams->Begin();i!=pStreams->End();++i,++j)
	    {
		// reset...
		streamNumber	= 0;
		needReliable	= 0;
		rtpPayloadType	= (UINT32)-1;
		ulIsLive	= ulIsSessionLive;
		pControlString	= 0;

		ppValues[j] = (IHXValues*)(*i);

		// build stream info list
		RTSPStreamInfo* pInfo = new RTSPStreamInfo;
                if(!pInfo)
                {
                    rc = HXR_OUTOFMEMORY;
                    HX_DELETE(pMsg);
                    HX_VECTOR_DELETE(ppValues);
                    goto overandout;
                }
		ppValues[j]->GetPropertyULONG32("StreamNumber",
		    streamNumber);
		ppValues[j]->GetPropertyULONG32("NeedReliablePackets",
		    needReliable);
		ppValues[j]->GetPropertyULONG32("RTPPayloadType",
		    rtpPayloadType);
		ppValues[j]->GetPropertyCString("Control",
		    pControlString);
		ppValues[j]->GetPropertyULONG32("LiveStream", ulIsLive);

		pInfo->m_streamNumber = (UINT16)streamNumber;
		pInfo->m_bNeedReliablePackets = needReliable? TRUE: FALSE;
		pInfo->m_rtpPayloadType = (INT16)rtpPayloadType;
		pInfo->m_bIsLive = ulIsLive ? TRUE : FALSE;
		pInfo->m_sPort = 0;
		if(pControlString)
		{
		    pInfo->m_streamControl = pControlString->GetBuffer();

		    // done with the buffer
		    pControlString->Release();
		    pControlString = NULL;
		}
		else
		{
		    char tmp[32];
		    SafeSprintf(tmp,32, "streamid=%u", (UINT16)streamNumber);
		    pInfo->m_streamControl = tmp;
		}
		m_streamInfoList.AddTail(pInfo);
	    }
	    pSD->GetDescription(nStreams+2, ppValues, pDescription);
	    pDesc = (const char*)pDescription->GetBuffer();
	    pSD->Release();
	    delete[] ppValues;
	}
    }
    if(pDesc)
    {
	m_bSetupRecord = TRUE;
#ifdef _MACINTOSH
// someday, someone in core should look at why m_pSession is NULL when
// an invalid port is used, and yet m_pSession is assumed to be valid, and subsequently
// crashes macs HARD. I would attempt to investigate this further, however
// the core deferred task keeps crashing the debugger while I am attempting
// to trace through why m_pSession never gets assigned. since Mac Producer goes
// beta in 2 weeks, I'm putting this 'fix' in here now.. rlovejoy 2/16/00

		if (m_pSession == NULL) {
			rc = HXR_PORT_IN_USE;
		} else
#endif
		{
        UINT32 seqNo = m_pSession->getNextSeqNo(this);
	rc = sendRequest(pMsg, pDesc, pMimeType, seqNo);
		}
	// done with the description, we need to clean it up
	pDescription->Release();
    }
    else
    {
	rc = HXR_FAIL;
    }
overandout:
    delete[] pMimeType;
    m_pMutex->Unlock();
    return rc;
}


STDMETHODIMP
RTSPClientProtocol::SendSetupRequest
(
    RTSPTransportType* pTransType,
    UINT16 nTransTypes,
    IHXValues* pIHXValuesRequestHeaders
)
{
    m_pMutex->Lock();

    HX_RESULT           rc = HXR_OK;
    IHXUDPSocket*       pUDPSocket = NULL;
    IHXUDPSocket*       pRTCPUDPSocket = NULL;
    RTSPTransport*      pTrans = NULL;
    RTCPUDPTransport*   pRTCPTrans = NULL;
    RTSPStreamInfo*     pStreamInfo = NULL;
    IHXSetSocketOption* pSockOpt = NULL;
    CHXSimpleList::Iterator i;

#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)
    if (m_bSDPInitiated && m_bMulticast)
    {
        RTSPTransportRequest* pRequest = new RTSPTransportRequest(RTSP_TR_RTP_MCAST, 0);
        if(pRequest)
        {
	    m_transportRequestList.AddTail(pRequest);
	}
        else
        {
            rc = HXR_OUTOFMEMORY;
            goto cleanup;
        }

        for (i=m_streamInfoList.Begin();i!=m_streamInfoList.End();++i)
        {
            pStreamInfo = (RTSPStreamInfo*)(*i);

            pUDPSocket = (IHXUDPSocket*)(*m_pUDPSocketStreamMap)[pStreamInfo->m_streamNumber];
            pRTCPUDPSocket = (IHXUDPSocket*)(*m_pRTCPSocketStreamMap)[pStreamInfo->m_streamNumber];

            // create a new transport for each setup
            pTrans = new RTPUDPTransport(m_bSetupRecord);
            if(!pTrans)
            {
                rc = HXR_OUTOFMEMORY;
                goto cleanup;
            }
            pTrans->AddRef();

            if (HXR_OK != ((RTPUDPTransport*)pTrans)->init(m_pContext,
	                                                   pUDPSocket,
	                                                   (IHXRTSPTransportResponse*)this))
            {
                rc = HXR_BAD_TRANSPORT;
                goto cleanup;
            }
            pTrans->notifyEmptyRTPInfo();

            // create an RTCP transport for this stream
            pRTCPTrans = new RTCPUDPTransport(m_bSetupRecord);
            if (!pRTCPTrans)
            {
                rc = HXR_OUTOFMEMORY;
                goto cleanup;
            }
            pRTCPTrans->AddRef();

            if (HXR_OK != pRTCPTrans->init(m_pContext, pRTCPUDPSocket, (RTPUDPTransport*)pTrans,
		                           (IHXRTSPTransportResponse*) this, pStreamInfo->m_streamNumber))
            {
                rc = HXR_BAD_TRANSPORT;
                goto cleanup;
            }
            pRTCPTrans->notifyEmptyRTPInfo();

            ((RTPUDPTransport*)pTrans)->setRTCPTransport(pRTCPTrans);

            pTrans->addStreamInfo(pStreamInfo);
	    (*m_pTransportStreamMap)[pStreamInfo->m_streamNumber] = pTrans;

	    (*m_pTransportMPortMap)[pStreamInfo->m_sPort] = pTrans;
            pTrans->JoinMulticast(m_ulConnectToAddr, pStreamInfo->m_sPort, pUDPSocket);

	    (*m_pTransportMPortMap)[pStreamInfo->m_sPort+1] = pRTCPTrans;
            pRTCPTrans->JoinMulticast(m_ulConnectToAddr, pStreamInfo->m_sPort + 1, pRTCPUDPSocket);

	    if ((!m_bHasSyncMasterStream) && 
		(pStreamInfo->m_eMediaType == RTSPMEDIA_TYPE_AUDIO))
	    {
	        pStreamInfo->m_bIsSyncMaster = TRUE;
		m_bHasSyncMasterStream = TRUE;
            }

	    mapControlToStreamNo(pStreamInfo->m_streamControl, pStreamInfo->m_streamNumber);

	    rc = pRequest->addTransportInfo(pTrans, (RTCPBaseTransport*)pRTCPTrans, pStreamInfo->m_streamNumber, 0);
            if( rc == HXR_OUTOFMEMORY )
            {
                goto cleanup;
            }
            
 	    rc = pUDPSocket->Read(HX_SAFEUINT(MAX_UDP_PACKET));
            if( rc == HXR_OUTOFMEMORY )
            {
                goto cleanup;
            }
            rc = pRTCPUDPSocket->Read(HX_SAFEUINT(MAX_UDP_PACKET));
            if( rc == HXR_OUTOFMEMORY )
            {
                goto cleanup;
            }
        }

        m_uProtocolType = 1;
        m_pResp->HandleSetupResponse(HXR_OK);

        goto cleanup;
    }
#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */

    if( HXR_OUTOFMEMORY == extractExistingAuthorizationInformation(pIHXValuesRequestHeaders))
    {
        rc = HXR_OUTOFMEMORY;
        goto cleanup;
    }

    if(pTransType)
    {
	for(int i=0;i<nTransTypes;++i)
	{
	    RTSPTransportRequest* pRequest =
		new RTSPTransportRequest(pTransType[i].m_lTransportType,
		    pTransType[i].m_sPort);
            if(pRequest)
            {
	        m_transportRequestList.AddTail(pRequest);
	    }
            else
            {
                rc = HXR_OUTOFMEMORY;
                break;
            }
	}
    }

    if (m_bIPTV && rc == HXR_OK)
    {
	// we are going to keep this around for now to send cookie in all SETUP.
	m_pSetupRequestHeader = pIHXValuesRequestHeaders;
	m_pSetupRequestHeader->AddRef();
    }


    if (rc == HXR_OK)
    {
        rc =  sendFirstSetupRequest(pIHXValuesRequestHeaders);
    }

cleanup:

    if (HXR_OK != rc)
    {
        HX_RELEASE(pRTCPTrans);
        HX_RELEASE(pTrans);
    }

    m_pMutex->Unlock();

    return rc;
}

HX_RESULT
RTSPClientProtocol::sendFirstSetupRequest
(
    IHXValues* pIHXValuesRequestHeaders
)
{
    m_setupResponseCount = 0;

    if (!m_streamInfoList.IsEmpty())
    {
	RTSPStreamInfo* pStreamInfo = (RTSPStreamInfo*)m_streamInfoList.GetHead();
	if(pStreamInfo)
	{
	    return sendSetupRequestMessage
	    (
		pStreamInfo,
		pIHXValuesRequestHeaders,
		TRUE
	    );
	}
    }
    return HXR_FAIL;
}

HX_RESULT
RTSPClientProtocol::sendRemainingSetupRequests()
{
    HX_RESULT status = HXR_OK;
    CHXSimpleList::Iterator i;
    BOOL bFirst = TRUE;
    for(i=m_streamInfoList.Begin();
	    status == HXR_OK && (i!=m_streamInfoList.End());++i)
    {
	if(bFirst)
	{
	    bFirst = FALSE;
	}
	else
	{
	    RTSPStreamInfo* pStreamInfo = (RTSPStreamInfo*)(*i);
	    status = sendSetupRequestMessage(pStreamInfo, NULL, FALSE);
	}
    }
    return status;
}

HX_RESULT
RTSPClientProtocol::sendSetupRequestMessage(RTSPStreamInfo* pStreamInfo,
    IHXValues* pIHXValuesRequestHeaders, BOOL bFirstSetup)
{
    m_pMutex->Lock();
    RTSPSetupMessage* pMsg = new RTSPSetupMessage;
    if(!pMsg)
    {
        m_pMutex->Unlock();
        return HXR_OUTOFMEMORY;
    }

    HX_RESULT status = HXR_OK;
    status = sendSetupRequestMessageExt(pStreamInfo,
					pIHXValuesRequestHeaders,
					bFirstSetup,
					pMsg);

    pMsg->addHeader("User-Agent", m_versionString);

    if (bFirstSetup && !m_sessionID.IsEmpty())
    {
        pMsg->addHeader("If-Match", m_sessionID);
    }
    else if (!m_sessionID.IsEmpty())
    {
        pMsg->addHeader("Session", m_sessionID);
    }

    // append stream control string to request
    setSetupRequestURL(pMsg, pStreamInfo);

    if (pIHXValuesRequestHeaders)
    {
	addUAProfHeaders(pIHXValuesRequestHeaders);
	addRFC822Headers(pMsg, pIHXValuesRequestHeaders);
    }

    UINT32 seqNo;
    seqNo = m_pSession->getNextSeqNo(this);

    /* Why are we not checking for any error code from above ??? */
    status = sendRequest(pMsg, seqNo);

    m_pMutex->Unlock();
    return status;
}

HX_RESULT
RTSPClientProtocol::sendSetupRequestMessageExt(RTSPStreamInfo* pStreamInfo,
					       IHXValues*& pIHXValuesRequestHeaders,
					       BOOL bFirstSetup,
					       RTSPSetupMessage*& pMsg)
{
    MIMEHeader* pHeader = new MIMEHeader("Transport");
    if(!pHeader)
    {
        return HXR_OUTOFMEMORY;
    }

    HX_RESULT status = HXR_OK;

    CHXSimpleList::Iterator i;

    for(i=m_transportRequestList.Begin();i!=m_transportRequestList.End();++i)
    {
	RTSPTransportRequest* pRequest = (RTSPTransportRequest*)(*i);
	UINT16 streamNumber = pStreamInfo->m_streamNumber;
	UINT16 nUDPPort = 0;

#if defined(HELIX_FEATURE_RTP)
	switch(pRequest->m_lTransportType)
	{
	    case RTSP_TR_RTP_UDP:
	    {
		// create a new transport for each setup
		RTSPTransport* pTrans =
				    new RTPUDPTransport(m_bSetupRecord);
                if(!pTrans)
                {
                    HX_DELETE(pHeader);
                    return HXR_OUTOFMEMORY;
                }
		pTrans->AddRef();

		if (m_bPrefetch)
		{
		    pTrans->EnterPrefetch();
		}

		IHXUDPSocket* pUDPSocket = (IHXUDPSocket*)
		    (*m_pUDPSocketStreamMap)[streamNumber];
		pUDPSocket->GetLocalPort(nUDPPort);

		IHXUDPSocket* pRTCPSocket = (IHXUDPSocket*)
		    (*m_pRTCPSocketStreamMap)[streamNumber];

		if (HXR_OK !=
		    ((RTPUDPTransport*)pTrans)->init(
			m_pContext,
			pUDPSocket,
			(IHXRTSPTransportResponse*) this))
		{
		    pTrans->Release();
		    return HXR_BAD_TRANSPORT;
		}

⌨️ 快捷键说明

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