private void WriteSuperIndex(ref AviSuperIndex superIndex, uint chunkId, int entriesToWrite) { // AviSuperIndex _bw.Write(FourCC.indx); _bw.Write(5U * sizeof(uint) + sizeof(ushort) + 2 * sizeof(byte) + SuperIndexCapacity * (uint)Marshal.SizeOf <AviSuperIndexEntry>()); _bw.Write((ushort)4); // wLongsPerEntry _bw.Write((byte)0); // bIndexSubType _bw.Write((byte)0); // bIndexType _bw.Write((uint)superIndex.EntriesInUse); // nEntriesInUse _bw.Write(chunkId); // dwChunkId for (var i = 0; i < 3; i++) // dwReserved { _bw.Write(0U); } for (var i = 0; i < entriesToWrite; i++) // aIndex { var entry = superIndex.SuperIndexEntries[i]; _bw.Write(entry.qwOffset); _bw.Write(entry.dwSize); _bw.Write(entry.dwDuration); } var bytesRemaining = (SuperIndexCapacity - entriesToWrite) * Marshal.SizeOf <AviSuperIndexEntry>(); if (bytesRemaining > 0) { _fs.Seek(bytesRemaining, SeekOrigin.Current); } }
private bool IndexChunk(ref AviSuperIndex superIndex, uint fcc, uint chunkId, int size, long chunk, bool keyFrame, int duration) { if (_firstRiff) { var oldIndexEntry = default(AviOldIndexEntry); oldIndexEntry.dwChunkId = chunkId; oldIndexEntry.dwFlags = keyFrame ? AviifKeyframe : 0; oldIndexEntry.dwOffset = (uint)(chunk - _currentMovi); oldIndexEntry.dwSize = (uint)size; _legacyIndex.Add(oldIndexEntry); } long relativeOffset; if (superIndex.LastIndexEntries.Count == 0 || (relativeOffset = chunk + ChunkHeaderSize - superIndex.LastBaseOffset) > uint.MaxValue) { if (superIndex.LastIndexEntries.Count > 0 && !FlushStandardIndex(ref superIndex, fcc, chunkId)) { return(false); } superIndex.LastBaseOffset = chunk + ChunkHeaderSize; relativeOffset = 0; } var stdIndexEntry = default(AviStdIndexEntry); stdIndexEntry.dwOffset = (uint)relativeOffset; stdIndexEntry.dwSize = keyFrame ? (uint)size : (uint)size | 0x80000000; superIndex.LastIndexEntries.Add(stdIndexEntry); superIndex.SuperIndexEntries[superIndex.EntriesInUse].dwDuration += (uint)duration; return(true); }
private AviFileWriter(string path, int frameRate, uint videoChunkId, uint videoFccHandler, uint videoSampleSize, BitmapInfo videoFormat, bool audio) { _fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None); _bw = new BinaryWriter(_fs, Encoding.ASCII, true); _frameRate = frameRate; _videoChunkId = videoChunkId; _videoFccHandler = videoFccHandler; _videoSampleSize = videoSampleSize; _videoFormat = videoFormat; _audio = audio; _videoLengthInFirstRiff = 0; _videoLength = 0; _videoChunkMaxSize = 0; _audioLength = 0; _audioChunkMaxSize = 0; _legacyIndex = new List <AviOldIndexEntry>(OldIndexInitialCapacity); _videoSuperIndex = new AviSuperIndex(SuperIndexCapacity, StandardIndexInitialCapacity); if (audio) { _audioSuperIndex = new AviSuperIndex(SuperIndexCapacity, StandardIndexInitialCapacity); } try { CreateFirstRiff(); } catch (Exception) { _bw.Dispose(); _fs.Dispose(); throw; } }
private bool FlushStandardIndex(ref AviSuperIndex superIndex, uint fcc, uint chunkId) { if (superIndex.LastIndexEntries.Count == 0) { return(true); } if (superIndex.EntriesInUse >= SuperIndexCapacity) { return(false); } var pos = (ulong)_fs.Position; var size = sizeof(ulong) + 3U * sizeof(uint) + sizeof(ushort) + 2U * sizeof(byte) + (uint)superIndex.LastIndexEntries.Count * 2 * sizeof(uint); // AviStdIndex _bw.Write(fcc); _bw.Write(size); _bw.Write((ushort)2); // wLongsPerEntry _bw.Write((byte)0); // bIndexSubType _bw.Write((byte)1); // bIndexType _bw.Write((uint)superIndex.LastIndexEntries.Count); // nEntriesInUse _bw.Write(chunkId); // dwChunkId _bw.Write(superIndex.LastBaseOffset); // qwBaseOffset _bw.Write(0); // dwReserved_3 foreach (var entry in superIndex.LastIndexEntries) // aIndex { _bw.Write(entry.dwOffset); _bw.Write(entry.dwSize); } superIndex.LastIndexEntries.Clear(); superIndex.SuperIndexEntries[superIndex.EntriesInUse].qwOffset = pos; superIndex.SuperIndexEntries[superIndex.EntriesInUse].dwSize = ChunkHeaderSize + size; superIndex.EntriesInUse++; return(true); }