private void WriteHeaders() { const uint AVIF_HASINDEX = 0x00000010; const uint AVIF_ISINTERLEAVED = 0x00000100; AVIMAINHEADER aviH = new AVIMAINHEADER(); AVIStream vidStr = _streamList[_videoStreamID]; AVISTREAMHEADER vidStrH = vidStr.Header; BITMAPINFOHEADER vidStrF = vidStr.VideoFormat; if (vidStrH.dwRate != 0) { aviH.dwMicroSecPerFrame = Convert.ToUInt32(((double)vidStrH.dwScale / vidStrH.dwRate) * 1000000.0); } aviH.dwFlags = AVIF_HASINDEX | AVIF_ISINTERLEAVED; aviH.dwTotalFrames = (uint)vidStr.ChunksInFirstMOVI; aviH.dwStreams = (uint)_streamList.Count; aviH.dwWidth = (uint)vidStrF.biWidth; aviH.dwHeight = (uint)Math.Abs(vidStrF.biHeight); Seek(_avihOffset); WriteChunk("avih", StructHelper <AVIMAINHEADER> .ToBytes(aviH, false)); for (int i = 0; i < _streamList.Count; i++) { AVIStream s = _streamList[i]; AVISTREAMHEADER sHeader = s.Header; sHeader.dwLength = (s.Type == AVIStreamType.Video) ? (uint)s.ChunkList.Count : CalculateDuration(s.ChunkList, 0, s.ChunkList.Count); sHeader.dwSuggestedBufferSize = FindLargestChunk(s.ChunkList); Seek(s.STRHOffset); WriteChunk("strh", StructHelper <AVISTREAMHEADER> .ToBytes(sHeader, false)); Seek(s.STRFOffset); WriteChunk("strf", s.MakeSTRFChunk()); if (s.OpenDMLSuperIndex != null) { Seek(s.INDXOffset); WriteChunk("indx", s.OpenDMLSuperIndex); } } Seek(_dmlhOffset); WriteChunk("dmlh", MakeDMLHChunk((uint)vidStr.ChunkList.Count)); }
private void StartFile() { if (_videoStreamID == -1) { throw new Exception("AVI must have a video stream."); } _isFileStarted = true; _riffOffset = StartList("RIFF", "AVI "); StartList("LIST", "hdrl"); _avihOffset = WriteChunk("avih", (uint)StructHelper <AVIMAINHEADER> .SizeOf); for (int i = 0; i < _streamList.Count; i++) { AVIStream s = _streamList[i]; StartList("LIST", "strl"); s.STRHOffset = WriteChunk("strh", (uint)StructHelper <AVISTREAMHEADER> .SizeOf); s.STRFOffset = WriteChunk("strf", s.MakeSTRFChunk()); if (s.STRNData != null) { WriteChunk("strn", s.STRNData); } s.INDXOffset = WriteChunk("JUNK", OpenDMLSuperIndexSize(MaxOpenDMLSuperIndexEntries)); EndList(); } StartList("LIST", "odml"); _dmlhOffset = WriteChunk("dmlh", MakeDMLHChunk(0)); EndList(); EndList(); // 'hdrl' // Pad to a multiple of 2K (8K at least) if ((_fileOffset < 8192) || ((_fileOffset % 2048) != 0)) { int paddingStart = (int)_fileOffset + 8; int toNext2K = (2048 - (paddingStart % 2048)) % 2048; int to8K = 8192 - paddingStart; WriteChunk("JUNK", (uint)Math.Max(to8K, toNext2K)); } _moviOffset = StartList("LIST", "movi"); }