DSS 代码分析【RTP over tcp实现】

Darwin流媒体服务器RTP包可以指定通过 RTSP TCP channel进行传输。

1.调用RTPStream::Write发送RTP包时,会判断是否使用TCP的方式进行传输,使用TCP传输时调用InterleavedWrite

if (fTransportType == qtssRTPTransportTypeTCP)    // write out in interleave format on the RTSP TCP channel.
    err = this->InterleavedWrite(thePacket->packetData, inLen, outLenWritten, fRTPChannel);
else if (fTransportType == qtssRTPTransportTypeReliableUDP)
	err = this->ReliableRTPWrite(thePacket->packetData, inLen, theCurrentPacketDelay);
else if (inLen > 0)
{
	(void)fSockets->GetSocketA()->SendTo(fRemoteAddr, fRemoteRTPPort, thePacket->packetData, inLen);

	 this->UDPMonitorWrite(thePacket->packetData, inLen, kIsRTPPacket);
}

2.RTPStream::InterleavedWrite中获取RTPStream所属的RTSPSession,并调用该类提供的InterleavedWrite方法

QTSS_Error  RTPStream::InterleavedWrite(void* inBuffer, UInt32 inLen, UInt32* outLenWritten, unsigned char channel)
{
	if (fSession->GetRTSPSession() == NULL) // RTSPSession required for interleaved write
	{
		return EAGAIN;
	}

	//char blahblah[2048];

	QTSS_Error err = fSession->GetRTSPSession()->InterleavedWrite(inBuffer, inLen, outLenWritten, channel);
}

3.RTSPSessionInterface::InterleavedWrite 使用interleaved format进行写入,由于RTSP还要用来发送RTSP请求的响应消息(Pause,Teardown等),因此要区分发送的是RTP包还是RTSP响应消息,区分标识为RTPInterleaveHeader的结构体(4个字节:第一个字节为$,第二个字节为channel,后面两个字节代表RTP的长度),RTP包在通过RTSP发送时需要以$作为开始标识。

RTSPSessionInterface::InterleavedWrite最终调用RTSPResponseStream::WriteV进行写入。

QTSS_Error RTSPSessionInterface::InterleavedWrite(void* inBuffer, UInt32 inLen, UInt32* outLenWritten, unsigned char channel)
{
......
        // DMS - this struct should be packed.
	//rt todo -- is this struct more portable (byte alignment could be a problem)?
	struct  RTPInterleaveHeader
	{
		unsigned char header;
		unsigned char channel;
		UInt16      len;
	};

		if (err == QTSS_NoErr)
	{

		if (inLen > kTCPCoalesceDirectWriteSize)
		{
			struct RTPInterleaveHeader  rih;

			// write direct to stream
			rih.header = '$';
			rih.channel = channel;
			rih.len = htons((UInt16)inLen);

			iov[1].iov_base = (char*)&rih;
			iov[1].iov_len = sizeof(rih);

			iov[2].iov_base = (char*)inBuffer;
			iov[2].iov_len = inLen;

			err = this->GetOutputStream()->WriteV(iov, 3, inLen + sizeof(rih), outLenWritten, RTSPResponseStream::kAllOrNothing);

#if RTSP_SESSION_INTERFACE_DEBUGGING 
			qtss_printf("InterleavedWrite: bypass %li\n", inLen);
#endif

		}
		else
		{
			// coalesce with other small writes

			fTCPCoalesceBuffer[fNumInCoalesceBuffer] = '$';
			fNumInCoalesceBuffer++;;

			fTCPCoalesceBuffer[fNumInCoalesceBuffer] = channel;
			fNumInCoalesceBuffer++;

			//*((short*)&fTCPCoalesceBuffer[fNumInCoalesceBuffer]) = htons(inLen);
			// if we ever turn TCPCoalesce back on, this should be optimized
			// for processors w/o alignment restrictions as above.

			SInt16  pcketLen = htons((UInt16)inLen);
			::memcpy(&fTCPCoalesceBuffer[fNumInCoalesceBuffer], &pcketLen, 2);
			fNumInCoalesceBuffer += 2;

			::memcpy(&fTCPCoalesceBuffer[fNumInCoalesceBuffer], inBuffer, inLen);
			fNumInCoalesceBuffer += inLen;

#if RTSP_SESSION_INTERFACE_DEBUGGING 
			qtss_printf("InterleavedWrite: coalesce %li, total bufff %li\n", inLen, fNumInCoalesceBuffer);
#endif
		}
	}

......
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值