Darwin 流媒体在发送RTP时会定期的发送SR发送端报告,具体调用过程如下
SR发送的函数具体实现如下:
void RTPStream::SendRTCPSR(const SInt64& inTime, Bool16 inAppendBye)
{
// This will roll over, after which payloadByteCount will be all messed up.
// But because it is a 32 bit number, that is bound to happen eventually,
// and we are limited by the RTCP packet format in that respect, so this is
// pretty much ok.
UInt32 payloadByteCount = fByteCount - (12 * fPacketCount);
RTCPSRPacket* theSR = fSession->GetSRPacket();
theSR->SetSSRC(fSsrc);
theSR->SetClientSSRC(fClientSSRC);
//fLastNTPTimeStamp = fSession->GetNTPPlayTime() + OS::TimeMilli_To_Fixed64Secs(inTime - fSession->GetPlayTime());
fLastNTPTimeStamp = OS::TimeMilli_To_1900Fixed64Secs(OS::Milliseconds()); //The time value should be filled in as late as possible.
theSR->SetNTPTimestamp(fLastNTPTimeStamp);
theSR->SetRTPTimestamp(fLastRTPTimestamp);
theSR->SetPacketCount(fPacketCount);
theSR->SetByteCount(payloadByteCount);
#if RTP_PACKET_RESENDER_DEBUGGING
fResender.logprintf("Recommending ack timeout of: %d\n", fSession->GetBandwidthTracker()->RecommendedClientAckTimeout());
#endif
theSR->SetAckTimeout(fSession->GetBandwidthTracker()->RecommendedClientAckTimeout());
UInt32 thePacketLen = theSR->GetSRPacketLen();
if (inAppendBye)
thePacketLen = theSR->GetSRWithByePacketLen();
QTSS_Error err = QTSS_NoErr;
if (fTransportType == qtssRTPTransportTypeTCP) // write out in interleave format on the RTSP TCP channel
{
UInt32 wasWritten;
err = this->InterleavedWrite(theSR->GetSRPacket(), thePacketLen, &wasWritten, fRTCPChannel);
}
else
{
void *ptr = theSR->GetSRPacket();
err = fSockets->GetSocketB()->SendTo(fRemoteAddr, fRemoteRTCPPort, ptr, thePacketLen);
this->UDPMonitorWrite(ptr, thePacketLen, kIsRTCPPacket);
}
if (err == QTSS_NoErr)
this->PrintPacketPrefEnabled((char *)theSR->GetSRPacket(), thePacketLen, (SInt32)RTPStream::rtcpSR); // if we are flow controlled this packet is not sent
}
SR包的详细格式请参照
http://blog.csdn.net/weixin_39799839/article/details/78586529
RTPStream::SendRTCPSR是在RTPStream::Write中被调用,当发送完RTP包后,会检查RTCP的发送周期是否到了,如果到了,就发送SR包
// Send an RTCP sender report if it's time. Again, we only want to send an
// RTCP if the RTP packet was sent sucessfully
// If doing rate-adaptation, then send an RTCP SR every seconds so that we get faster RTT feedback.
UInt32 senderReportInterval = fStream3GPP->RateAdaptationEnabled() ? kSenderReportInterval3GPPInSecs : kSenderReportIntervalInSecs;
if ((fSession->GetPlayFlags() & qtssPlayFlagsSendRTCP) &&
(theTime > (fLastSenderReportTime + (senderReportInterval * 1000))))
{
fLastSenderReportTime = theTime;
// CISCO comments
// thePacket->packetTransmissionTime is
// the expected transmission time, which
// is what we should report in RTCP for
// synchronization purposes, not theTime,
// which is the actual transmission time.
this->SendRTCPSR(thePacket->packetTransmitTime);
}