public virtual void SaveIndex() { if (BlockIndex == null || BlockIndex.Length == 0) { return; } MLVTypes.mlv_file_hdr_t fileHeader = ReadMainHeader(); MLVTypes.mlv_xref_hdr_t xrefHdr = new MLVTypes.mlv_xref_hdr_t(); /* update MLVI header */ fileHeader.blockSize = (uint)Marshal.SizeOf(fileHeader); fileHeader.videoFrameCount = 0; fileHeader.audioFrameCount = 0; fileHeader.fileNum = (ushort)FileNames.Length; /* create XREF block */ xrefHdr.blockType = "XREF"; xrefHdr.blockSize = (uint)(Marshal.SizeOf(xrefHdr) + BlockIndex.Length * Marshal.SizeOf(new MLVTypes.mlv_xref_t())); xrefHdr.timestamp = 1; xrefHdr.frameType = 3; /* video+audio */ xrefHdr.entryCount = (uint)BlockIndex.Length; /* open file */ BinaryWriter writer = new BinaryWriter(new FileStream(IndexName, FileMode.Create, FileAccess.Write)); writer.Write(MLVTypes.ToByteArray(fileHeader)); writer.Write(MLVTypes.ToByteArray(xrefHdr)); foreach (var entry in BlockIndex) { MLVTypes.mlv_xref_t xrefEntry = new MLVTypes.mlv_xref_t(); xrefEntry.fileNumber = (ushort)entry.fileNumber; xrefEntry.frameOffset = (ulong)entry.position; xrefEntry.empty = 0; switch (entry.type) { case "VIDF": xrefEntry.frameType = 1; break; case "AUDF": xrefEntry.frameType = 2; break; default: xrefEntry.frameType = 0; break; } writer.Write(MLVTypes.ToByteArray(xrefEntry)); } writer.Close(); }
private void LoadIndex() { BinaryReader index = new BinaryReader(File.Open(IndexName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); /* read MLV block header */ byte[] mlvBlockBuf = ReadBlockData(index); MLVTypes.mlv_file_hdr_t fileHeader = (MLVTypes.mlv_file_hdr_t)MLVTypes.ToStruct("MLVI", mlvBlockBuf); MLVTypes.mlv_file_hdr_t mainHeader = ReadMainHeader(); if (mainHeader.fileGuid != fileHeader.fileGuid) { throw new Exception("GUID mismatch"); } byte[] xrefBlockBuf = ReadBlockData(index); MLVTypes.mlv_xref_hdr_t xrefHeader = (MLVTypes.mlv_xref_hdr_t)MLVTypes.ToStruct("XREF", xrefBlockBuf); BlockIndex = new xrefEntry[xrefHeader.entryCount]; int entrySize = Marshal.SizeOf(new MLVTypes.mlv_xref_t()); for (int pos = 0; pos < xrefHeader.entryCount; pos++) { MLVTypes.mlv_xref_t xrefEntry = (MLVTypes.mlv_xref_t)MLVTypes.ToStruct("XREF_ENTRY", xrefBlockBuf, Marshal.SizeOf(xrefHeader) + pos * entrySize); BlockIndex[pos] = new xrefEntry(); BlockIndex[pos].fileNumber = xrefEntry.fileNumber; BlockIndex[pos].position = (long)xrefEntry.frameOffset; BlockIndex[pos].size = 0; switch (xrefEntry.frameType) { case 0: BlockIndex[pos].type = ""; break; case 1: BlockIndex[pos].type = "VIDF"; break; case 2: BlockIndex[pos].type = "AUDF"; break; } } }
public void HandleBlock(string type, MLVTypes.mlv_file_hdr_t header, byte[] raw_data, int raw_pos, int raw_length) { FileHeader = header; }
private bool FilesValid() { MLVTypes.mlv_file_hdr_t mainFileHeader; mainFileHeader.fileGuid = 0; for (int fileNum = 0; fileNum < Reader.Length; fileNum++) { byte[] buf = new byte[16]; Reader[fileNum].BaseStream.Position = 0; /* read MLV block header */ if (Reader[fileNum].Read(buf, 0, 16) != 16) { break; } string type = Encoding.UTF8.GetString(buf, 0, 4); if (type != "MLVI") { MessageBox.Show("File '" + FileNames[fileNum] + "' has a invalid header."); return(false); } /* seems to be a valid header, proceed */ UInt32 length = BitConverter.ToUInt32(buf, 4); UInt64 timestamp = BitConverter.ToUInt64(buf, 8); /* resize buffer to the block size */ Array.Resize <byte>(ref buf, (int)length); /* now read the rest of the block */ if (Reader[fileNum].Read(buf, 16, (int)length - 16) != (int)length - 16) { MessageBox.Show("File '" + FileNames[fileNum] + "' has a invalid header."); return(false); } MLVTypes.mlv_file_hdr_t hdr = (MLVTypes.mlv_file_hdr_t)MLVTypes.ToStruct(type, buf); if (hdr.versionString != "v2.0") { MessageBox.Show("File '" + FileNames[fileNum] + "' has a invalid version '" + hdr.versionString + "'."); return(false); } if (fileNum == 0) { mainFileHeader = hdr; } else { if (mainFileHeader.fileGuid != hdr.fileGuid) { MessageBox.Show("File '" + FileNames[fileNum] + "' has a different GUID from the main .MLV. Please delete or rename it to fix that issue."); return(false); } } } return(true); }