Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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);
        }