public byte[] GetBytes() { // RTP Packet Header // 0 - Version, P, X, CC, M, PT and Sequence Number //32 - Timestamp. //64 - SSRC //96 - CSRCs (optional) //nn - Extension ID and Length //nn - Extension header int padding = Padding ? 1 : 0; int extension = Extension ? 1 : 0; int marker = Marker ? 1 : 0; packetBytes[0] = (byte)((Version << 6) | (padding << 5) | (extension << 4) | CSRCCount); packetBytes[1] = (byte)(((marker & 0x01) << 7) | (PayloadType & 0x7F)); BigEndian.WriteUInt16(packetBytes, 2, Sequence); BigEndian.WriteUInt32(packetBytes, 4, Timestamp); BigEndian.WriteUInt32(packetBytes, 8, SSRC); return(packetBytes); }
private void SendPackets(Socket _socket) { if (!running) { return; } int bytesSend = 0; while (packetQueue.Count > 0) { if (!running) { break; } RtpPacket pkt = null; lock (locker) { pkt = packetQueue.Dequeue(); } if (pkt != null) { try { // RFC 2326 10.12 Embedded (Interleaved) Binary Data /* * S->C: $\000{2 byte length}{"length" bytes data, w/RTP header} * S->C: $\000{2 byte length}{"length" bytes data, w/RTP header} * S->C: $\001{2 byte length}{"length" bytes RTCP packet} */ const byte magicSymbol = (byte)'$'; byte channelId = 0x42; var data = pkt.GetBytes(); ushort dataLength = (ushort)data.Length; int frameSize = data.Length + 4; // data + header byte[] frameBytes = new byte[frameSize]; int offset = 0; frameBytes[offset] = magicSymbol; offset++; frameBytes[offset] = channelId; offset++; BigEndian.WriteUInt16(frameBytes, offset, dataLength); offset += 2; Array.Copy(data, 0, frameBytes, offset, data.Length); offset += data.Length; _socket?.Send(frameBytes, 0, frameBytes.Length, SocketFlags.None); bytesSend += frameBytes.Length; // Statistic.RtpStats.Update(MediaTimer.GetRelativeTime(), rtp.Length); } catch (ObjectDisposedException) { } } } }