private AsfDataPacketPayloadObject parseAsfDataPacketPayloadObject(Stream inStream, long currentOffset, AsfDataPacketPayloadParsingObject payloadParsingObject, MpegStream.DemuxOptionsStruct demuxOptions) { AsfDataPacketPayloadObject packetPayloadObject = new AsfDataPacketPayloadObject(); uint bytesRead = 0; uint valueOffset = 0; uint packetLength; packetPayloadObject.StreamNumber = ParseFile.ParseSimpleOffset(inStream, currentOffset, 1)[0]; packetPayloadObject.KeyFrame = (byte)((packetPayloadObject.StreamNumber & 0x80) >> 7); packetPayloadObject.StreamNumber = (byte)(packetPayloadObject.StreamNumber & 0x7F); valueOffset += 1; packetPayloadObject.MediaObjectNumber = this.GetLengthTypeValue(inStream, currentOffset + valueOffset, payloadParsingObject.MediaObjectNumberLengthType, ref bytesRead); valueOffset += bytesRead; packetPayloadObject.OffsetIntoMediaObject = this.GetLengthTypeValue(inStream, currentOffset + valueOffset, payloadParsingObject.OffsetIntoMediaObjectLengthType, ref bytesRead); valueOffset += bytesRead; packetPayloadObject.ReplicatedDataLength = this.GetLengthTypeValue(inStream, currentOffset + valueOffset, payloadParsingObject.ReplicatedDataLengthType, ref bytesRead); valueOffset += bytesRead; if (packetPayloadObject.ReplicatedDataLength == 1) { throw new FormatException(String.Format("Error processing data packet payload at offset 0x{0}, compressed payloads are not supported.", currentOffset.ToString("X8"))); } // get replicated data packetPayloadObject.ReplicatedData = ParseFile.ParseSimpleOffset(inStream, currentOffset + valueOffset, (int)packetPayloadObject.ReplicatedDataLength); valueOffset += packetPayloadObject.ReplicatedDataLength; if (payloadParsingObject.MultiplePayloadsPresent) { packetPayloadObject.PayloadDataLength = this.GetLengthTypeValue(inStream, currentOffset + valueOffset, payloadParsingObject.PayloadLengthType, ref bytesRead); valueOffset += bytesRead; } else { packetLength = payloadParsingObject.PacketLengthType == LengthType.NotExist ? this.Header.FileProperties.MinimumPacketSize : payloadParsingObject.PacketLength; packetPayloadObject.PayloadDataLength = packetLength - payloadParsingObject.PacketOverheadLength - valueOffset - payloadParsingObject.PaddingLength; } packetPayloadObject.PayloadData = ParseFile.ParseSimpleOffset(inStream, currentOffset + valueOffset, (int)packetPayloadObject.PayloadDataLength); valueOffset += packetPayloadObject.PayloadDataLength; // set payload size and get raw block packetPayloadObject.PayloadSize = valueOffset; // packetPayloadObject.RawBlock = ParseFile.ParseSimpleOffset(inStream, currentOffset, (int)packetPayloadObject.PayloadSize); // write raw data to stream if ((demuxOptions.ExtractAudio) && this.IsAudioStream(packetPayloadObject.StreamNumber)) { this.writeChunkToStream(packetPayloadObject.PayloadData, (uint)packetPayloadObject.StreamNumber, this.FileExtensionAudio); } if ((demuxOptions.ExtractVideo) && this.IsVideoStream(packetPayloadObject.StreamNumber)) { this.writeChunkToStream(packetPayloadObject.PayloadData, (uint)packetPayloadObject.StreamNumber, this.FileExtensionVideo); } return(packetPayloadObject); }
private AsfDataPacketPayloadParsingObject parseAsfDataPacketPayloadParsingObject(Stream inStream, long currentOffset) { AsfDataPacketPayloadParsingObject dataPacketPayloadParsingObject = new AsfDataPacketPayloadParsingObject(); uint ErrCorrectBlockLength; uint bytesRead = 0; uint valueOffset = 0; // parse error correction info dataPacketPayloadParsingObject.ErrorCorrectionData = ParseFile.ParseSimpleOffset(inStream, currentOffset, 1)[0]; dataPacketPayloadParsingObject.IsErrorCorrectionPresent = (dataPacketPayloadParsingObject.ErrorCorrectionData & 0x80) == 0x80; if (dataPacketPayloadParsingObject.IsErrorCorrectionPresent) { dataPacketPayloadParsingObject.ErrorCorrectionLength = (byte)(dataPacketPayloadParsingObject.ErrorCorrectionData & 0x0F); } ErrCorrectBlockLength = 1u + dataPacketPayloadParsingObject.ErrorCorrectionLength; // parse Length Type Flags dataPacketPayloadParsingObject.LengthTypeFlags = ParseFile.ParseSimpleOffset(inStream, currentOffset + ErrCorrectBlockLength, 1)[0]; dataPacketPayloadParsingObject.MultiplePayloadsPresent = (dataPacketPayloadParsingObject.LengthTypeFlags & 1) == 1; dataPacketPayloadParsingObject.SequenceType = (LengthType)((dataPacketPayloadParsingObject.LengthTypeFlags & 0x6) >> 1); dataPacketPayloadParsingObject.PaddingLengthType = (LengthType)((dataPacketPayloadParsingObject.LengthTypeFlags & 0x18) >> 3); dataPacketPayloadParsingObject.PacketLengthType = (LengthType)((dataPacketPayloadParsingObject.LengthTypeFlags & 0x60) >> 5); if ((dataPacketPayloadParsingObject.LengthTypeFlags & 0x80) == 0x80) { throw new FormatException(String.Format("Error processing data packet at offset 0x{0}, error correction data found.", currentOffset.ToString("X8"))); } // parse Property Flags dataPacketPayloadParsingObject.PropertyFlags = ParseFile.ParseSimpleOffset(inStream, currentOffset + ErrCorrectBlockLength + 1, 1)[0]; dataPacketPayloadParsingObject.ReplicatedDataLengthType = (LengthType)(dataPacketPayloadParsingObject.PropertyFlags & 3); dataPacketPayloadParsingObject.OffsetIntoMediaObjectLengthType = (LengthType)((dataPacketPayloadParsingObject.PropertyFlags & 0x0C) >> 2); dataPacketPayloadParsingObject.MediaObjectNumberLengthType = (LengthType)((dataPacketPayloadParsingObject.PropertyFlags & 0x30) >> 4); dataPacketPayloadParsingObject.StreamNumberLengthType = (LengthType)((dataPacketPayloadParsingObject.PropertyFlags & 0xC0) >> 6); // get values valueOffset = 2; dataPacketPayloadParsingObject.PacketLength = GetLengthTypeValue(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, dataPacketPayloadParsingObject.PacketLengthType, ref bytesRead); valueOffset += bytesRead; dataPacketPayloadParsingObject.Sequence = GetLengthTypeValue(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, dataPacketPayloadParsingObject.SequenceType, ref bytesRead); valueOffset += bytesRead; dataPacketPayloadParsingObject.PaddingLength = GetLengthTypeValue(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, dataPacketPayloadParsingObject.PaddingLengthType, ref bytesRead); valueOffset += bytesRead; // get send time and dureation (not used right now, but why not?) dataPacketPayloadParsingObject.SendTime = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, 4), 0); valueOffset += sizeof(uint); dataPacketPayloadParsingObject.Duration = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, 2), 0); valueOffset += sizeof(ushort); if (dataPacketPayloadParsingObject.MultiplePayloadsPresent) { dataPacketPayloadParsingObject.PayloadFlags = ParseFile.ParseSimpleOffset(inStream, currentOffset + ErrCorrectBlockLength + valueOffset, 1)[0]; dataPacketPayloadParsingObject.PayloadLengthType = (LengthType)((dataPacketPayloadParsingObject.PayloadFlags & 0xC0) >> 6); dataPacketPayloadParsingObject.NumberOfPayloads = (byte)(dataPacketPayloadParsingObject.PayloadFlags & 0x3F); valueOffset += sizeof(byte); } else { // single payload dataPacketPayloadParsingObject.NumberOfPayloads = 1; } // calculate packet overhead and get raw header dataPacketPayloadParsingObject.PacketOverheadLength = ErrCorrectBlockLength + valueOffset; dataPacketPayloadParsingObject.RawBlock = ParseFile.ParseSimpleOffset(inStream, currentOffset, (int)dataPacketPayloadParsingObject.PacketOverheadLength); return(dataPacketPayloadParsingObject); }