public void Parse(IMpeg2SystemReader reader, IAttributeState resultState) { resultState.Name = _attributeName; ulong bits32To30 = reader.GetBits(3, "Bits [32..30]"); reader.GetMarker(); ulong bits29To15 = reader.GetBits(15, "Bits [29..15]"); reader.GetMarker(); ulong bits14To0 = reader.GetBits(15, "Bits [14..0]"); reader.GetMarker(); ulong value = (bits32To30 << 30) | (bits29To15 << 15) | bits14To0; if (_hasExtension && reader.State.IsMpeg2()) { ulong extension = reader.GetBits(9, "Extension"); // TODO: what if extension >= 300 ? value = (300 * value) + extension; } resultState.Value = value; reader.State.LastTimestamp = value; }
public Mpeg2SystemCarver(IMpeg2SystemReader reader, IResultParser <IMpeg2SystemReader> systemHeaderParser, IScanContext scanContext) { _reader = reader; _systemHeaderParser = systemHeaderParser; _scanContext = scanContext; _state = reader.State; _minHeaderCount = (uint)Mpeg2SystemDetector.Configurable[Mpeg2SystemDetector.ConfigurationKey.MinSystemHeaderCount]; }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; // This header should not be the first header in a block or directly succeeding a program end code string lastHeaderName = reader.State.LastHeaderName; if ((lastHeaderName == null) || (lastHeaderName == Name)) { resultState.Invalidate(); } }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; resultState.ParentName = PackHeader.Name; // if no pack headers have been encountered, it ends up in the root. int bytesRemaining = (int)reader.GetBits(16, Attribute.ProgramStreamMapLength, n => (n >= 10) && (n <= Math.Min(1018, reader.BytesRemaining))); if (!resultState.Valid) { return; } reader.GetBits(1, Attribute.CurrentNextIndicator); reader.GetReservedBits(2); reader.GetBits(5, Attribute.ProgramStreamMapVersion); reader.GetReservedBits(7); reader.GetMarker(); bytesRemaining -= 2; // TODO: issue 2282: MPEG-2 system detector does not implement full specification int maxProgramStreamInfoLength = (bytesRemaining - 2); uint programStreamInfoLength = reader.GetBits(16, Attribute.ProgramStreamInfoLength, n => n <= maxProgramStreamInfoLength); if (!resultState.Valid) { return; } bytesRemaining -= 2 + reader.SkipBytes((int)programStreamInfoLength); int maxElementaryStreamInfoLength = (bytesRemaining - 2); uint elementaryStreamInfoLength = reader.GetBits(16, Attribute.ElementaryStreamMapLength, n => n <= maxElementaryStreamInfoLength); if (!resultState.Valid) { return; } bytesRemaining -= 2 + reader.SkipBytes((int)elementaryStreamInfoLength); if (bytesRemaining < 4) { resultState.Invalidate(); return; } reader.GetBits(32, Attribute.Crc32); reader.SkipBytes(bytesRemaining - 4); }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; resultState.ParentName = PackHeader.Name; uint pesPacketLength = reader.GetBits(16, Attribute.PesPacketLength, n => n <= reader.BytesRemaining); if (!resultState.Valid) { return; } // TODO: issue 2282: MPEG-2 system detector does not implement full specification reader.SkipBytes((int)pesPacketLength); }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; resultState.ParentName = PackHeader.Name; // This header should be preceeded by a pack header, but which may have been overwritten if ((reader.State.LastHeaderName != PackHeader.Name) && reader.State.SeenPackHeader /*|| SeenPesPacket)*/) { resultState.Invalidate(); return; } reader.GetBits(16, Attribute.HeaderLength); reader.GetMarker(); uint rateBound = reader.GetBits(22, Attribute.RateBound); if (reader.State.SeenPackHeader && (rateBound < reader.State.ProgramMuxRate)) { resultState.Invalidate(); return; } reader.GetMarker(); reader.GetBits(6, Attribute.AudioBound, ab => ab <= 32); reader.GetFlag(Attribute.FixedFlag); reader.GetFlag(Attribute.CspsFlag); reader.GetFlag(Attribute.SystemAudioLockFlag); reader.GetFlag(Attribute.SystemVideoLockFlag); reader.GetMarker(); reader.GetBits(5, Attribute.VideoBound, vb => vb <= 16); reader.GetFlag(Attribute.PacketRateRestrictionFlag); reader.GetReservedBits(7); // 0x7F // Stream information (MPEG-2 only) while (resultState.Valid && (reader.ShowBits(1) == 1)) { resultState.Parse(_streamInfoAttributeParser, reader); } }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; if (reader.ShowBits(2) == 1) { reader.GetBits(2, Attribute.Mpeg2Flag); reader.SetMpegFormat(CodecID.Mpeg2System); } else if (reader.ShowBits(4) == 2) { reader.GetBits(4, Attribute.Mpeg2Flag); reader.SetMpegFormat(CodecID.Mpeg1System); } else { // Unknown whether it is MPEG-1 or 2, cannot parse header! reader.GetBits(2, Attribute.Mpeg2Flag, mpeg2Flag => false); resultState.Invalidate(); return; } reader.GetAttribute(_systemClockReferenceAttribute); reader.GetMarker(); reader.State.ProgramMuxRate = reader.GetBits(22, Attribute.ProgramMuxRate, muxRate => muxRate != 0); reader.GetMarker(); if (reader.State.IsMpeg2()) { reader.GetMarker(); reader.GetReservedBits(5); int packStuffingLength = (int)reader.GetBits(3, Attribute.PackStuffingLength); if (packStuffingLength > 0) { reader.GetStuffingBytes(packStuffingLength); } } }
public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState) { resultState.Name = Name; resultState.ParentName = PackHeader.Name; uint pesPacketLength = reader.GetBits(16, Attribute.PesPacketLength, n => n <= reader.BytesRemaining); long pesPacketEnd = reader.Position + pesPacketLength; resultState.Recover(); // Invalid PES packets should not end the current block! ushort streamId = (ushort)(reader.State.StartCode & 0xFF); if (streamId == 0xBE || streamId == 0xBF || streamId == 0xF0 || streamId == 0xF1 || streamId == 0xF2 || streamId == 0xF8) { // These streams do not contain further header details } else if (reader.ShowBits(2) == 2) { #region MPEG-2 reader.SetMpegFormat(CodecID.Mpeg2System); reader.GetBits(2, Attribute.Mpeg2Flag, f => f == 0x2); reader.GetBits(2, Attribute.PesScramblingControl); reader.GetBits(1, Attribute.PesPriority); reader.GetFlag(Attribute.DataAlignmentIndicator); reader.GetFlag(Attribute.Copyright); reader.GetFlag(Attribute.OriginalOrCopy); uint ptsDtsFlags = reader.GetBits(2, Attribute.PtsDtsFlags, f => f != 0x1); bool escrFlag = reader.GetFlag(Attribute.EscrFlag); bool esRateFlag = reader.GetFlag(Attribute.ESRateFlag); bool dsmTrickModeFlag = reader.GetFlag(Attribute.DsmTrickModeFlag); bool additionalCopyInfoFlag = reader.GetFlag(Attribute.AdditionalCopyInfoFlag); bool pesCrcFlag = reader.GetFlag(Attribute.PesCrcFlag); bool pesExtensionFlag = reader.GetFlag(Attribute.PesExtensionFlag); uint bytesRemaining = pesPacketLength - 3; uint pesHeaderDataLength = reader.GetBits(8, Attribute.PesHeaderDataLength, n => n <= bytesRemaining); long pesHeaderDataEnd = reader.Position + pesHeaderDataLength; if (!resultState.Valid) { return; } // Decode optional header fields switch (ptsDtsFlags) { case 2: reader.GetBits(4, 0x2); reader.GetAttribute(_presentationTimeStampAttribute); break; case 3: reader.GetBits(4, 0x3); reader.GetAttribute(_presentationTimeStampAttribute); reader.GetBits(4, 0x1); reader.GetAttribute(_decodingTimeStampAttribute); break; } if (escrFlag) { reader.GetAttribute(_escrAttribute); reader.GetMarker(); } if (esRateFlag) { reader.GetMarker(); reader.GetBits(22, Attribute.ESRate); reader.GetMarker(); } if (dsmTrickModeFlag) { switch (reader.GetBits(3, Attribute.TrickModeControl)) { case 0: case 3: reader.GetBits(2, Attribute.FieldId); reader.GetFlag(Attribute.IntraSliceRefresh); reader.GetBits(1, Attribute.FrequencyTruncation); // TODO: is this a flag?? break; case 1: case 4: reader.GetBits(5, Attribute.RepCntrl); break; case 2: reader.GetBits(2, Attribute.FieldId); reader.GetBits(3, Attribute.TrickModeReserved); break; default: reader.GetBits(5, Attribute.TrickModeReserved); break; } } if (additionalCopyInfoFlag) { reader.GetMarker(); reader.GetBits(7, Attribute.AdditionalCopyInfo); } if (pesCrcFlag) { reader.GetBits(16, Attribute.PreviousPesPacketCrc); } if (pesExtensionFlag) { bool pesPrivateDataFlag = reader.GetFlag(Attribute.PesPrivateDataFlag); bool packHeaderFieldFlag = reader.GetFlag(Attribute.PackHeaderFieldFlag); bool programPacketSequenceCounterFlag = reader.GetFlag(Attribute.ProgramPacketSequenceCounterFlag); bool pStdBufferFlag = reader.GetFlag(Attribute.PStdBufferFlag); reader.GetReservedBits(3); bool pesExtensionFlag2 = reader.GetFlag(Attribute.PesExtensionFlag2); if (pesPrivateDataFlag) { reader.GetData(Attribute.PesPrivateData, 16); } if (packHeaderFieldFlag) { reader.GetBits(8, Attribute.PackFieldLength); // TODO: pack_header(); } if (programPacketSequenceCounterFlag) { reader.GetMarker(); reader.GetBits(7, Attribute.ProgramPacketSequenceCounter); reader.GetMarker(); reader.GetBits(1, Attribute.Mpeg1Mpeg2Identifier); reader.GetBits(6, Attribute.OriginalStuffLength); } if (pStdBufferFlag) { reader.GetBits(2, 0x1); reader.GetBits(1, Attribute.PStdBufferBoundScale); reader.GetBits(13, Attribute.PStdBufferSizeBound); } if (pesExtensionFlag2) { reader.GetMarker(); uint pesExtensionFieldLength = reader.GetBits(7, Attribute.PesExtensionFieldLength); reader.GetData(Attribute.PesExtensionField, (int)pesExtensionFieldLength); } } if (reader.Position > pesHeaderDataEnd || reader.Position < (pesHeaderDataEnd - 32)) { // FIXME: reader.CheckAttribute(Attribute.PesHeaderDataLength, false); resultState.Invalidate(); return; } int stuffingBytes = (int)(pesHeaderDataEnd - reader.Position); if (stuffingBytes > 0) { // TODO issue 2323 MPEG-2 systems detector does not check header stuffing of private stream 1 if (streamId == 0xBD) { // Note: The format of these bytes is different! reader.SkipBytes(stuffingBytes); } else { reader.GetStuffingBytes(stuffingBytes); } } #endregion MPEG-2 } else { #region MPEG-1 reader.SetMpegFormat(CodecID.Mpeg1System); //FIXME: Attributes.Add(new FormattedAttribute<Attribute, bool>(Attribute.Mpeg2Flag, false)); uint maxUnknownByteCount = (uint)Mpeg2SystemDetector.Configurable[Mpeg2SystemDetector.ConfigurationKey.PesPacketMaxUnknownByteCount]; int count = 0; // Sanity check while (reader.ShowBits(1) == 1 && count++ < maxUnknownByteCount) { reader.GetBits(8); // TODO: attribute? } if (reader.ShowBits(2) == 0x1) { reader.GetBits(2, 0x1); reader.GetBits(1, Attribute.PStdBufferBoundScale); reader.GetBits(13, Attribute.PStdBufferSizeBound); } switch (reader.GetBits(4, Attribute.PtsDtsFlags)) { case 0: reader.GetBits(4, 0xF); break; case 2: reader.GetAttribute(_presentationTimeStampAttribute); break; case 3: reader.GetAttribute(_presentationTimeStampAttribute); reader.GetBits(4, 0x1); reader.GetAttribute(_decodingTimeStampAttribute); break; default: //reader.CheckAttribute(Attribute.PtsDtsFlags, false); break; } #endregion MPEG-1 } if (reader.Position >= pesPacketEnd) { // FIXME: reader.CheckAttribute(Attribute.PesPacketLength, reader.Position <= pesPacketEnd); resultState.Invalidate(); return; } int dataLength = (int)Math.Min((pesPacketEnd - reader.Position), reader.BytesRemaining); if (streamId == 0xBE) // Padding stream { // Read padding bytes if (reader.ShowBits(8) == 0x0F) { reader.GetByte(); // MPEG-1 padding stream dataLength--; } for (int i = 0; i < dataLength; i++) { if (reader.GetByte() != 0xFF) { // Truncate packet // TODO: reader.CheckAttribute(Attribute.PesPacketLength, reader.GetByte() == 0xFF, false)) pesPacketEnd = reader.Position - 1; reader.SkipBytes(dataLength - i - 1); break; } } } else { IDataPacket pesPacketData = reader.GetDataPacket(reader.Position, dataLength); reader.SkipBytes(dataLength); reader.State.Streams[streamId].AddPayload(pesPacketData); } // TODO: Check for truncated packet }