Пример #1
0
        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));
        }
Пример #2
0
 public void SetStreamHeader(int streamID, AVISTREAMHEADER header)
 {
     _streamList[streamID].Header = header;
 }
Пример #3
0
        private void ReadHeaders()
        {
            uint chunkID, dataSize, listType;
            long chunkOffset, firstRIFFEnd, moviEnd;

            byte[] data;
            bool   inMOVI;

            moviEnd = -1;

            chunkOffset = ReadChunkHeader(out chunkID, out dataSize, out listType);
            if ((chunkOffset == -1) || (chunkID != AVIHelper.FourCC("RIFF")) ||
                (listType != AVIHelper.FourCC("AVI ")))
            {
                throw new Exception("File isn't an AVI.");
            }
            firstRIFFEnd = _fileOffset + dataSize;

            while (_fileOffset < firstRIFFEnd)
            {
                chunkOffset = ReadChunkHeader(out chunkID, out dataSize, out listType);
                if (chunkOffset == -1)
                {
                    break;
                }

                if (chunkID == ckIDLIST)
                {
                    if (listType == AVIHelper.FourCC("movi"))
                    {
                        if (_videoStreamID == -1)
                        {
                            throw new Exception("Video stream not found.");
                        }
                        _moviOffset = chunkOffset;
                        moviEnd     = _fileOffset + dataSize;
                    }
                    continue;
                }

                inMOVI = (_moviOffset != -1) && (chunkOffset >= _moviOffset) && (chunkOffset < moviEnd);

                if (!inMOVI)
                {
                    data = ReadChunkData(dataSize);
                    if (data.Length < dataSize)
                    {
                        break;
                    }
                }
                else
                {
                    SkipChunkData(dataSize);
                    data = null;
                }

                if (chunkID == AVIHelper.FourCC("strh"))
                {
                    AVISTREAMHEADER strH = StructHelper <AVISTREAMHEADER> .FromBytes(data, 0, false);

                    AVIStream s;

                    if (strH.fccType == AVIHelper.FourCC("vids"))
                    {
                        s = new AVIStream(AVIStreamType.Video);
                        if (_videoStreamID == -1)
                        {
                            _videoStreamID = _streamList.Count;
                        }
                    }
                    else if (strH.fccType == AVIHelper.FourCC("auds"))
                    {
                        s = new AVIStream(AVIStreamType.Audio);
                    }
                    else
                    {
                        s = new AVIStream(AVIStreamType.Other);
                    }

                    s.Header = strH;
                    _streamList.Add(s);
                }
                if (chunkID == AVIHelper.FourCC("strf"))
                {
                    AVIStream stream  = _streamList[_streamList.Count - 1];
                    int       fmtSize = 0;
                    int       fmtExtraSize;

                    if (stream.Type == AVIStreamType.Video)
                    {
                        stream.VideoFormat = StructHelper <BITMAPINFOHEADER> .FromBytes(data, 0, false);

                        fmtSize = StructHelper <BITMAPINFOHEADER> .SizeOf;
                    }
                    else if (stream.Type == AVIStreamType.Audio)
                    {
                        stream.AudioFormat = StructHelper <WAVEFORMATEX> .FromBytes(data, 0, false);

                        fmtSize = StructHelper <WAVEFORMATEX> .SizeOf;
                    }
                    else
                    {
                        fmtSize = 0;
                    }

                    fmtExtraSize = data.Length - fmtSize;
                    if (fmtExtraSize > 0)
                    {
                        stream.FormatExtra = new byte[fmtExtraSize];
                        Buffer.BlockCopy(data, fmtSize, stream.FormatExtra, 0, fmtExtraSize);
                    }
                }
                if (chunkID == AVIHelper.FourCC("strn"))
                {
                    _streamList[_streamList.Count - 1].STRNData = data;
                }
                if (inMOVI && (AVIHelper.StreamID(chunkID, false) == _videoStreamID))
                {
                    _firstVideoChunkOffset = chunkOffset;
                    Seek(moviEnd);
                }
                if (chunkID == AVIHelper.FourCC("indx"))
                {
                    _isOpenDML  = true;
                    _foundIndex = ParseOpenDMLIndex(data);
                }
                if (chunkID == AVIHelper.FourCC("idx1"))
                {
                    if (!_isOpenDML)
                    {
                        ParseOldIndex(data);
                        _foundIndex = true;
                    }
                }
            }
            if (_moviOffset == -1)
            {
                throw new Exception("\"movi\" list not found.");
            }

            SeekToStart();
        }