예제 #1
0
        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();
        }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
 public void HandleBlock(string type, MLVTypes.mlv_file_hdr_t header, byte[] raw_data, int raw_pos, int raw_length)
 {
     FileHeader = header;
 }
예제 #4
0
        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);
        }