Exmaples of size Payload Header size calculations: For length of first parition 54: S0 = 4, S1 = 0x32, S2 = 0. For length of first parition 1777: S0 = 1, S1 = 0xde, S2 = 0.
Пример #1
0
        public static RTPVP8Header GetVP8Header(byte[] rtpPayload)
        {
            RTPVP8Header vp8Header = new RTPVP8Header();
            int          payloadHeaderStartIndex = 1;

            // First byte of payload descriptor.
            vp8Header.ExtendedControlBitsPresent = ((rtpPayload[0] >> 7) & 0x01) == 1;
            vp8Header.StartOfVP8Partition        = ((rtpPayload[0] >> 4) & 0x01) == 1;
            vp8Header._length = 1;

            // Is second byte being used.
            if (vp8Header.ExtendedControlBitsPresent)
            {
                vp8Header.IsPictureIDPresent = ((rtpPayload[1] >> 7) & 0x01) == 1;
                vp8Header._length            = 2;
                payloadHeaderStartIndex      = 2;
            }

            // Is the picture ID being used.
            if (vp8Header.IsPictureIDPresent)
            {
                if (((rtpPayload[2] >> 7) & 0x01) == 1)
                {
                    // The Picure ID is using two bytes.
                    vp8Header._length       = 4;
                    payloadHeaderStartIndex = 4;
                    vp8Header.PictureID     = BitConverter.ToUInt16(rtpPayload, 2);
                }
                else
                {
                    // The picture ID is using one byte.
                    vp8Header.PictureID     = rtpPayload[2];
                    vp8Header._length       = 3;
                    payloadHeaderStartIndex = 3;
                }
            }

            vp8Header._payloadDescriptorLength = payloadHeaderStartIndex;

            // Payload header only on first packet in frame.
            if (vp8Header.StartOfVP8Partition)
            {
                byte s0 = (byte)((rtpPayload[payloadHeaderStartIndex] >> 5) & 0x07);
                vp8Header.ShowFrame  = (byte)((rtpPayload[payloadHeaderStartIndex] >> 4) & 0x01) == 1;
                vp8Header.IsKeyFrame = (rtpPayload[payloadHeaderStartIndex] & 0x01) == 0;
                byte s1 = rtpPayload[payloadHeaderStartIndex + 1];
                byte s2 = rtpPayload[payloadHeaderStartIndex + 2];
                vp8Header.FirstPartitionSize = s0 + (8 * s1) + (2048 * s2);

                vp8Header._length += 3;
            }

            return(vp8Header);
        }
Пример #2
0
        public static RTPVP8Header GetVP8Header(byte[] rtpPayload)
        {
            RTPVP8Header vp8Header = new RTPVP8Header();
            int payloadHeaderStartIndex = 1;

            // First byte of payload descriptor.
            vp8Header.ExtendedControlBitsPresent = ((rtpPayload[0] >> 7) & 0x01) == 1;
            vp8Header.StartOfVP8Partition = ((rtpPayload[0] >> 4) & 0x01) == 1;
            vp8Header._length = 1;

            // Is second byte being used.
            if(vp8Header.ExtendedControlBitsPresent)
            {
                vp8Header.IsPictureIDPresent = ((rtpPayload[1] >> 7) & 0x01) == 1;
                vp8Header._length = 2;
                payloadHeaderStartIndex = 2;
            }

            // Is the picture ID being used.
            if(vp8Header.IsPictureIDPresent)
            {
                if (((rtpPayload[2] >> 7) & 0x01) == 1)
                {
                    // The Picure ID is using two bytes.
                    vp8Header._length = 4;
                    payloadHeaderStartIndex = 4;
                    vp8Header.PictureID = BitConverter.ToUInt16(rtpPayload, 2);
                }
                else
                {
                    // The picture ID is using one byte.
                    vp8Header.PictureID = rtpPayload[2];
                    vp8Header._length = 3;
                    payloadHeaderStartIndex = 3;
                }
            }

            vp8Header._payloadDescriptorLength = payloadHeaderStartIndex;

            // Payload header only on first packet in frame.
            if (vp8Header.StartOfVP8Partition)
            {
                byte s0 = (byte)((rtpPayload[payloadHeaderStartIndex] >> 5) & 0x07);
                vp8Header.ShowFrame = (byte)((rtpPayload[payloadHeaderStartIndex] >> 4) & 0x01) == 1;
                vp8Header.IsKeyFrame = (rtpPayload[payloadHeaderStartIndex] & 0x01) == 0;
                byte s1 = rtpPayload[payloadHeaderStartIndex + 1];
                byte s2 = rtpPayload[payloadHeaderStartIndex + 2];
                vp8Header.FirstPartitionSize = s0 + (8 * s1) + (2048 * s2);

                vp8Header._length += 3;
            }

            return vp8Header;
        }
Пример #3
0
        public byte[] GetFramePayload()
        {
            List <byte> payload = new List <byte>();

            foreach (var rtpPacket in _packets.OrderBy(x => x.Header.SequenceNumber))
            {
                if (FrameType == FrameTypesEnum.VP8)
                {
                    var vp8Header = RTPVP8Header.GetVP8Header(rtpPacket.Payload);
                    payload.AddRange(rtpPacket.Payload.Skip(vp8Header.PayloadDescriptorLength));
                }
                else
                {
                    payload.AddRange(rtpPacket.Payload);
                }
            }

            return(payload.ToArray());
        }
Пример #4
0
        private static void SendRTPFromVP8FramesFile(string file)
        {
            try
            {
                StreamReader sr = new StreamReader(file);
                List<string> samples = new List<string>();
                while (!sr.EndOfStream)
                {
                    string sample = sr.ReadLine();
                    samples.Add(sample);

                    //Console.WriteLine(sample);

                    //string[] sampleFields = sample.Split(',');
                    //RTPVP8Header frameVP8Header = RTPVP8Header.GetVP8Header(Convert.FromBase64String(sampleFields[0]));
                    //byte[] rtpPaylaod = Convert.FromBase64String(sampleFields[1]);

                    //Console.WriteLine((frameVP8Header.IsKeyFrame) ? "K" : "." + " " + frameVP8Header.FirstPartitionSize + " " + rtpPaylaod.Length + ".");
                }
                sr.Close();
                logger.Debug(samples.Count + " encoded samples loaded.");

                //_newRTPReceiverSRTP = new SRTPManaged(Convert.FromBase64String(_sourceSRTPKey));
                //_newRTPReceiverSRTP = new SRTPManaged();
                int sampleIndex = 0;

                while (true)
                {
                    if (_webRTCClients.Count != 0)
                    {
                        var sampleItem = samples[sampleIndex];
                        string[] sampleFields = sampleItem.Split(',');

                        RTPVP8Header frameVP8Header = RTPVP8Header.GetVP8Header(Convert.FromBase64String(sampleFields[0]));
                        byte[] sample = Convert.FromBase64String(sampleFields[1]);

                        if (frameVP8Header.IsKeyFrame)
                        {
                            Console.WriteLine("Key frame.");
                        }

                        lock (_webRTCClients)
                        {
                            foreach (var client in _webRTCClients.Where(x => x.STUNExchangeComplete))
                            {
                                try
                                {
                                    if (client.LastTimestamp == 0)
                                    {
                                        client.LastTimestamp = RTSPSession.DateTimeToNptTimestamp32(DateTime.Now);
                                    }

                                    for (int index = 0; index * RTP_MAX_PAYLOAD < sample.Length; index++)
                                    {
                                        int offset = (index == 0) ? 0 : (index * RTP_MAX_PAYLOAD);
                                        int payloadLength = (offset + RTP_MAX_PAYLOAD < sample.Length) ? RTP_MAX_PAYLOAD : sample.Length - offset;

                                        RTPVP8Header packetVP8Header = new RTPVP8Header()
                                        {
                                            ExtendedControlBitsPresent = true,
                                            IsPictureIDPresent = true,
                                            ShowFrame = true,
                                        };

                                        if (index == 0)
                                        {
                                            packetVP8Header.StartOfVP8Partition = true;
                                            //packetVP8Header.FirstPartitionSize = frameVP8Header.FirstPartitionSize;
                                            packetVP8Header.IsKeyFrame = frameVP8Header.IsKeyFrame;
                                            packetVP8Header.PictureID = (frameVP8Header.IsKeyFrame) ? (byte)0x00 : frameVP8Header.PictureID;
                                        }

                                        byte[] vp8HeaderBytes = packetVP8Header.GetBytes();

                                        RTPPacket rtpPacket = new RTPPacket(packetVP8Header.Length + payloadLength + SRTP_AUTH_KEY_LENGTH);
                                        rtpPacket.Header.SyncSource = client.SSRC;
                                        rtpPacket.Header.SequenceNumber = client.SequenceNumber++;
                                        rtpPacket.Header.Timestamp = client.LastTimestamp;
                                        rtpPacket.Header.MarkerBit = ((offset + payloadLength) >= sample.Length) ? 1 : 0;
                                        rtpPacket.Header.PayloadType = 100;

                                        Buffer.BlockCopy(vp8HeaderBytes, 0, rtpPacket.Payload, 0, packetVP8Header.Length);
                                        Buffer.BlockCopy(sample, offset, rtpPacket.Payload, packetVP8Header.Length, payloadLength);

                                        var rtpBuffer = rtpPacket.GetBytes();

                                        _webRTCReceiverClient.Send(rtpBuffer, rtpBuffer.Length - SRTP_AUTH_KEY_LENGTH, _wiresharpEP);

                                        int rtperr = client.SrtpContext.ProtectRTP(rtpBuffer, rtpBuffer.Length - SRTP_AUTH_KEY_LENGTH);
                                        if (rtperr != 0)
                                        {
                                            logger.Debug("New RTP packet protect result " + rtperr + ".");
                                        }

                                        logger.Debug("Sending RTP " + sample.Length + " bytes to " + client.SocketAddress + ", timestamp " + client.LastTimestamp + ", marker " + rtpPacket.Header.MarkerBit + ".");

                                        _webRTCReceiverClient.Send(rtpBuffer, rtpBuffer.Length, client.SocketAddress);
                                    }

                                    client.LastTimestamp += TIMESTAMP_SPACING;
                                }
                                catch (Exception sendExcp)
                                {
                                    logger.Error("SendRTPFromVP8FramesFile exception sending to " + client.SocketAddress + ". " + sendExcp.Message);
                                }
                            }
                        }

                        sampleIndex++;
                        if (sampleIndex >= samples.Count - 1)
                        {
                            sampleIndex = 0;
                        }

                        Thread.Sleep(30);
                    }
                }
            }
            catch (Exception excp)
            {
                Console.WriteLine("Exception SendRTPFromVP8FramesFile. " + excp);
            }
        }