Exemple #1
0
        private byte[] MakeOpenDMLStandardIndexChunk(List <StreamChunkInfo> chunkList, int start, int length, uint streamFourCC)
        {
            const byte AVI_INDEX_OF_CHUNKS = 0x01;

            long             baseOffset = chunkList[start].Offset + 8;
            AVISTDINDEX      header     = new AVISTDINDEX();
            AVISTDINDEXENTRY entry;

            byte[] buff    = new byte[OpenDMLStandardIndexSize((uint)length)];
            int    buffPos = 0;

            header.wLongsPerEntry = 2;
            header.bIndexSubType  = 0;
            header.bIndexType     = AVI_INDEX_OF_CHUNKS;
            header.nEntriesInUse  = (uint)length;
            header.dwChunkID      = streamFourCC;
            header.qwBaseOffset   = (ulong)baseOffset;

            buffPos += StructHelper <AVISTDINDEX> .ToBytes(header, buff, buffPos, false);

            for (int i = 0; i < length; i++)
            {
                StreamChunkInfo c = chunkList[start + i];

                entry.dwOffset = (uint)((c.Offset + 8) - baseOffset);
                entry.dwSize   = c.Size | (c.IsKeyFrame ? 0 : 0x80000000);

                BitConverterLE.WriteBytes(entry.dwOffset, buff, buffPos);
                BitConverterLE.WriteBytes(entry.dwSize, buff, buffPos + 4);
                buffPos += 8;
            }

            return(buff);
        }
Exemple #2
0
        private void MakeOpenDMLIndexes()
        {
            for (int iStream = 0; iStream < _streamList.Count; iStream++)
            {
                const byte AVI_INDEX_OF_INDEXES = 0x00;

                AVIStream stream = _streamList[iStream];
                List <StreamChunkInfo> chunkList = stream.ChunkList;

                AVISUPERINDEX      header = new AVISUPERINDEX();
                AVISUPERINDEXENTRY entry;
                int    entriesPerChunk, entryOffset, chunksLeft, buffPos;
                uint   indexChunkID = AVIHelper.StreamFourCC(AVIHelper.StreamID(stream.FourCC, false), "ix", true);
                byte[] buff;

                buffPos         = 0;
                buff            = new byte[OpenDMLSuperIndexSize(MaxOpenDMLSuperIndexEntries)];
                entriesPerChunk = (int)CalculateOpenDMLStandardIndexEntryCount(chunkList);
                entryOffset     = 0;
                chunksLeft      = chunkList.Count;

                header.wLongsPerEntry = 4;
                header.bIndexSubType  = 0;
                header.bIndexType     = AVI_INDEX_OF_INDEXES;
                header.nEntriesInUse  = (uint)((chunksLeft + (entriesPerChunk - 1)) / entriesPerChunk);
                header.dwChunkID      = stream.FourCC;

                if (header.nEntriesInUse > MaxOpenDMLSuperIndexEntries)
                {
                    throw new Exception("Too many super-index entries.");
                }

                buffPos += StructHelper <AVISUPERINDEX> .ToBytes(header, buff, buffPos, false);

                while (chunksLeft > 0)
                {
                    int    length = Math.Min(entriesPerChunk, chunksLeft);
                    byte[] tmp    = MakeOpenDMLStandardIndexChunk(chunkList, entryOffset, length,
                                                                  stream.FourCC);

                    CheckExtend((uint)tmp.Length);

                    entry.qwOffset   = (ulong)WriteChunk(indexChunkID, tmp);
                    entry.dwSize     = (uint)tmp.Length + 8;
                    entry.dwDuration = (stream.Type == AVIStreamType.Video) ? (uint)length :
                                       CalculateDuration(chunkList, entryOffset, length);

                    BitConverterLE.WriteBytes(entry.qwOffset, buff, buffPos);
                    BitConverterLE.WriteBytes(entry.dwSize, buff, buffPos + 8);
                    BitConverterLE.WriteBytes(entry.dwDuration, buff, buffPos + 12);
                    buffPos += 16;

                    entryOffset += length;
                    chunksLeft  -= length;
                }

                stream.OpenDMLSuperIndex = buff;
            }
        }
Exemple #3
0
        public static string FourCC(uint fourCC)
        {
            byte[] bytes = new byte[4];
            string s;

            BitConverterLE.WriteBytes(fourCC, bytes, 0);
            s = Encoding.ASCII.GetString(bytes).Replace('\0', ' ');
            return((s.Length == 4) ? s : new string(' ', 4));
        }
Exemple #4
0
 private void FinalizeLists()
 {
     byte[] hdr = new byte[4];
     foreach (ListInfo li in _closedLists)
     {
         Seek(li.Offset + 4);
         BitConverterLE.WriteBytes(li.Size, hdr, 0);
         _fs.Write(hdr, 0, 4);
     }
     _fileOffset += 4;
 }
Exemple #5
0
        private long StartList(string chunkID, string listType)
        {
            long offset = _fileOffset;

            byte[] hdr = new byte[12];
            _openLists.Push(offset);
            BitConverterLE.WriteBytes(AVIHelper.FourCC(chunkID), hdr, 0);
            BitConverterLE.WriteBytes((uint)0, hdr, 4);
            BitConverterLE.WriteBytes(AVIHelper.FourCC(listType), hdr, 8);
            _fs.Write(hdr, 0, 12);
            _fileOffset += 12;
            return(offset);
        }
Exemple #6
0
        private long WriteChunk(uint chunkID, byte[] data)
        {
            long offset = _fileOffset;

            byte[] hdr = new byte[8];
            uint   len = (uint)data.Length;

            BitConverterLE.WriteBytes(chunkID, hdr, 0);
            BitConverterLE.WriteBytes(len, hdr, 4);
            _fs.Write(hdr, 0, 8);
            _fs.Write(data, 0, (int)len);
            _fileOffset += (long)len + 8;
            if ((len & 1) != 0)
            {
                _fs.WriteByte(0);
                _fileOffset += 1;
            }
            return(offset);
        }
Exemple #7
0
        private byte[] MakeOldIndexChunk()
        {
            const uint AVIIF_KEYFRAME = 0x10;

            List <List <StreamChunkInfo> > cilList = new List <List <StreamChunkInfo> >();
            List <int>       cilIndex  = new List <int>();
            List <int>       cilLength = new List <int>();
            List <uint>      cilFourCC = new List <uint>();
            AVIOLDINDEXENTRY entry;

            byte[] buff;
            int    i, entryCount, buffPos, u;

            entryCount = 0;
            for (i = 0; i < _streamList.Count; i++)
            {
                AVIStream s = _streamList[i];

                if (s.ChunkList.Count > 0)
                {
                    cilList.Add(s.ChunkList);
                    cilIndex.Add(0);
                    cilLength.Add(s.ChunksInFirstMOVI);
                    cilFourCC.Add(s.FourCC);

                    entryCount += s.ChunksInFirstMOVI;
                }
            }

            buffPos = 0;
            buff    = new byte[entryCount * 16];
            while (entryCount > 0)
            {
                // Find the chunk with the lowest offset
                u = 0;
                for (i = 1; i < cilList.Count; i++)
                {
                    if (cilList[i][cilIndex[i]].Offset < cilList[u][cilIndex[u]].Offset)
                    {
                        u = i;
                    }
                }

                entry.dwChunkID = cilFourCC[u];
                entry.dwFlags   = cilList[u][cilIndex[u]].IsKeyFrame ? AVIIF_KEYFRAME : 0;
                entry.dwOffset  = (uint)(cilList[u][cilIndex[u]].Offset - (_moviOffset + 8));
                entry.dwSize    = cilList[u][cilIndex[u]].Size;

                BitConverterLE.WriteBytes(entry.dwChunkID, buff, buffPos);
                BitConverterLE.WriteBytes(entry.dwFlags, buff, buffPos + 4);
                BitConverterLE.WriteBytes(entry.dwOffset, buff, buffPos + 8);
                BitConverterLE.WriteBytes(entry.dwSize, buff, buffPos + 12);
                buffPos += 16;

                // If all the chunks from this stream have been written in the index,
                // stop checking this stream
                cilIndex[u]++;
                if (cilIndex[u] >= cilLength[u])
                {
                    cilList.RemoveAt(u);
                    cilIndex.RemoveAt(u);
                    cilLength.RemoveAt(u);
                    cilFourCC.RemoveAt(u);
                }

                entryCount--;
            }

            return(buff);
        }
Exemple #8
0
 private byte[] MakeDMLHChunk(uint dwTotalFrames)
 {
     byte[] buff = new byte[248];
     BitConverterLE.WriteBytes(dwTotalFrames, buff, 0);
     return(buff);
 }