public void SendJpegFrame(byte[] jpegBytes, int jpegQuality, int jpegWidth, int jpegHeight, int framesPerSecond)
{
try
{
if (_isClosed)
{
logger.Warn("SendJpegFrame cannot be called on a closed session.");
}
else if (_rtpSocketError != SocketError.Success)
{
logger.Warn("SendJpegFrame was called for an RTP socket in an error state of " + _rtpSocketError + ".");
}
else
{
_timestamp = (_timestamp == 0) ? DateTimeToNptTimestamp32(DateTime.Now) : (_timestamp + (uint)(RFC_2435_FREQUENCY_BASELINE / framesPerSecond)) % UInt32.MaxValue;
//System.Diagnostics.Debug.WriteLine("Sending " + jpegBytes.Length + " encoded bytes to client, timestamp " + _timestamp + ", starting sequence number " + _sequenceNumber + ", image dimensions " + jpegWidth + " x " + jpegHeight + ".");
for (int index = 0; index * RTP_MAX_PAYLOAD < jpegBytes.Length; index++)
{
uint offset = Convert.ToUInt32(index * RTP_MAX_PAYLOAD);
int payloadLength = ((index + 1) * RTP_MAX_PAYLOAD < jpegBytes.Length) ? RTP_MAX_PAYLOAD : jpegBytes.Length - index * RTP_MAX_PAYLOAD;
byte[] jpegHeader = CreateLowQualityRtpJpegHeader(offset, jpegQuality, jpegWidth, jpegHeight);
List<byte> packetPayload = new List<byte>();
packetPayload.AddRange(jpegHeader);
packetPayload.AddRange(jpegBytes.Skip(index * RTP_MAX_PAYLOAD).Take(payloadLength));
RTPPacket rtpPacket = new RTPPacket(packetPayload.Count);
rtpPacket.Header.SyncSource = _syncSource;
rtpPacket.Header.SequenceNumber = _sequenceNumber++;
rtpPacket.Header.Timestamp = _timestamp;
rtpPacket.Header.MarkerBit = ((index + 1) * RTP_MAX_PAYLOAD < jpegBytes.Length) ? 0 : 1;
rtpPacket.Header.PayloadType = (int)SDPMediaFormatsEnum.JPEG;
rtpPacket.Payload = packetPayload.ToArray();
byte[] rtpBytes = rtpPacket.GetBytes();
//System.Diagnostics.Debug.WriteLine(" offset " + offset + ", payload length " + payloadLength + ", sequence number " + rtpPacket.Header.SequenceNumber + ", marker " + rtpPacket.Header.MarkerBit + ".");
//Stopwatch sw = new Stopwatch();
//sw.Start();
_rtpSocket.SendTo(rtpBytes, _remoteEndPoint);
//sw.Stop();
//if (sw.ElapsedMilliseconds > 15)
//{
// logger.Warn(" SendJpegFrame offset " + offset + ", payload length " + payloadLength + ", sequence number " + rtpPacket.Header.SequenceNumber + ", marker " + rtpPacket.Header.MarkerBit + ", took " + sw.ElapsedMilliseconds + "ms.");
//}
}
//sw.Stop();
//System.Diagnostics.Debug.WriteLine("SendJpegFrame took " + sw.ElapsedMilliseconds + ".");
}
}
catch (Exception excp)
{
if (!_isClosed)
{
logger.Warn("Exception RTPChannel.SendJpegFrame attempting to send to the RTP socket at " + _remoteEndPoint + ". " + excp);
//_rtpSocketError = SocketError.SocketError;
OnRTPSocketDisconnected?.Invoke();
}
}
}