예제 #1
0
        /// <summary>
        /// Gets the byte section of the table.
        /// </summary>
        /// <param name="packet">The starting packet for the table.</param>
        /// <param name="tableId">TableId</param>
        /// <returns>Section of bytes.</returns>
        private byte[] GetEntireTable(TSPacketInfo packet, int tableId)
        {
            Ensure.IsNotNull(Log, packet, "packet is null");

            if (!packet.PayloadUnitStartIndicator || !packet.HasPayload)
            {
                //throw new CustomException("The packet doesn't contain a table section.");
                return(null);
            }

            var pointerField = packet.GetDataByte(0);

            if (pointerField != 0)
            {
                //Ensure.IsZero(Log, pointerField, "pointer field must be zero.");
                return(null);
            }

            // TODO: move to PATSection
            var pTableId = packet.GetDataByte(1);

            if (tableId != pTableId)
            {
                //Ensure.AreEqual(Log, tableId, pTableId, "TableId is invalid.");
                return(null);
            }

            var sectionSyntaxIndicator = BinaryUtils.ReadBool(packet.GetDataByte(2), 0);

            if (!sectionSyntaxIndicator)
            {
                //Ensure.IsTrue(Log, sectionSyntaxIndicator, "sectionSyntaxIndicator is not true.");
                return(null);
            }

            var padding = BinaryUtils.ReadBool(packet.GetDataByte(2), 1);

            if (padding)
            {
                //Ensure.IsFalse(Log, padding, "padding is not false.");
                return(null);
            }

            var reserved = BinaryUtils.GetBits(packet.GetDataByte(2), 2, 2);

            if (reserved != 3)
            {
                //Ensure.AreEqual(Log, 3, reserved, "reserved is not 11b (3).");
                return(null);
            }

            var sectionLen = BinaryUtils.GetBitsEx(packet.Segment, packet.DataBytePos + 2, 4, 12);

            sectionLen = Math.Min(4096, sectionLen) - (Constants.TSPacketSize - packet.DataBytePos - 3); // TODO: Review.

            var sectionData   = new byte[4096];
            var sectionOffset = 0;

            Buffer.BlockCopy(packet.Segment.Array, packet.Segment.Offset, sectionData, sectionOffset, packet.Segment.Count);
            sectionOffset += packet.Segment.Count;

            while (sectionLen > 0)
            {
                var nextPacket = this.GetPacket();
                if (nextPacket == null)
                {
                    continue;
                }

                if (!nextPacket.PayloadUnitStartIndicator &&
                    nextPacket.AdaptationFieldControl == AdaptationType.Payload &&
                    nextPacket.PID == packet.PID)
                {
                    var len = nextPacket.Segment.Count - 4;
                    Buffer.BlockCopy(nextPacket.Segment.Array, nextPacket.Segment.Offset + 4, sectionData, sectionOffset, len);
                    sectionOffset += len;
                    sectionLen    -= len;
                }
            }

            return(sectionData);
        }
예제 #2
0
        /// <summary>
        /// Parse stream and search for A / V types.
        /// </summary>
        private void ParseStream()
        {
            subStreams.Clear();

            #region Looking for PAT

            var count = 0;
            var packet = GetPacket();
            while (packet == null || packet.PID != 0)
            {
                packet = GetPacket();
                count++;

                if (count > 4000)
                {
                    throw new CustomException("PAT is not found.");
                }
            }

            #endregion

            #region Parse PAT (Program Association Table)

            var table = GetEntireTable(packet, 0x00);
            if (table == null)
            {
                throw new CustomException("PAT is not parsed");
            }

            var pTable = new TSPacketInfo(table);

            var sectionLen = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 2, 4, 12);
            //var transportStreamId = BinaryUtils.GetBitsEx(pTable.Bytes, pTable.DataBytePos + 4, 0, 16);
            //var patVersion = BinaryUtils.GetBitsEx(pTable.Bytes, pTable.DataBytePos + 6, 2, 5);

            var infoLen = sectionLen - 5 - 4;
            var numOfId = infoLen / 4;

            var programs = new List<Tuple<long, long>>();
            for (var i = 0; i < numOfId; i++)
            {
                var progNum = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 9 + 4 * i, 0, 16);
                var pid = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 11 + 4 * i, 3, 13);

                if (progNum == 0)
                {
                    //var networkId = pid;
                }
                else
                {
                    programs.Add(new Tuple<long, long>(progNum, pid));
                }
            }

            #endregion

            #region Parse PMT (Program Map Table)

            Ensure.IsNotZero(Log, programs.Count, "No programs are found");
            count = 0;
            //var list = new List<int>();
            byte[] pmtTable;

            while (true)
            {
                #region GUARD (COUNT)

                count++;

                if (count > 20000)
                {
                    //break;
                    throw new CustomException("PMT is not found.");
                }

                #endregion

                #region SEARCH PMT

                var nextPacket = this.GetPacket();
                if (nextPacket == null)
                {
                    continue;
                }

                pmtTable = this.GetEntireTable(nextPacket, 0x02);
                if (pmtTable == null)
                {
                    continue;
                }

                //list.Add(nextPacket.PID);
                //continue;

                #endregion

                #region CHECK PROGRAMS

                var found = false;
                foreach (var prog in programs)
                {
                    if (prog.Second == nextPacket.PID)
                    {
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    break;
                }

                #endregion
            }

            #endregion

            var pmtPacket = new TSPacketInfo(pmtTable);
            sectionLen = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtPacket.DataBytePos + 2, 4, 12);
            var programInfoLen = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtPacket.DataBytePos + 11, 4, 12);

            var pmtInfoLen = sectionLen - 13 - programInfoLen;
            var pmtStartPos = Convert.ToInt32(pmtPacket.DataBytePos + 13 + programInfoLen);

            while (pmtInfoLen > 0)
            {
                var streamType = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos, 0, 8);
                var ePID = Convert.ToInt32(BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos + 1, 3, 13));
                var eLen = Convert.ToInt32(BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos + 3, 4, 12));

                SubStreamType subStreamType = SubStreamType.None;
                switch (streamType)
                {
                    case 0x02:
                        subStreamType = SubStreamType.VideoMP2;
                        break;
                    case 0x03:
                    case 0x04:
                        subStreamType = SubStreamType.AudioMP2;
                        break;
                    case 0x06:

                        // DTS checking
                        if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x73))
                        {
                            subStreamType = SubStreamType.AudioDTS;
                        }
                        // Subtitle checking
                        else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x59))
                        {
                            subStreamType = SubStreamType.Subtitle;
                        }
                        // AC3 checking
                        else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x6a))
                        {
                            subStreamType = SubStreamType.AudioAC3;
                        }
                        // Teletext checking
                        else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x56))
                        {
                            subStreamType = SubStreamType.Teletext;
                        }

                        break;
                    case 0x0B:
                        subStreamType = SubStreamType.Subtitle;
                        break;
                    case 0x0F:
                    case 0x11:
                        subStreamType = SubStreamType.AudioAAC;
                        break;
                    case 0x10:
                        subStreamType = SubStreamType.VideoMP4;
                        break;
                    case 0x1b:
                        subStreamType = SubStreamType.VideoH264;
                        break;

                    case 0x81:
                    case 0x83:
                    case 0x85:
                    case 0x8A:
                        subStreamType = SubStreamType.AudioAC3;
                        break;
                }

                subStreams.Add(new Tuple<int, SubStreamType>(ePID, subStreamType));

                pmtInfoLen -= (eLen + 5);
                pmtStartPos += (eLen + 5);
            }
        }
예제 #3
0
        /// <summary>
        /// Parse stream and search for A / V types.
        /// </summary>
        private void ParseStream()
        {
            subStreams.Clear();

            #region Looking for PAT

            var count  = 0;
            var packet = GetPacket();
            while (packet == null || packet.PID != 0)
            {
                packet = GetPacket();
                count++;

                if (count > 4000)
                {
                    throw new CustomException("PAT is not found.");
                }
            }

            #endregion

            #region Parse PAT (Program Association Table)

            var table = GetEntireTable(packet, 0x00);
            if (table == null)
            {
                throw new CustomException("PAT is not parsed");
            }

            var pTable = new TSPacketInfo(table);

            var sectionLen = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 2, 4, 12);
            //var transportStreamId = BinaryUtils.GetBitsEx(pTable.Bytes, pTable.DataBytePos + 4, 0, 16);
            //var patVersion = BinaryUtils.GetBitsEx(pTable.Bytes, pTable.DataBytePos + 6, 2, 5);

            var infoLen = sectionLen - 5 - 4;
            var numOfId = infoLen / 4;

            var programs = new List <Tuple <long, long> >();
            for (var i = 0; i < numOfId; i++)
            {
                var progNum = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 9 + 4 * i, 0, 16);
                var pid     = BinaryUtils.GetBitsEx(pTable.Segment, pTable.DataBytePos + 11 + 4 * i, 3, 13);

                if (progNum == 0)
                {
                    //var networkId = pid;
                }
                else
                {
                    programs.Add(new Tuple <long, long>(progNum, pid));
                }
            }

            #endregion

            #region Parse PMT (Program Map Table)

            Ensure.IsNotZero(Log, programs.Count, "No programs are found");
            count = 0;
            //var list = new List<int>();
            byte[] pmtTable;

            while (true)
            {
                #region GUARD (COUNT)

                count++;

                if (count > 20000)
                {
                    //break;
                    throw new CustomException("PMT is not found.");
                }

                #endregion

                #region SEARCH PMT

                var nextPacket = this.GetPacket();
                if (nextPacket == null)
                {
                    continue;
                }

                pmtTable = this.GetEntireTable(nextPacket, 0x02);
                if (pmtTable == null)
                {
                    continue;
                }

                //list.Add(nextPacket.PID);
                //continue;

                #endregion

                #region CHECK PROGRAMS

                var found = false;
                foreach (var prog in programs)
                {
                    if (prog.Second == nextPacket.PID)
                    {
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    break;
                }

                #endregion
            }

            #endregion

            var pmtPacket = new TSPacketInfo(pmtTable);
            sectionLen = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtPacket.DataBytePos + 2, 4, 12);
            var programInfoLen = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtPacket.DataBytePos + 11, 4, 12);

            var pmtInfoLen  = sectionLen - 13 - programInfoLen;
            var pmtStartPos = Convert.ToInt32(pmtPacket.DataBytePos + 13 + programInfoLen);

            while (pmtInfoLen > 0)
            {
                var streamType = BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos, 0, 8);
                var ePID       = Convert.ToInt32(BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos + 1, 3, 13));
                var eLen       = Convert.ToInt32(BinaryUtils.GetBitsEx(pmtPacket.Segment, pmtStartPos + 3, 4, 12));

                SubStreamType subStreamType = SubStreamType.None;
                switch (streamType)
                {
                case 0x02:
                    subStreamType = SubStreamType.VideoMP2;
                    break;

                case 0x03:
                case 0x04:
                    subStreamType = SubStreamType.AudioMP2;
                    break;

                case 0x06:

                    // DTS checking
                    if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x73))
                    {
                        subStreamType = SubStreamType.AudioDTS;
                    }
                    // Subtitle checking
                    else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x59))
                    {
                        subStreamType = SubStreamType.Subtitle;
                    }
                    // AC3 checking
                    else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x6a))
                    {
                        subStreamType = SubStreamType.AudioAC3;
                    }
                    // Teletext checking
                    else if (CheckDescriptorES(pmtPacket.Segment, pmtStartPos + 5, eLen, 0x56))
                    {
                        subStreamType = SubStreamType.Teletext;
                    }

                    break;

                case 0x0B:
                    subStreamType = SubStreamType.Subtitle;
                    break;

                case 0x0F:
                case 0x11:
                    subStreamType = SubStreamType.AudioAAC;
                    break;

                case 0x10:
                    subStreamType = SubStreamType.VideoMP4;
                    break;

                case 0x1b:
                    subStreamType = SubStreamType.VideoH264;
                    break;

                case 0x81:
                case 0x83:
                case 0x85:
                case 0x8A:
                    subStreamType = SubStreamType.AudioAC3;
                    break;
                }

                subStreams.Add(new Tuple <int, SubStreamType>(ePID, subStreamType));

                pmtInfoLen  -= (eLen + 5);
                pmtStartPos += (eLen + 5);
            }
        }
예제 #4
0
        /// <summary>
        /// Gets the byte section of the table.
        /// </summary>
        /// <param name="packet">The starting packet for the table.</param>
        /// <param name="tableId">TableId</param>
        /// <returns>Section of bytes.</returns>
        private byte[] GetEntireTable(TSPacketInfo packet, int tableId)
        {
            Ensure.IsNotNull(Log, packet, "packet is null");

            if (!packet.PayloadUnitStartIndicator || !packet.HasPayload)
            {
                //throw new CustomException("The packet doesn't contain a table section.");
                return null;
            }

            var pointerField = packet.GetDataByte(0);
            if (pointerField != 0)
            {
                //Ensure.IsZero(Log, pointerField, "pointer field must be zero.");
                return null;
            }

            // TODO: move to PATSection
            var pTableId = packet.GetDataByte(1);
            if (tableId != pTableId)
            {
                //Ensure.AreEqual(Log, tableId, pTableId, "TableId is invalid.");
                return null;
            }

            var sectionSyntaxIndicator = BinaryUtils.ReadBool(packet.GetDataByte(2), 0);
            if (!sectionSyntaxIndicator)
            {
                //Ensure.IsTrue(Log, sectionSyntaxIndicator, "sectionSyntaxIndicator is not true.");
                return null;
            }

            var padding = BinaryUtils.ReadBool(packet.GetDataByte(2), 1);
            if (padding)
            {
                //Ensure.IsFalse(Log, padding, "padding is not false.");
                return null;
            }

            var reserved = BinaryUtils.GetBits(packet.GetDataByte(2), 2, 2);
            if (reserved != 3)
            {
                //Ensure.AreEqual(Log, 3, reserved, "reserved is not 11b (3).");
                return null;
            }

            var sectionLen = BinaryUtils.GetBitsEx(packet.Segment, packet.DataBytePos + 2, 4, 12);
            sectionLen = Math.Min(4096, sectionLen) - (Constants.TSPacketSize - packet.DataBytePos - 3); // TODO: Review.

            var sectionData = new byte[4096];
            var sectionOffset = 0;

            Buffer.BlockCopy(packet.Segment.Array, packet.Segment.Offset, sectionData, sectionOffset, packet.Segment.Count);
            sectionOffset += packet.Segment.Count;

            while (sectionLen > 0)
            {
                var nextPacket = this.GetPacket();
                if (nextPacket == null)
                {
                    continue;
                }

                if (!nextPacket.PayloadUnitStartIndicator &&
                    nextPacket.AdaptationFieldControl == AdaptationType.Payload &&
                    nextPacket.PID == packet.PID)
                {
                    var len = nextPacket.Segment.Count - 4;
                    Buffer.BlockCopy(nextPacket.Segment.Array, nextPacket.Segment.Offset + 4, sectionData, sectionOffset, len);
                    sectionOffset += len;
                    sectionLen -= len;
                }
            }

            return sectionData;
        }