123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- namespace MatrixIO.IO.MpegTs
- {
- public enum ScramblingControl : byte
- {
- NotScambled = 0,
- Reserved = 1,
- ScrambledWithEvenKey = 2,
- ScambledWithOddKey = 3,
- }
- public enum PacketIdentifier : ushort
- {
- ProgramAssociationTable = 0x0000, // TID 0x00
- ConditionalAccessTable = 0x0001, // TID 0x01
- TsDescriptionTable = 0x0002, // TID 0x03
- // 0x03 to 0x0F RESERVED
- NetworkInformationTable = 0x0010, // TID 0x40 (current) & 0x41 (other)
- ServiceDescriptionTable = 0x0011, // TID 0x42,0x46 (ServiceDescription) & 0x4A (BouquetAssociation)
- EventInformationTable = 0x0012,
- RunningStatusTable = 0x0013,
- TimeTables = 0x0014, // TID 0x70 (TimeAndDate) & 0x73 (TimeOffset)
- NetworkSynchronization = 0x0015,
- ResolutionNotificationTable = 0x0016,
- // 0x0017 to 0x001B RESERVED
- InbandSignalling = 0x001C,
- Measurement = 0x001D,
- DiscontinuityInformation = 0x001E,
- SectionIformation = 0x001F,
- // USER DEFINED
- NullPacket = 0x1FFF,
- }
- public class TsPacket
- {
- public const int Length = 188;
- internal const byte SyncByte = 0x47;
- private ushort _header1;
- private byte _header2;
- public bool TransportErrorIndicator
- {
- get { return (_header1 & 0x8000) != 0; }
- set { if (value) _header1 |= 0x8000; else _header1 &= 0x7FFF; }
- }
- public bool PayloadUnitStartIndicator
- {
- get { return (_header1 & 0x4000) != 0; }
- set { if (value) _header1 |= 0x4000; else _header1 &= 0xBFFF; }
- }
- public bool TransportPriority
- {
- get { return (_header1 & 0x2000) != 0; }
- set { if (value) _header1 |= 0x2000; else _header1 &= 0xDFFF; }
- }
- /// <summary>
- /// 13 bit identifier. Valid values are 0 to 8191.
- /// </summary>
- public ushort PacketIdentifier
- {
- get { return (ushort)(_header1 & 0x1FFF); }
- set
- {
- Debug.Assert(value < 8192, "PacketIdentifier must be in the range of 0 to 8191.");
- _header1 = (ushort)((_header1 & 0xE000) | (value & 0x1FFF));
- }
- }
- public ScramblingControl ScramblingControl
- {
- get { return (ScramblingControl)((_header2 & 0xC0) >> 6); }
- set
- {
- Debug.Assert((int)value < 4, "ScramblingControl must be in the range of 0 to 3.");
- _header2 = (byte)((_header2 & 0x3F) | (((byte)value << 6) & 0xC0));
- }
- }
- private bool HasAdaptationField
- {
- get { return (_header2 & 0x20) != 0; }
- set { if (value) _header2 |= 0x20; else _header2 &= 0xDF; }
- }
- private bool HasPayload
- {
- get { return (_header2 & 0x10) != 0; }
- set { if (value) _header2 |= 0x10; else _header2 &= 0xEF; }
- }
- /// <summary>
- /// 4 bit counter. Valid values are 0 to 15.
- /// </summary>
- public byte ContinuityCounter
- {
- get { return (byte)(_header2 & 0x0F); }
- set
- {
- Debug.Assert((int) value < 16, "ContinuityCounter must be in the range of 0 to 15.");
- _header2 = (byte)((_header2 & 0xF0) | (value & 0x0F));
- }
- }
- private AdaptationField _adaptationField;
- public AdaptationField AdaptationField
- {
- get
- {
- return HasAdaptationField ? _adaptationField : null;
- }
- set
- {
- _adaptationField = value;
- HasAdaptationField = (value != null);
- }
- }
- private byte[] _payload;
- public byte[] Payload
- {
- get { return HasPayload ? _payload : null; }
- set
- {
- _payload = value;
- HasPayload = (value != null);
- }
- }
- public byte[] Stuffing { get; set; }
- public TsPacket(byte[] buffer, int offset=0)
- {
- int position = offset;
- if (buffer.Length - offset < Length)
- throw new ArgumentOutOfRangeException("Buffer must contain at least " + Length + " bytes.");
- if (buffer[position++] != SyncByte)
- throw new ArgumentException("Packet does not begin with 0x" + SyncByte.ToString("X2") + " sync byte.");
- _header1 = (ushort)((buffer[position++] << 8) | buffer[position++]);
- _header2 = buffer[position++];
- if(HasAdaptationField)
- {
- _adaptationField = new AdaptationField(buffer, position);
- position += AdaptationField.Length + 1;
- }
- if (HasPayload)
- {
- int payloadLength = Length - (position - offset);
- _payload = new byte[payloadLength];
- Buffer.BlockCopy(buffer, position, _payload, 0, payloadLength);
- position += payloadLength;
- }
- int stuffingLength = Length - (position - offset);
- if (stuffingLength > 0)
- {
- Debug.WriteLine("Has " + stuffingLength + " bytes of Transport Packet stuffing.");
- Stuffing = new byte[stuffingLength];
- }
- }
- }
- }
|