/// <summary> /// Метод нужно допилить. Он работает, но гарантии, что он будет работать /// на других камерах, нет /// </summary> /// <param name="cname"></param> /// <returns></returns> private byte[] CreateRecieveReportBytes(RtcpRecieverReportPacket packet) { int packetSize = 32 + (( // receiver report 1 + // source description: version + padding + source count 1 + // source description: packet type 2 + // source description: length 4 + // source description: chunk1: ssrc 1 + // source description: chunk1: type 1 + // source description: chunk1: length CNAME.Length) / 4 + 1) * 4; byte[] data = new byte[packetSize]; data[0] = 0x81; data[1] = 0xC9; data[2] = 0x00; data[3] = 0x07; BigEndian.WriteUInt32(data, 4, packet.SenderSSRC); BigEndian.WriteUInt32(data, 8, packet.RecieverSSRC); data[12] = packet.FractionLost; data[13] = 0; data[14] = 0; data[15] = 0; BigEndian.WriteUInt32(data, 16, packet.ReceivedRtpPackets); if (receivedRtpPackets > ushort.MaxValue) { // ... } BigEndian.WriteUInt32(data, 20, (uint)(packet.Jitter * 1000)); BigEndian.WriteUInt32(data, 24, packet.LastSRTimestamp); BigEndian.WriteUInt32(data, 28, packet.DelaySinceLastSRTimestamp); data[32] = 0x81; data[33] = 0xCA; data[34] = 0x00; data[35] = (byte)((packetSize - 32) / 4 - 1); BigEndian.WriteUInt32(data, 36, packet.SenderSSRC); data[40] = 0x01; data[41] = (byte)CNAME.Length; Encoding.UTF8.GetBytes(CNAME, 0, CNAME.Length, data, 42); //Logger.Write(String.Format("recieverSSRC={0}, senderSSRC={1}, jitter={2}, LSR={3}, DSLR={4}", // packet.RecieverSSRC, packet.SenderSSRC, packet.Jitter, packet.LastSRTimestamp, packet.DelaySinceLastSRTimestamp), EnumLoggerType.DebugLog); recieverReportCount++; return(data); }
/// <summary> /// Обработчик события udpClient.ReceivedUdpPacket /// </summary> /// <param name="remoteEndPoint">Адрес хоста, с которого пришли данные</param> /// <param name="data">Указатель на пришедшие данные в неуправляемой памяти</param> /// <param name="count">Количество </param> private void udpClient_ReceivedUdpPacket(IPEndPoint remoteEndPoint, IntPtr data, int count) { //this.remoteEndPoint = remoteEndPoint; // обрабатывается rtcp пакет от Sender-а (SR, SD) rtcpHandler.CreateRtcpPacket(data, count); // ответ Reciever-а (RR) // Не совсем правильно т.к. отчеты ресивера посылаются как ответ на отчета сендера, // В спецификации отправка ресивером RTCP пакетов должна быть не зависима от сендера и происходить максимально часто, // ограничение полоса пропускания RTCP не должна занимать более 5% трафика индивидуального отправителя RtcpRecieverReportPacket packet = CreateRtcpRecieverReportPacket(); byte[] rtcp = CreateRecieveReportBytes(packet); udpClient.Send(remoteEndPoint, rtcp); }
/// <summary> /// Метод нужно допилить. Он работает, но гарантии, что он будет работать /// на других камерах, нет /// </summary> /// <param name="cname"></param> /// <returns></returns> private byte[] CreateRecieveReportBytes(RtcpRecieverReportPacket packet) { int packetSize = 32 + ((// receiver report 1 + // source description: version + padding + source count 1 + // source description: packet type 2 + // source description: length 4 + // source description: chunk1: ssrc 1 + // source description: chunk1: type 1 + // source description: chunk1: length CNAME.Length) / 4 + 1) * 4; byte[] data = new byte[packetSize]; data[0] = 0x81; data[1] = 0xC9; data[2] = 0x00; data[3] = 0x07; BigEndian.WriteUInt32(data, 4, packet.SenderSSRC); BigEndian.WriteUInt32(data, 8, packet.RecieverSSRC); data[12] = packet.FractionLost; data[13] = 0; data[14] = 0; data[15] = 0; BigEndian.WriteUInt32(data, 16, packet.ReceivedRtpPackets); if (receivedRtpPackets > ushort.MaxValue) { // ... } BigEndian.WriteUInt32(data, 20, (uint)(packet.Jitter*1000)); BigEndian.WriteUInt32(data, 24, packet.LastSRTimestamp); BigEndian.WriteUInt32(data, 28, packet.DelaySinceLastSRTimestamp); data[32] = 0x81; data[33] = 0xCA; data[34] = 0x00; data[35] = (byte)((packetSize - 32) / 4 - 1); BigEndian.WriteUInt32(data, 36, packet.SenderSSRC); data[40] = 0x01; data[41] = (byte)CNAME.Length; Encoding.UTF8.GetBytes(CNAME, 0, CNAME.Length, data, 42); //Logger.Write(String.Format("recieverSSRC={0}, senderSSRC={1}, jitter={2}, LSR={3}, DSLR={4}", // packet.RecieverSSRC, packet.SenderSSRC, packet.Jitter, packet.LastSRTimestamp, packet.DelaySinceLastSRTimestamp), EnumLoggerType.DebugLog); recieverReportCount++; return data; }