Exemple #1
0
        /// <summary>
        /// Обработчик события rtcpHandler.CreatedRtcpSenderReport
        /// </summary>
        /// <param name="packet">RTCP пакет отправителя данных (камеры)</param>
        private void rtcpHandler_CreatedRtcpSenderReport(RtcpSenderReportPacket packet)
        {
            lock (locker)
            {
                if (senderSSRC == 0)
                {
                    senderSSRC = packet.SenderSSRC;
                }
                if (senderReportCount == 0)
                {
                    uint     timestamp = packet.RTPTimestamp;
                    uint     msec      = (uint)(Math.Round((double)packet.TimestampLSW / (double)uint.MaxValue, 3) * 1000);
                    DateTime time      = new DateTime(1900, 1, 1).AddSeconds(packet.TimestampMSW).AddMilliseconds(msec);

                    TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time);
                    time = time + offset;

                    if (initTimestamp != 0)
                    {
                        double msecSinceStart = (double)(timestamp - initTimestamp) / sampleFrequency * 1000;
                        time -= TimeSpan.FromMilliseconds(msecSinceStart);
                        if (time != startRtpSessionTime)
                        {
                            startRtpSessionTime = time;
                            OnSessionTimeCorrecting(initTimestamp, startRtpSessionTime);
                            //Logger.Write(String.Format("StartSessionTime={0}", startRtpSessionTime.ToString("HH:mm:ss.fff")), EnumLoggerType.DebugLog);
                        }
                    }
                }

                rtpTimestamp    = packet.RTPTimestamp;
                ntpTimestampLSW = packet.TimestampLSW;
                ntpTimestampMSW = packet.TimestampMSW;

                senderReportTime = DateTime.Now;

                senderReportCount++;
            }
        }
Exemple #2
0
        /// <summary>
        /// Обработчик события rtcpHandler.CreatedRtcpSenderReport
        /// </summary>
        /// <param name="packet">RTCP пакет отправителя данных (камеры)</param>
        private void rtcpHandler_CreatedRtcpSenderReport(RtcpSenderReportPacket packet)
        {
            lock (locker)
            {
                if (senderSSRC == 0)
                {
                    senderSSRC = packet.SenderSSRC;
                }
                if (senderReportCount == 0)
                {
                    uint timestamp = packet.RTPTimestamp;
                    uint msec = (uint)(Math.Round((double)packet.TimestampLSW / (double)uint.MaxValue, 3) * 1000);
                    DateTime time = new DateTime(1900, 1, 1).AddSeconds(packet.TimestampMSW).AddMilliseconds(msec);

                    TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time);
                    time = time+offset;

                    if (initTimestamp != 0)
                    {
                        double msecSinceStart = (double)(timestamp - initTimestamp) / sampleFrequency * 1000;
                        time-= TimeSpan.FromMilliseconds(msecSinceStart);
                        if (time != startRtpSessionTime)
                        {
                            startRtpSessionTime = time;
                            OnSessionTimeCorrecting(initTimestamp, startRtpSessionTime);
                            //Logger.Write(String.Format("StartSessionTime={0}", startRtpSessionTime.ToString("HH:mm:ss.fff")), EnumLoggerType.DebugLog);
                        }

                    }
                }

                rtpTimestamp = packet.RTPTimestamp;
                ntpTimestampLSW = packet.TimestampLSW;
                ntpTimestampMSW = packet.TimestampMSW;

                senderReportTime = DateTime.Now;

                senderReportCount++;

            }
        }
Exemple #3
0
        /// <summary>
        /// Обрабатывает пришедшие данные и вызывает всякие события
        /// </summary>
        /// <param name="data">Указатель область памяти,
        /// где располагаются данные RTCP пакета</param>
        /// <param name="count">Размер области памяти в байтах</param>
        public void CreateRtcpPacket(IntPtr data, int count)
        {
            Marshal.Copy(data, buffer, 0, count);
            // сейчас в массиве buffer содержится один или более RTCP пакетов
            // их нужно обработать в цикле
            // сначала обрабатывается первый пакет, который находится в начале
            // буфера, потом данные в буфере сдвигаются к началу, и т. д.,
            // пока не будут обработаны все пакеты
            while (count > 0)
            {
                int version = buffer[0] >> 6;
                if (version != 2)
                {
                    return;
                }
                bool           padding    = (buffer[0] & _00100000) == _00100000;
                RtcpPacketType packetType = (RtcpPacketType)buffer[1];
                int            length     = (BigEndian.ReadUInt16(buffer, 2) + 1) * 4;

                switch (packetType)
                {
                case RtcpPacketType.SenderReport:
                    RtcpSenderReportPacket packet = new RtcpSenderReportPacket();
                    packet.Version = (byte)(buffer[0] >> 6);
                    packet.Padding = ((buffer[0] & _00100000) == _00100000);
                    packet.ReceptionReportCount = (byte)(buffer[0] & _00011111);
                    packet.PayloadType          = RtcpPacketType.SenderReport;
                    packet.SenderSSRC           = BigEndian.ReadUInt32(buffer, 4);
                    packet.TimestampMSW         = BigEndian.ReadUInt32(buffer, 8);
                    packet.TimestampLSW         = BigEndian.ReadUInt32(buffer, 12);
                    packet.RTPTimestamp         = BigEndian.ReadUInt32(buffer, 16);
                    packet.SenderPacketCount    = BigEndian.ReadUInt32(buffer, 20);
                    packet.SenderOctetCount     = BigEndian.ReadUInt32(buffer, 24);
                    CreatedRtcpSenderReport(packet);
                    break;

                case RtcpPacketType.ReceiverReport:
                    // ничего не делать, т. к. нам не будут приходить пакеты такого типа
                    break;

                case RtcpPacketType.SourceDescription:
                    // прочитать количество источников
                    int sourceCount = buffer[0] & _00011111;
                    int pos         = 4;

                    RtcpSourceDescription[] result = new RtcpSourceDescription[sourceCount];

                    for (int i = 0; i < sourceCount; i++)
                    {
                        result[i]      = new RtcpSourceDescription();
                        result[i].SSRC = BigEndian.ReadUInt32(buffer, pos);
                        pos           += 4;
                        List <RtcpSourceDescriptionItem> items = new List <RtcpSourceDescriptionItem>();
                        while (buffer[pos] != 0)
                        {
                            RtcpSourceDescriptionType type = (RtcpSourceDescriptionType)buffer[pos];
                            pos += 1;
                            int itemLength = buffer[pos];
                            pos += 1;
                            string itemText = Encoding.UTF8.GetString(buffer, pos, itemLength);
                            pos += itemLength;
                            items.Add(new RtcpSourceDescriptionItem()
                            {
                                Type = type,
                                Text = itemText
                            });
                        }
                        result[i].Items = items.ToArray();

                        // выравниваем по 4 байтам
                        while (pos % 4 != 0)
                        {
                            pos++;
                        }
                    }

                    CreatedRtcpSourceDescription(result);
                    break;

                case RtcpPacketType.Goodbye:
                    // ничего не делать
                    break;

                case RtcpPacketType.ApplicationDefined:
                    // ничего не делать
                    break;
                }
                // смещаем оставшиеся данные в буфере к началу
                for (int i = length; i < count; i++)
                {
                    buffer[i - length] = buffer[i];
                    buffer[i]          = 0;
                }
                count -= length;
            }
        }
        /// <summary>
        /// Обрабатывает пришедшие данные и вызывает всякие события
        /// </summary>
        /// <param name="data">Указатель область памяти,
        /// где располагаются данные RTCP пакета</param>
        /// <param name="count">Размер области памяти в байтах</param>
        public void CreateRtcpPacket(IntPtr data, int count)
        {
            Marshal.Copy(data, buffer, 0, count);
            // сейчас в массиве buffer содержится один или более RTCP пакетов
            // их нужно обработать в цикле
            // сначала обрабатывается первый пакет, который находится в начале
            // буфера, потом данные в буфере сдвигаются к началу, и т. д.,
            // пока не будут обработаны все пакеты
            while (count > 0)
            {
                int version = buffer[0] >> 6;
                if (version != 2)
                    return;
                bool padding = (buffer[0] & _00100000) == _00100000;
                RtcpPacketType packetType = (RtcpPacketType)buffer[1];
                int length = (BigEndian.ReadUInt16(buffer, 2) + 1) * 4;

                switch (packetType)
                {
                    case RtcpPacketType.SenderReport:
                        RtcpSenderReportPacket packet = new RtcpSenderReportPacket();
                        packet.Version = (byte)(buffer[0] >> 6);
                        packet.Padding = ((buffer[0] & _00100000) == _00100000);
                        packet.ReceptionReportCount = (byte)(buffer[0] & _00011111);
                        packet.PayloadType = RtcpPacketType.SenderReport;
                        packet.SenderSSRC = BigEndian.ReadUInt32(buffer, 4);
                        packet.TimestampMSW = BigEndian.ReadUInt32(buffer, 8);
                        packet.TimestampLSW = BigEndian.ReadUInt32(buffer, 12);
                        packet.RTPTimestamp = BigEndian.ReadUInt32(buffer, 16);
                        packet.SenderPacketCount = BigEndian.ReadUInt32(buffer, 20);
                        packet.SenderOctetCount = BigEndian.ReadUInt32(buffer, 24);
                        CreatedRtcpSenderReport(packet);
                        break;
                    case RtcpPacketType.ReceiverReport:
                        // ничего не делать, т. к. нам не будут приходить пакеты такого типа
                        break;
                    case RtcpPacketType.SourceDescription:
                        // прочитать количество источников
                        int sourceCount = buffer[0] & _00011111;
                        int pos = 4;

                        RtcpSourceDescription[] result = new RtcpSourceDescription[sourceCount];

                        for (int i = 0; i < sourceCount; i++)
                        {
                            result[i] = new RtcpSourceDescription();
                            result[i].SSRC = BigEndian.ReadUInt32(buffer, pos);
                            pos += 4;
                            List<RtcpSourceDescriptionItem> items = new List<RtcpSourceDescriptionItem>();
                            while (buffer[pos] != 0)
                            {
                                RtcpSourceDescriptionType type = (RtcpSourceDescriptionType)buffer[pos];
                                pos += 1;
                                int itemLength = buffer[pos];
                                pos += 1;
                                string itemText = Encoding.UTF8.GetString(buffer, pos, itemLength);
                                pos += itemLength;
                                items.Add(new RtcpSourceDescriptionItem()
                                {
                                    Type = type,
                                    Text = itemText
                                });
                            }
                            result[i].Items = items.ToArray();

                            // выравниваем по 4 байтам
                            while (pos % 4 != 0)
                                pos++;
                        }

                        CreatedRtcpSourceDescription(result);
                        break;
                    case RtcpPacketType.Goodbye:
                        // ничего не делать
                        break;
                    case RtcpPacketType.ApplicationDefined:
                        // ничего не делать
                        break;
                }
                // смещаем оставшиеся данные в буфере к началу
                for (int i = length; i < count; i++)
                {
                    buffer[i - length] = buffer[i];
                    buffer[i] = 0;
                }
                count -= length;
            }
        }