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; } } }