예제 #1
0
        private static byte[] PacketizeSingleNAL(Span <byte> raw_nal, UInt32 rtp_timestamp)
        {
            // Put the whole NAL into one RTP packet.
            // Note some receivers will have maximum buffers and be unable to handle large RTP packets.
            // Also with RTP over RTSP there is a limit of 65535 bytes for the RTP packet.

            byte[] rtp_packet = new byte[RTPPacketUtil.HeaderLength + raw_nal.Length];             // 12 is header size when there are no CSRCs or extensions
            // Create an single RTP fragment
            bool rtp_marker = (raw_nal[0] & 0x1F) <= 5;

            RTPPacketUtil.WriteHeader(rtp_packet, rtp_version, rtp_padding, rtp_extension, rtp_csrc_count, rtp_marker, rtp_payload_type);

            UInt32 empty_sequence_id = 0;

            RTPPacketUtil.WriteSequenceNumber(rtp_packet, empty_sequence_id);

            RTPPacketUtil.WriteTS(rtp_packet, rtp_timestamp);

            UInt32 empty_ssrc = 0;

            RTPPacketUtil.WriteSSRC(rtp_packet, empty_ssrc);

            // Now append the raw NAL
            raw_nal.CopyTo(new Span <byte>(rtp_packet, 12, raw_nal.Length));

            return(rtp_packet);
        }
예제 #2
0
        private static void PacketizeNAL_FUA(ref List <byte[]> rtp_packets, Span <byte> raw_nal, UInt32 rtp_timestamp)
        {
            int start_bit = 1;
            int end_bit   = 0;

            // consume first byte of the raw_nal. It is used in the FU header
            byte first_byte = raw_nal[0];

            raw_nal = raw_nal.Slice(1);

            while (raw_nal.Length > 0)
            {
                int payload_size = Math.Min(RTPPacketUtil.MaxPayloadSize - 2, raw_nal.Length);

                if (raw_nal.Length - payload_size == 0)
                {
                    end_bit = 1;
                }
                //for FU-A the marker is set when this is the last RTP packet
                bool rtp_marker = end_bit == 1;

                byte[] rtp_packet = new byte[RTPPacketUtil.HeaderLength + 2 + payload_size];                 // 2 bytes for FU-A header.

                RTPPacketUtil.WriteHeader(rtp_packet, rtp_version, rtp_padding, rtp_extension, rtp_csrc_count, rtp_marker, rtp_payload_type);

                UInt32 empty_sequence_id = 0;
                RTPPacketUtil.WriteSequenceNumber(rtp_packet, empty_sequence_id);

                RTPPacketUtil.WriteTS(rtp_packet, rtp_timestamp);

                UInt32 empty_ssrc = 0;
                RTPPacketUtil.WriteSSRC(rtp_packet, empty_ssrc);

                // Now append the Fragmentation Header (with Start and End marker) and part of the raw_nal
                byte f_bit = 0;
                byte nri   = (byte)((first_byte >> 5) & 0x03); // Part of the 1st byte of the Raw NAL (NAL Reference ID)
                byte type  = 28;                               // FU-A Fragmentation

                rtp_packet[12] = (byte)((f_bit << 7) + (nri << 5) + type);
                rtp_packet[13] = (byte)((start_bit << 7) + (end_bit << 6) + (0 << 5) + (first_byte & 0x1F));

                raw_nal.Slice(0, payload_size).CopyTo(new Span <byte>(rtp_packet, 14, payload_size));

                raw_nal = raw_nal.Slice(payload_size);

                rtp_packets.Add(rtp_packet);

                start_bit = 0;
            }
        }
예제 #3
0
        //TODO: reimplement these using Memory and Span<byte>

        public static List <byte[]> PacketizeSamples(Memory <byte> samples, ulong tsMs)
        {
            List <byte[]> rtp_packets = new List <byte[]>();

            Span <byte> smp    = samples.Span;
            double      diffTs = 0;

            while (smp.Length > 0)
            {
                int dataLen = smp.Length > RTPPacketUtil.MaxPayloadSize ? RTPPacketUtil.MaxPayloadSize : smp.Length;

                byte[]      packet     = new byte[dataLen + RTPPacketUtil.HeaderLength];
                Span <byte> packetData = new Span <byte>(packet, RTPPacketUtil.HeaderLength, dataLen);

                for (int i = 0; i < dataLen; i += 2)
                {
                    packetData[i]     = smp[i + 1];
                    packetData[i + 1] = smp[i];
                }

                RTPPacketUtil.WriteHeader(packet, rtp_version, rtp_padding, rtp_extension, rtp_csrc_count, false, rtp_payload_type);

                UInt32 empty_sequence_id = 0;
                RTPPacketUtil.WriteSequenceNumber(packet, empty_sequence_id);

                RTPPacketUtil.WriteTS(packet, (UInt32)((tsMs + diffTs) * 48));

                UInt32 empty_ssrc = 0;
                RTPPacketUtil.WriteSSRC(packet, empty_ssrc);

                rtp_packets.Add(packet);

                smp     = smp.Slice(dataLen);
                diffTs += AudiolenRtpPackeMs;
            }

            return(rtp_packets);
        }