Esempio n. 1
0
        private List <EsInfo> ReadEsInfoElements(short sectionLength, int startOfNextField)
        {
            var streams = new List <EsInfo>();

            while (startOfNextField < sectionLength)
            {
                var es = new EsInfo
                {
                    StreamType    = Data[startOfNextField],
                    ElementaryPid = (short)(((Data[startOfNextField + 1] & 0x1f) << 8) + Data[startOfNextField + 2]),
                    EsInfoLength  = (ushort)(((Data[startOfNextField + 3] & 0x3) << 8) + Data[startOfNextField + 4])
                };

                es.SourceData = new byte[5 + es.EsInfoLength];
                Buffer.BlockCopy(Data, startOfNextField, es.SourceData, 0, es.SourceData.Length);

                var descriptors = new List <Descriptor>();

                startOfNextField = startOfNextField + 5;
                var endOfDescriptors = startOfNextField + es.EsInfoLength;
                while (startOfNextField < endOfDescriptors)
                {
                    var des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                    descriptors.Add(des);
                    startOfNextField += (des.DescriptorLength + 2);
                }

                es.Descriptors = descriptors;
                streams.Add(es);
            }

            return(streams);
        }
Esempio n. 2
0
        public void LinkageDescriptorTest(byte[] hexBytes)
        {
            var descriptor = DescriptorFactory.DescriptorFromData(hexBytes, 0) as LinkageDescriptor;

            Assert.IsNotNull(descriptor);
            Assert.AreEqual(descriptor.TransportStreamId, 0x12);
            Assert.AreEqual(descriptor.OriginalNetworkId, 0x600);
            Assert.AreEqual(descriptor.ServiceId, 0x4544);
            Assert.AreEqual(descriptor.LinkageType, 0x5);
        }
        protected int GetDescriptors(int descriptorsLength, int startOfNextField)
        {
            var descriptors = new List <Descriptor>();
            var startPos    = startOfNextField;

            while (startOfNextField < startPos + descriptorsLength)
            {
                var des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                descriptors.Add(des);
                startOfNextField += (byte)(des.DescriptorLength + 2);
            }

            InProgressTable.Descriptors = descriptors;

            return(startOfNextField);
        }
        public void AddPacket(TsPacket packet)
        {
            CheckPid(packet.Pid);

            if (packet.PayloadUnitStartIndicator)
            {
                InProgressTable = new NetworkInformationTable {
                    Pid = packet.Pid, PointerField = packet.Payload[0]
                };

                if (InProgressTable != null)
                {
                    if (InProgressTable.PointerField > packet.Payload.Length)
                    {
                        Debug.Assert(true, "Network Information Table has packet pointer outside the packet.");
                    }
                }

                var pos = 1 + InProgressTable.PointerField;

                InProgressTable.VersionNumber = (byte)(packet.Payload[pos + 5] & 0x3E);

                InProgressTable.TableId = packet.Payload[pos];

                //TODO: Refactor with enum for well-known table IDs, and add option below as filter
                if (InProgressTable.TableId != 0x40)
                {
                    InProgressTable = null;
                    return;
                }

                if ((NetworkInformationTable == null) || (NetworkInformationTable.VersionNumber != InProgressTable.VersionNumber))
                {
                    //if the version number of any section jumps, we need to refresh
                    _sectionsCompleted      = new HashSet <int>();
                    NetworkInformationItems = new List <NetworkInformationItem>();
                }

                InProgressTable.SectionLength =
                    (short)(((packet.Payload[pos + 1] & 0x3) << 8) + packet.Payload[pos + 2]);

                InProgressTable.TransportStreamId    = (ushort)((packet.Payload[pos + 3] << 8) + packet.Payload[pos + 4]);
                InProgressTable.CurrentNextIndicator = (packet.Payload[pos + 5] & 0x1) != 0;
                InProgressTable.SectionNumber        = packet.Payload[pos + 6];
                InProgressTable.LastSectionNumber    = packet.Payload[pos + 7];
            }

            if (InProgressTable == null)
            {
                return;
            }

            if (_sectionsCompleted.Contains(InProgressTable.SectionNumber))
            {
                InProgressTable = null;
                return;
            }

            AddData(packet);

            if (!HasAllBytes())
            {
                return;
            }

            InProgressTable.NetworkDescriptorsLength = (ushort)(((Data[InProgressTable.PointerField + 9] & 0x3) << 8) + Data[InProgressTable.PointerField + 10]);

            var startOfNextField = (ushort)(InProgressTable.PointerField + 11);

            List <Descriptor> descriptors = new List <Descriptor>();
            var endOfDescriptors          = InProgressTable.PointerField + 11 + InProgressTable.NetworkDescriptorsLength;

            if (endOfDescriptors > Data.Length)
            {
                throw new InvalidDataException("Descriptor data in Network Information is marked beyond available data");
            }

            while (startOfNextField < endOfDescriptors)
            {
                Descriptor des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                descriptors.Add(des);
                startOfNextField += (byte)(des.DescriptorLength + 2);
            }
            InProgressTable.Descriptors = descriptors;

            InProgressTable.TransportStreamLoopLength = (ushort)(((Data[startOfNextField] & 0x3) << 8) + Data[startOfNextField + 1]);

            startOfNextField += 2;
            var transportStreamLoopEnd = (byte)(startOfNextField + InProgressTable.TransportStreamLoopLength);

            var items = new List <NetworkInformationItem>();

            while (startOfNextField < transportStreamLoopEnd)
            {
                var item = new NetworkInformationItem
                {
                    TransportStreamId          = (ushort)((Data[startOfNextField] << 8) + Data[startOfNextField + 1]),
                    OriginalNetworkId          = (ushort)((Data[startOfNextField + 2] << 8) + Data[startOfNextField + 3]),
                    ReservedFutureUse          = (byte)((Data[startOfNextField + 4] >> 4) & 0x0F),
                    TransportDescriptorsLength = (ushort)(((Data[startOfNextField + 4] & 0x3) << 8) + Data[startOfNextField + 5])
                };

                descriptors = new List <Descriptor>();

                startOfNextField = (byte)(startOfNextField + 6);
                endOfDescriptors = (byte)(startOfNextField + item.TransportDescriptorsLength);

                if (endOfDescriptors > Data.Length)
                {
                    throw new InvalidDataException("Descriptor data in Network Information Item is marked beyond available data");
                }

                while (startOfNextField < endOfDescriptors)
                {
                    Descriptor des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                    descriptors.Add(des);
                    startOfNextField += (byte)(des.DescriptorLength + 2);
                }
                item.Descriptors = descriptors;
                items.Add(item);
            }

            InProgressTable.Items = items;

            NetworkInformationItems.AddRange(items);

            NetworkInformationTable = InProgressTable;
            _sectionsCompleted.Add(InProgressTable.SectionNumber);

            OnTableChangeDetected();
        }
Esempio n. 5
0
        public void AddPacket(TsPacket packet)
        {
            CheckPid(packet.Pid);

            if (packet.PayloadUnitStartIndicator)
            {
                InProgressTable = new EventInformationTable {
                    Pid = packet.Pid, PointerField = packet.Payload[0]
                };

                if (InProgressTable.PointerField > packet.Payload.Length)
                {
                    Debug.Assert(true, "Event Information Table has packet pointer outside the packet.");
                }

                var pos = 1 + InProgressTable.PointerField;

                InProgressTable.VersionNumber = (byte)(packet.Payload[pos + 5] & 0x3E);

                InProgressTable.TableId = packet.Payload[pos];

                //TODO: Refactor with enum for well-known table IDs, and add option below as filter
                if (InProgressTable.TableId != 0x4e)
                {
                    InProgressTable = null;
                    return;
                }

                if (EventInformationTable?.VersionNumber != InProgressTable.VersionNumber)
                {
                    //if the version number of any section jumps, we need to refresh
                    _sectionsCompleted    = new HashSet <int>();
                    EventInformationItems = new List <EventInformationItem>();
                }

                InProgressTable.SectionLength =
                    (short)(((packet.Payload[pos + 1] & 0x3) << 8) + packet.Payload[pos + 2]);

                InProgressTable.SericeId             = (ushort)((packet.Payload[pos + 3] << 8) + packet.Payload[pos + 4]);
                InProgressTable.CurrentNextIndicator = (packet.Payload[pos + 5] & 0x1) != 0;
                InProgressTable.SectionNumber        = packet.Payload[pos + 6];
                InProgressTable.LastSectionNumber    = packet.Payload[pos + 7];
                InProgressTable.TransportStreamId    = (ushort)((packet.Payload[pos + 8] << 8) + packet.Payload[pos + 9]);
                InProgressTable.OriginalNetworkId    = (ushort)((packet.Payload[pos + 10] << 8) + packet.Payload[pos + 11]);
            }

            if (InProgressTable == null)
            {
                return;
            }

            if (_sectionsCompleted.Contains(InProgressTable.SectionNumber))
            {
                InProgressTable = null;
                return;
            }

            AddData(packet);

            if (!HasAllBytes())
            {
                return;
            }



            InProgressTable.SegmentLastSectionNumber = (Data[InProgressTable.PointerField + 13]);
            InProgressTable.LastTableId = (Data[InProgressTable.PointerField + 14]);

            var startOfNextField = (ushort)(InProgressTable.PointerField + 15);

            var transportStreamLoopEnd = (ushort)(InProgressTable.SectionLength - 4);

            var items = new List <EventInformationItem>();

            while (startOfNextField < transportStreamLoopEnd)
            {
                var item = new EventInformationItem
                {
                    EventId               = (ushort)((Data[startOfNextField] << 8) + Data[startOfNextField + 1]),
                    StartTime             = (ulong)(((ulong)(Data[startOfNextField + 2]) << 32) + ((ulong)(Data[startOfNextField + 3]) << 24) + ((ulong)(Data[startOfNextField + 4]) << 16) + ((ulong)(Data[startOfNextField + 5]) << 8) + ((ulong)(Data[startOfNextField + 6]))),
                    Duration              = (uint)((Data[startOfNextField + 7] << 16) + (Data[startOfNextField + 8] << 8) + Data[startOfNextField + 9]),
                    RunningStatus         = (byte)((Data[startOfNextField + 10] >> 5) & 0x07),
                    FreeCAMode            = (bool)((Data[startOfNextField + 10] & 0x10) == 0x10),
                    DescriptorsLoopLength = (ushort)(((Data[startOfNextField + 10] & 0x3) << 8) + Data[startOfNextField + 11])
                };

                var descriptors = new List <Descriptor>();

                startOfNextField = (ushort)(startOfNextField + 12);
                var endOfDescriptors = (ushort)(startOfNextField + item.DescriptorsLoopLength);

                if (endOfDescriptors > Data.Length)
                {
                    throw new InvalidDataException("Descriptor data in Event Information is marked beyond available data");
                }

                while (startOfNextField < endOfDescriptors)
                {
                    var des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                    descriptors.Add(des);
                    startOfNextField += (ushort)(des.DescriptorLength + 2);
                }
                item.Descriptors = descriptors;
                items.Add(item);
            }

            InProgressTable.Items = items;

            EventInformationItems.AddRange(items);

            if (InProgressTable.VersionNumber == EventInformationTable?.VersionNumber)
            {
                return;
            }

            EventInformationTable = InProgressTable;
            _sectionsCompleted.Add(InProgressTable.SectionNumber);

            OnTableChangeDetected();
        }
        public void AddPacket(TsPacket packet)
        {
            CheckPid(packet.Pid);

            if (packet.PayloadUnitStartIndicator)
            {
                InProgressTable = new ServiceDescriptionTable {
                    Pid = packet.Pid, PointerField = packet.Payload[0]
                };

                if (InProgressTable.PointerField > packet.Payload.Length)
                {
                    Debug.Assert(true, "Service Description Table has packet pointer outside the packet.");
                }

                var pos = 1 + InProgressTable.PointerField;

                InProgressTable.VersionNumber = (byte)(packet.Payload[pos + 5] & 0x3E);

                InProgressTable.TableId = packet.Payload[pos];

                //TODO: Refactor with enum for well-known table IDs, and add option below as filter
                //if (InProgressTable.TableId != 0x42)
                //{
                //    InProgressTable = null;
                //    return;
                //}

                if ((ServiceDescriptionTable == null) || (ServiceDescriptionTable.VersionNumber != InProgressTable.VersionNumber))
                {
                    //if the version number of any section jumps, we need to refresh
                    _sectionsCompleted      = new HashSet <int>();
                    ServiceDescriptionItems = new List <ServiceDescriptionItem>();
                }

                InProgressTable.SectionLength =
                    (short)(((packet.Payload[pos + 1] & 0x3) << 8) + packet.Payload[pos + 2]);

                InProgressTable.TransportStreamId    = (ushort)((packet.Payload[pos + 3] << 8) + packet.Payload[pos + 4]);
                InProgressTable.CurrentNextIndicator = (packet.Payload[pos + 5] & 0x1) != 0;
                InProgressTable.SectionNumber        = packet.Payload[pos + 6];
                InProgressTable.LastSectionNumber    = packet.Payload[pos + 7];
                InProgressTable.OriginalNetworkId    = (ushort)((packet.Payload[pos + 8] << 8) + packet.Payload[pos + 9]);
            }

            if (InProgressTable == null)
            {
                return;
            }

            if (_sectionsCompleted.Contains(InProgressTable.SectionNumber))
            {
                InProgressTable = null;
                return;
            }

            AddData(packet);

            if (!HasAllBytes())
            {
                return;
            }

            var startOfNextField = (ushort)(InProgressTable.PointerField + 12);

            var transportStreamLoopEnd = (ushort)(InProgressTable.SectionLength - 4);

            var items = new List <ServiceDescriptionItem>();

            while (startOfNextField < transportStreamLoopEnd)
            {
                var item = new ServiceDescriptionItem
                {
                    ServiceId               = (ushort)((Data[startOfNextField] << 8) + Data[startOfNextField + 1]),
                    EitScheduleFlag         = ((Data[startOfNextField + 2]) & 0x02) == 0x02,
                    EitPresentFollowingFlag = ((Data[startOfNextField + 2]) & 0x01) == 0x01,
                    RunningStatus           = (byte)((Data[startOfNextField + 3] >> 5) & 0x07),
                    FreeCaMode              = (Data[startOfNextField + 3] & 0x10) == 0x10,
                    DescriptorsLoopLength   =
                        (ushort)(((Data[startOfNextField + 3] & 0xf) << 8) + Data[startOfNextField + 4])
                };

                var descriptors = new List <Descriptor>();

                startOfNextField = (ushort)(startOfNextField + 5);
                var endOfDescriptors = (ushort)(startOfNextField + item.DescriptorsLoopLength);

                if (endOfDescriptors > Data.Length)
                {
                    throw new InvalidDataException("Descriptor data in Service Description is marked beyond available data");
                }

                while (startOfNextField < endOfDescriptors)
                {
                    var des = DescriptorFactory.DescriptorFromData(Data, startOfNextField);
                    descriptors.Add(des);
                    startOfNextField += (ushort)(des.DescriptorLength + 2);
                }
                item.Descriptors = descriptors;
                items.Add(item);
            }

            ServiceDescriptionItems.AddRange(items);

            ServiceDescriptionTable       = InProgressTable;
            ServiceDescriptionTable.Items = ServiceDescriptionItems;

            _sectionsCompleted.Add(InProgressTable.SectionNumber);

            InProgressTable.ItemsIncomplete = false;

            for (var i = 0; i <= InProgressTable.LastSectionNumber; i++)
            {
                if (!_sectionsCompleted.Contains(i))
                {
                    InProgressTable.ItemsIncomplete = true;
                }
            }

            OnTableChangeDetected();
        }