public bool FeedData(ref MsgHdr message, double absoluteTimestamp, bool isAudio)
{
if (absoluteTimestamp == 0)return true;
double rate = isAudio ? OutStream.Capabilities.Samplerate : 90000.0;
var ssrc = isAudio ? OutStream.AudioSSRC : OutStream.VideoSSRC;
var messageLength = message.Buffers.Sum(t => t.Length);
if (!_rtpClient.hasAudio &&!_rtpClient.hasVideo) return true;
var packetsCount = isAudio ? _rtpClient.audioPacketsCount : _rtpClient.videoPacketsCount;
var bytesCount = isAudio ? _rtpClient.audioBytesCount : _rtpClient.videoBytesCount;
var startRTP = isAudio ? _rtpClient.audioStartRTP : _rtpClient.videoStartRTP;
if (startRTP == 0xffffffff)
{
startRTP = message.Buffers[0].ReadUInt(4);
if (isAudio) _rtpClient.audioStartRTP = startRTP;
else _rtpClient.videoStartRTP = startRTP;
if (isAudio) _rtpClient.audioStartTS = absoluteTimestamp;
else _rtpClient.videoStartTS = absoluteTimestamp;
}
if ((packetsCount % 500) == 0)
{
//FINEST("Send %c RTCP: %u", isAudio ? 'A' : 'V', packetsCount);
_rtcpMessage.Buffers[0].Write(4,ssrc);
//NTP
var integerValue = (uint)(absoluteTimestamp / 1000.0);
double fractionValue = (absoluteTimestamp / 1000.0 - ((uint)(absoluteTimestamp / 1000.0))) * 4294967296.0;
var ntpVal = (ulong)(_startupTime.SecondsFrom1970() + integerValue + 2208988800UL) << 32;
ntpVal |= (uint)fractionValue;
_rtcpNTP.Buffer.Write(_rtcpNTP.Offset,ntpVal);
//RTP
var rtp = (ulong)((integerValue + fractionValue / 4294967296.0) * rate);
rtp &= 0xffffffff;
_rtcpRTP.Buffer.Write(_rtcpRTP.Offset, rtp);
//packet count
_rtcpSPC.Buffer.Write(_rtcpSPC.Offset, packetsCount);
_rtcpSOC.Buffer.Write(_rtcpSOC.Offset, bytesCount);
//octet count
// FINEST("\n%s", STR(IOBuffer::DumpBuffer(((uint8_t *) _rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_BASE),
// _rtcpMessage.MSGHDR_MSG_IOV[0].IOVEC_IOV_LEN)));
if (_rtpClient.isUdp)
{
var rtcpSocket = isAudio ? _audioRTCPSocket : _videoRTCPSocket;
var rtcpAddress = isAudio ? _rtpClient.audioRtcpAddress : _rtpClient.videoRtcpAddress;
if (rtcpSocket.SendTo(_rtcpMessage.TotalBuffer, SocketFlags.None, rtcpAddress) < 0)
{
FATAL("Unable to send message");
return false;
}
}
else
{
if (_rtspProtocol != null)
{
if (!_rtspProtocol.SendRaw(_rtcpMessage,ref _rtpClient, isAudio, false))
{
FATAL("Unable to send raw rtcp audio data");
return false;
}
}
}
}
if (_rtpClient.isUdp)
{
var dataFd = isAudio ? _audioDataSocket : _videoDataSocket;
var dataAddress = isAudio ? _rtpClient.audioDataAddress : _rtpClient.videoDataAddress;
if ( dataFd.SendTo(message.TotalBuffer, SocketFlags.None, dataAddress) < 0)
{
FATAL("Unable to send message");
return false;
}
}
else
{
if (_rtspProtocol != null)
{
if (!_rtspProtocol.SendRaw(message,ref _rtpClient,isAudio, true))
{
FATAL("Unable to send raw rtcp audio data");
return false;
}
}
}
packetsCount++;
if (isAudio) _rtpClient.audioPacketsCount = packetsCount;
else _rtpClient.videoPacketsCount = packetsCount;
bytesCount += (uint)messageLength;
if (isAudio) _rtpClient.audioBytesCount = bytesCount;
else _rtpClient.videoBytesCount = bytesCount;
return true;
}
}