using System;
namespace Nikse.SubtitleEdit.Core.TransportStream
{
public class AdaptationField
{
///
/// Number of bytes in the adaptation field immediately following the Length
///
public int Length { get; set; }
public bool DiscontinuityIndicator { get; set; }
public bool RandomAccessIndicator { get; set; }
public bool ElementaryStreamPriorityIndicator { get; set; }
///
/// '1' indicates that the adaptation field contains a PCR field coded in two parts
///
public bool PcrFlag { get; set; }
///
/// '1' indicates that the adaptation field contains an OPCR field coded in two parts
///
public bool OpcrFlag { get; set; }
///
/// '1' indicates that a splice countdown field shall be present in the associated adaptation field
///
public bool SplicingPointFlag { get; set; }
///
/// 1' indicates that the adaptation field contains one or more private data bytes
///
public bool TransportPrivateDataFlag { get; set; }
///
/// '1' indicates the presence of an adaptation field extension
///
public bool AdaptationFieldExtensionFlag { get; set; }
public int ProgramClockReferenceBase { get; set; }
public int ProgramClockReferenceExtension { get; set; }
public int OriginalProgramClockReferenceBase { get; set; }
public int OriginalProgramClockReferenceExtension { get; set; }
public int SpliceCountdown { get; set; }
public int TransportPrivateDataLength { get; set; }
public byte[] TransportPrivateData { get; set; }
public int AdaptationFieldExtensionLength { get; set; }
public AdaptationField(byte[] packetBuffer)
{
Length = packetBuffer[4];
DiscontinuityIndicator = 1 == packetBuffer[5] >> 7;
RandomAccessIndicator = (packetBuffer[5] & 64) > 0; // and with 01000000 to get second byte
ElementaryStreamPriorityIndicator = (packetBuffer[5] & 32) > 0; // and with 00100000 to get third byte
PcrFlag = (packetBuffer[5] & 16) > 0; // and with 00010000 to get fourth byte
OpcrFlag = (packetBuffer[5] & 8) > 0; // and with 00001000 to get fifth byte
SplicingPointFlag = (packetBuffer[5] & 4) > 0; // and with 00000100 to get sixth byte
TransportPrivateDataFlag = (packetBuffer[5] & 4) > 0; // and with 00000100 to get seventh byte
AdaptationFieldExtensionFlag = (packetBuffer[5] & 2) > 0; // and with 00000010 to get 8th byte
int index = 6;
if (PcrFlag)
{
ProgramClockReferenceBase = (packetBuffer[index] * 256 + packetBuffer[index + 1]) << 1;
ProgramClockReferenceBase += packetBuffer[index + 2] >> 7;
ProgramClockReferenceExtension = (packetBuffer[index + 2] & Helper.B00000001) * 256 + packetBuffer[index + 3];
index += 4;
}
if (OpcrFlag)
{
OriginalProgramClockReferenceBase = (packetBuffer[index] * 256 + packetBuffer[index + 1]) << 1;
OriginalProgramClockReferenceBase += packetBuffer[index + 2] >> 7;
OriginalProgramClockReferenceExtension = (packetBuffer[index + 2] & Helper.B00000001) * 256 + packetBuffer[index + 3];
index += 4;
}
if (SplicingPointFlag)
{
SpliceCountdown = packetBuffer[index];
index++;
}
if (TransportPrivateDataFlag)
{
TransportPrivateDataLength = packetBuffer[index];
index++;
TransportPrivateData = new byte[TransportPrivateDataLength];
if (index + TransportPrivateDataLength <= packetBuffer.Length)
{
Buffer.BlockCopy(packetBuffer, index, TransportPrivateData, 0, TransportPrivateDataLength);
index += TransportPrivateDataLength;
}
}
if (AdaptationFieldExtensionFlag && index < packetBuffer.Length)
{
AdaptationFieldExtensionLength = packetBuffer[index];
}
}
}
}