/// <summary> /// Fügt ein Paket ohne Header einem Byte[] der Section hinzu. /// </summary> /// <param name="tsPacket">MPEG Transport-Strom-Paket ohne Header</param> /// <param name="plOffset">0 wenn erste Section in dem Packet. größer 0 wenn weitere packers vorhanden.</param> /// <returns>True wenn letzte benötigte Paket eingelesen und Prüfsumme korrekt berechnet wurde.</returns> private bool AddPacket184(byte[] tsPacket, int plOffset) { if (_AllowedTables == null) { throw new InvalidOperationException("Section wurde nicht korrekt initialisiert um 184 Byte Packets aufzunehmen."); } lock (this) { if (_Finished) { return(true); } // Dann sind Daten fehlerhaft, also Neustart: if (_Completed && !_Finished) { Reset(); } int plPointer = tsPacket[0]; if (_PacketCtr == 0 && plOffset == 0) { plOffset = 1 + plPointer; } if (plOffset > 180) // dann kann was nicht stimmen. { Reset(); return(false); } if (_PacketCtr == 0) { byte tableId = tsPacket[plOffset]; bool syntax = (tsPacket[plOffset + 1] & 0x80) > 0; bool isTable = false; for (int i = 0; i < _AllowedTables.Length; i++) { if (_AllowedTables[i] == tableId) { isTable = true; break; } } if ((tableId < 0x80 && !syntax) || !isTable) { Reset(); return(false); } } int len = (184) - plOffset; int remain; if (_PacketCtr == 0) { int u = Marshal.ReadByte(tsPacket, plOffset + 1); int l = Marshal.ReadByte(tsPacket, plOffset + 2); u &= 0x0f; l |= u << 8; remain = l + 3; } else { remain = SectionSize - _Ptr; } if (remain < len) { len = remain; } if (_Ptr + len > _SectionData.Length) { len -= _SectionData.Length - _Ptr; // einkürzen, damit in Buffer passt. } if (len <= 0) { Reset(); return(false); // fehler } Array.Copy(tsPacket, plOffset, SectionData, _Ptr, len); _PacketCtr++; _Ptr += len; int size = SectionSize; _DoCrc = _SectionData[0] < 0x80; // Table ID, kein CRC auf ECM/EMM if (size > 1023) // max len = 1024 nach en300468 { Reset(); return(false); } // wenn rest vom vorherige section zu lang ist, könnte teil der Section-Length fehlen // daher immer auf size prüfen. _Completed = size > 5 && (_Ptr >= size); if (_Completed) { // dann CRC prüfen, wenn gefordert, ECMs sind z.B. ohne.: _Finished = !_DoCrc || SectionCrc.Compare(_SectionData, size, 0x00000000); if (_Finished && _SectionData[size] != 0xff) // prüfen ob weitere Sections vorhanden sind: { NextSection = new SectionBase(_Pid, _AllowedTables); NextSection.AddPacket184(tsPacket, plOffset + size); // offsetstart + Section-Länge = start nächste Section } } return(_Finished); } }
/// <summary> /// Fügt ein Paket ohne Header der Section hinzu. /// </summary> /// <param name="tsPacket">MPEG Transport-Strom-Paket ohne Header</param> /// <param name="plOffset">0 wenn erste Section in dem Packet. größer 0 wenn weitere packers vorhanden.</param> /// <returns>True wenn letzte benötigte Paket eingelesen und Prüfsumme korrekt berechnet wurde.</returns> private bool AddPacket184(IntPtr tsPacket, int plOffset) { if (_AllowedTables == null) { throw new InvalidOperationException("Section wurde nicht korrekt initialisiert um 184 Byte Packets aufzunehmen."); } lock (this) { if (_Finished) { return(true); } // Dann sind Daten fehlerhaft, also Neustart: if (_Completed && !_Finished) { Reset(); } int plPointer = Marshal.ReadByte(tsPacket, 0); // nur von Wichtigkeit, wenn PL Start, nicht wenn plOffset gesetzt ist. // Ansonsten kann das letzte Packet auch in PL Start haben, der Start aber später erst anfängt. // PDF ISO/IEC 13818-1 : 2000 (E) Seite 19 (reader: 37) Punkt 2.4.3.3 payload_unit_start_indicator. // wenn adaption field gesetzt gilt dies auch // start des Payloads ermitteln, wenn Adaption-Field vorhanden //int plOffset = 0; // wenn != 0, dann ist das ein Nested Call für weitere Sections pro packet, z.b. bei EMM. if (_PacketCtr == 0 && plOffset == 0) { plOffset = 1 + plPointer; } if (plOffset > 180) // dann kann was nicht stimmen. { Reset(); return(false); } if (_PacketCtr == 0) { // check erlaubte Tabelle: byte tableId = Marshal.ReadByte(tsPacket, plOffset); bool syntax = (Marshal.ReadByte(tsPacket, plOffset + 1) & 0x80) > 0; bool isTable = false; for (int i = 0; i < _AllowedTables.Length; i++) { if (_AllowedTables[i] == tableId) { isTable = true; break; } } if ((tableId < 0x80 && !syntax) || !isTable) // bei ECM/EMM wird die section Syntax teilweise deaktiviert. { Reset(); return(false); } } int len = (184) - plOffset; int remain; // länge aus Header ermitteln, damit packetize später stimmt, sofern erstes packet... if (_PacketCtr == 0) { int u = Marshal.ReadByte(tsPacket, plOffset + 1); int l = Marshal.ReadByte(tsPacket, plOffset + 2); u &= 0x0f; l |= u << 8; remain = l + 3; } else { remain = SectionSize - _Ptr; } if (remain < len) { len = remain; } if (_Ptr + len > _SectionData.Length) { len -= _SectionData.Length - _Ptr; // einkürzen, damit in Buffer passt. } if (len <= 0) { Reset(); return(false); // fehler } Marshal.Copy(tsPacket + plOffset, SectionData, _Ptr, len); _PacketCtr++; _Ptr += len; int size = SectionSize; _DoCrc = _SectionData[0] < 0x80; // Table ID, kein CRC auf ECM/EMM if (size > 1023) // max len = 1024 nach en300468 { Reset(); return(false); } // wenn rest vom vorherige section zu lang ist, könnte teil der Section-Length fehlen // daher immer auf size prüfen. _Completed = size > 5 && (_Ptr >= size); if (_Completed) { // dann CRC prüfen, wenn gefordert, ECMs sind z.B. ohne.: _Finished = !_DoCrc || SectionCrc.Compare(_SectionData, size, 0x00000000); if (_Finished && _SectionData[size] != 0xff) // prüfen ob weitere Sections vorhanden sind: { NextSection = new SectionBase(_Pid, _AllowedTables); NextSection.AddPacket184(tsPacket, plOffset + size); // offsetstart + Section-Länge = start nächste Section } } return(_Finished); } }