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

📄 rtspclnt.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	    }	    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;}STDMETHODIMPRTSPClientProtocol::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;}STDMETHODIMPRTSPClientProtocol::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_RESULTRTSPClientProtocol::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_RESULTRTSPClientProtocol::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_RESULTRTSPClientProtocol::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_RESULTRTSPClientProtocol::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;		}		// create an RTCP transport for this stream		RTCPUDPTransport* pRTCPTran = new RTCPUDPTransport(m_bSetupRecord);                if(!pRTCPTran)                {                    HX_DELETE(pHeader);                    HX_RELEASE(pTrans);		    m_pMutex->Unlock();                    return HXR_OUTOFMEMORY;                }		pRTCPTran->AddRef();		pRTCPTran->init(m_pContext,				pRTCPSocket,				(RTPUDPTransport*)pTrans,				(IHXRTSPTransportResponse*) this,				streamNumber);		((RTPUDPTransport*)pTrans)->setRTCPTransport(pRTCPTran);		status = pRequest->addTransportInfo(pTrans, (RTCPBaseTransport*)pRTCPTran, streamNumber,		    nUDPPort);		if (m_bIPTV && m_pSetupRequestHeader && status != HXR_OUTOFMEMORY)		{		    addRFC822Headers(pMsg, m_pSetupRequestHeader);		    // don't add it twice...		    pIHXValuesRequestHeaders = NULL;		}	    }	    break;	    case RTSP_TR_RTP_TCP:	    {		RTSPTransport* pTrans = new RTPTCPTransport(m_bSetupRecord);                if(!pTrans)                {

⌨️ 快捷键说明

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