183 lines
6.5 KiB
C#
183 lines
6.5 KiB
C#
using System.IO;
|
|
using skyscraper5.Dvb;
|
|
using skyscraper5.Skyscraper;
|
|
using skyscraper5.Skyscraper.IO;
|
|
|
|
namespace skyscraper5.Mpeg2
|
|
{
|
|
public class DvbAdaptionField : Validatable
|
|
{
|
|
public DvbAdaptionField(Stream binaryReader, bool TEI)
|
|
{
|
|
byte adaptionFieldLength = binaryReader.ReadUInt8();
|
|
if (adaptionFieldLength > 183)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
byte[] adaptionField = binaryReader.ReadBytes(adaptionFieldLength);
|
|
binaryReader = new MemoryStream(adaptionField);
|
|
this.Length = adaptionFieldLength;
|
|
|
|
if (adaptionFieldLength == 0)
|
|
{
|
|
Valid = true;
|
|
return; //Seems valid according to ISO 13818-1
|
|
}
|
|
|
|
byte bitmask = binaryReader.ReadUInt8();
|
|
Discontinuity = ((bitmask & 0x80) >> 7) != 0;
|
|
RandomAccess = ((bitmask & 0x40) >> 6) != 0;
|
|
PriorityIndicator = ((bitmask & 0x20) >> 5) != 0;
|
|
PcrPresent = ((bitmask & 0x10) >> 4) != 0;
|
|
OpcrPresent = ((bitmask & 0x08) >> 3) != 0;
|
|
SplicingPointPresent = ((bitmask & 0x04) >> 2) != 0;
|
|
TransportPrivateDataPresent = ((bitmask & 0x02) >> 1) != 0;
|
|
AdaptionFieldExtensionPresent = ((bitmask & 0x01)) != 0;
|
|
|
|
if (PcrPresent)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() < 6)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
uint pcrA = binaryReader.ReadUInt32BE();
|
|
ushort pcrB = binaryReader.ReadUInt16BE();
|
|
ulong pcr_base = ((ulong)pcrA << 1) | ((ulong)pcrB >> 15);
|
|
ulong pcr_ext = (ulong)pcrB & 0x01ff;
|
|
PCR = pcr_base * 300 + pcr_ext;
|
|
}
|
|
if (OpcrPresent)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() < 6)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
uint opcrA = binaryReader.ReadUInt32BE();
|
|
ushort opcrB = binaryReader.ReadUInt16BE();
|
|
ulong pcr_base = ((ulong)opcrA << 1) | ((ulong)opcrB >> 15);
|
|
ulong pcr_ext = (ulong)opcrB & 0x01ff;
|
|
OPCR = pcr_base * 300 + pcr_ext;
|
|
}
|
|
if (SplicingPointPresent)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() == 0)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
SplicingPoint = binaryReader.ReadUInt8();
|
|
}
|
|
|
|
if (TransportPrivateDataPresent)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() == 0)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
byte TransportPrivateDataLength = binaryReader.ReadUInt8();
|
|
long maxLen = binaryReader.Length - binaryReader.Position;
|
|
if (TransportPrivateDataLength <= maxLen)
|
|
{
|
|
TransportPrivateData = binaryReader.ReadBytes(TransportPrivateDataLength);
|
|
}
|
|
else
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (AdaptionFieldExtensionPresent)
|
|
{
|
|
AdaptionFieldExtension = new TsAdaptionFieldExtension();
|
|
|
|
if (binaryReader.GetAvailableBytes() == 0)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
|
|
byte extensionFlags1 = binaryReader.ReadUInt8();
|
|
AdaptionFieldExtension.LtwFlag = (extensionFlags1 & 0x80) != 0;
|
|
AdaptionFieldExtension.PiecewiseRateFlag = (extensionFlags1 & 0x40) != 0;
|
|
AdaptionFieldExtension.SeamlessSpliceFlag = (extensionFlags1 & 0x20) != 0;
|
|
|
|
if (AdaptionFieldExtension.LtwFlag)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() < 2)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
|
|
ushort ltwRaw = binaryReader.ReadUInt16BE();
|
|
AdaptionFieldExtension.LtwValidFlag = (ltwRaw & 0x8000) != 0;
|
|
AdaptionFieldExtension.LtwOffset = (ltwRaw & 0x7fff);
|
|
}
|
|
|
|
if (AdaptionFieldExtension.PiecewiseRateFlag)
|
|
{
|
|
if (binaryReader.GetAvailableBytes() < 3)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
|
|
int piecewiseRaw = binaryReader.ReadByte() & 0xff;
|
|
piecewiseRaw += (binaryReader.ReadUInt16BE() & 0xffff) >> 8;
|
|
piecewiseRaw = piecewiseRaw & 0x3fffff;
|
|
AdaptionFieldExtension.PiecewiseRate = piecewiseRaw;
|
|
}
|
|
|
|
if (AdaptionFieldExtension.SeamlessSpliceFlag)
|
|
{
|
|
if (binaryReader.Length - binaryReader.Position < 5)
|
|
{
|
|
Valid = false;
|
|
return;
|
|
}
|
|
|
|
byte spliceRawA = binaryReader.ReadUInt8();
|
|
AdaptionFieldExtension.SpliceType = spliceRawA & 0xf0;
|
|
AdaptionFieldExtension.DtsNextAccessUnit = (long)(spliceRawA & 0x0f);
|
|
AdaptionFieldExtension.DtsNextAccessUnit += (((long)binaryReader.ReadUInt32BE() & 0xfffefffeL) >> 4);
|
|
}
|
|
}
|
|
|
|
Valid = true;
|
|
}
|
|
|
|
public bool PriorityIndicator { get; private set; }
|
|
|
|
public bool RandomAccess { get; private set; }
|
|
|
|
public bool Discontinuity { get; private set; }
|
|
|
|
public TsAdaptionFieldExtension AdaptionFieldExtension { get; private set; }
|
|
|
|
public bool AdaptionFieldExtensionPresent { get; private set; }
|
|
|
|
public byte[] TransportPrivateData { get; private set; }
|
|
|
|
public bool TransportPrivateDataPresent { get; private set; }
|
|
|
|
public byte SplicingPoint { get; private set; }
|
|
|
|
public bool SplicingPointPresent { get; private set; }
|
|
|
|
public ulong OPCR { get; set; }
|
|
|
|
public bool OpcrPresent { get; private set; }
|
|
|
|
public ulong PCR { get; private set; }
|
|
|
|
public bool PcrPresent { get; private set; }
|
|
|
|
public byte Length { get; private set; }
|
|
}
|
|
}
|