예제 #1
0
        public SectionBase(byte[] source, int offset, int pid, bool crc)
        {
            _SectionData = new byte[4096];
            _DoCrc       = crc;

            int u = source[1 + offset];
            int l = source[2 + offset];

            u &= 0x0f;
            l |= u << 8;
            l += 3;

            Array.Copy(source, offset, SectionData, 0, l);
            _Pid = pid;

            _Ptr = l;

            _Completed = true;
            _Finished  = !_DoCrc || SectionCrc.Compare(_SectionData, l, 0x00000000);
        }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
        /// <summary>
        /// Fügt ein Paket aus einem Byte[] der Section hinzu
        /// </summary>
        /// <param name="tsPacket">MPEG Transport-Strom-Paket</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 AddPacket(byte[] tsPacket, int plOffset)
        {
            lock (this)
            {
                if (_Finished)
                {
                    return(true);
                }

                if (_Completed && !_Finished)
                {
                    Reset();
                }

                int err   = tsPacket[1] & 0x80;
                int start = tsPacket[1] & 0x40;
                int prio  = tsPacket[1] & 0x20;
                int pid   = ((tsPacket[1] << 8) | tsPacket[2]) & 0x1fff;

                int scrambling = (tsPacket[3] & 0xc0) >> 6;
                int adaption   = (tsPacket[3] & 0x30) >> 4;
                int contCtr    = tsPacket[3] & 0x0f;

                int plPointer = tsPacket[4];

                if (pid != _Pid && _Pid != -1)
                {
                    return(false);
                }

                if (err != 0)
                {
                    return(false);
                }

                if ((_PacketCtr == 0 && start == 0) || adaption == 0)
                {
                    return(false);
                }

                if (start == 0 && _PacketCtr != 0 &&
                    ((_ContCtr + 1) & 0x0f) != contCtr)
                {
                    Reset();
                    return(false);
                }

                if (adaption == 2)
                {
                    return(false);
                }

                if (plOffset == 0 && (adaption == 3 || start != 0))
                {
                    plOffset += 1 + plPointer;
                }

                int len = (188 - 4) - plOffset;
                int remain;

                if (_PacketCtr == 0)
                {
                    int u = tsPacket[4 + plOffset + 1];
                    int l = tsPacket[4 + 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;
                }

                if (len <= 0)
                {
                    Reset();
                    return(false);
                }

                Array.Copy(tsPacket, 4 + plOffset, SectionData, _Ptr, len);

                _ContCtr = contCtr;
                _PacketCtr++;

                _Ptr += len;

                int size = SectionSize;

                _Completed = size > 3 && (_Ptr >= size);

                if (_Completed)
                {
                    _Finished = !_DoCrc || SectionCrc.Compare(_SectionData, size, 0x00000000);

                    if (_Finished && start != 0 && _SectionData[size] != 0xff)
                    {
                        NextSection = new SectionBase(_Pid, _DoCrc);
                        NextSection.AddPacket(tsPacket, plOffset + size);
                    }
                }

                return(_Finished);
            }
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <summary>
        /// Fügt ein Paket der Section hinzu.
        /// </summary>
        /// <param name="tsPacket">MPEG Transport-Strom-Paket</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 AddPacket(IntPtr tsPacket, int plOffset)
        {
            lock (this)
            {
                if (_Finished)
                {
                    return(true);
                }

                // Dann sind Daten fehlerhaft, also Neustart:
                if (_Completed && !_Finished)
                {
                    Reset();
                }

                int tmp = IPAddress.NetworkToHostOrder(Marshal.ReadInt16(tsPacket, 1));

                int err   = tmp & 0x8000;
                int start = tmp & 0x4000;
                int prio  = tmp & 0x2000;
                int pid   = tmp & 0x1fff;

                tmp = Marshal.ReadByte(tsPacket, 3);

                int scrambling = (tmp & 0xc0) >> 6; // 0 = unscrambled, 2 = even CW, 3 = odd cw, 1 = ?
                int adaption   = (tmp & 0x30) >> 4; // 0 = invalid, 1 = payload only, 2 = a. only, 3 = a folow pl
                int contCtr    = tmp & 0x0f;

                int plPointer = Marshal.ReadByte(tsPacket, 4);
                // nur von Wichtigkeit, wenn PL Start.
                // 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

                // bei nicht passender Pid raus:
                if (pid != _Pid && _Pid != -1)
                {
                    return(false);
                }

                // Bei fehlerhaften Packets raus:
                if (err != 0)
                {
                    return(false);
                }

                // Wenn noch kein Payload-Start und kein Paket eingelesen wurde, dann raus, ebenso wenn adaption-control 0 ist.
                if ((_PacketCtr == 0 && start == 0) || adaption == 0)
                {
                    return(false);
                }

                // wenn schon Packets vorhanden, und wieder PL Start, dann Reset, neuer Anlauf.
                // entfernt. Siehe oben plPointer Kommentar.
                //if (_PacketCtr && start)
                //{
                //	Reset();
                //}

                // start und !_packetCtr
                // !start und _packetCtr <-- hier contCtr prüfen!

                if (start == 0 && _PacketCtr != 0 &&
                    ((_ContCtr + 1) & 0x0f) != contCtr)
                {
                    // Dann fehlt ein oder mehrere packets. Reset und raus.
                    Reset();
                    return(false);
                }

                // hier dürfte nun nichts falsches mehr sein. Wenn doch was schief geht, stimmt CRC am ende nicht.

                // nichts zu kopieren, raus:
                if (adaption == 2)
                {
                    return(false);
                }

                // 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 (plOffset == 0 && (adaption == 3 || start != 0))
                {
                    plOffset += 1 + plPointer;
                }

                int len = (188 - 4) - plOffset;
                int remain;

                // länge aus Header ermitteln, damit packetize später stimmt, sofern erstes packet...
                if (_PacketCtr == 0)
                {
                    int u = Marshal.ReadByte(tsPacket, 4 + plOffset + 1);
                    int l = Marshal.ReadByte(tsPacket, 4 + 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 + (4 + plOffset), SectionData, _Ptr, len);

                // zähler setzen:
                _ContCtr = contCtr;
                _PacketCtr++;

                _Ptr += len;

                int size = SectionSize;

                // wenn rest vom vorherige section oder adaption field zu lang ist, könnte teil der Section-Length fehlen
                // daher immer auf size prüfen.
                _Completed = size > 3 && (_Ptr >= size);

                if (_Completed)
                {
                    // dann CRC prüfen, wenn gefordert, ECMs sind z.B. ohne.:
                    _Finished = !_DoCrc || SectionCrc.Compare(_SectionData, size, 0x00000000);

                    if (_Finished && start != 0 && _SectionData[size] != 0xff) // prüfen ob weitere Sections vorhanden sind:
                    {
                        NextSection = new SectionBase(_Pid, _DoCrc);
                        NextSection.AddPacket(tsPacket, plOffset + size); // offsetstart + Section-Länge = start nächste Section
                    }
                }

                return(_Finished);
            }
        }