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); }
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(); }
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(); }