Ejemplo n.º 1
0
        public Packet(byte[] packetBuffer)
        {
            TransportErrorIndicator   = 1 == packetBuffer[1] >> 7;                   // Set by demodulator if can't correct errors in the stream, to tell the demultiplexer that the packet has an uncorrectable error
            PayloadUnitStartIndicator = 1 == ((packetBuffer[1] & 64) >> 6);          // and with 01000000 to get second byte - 1 means start of PES data or PSI otherwise zero
            TransportPriority         = 1 == ((packetBuffer[1] & 32) >> 5);          // and with 00100000 to get third byte - 1 means higher priority than other packets with the same PID
            PacketId               = (packetBuffer[1] & 31) * 256 + packetBuffer[2]; // and with 00011111 to get last 5 bytes
            ScramblingControl      = packetBuffer[3] >> 6;                           // '00' = Not scrambled.   The following per DVB spec:[12]   '01' = Reserved for future use,   '10' = Scrambled with even key,   '11' = Scrambled with odd key
            AdaptationFieldControl = (packetBuffer[3] & 48) >> 4;                    // and with 00110000, 01 = no adaptation fields (payload only), 10 = adaptation field only, 11 = adaptation field and payload
            ContinuityCounter      = packetBuffer[3] & 15;
            AdaptionFieldLength    = AdaptationFieldControl > 1 ? (0xFF & packetBuffer[4]) + 1 : 0;

            if (AdaptationFieldControl == Helper.B00000010 || AdaptationFieldControl == Helper.B00000011)
            {
                AdaptationField = new AdaptationField(packetBuffer);
            }

            if (AdaptationFieldControl == Helper.B00000001 || AdaptationFieldControl == Helper.B00000011) // Payload exists -  binary '01' || '11'
            {
                int payloadStart = 4;
                if (AdaptationField != null)
                {
                    payloadStart += (1 + AdaptationField.Length);
                }

                if (PacketId == ProgramAssociationTablePacketId)                                           // PAT = Program Association Table: lists all programs available in the transport stream.
                {
                    ProgramAssociationTable = new ProgramAssociationTable(packetBuffer, payloadStart + 1); // TODO: What index?
                }

                // Save payload
                Payload = new byte[packetBuffer.Length - payloadStart];
                Buffer.BlockCopy(packetBuffer, payloadStart, Payload, 0, Payload.Length);
            }
        }
Ejemplo n.º 2
0
        public Packet(byte[] packetBuffer)
        {
            TransportErrorIndicator = 1 == packetBuffer[1] >> 7; // Set by demodulator if can't correct errors in the stream, to tell the demultiplexer that the packet has an uncorrectable error
            PayloadUnitStartIndicator = 1 == ((packetBuffer[1] & 64) >> 6); // and with 01000000 to get second byte - 1 means start of PES data or PSI otherwise zero
            TransportPriority = 1 == ((packetBuffer[1] & 32) >> 5); // and with 00100000 to get third byte - 1 means higher priority than other packets with the same PID
            PacketId = (packetBuffer[1] & 31) * 256 + packetBuffer[2];// and with 00011111 to get last 5 bytes
            ScramblingControl = packetBuffer[3] >> 6; // '00' = Not scrambled.   The following per DVB spec:[12]   '01' = Reserved for future use,   '10' = Scrambled with even key,   '11' = Scrambled with odd key
            AdaptationFieldControl = (packetBuffer[3] & 48) >> 4; // and with 00110000, 01 = no adaptation fields (payload only), 10 = adaptation field only, 11 = adaptation field and payload
            ContinuityCounter = packetBuffer[3] & 15;
            AdaptionFieldLength = AdaptationFieldControl > 1 ? (0xFF & packetBuffer[4]) + 1 : 0;

            if (AdaptationFieldControl == Helper.B00000010 || AdaptationFieldControl == Helper.B00000011)
                AdaptationField = new AdaptationField(packetBuffer);

            if (AdaptationFieldControl == Helper.B00000001 || AdaptationFieldControl == Helper.B00000011) // Payload exists -  binary '01' || '11'
            {
                int payloadStart = 4;
                if (AdaptationField != null)
                    payloadStart += (1 + AdaptationField.Length);

                if (PacketId == ProgramAssociationTablePacketId) // PAT = Program Association Table: lists all programs available in the transport stream.
                {
                    ProgramAssociationTable = new ProgramAssociationTable(packetBuffer, payloadStart + 1); // TODO: What index?
                }

                // Save payload
                Payload = new byte[packetBuffer.Length - payloadStart];
                Buffer.BlockCopy(packetBuffer, payloadStart, Payload, 0, Payload.Length);
            }
        }
        /// <summary>
        /// Get Program Map Tables for a Transport Stream, especially language for subtitle tracks
        /// </summary>
        /// <param name="ms">Input stream</param>
        public void Parse(Stream ms)
        {
            try
            {
                ms.Position = 0;
                const int packetLength        = 188;
                var       isM2TransportStream = TransportStreamParser.IsM3TransportStream(ms);
                var       packetBuffer        = new byte[packetLength];
                var       m2TsTimeCodeBuffer  = new byte[4];
                long      position            = 0;

                // check for Topfield .rec file
                ms.Seek(position, SeekOrigin.Begin);
                ms.Read(m2TsTimeCodeBuffer, 0, 3);
                if (m2TsTimeCodeBuffer[0] == 0x54 && m2TsTimeCodeBuffer[1] == 0x46 && m2TsTimeCodeBuffer[2] == 0x72)
                {
                    position = 3760;
                }

                var pmtPids = new List <int>();
                _programMapTables = new List <ProgramMapTable>();
                long transportStreamLength = ms.Length;
                var  max = Math.Min(transportStreamLength, MaxScanSize + position);
                while (position < max)
                {
                    ms.Seek(position, SeekOrigin.Begin);

                    if (isM2TransportStream)
                    {
                        ms.Read(m2TsTimeCodeBuffer, 0, m2TsTimeCodeBuffer.Length);
                        position += m2TsTimeCodeBuffer.Length;
                    }

                    ms.Read(packetBuffer, 0, packetLength);
                    if (packetBuffer[0] == Packet.SynchronizationByte)
                    {
                        var packet = new Packet(packetBuffer);

                        if (pmtPids.Contains(packet.PacketId))
                        {
                            var pmt = new ProgramMapTable(packet.Payload, 0);
                            _programMapTables.Add(pmt);
                        }
                        else if (packet.IsProgramAssociationTable)
                        {
                            var pat = new ProgramAssociationTable(packet.Payload, 0);
                            pmtPids.AddRange(pat.ProgramIds.Where(p => !pmtPids.Contains(p)));
                        }

                        position += packetLength;
                    }
                    else
                    {
                        position++;
                    }
                }
            }
            catch (Exception e)
            {
                Exception = e;
            }
        }