private void ParseOldIndex(byte[] data) { const uint AVIIF_KEYFRAME = 0x10; int dataPos = 0; StreamChunkInfo chunkInfo = new StreamChunkInfo(); AVIOLDINDEXENTRY entry; int streamID; long firstVideoChunkOffset = -1; long offsetCorrection; while (dataPos <= (data.Length - 16)) { entry.dwChunkID = BitConverterLE.ToUInt32(data, dataPos); entry.dwFlags = BitConverterLE.ToUInt32(data, dataPos + 4); entry.dwOffset = BitConverterLE.ToUInt32(data, dataPos + 8); entry.dwSize = BitConverterLE.ToUInt32(data, dataPos + 12); dataPos += 16; streamID = AVIHelper.StreamID(entry.dwChunkID, false); if ((streamID == -1) || (streamID >= _streamList.Count)) { continue; } if (_streamList[streamID].FourCC == 0) { _streamList[streamID].FourCC = entry.dwChunkID; } chunkInfo.Offset = (long)entry.dwOffset; chunkInfo.Size = entry.dwSize; chunkInfo.IsKeyFrame = (entry.dwFlags & AVIIF_KEYFRAME) != 0; if ((firstVideoChunkOffset == -1) && (streamID == _videoStreamID)) { firstVideoChunkOffset = chunkInfo.Offset; } _streamList[streamID].ChunkList.Add(chunkInfo); } if ((_firstVideoChunkOffset == -1) || (firstVideoChunkOffset == -1)) { throw new Exception("Video stream not found."); } // Add 8 because the offset needs to point to the start of the data offsetCorrection = (_firstVideoChunkOffset - firstVideoChunkOffset) + 8; foreach (AVIStream stream in _streamList) { for (int i = 0; i < stream.ChunkList.Count; i++) { chunkInfo = stream.ChunkList[i]; chunkInfo.Offset += offsetCorrection; stream.ChunkList[i] = chunkInfo; } } }
private bool ParseOpenDMLSuperIndex(byte[] data) { AVISUPERINDEX header; AVISUPERINDEXENTRY entry; int dataPos = 0; long oldOffset = _fileOffset; uint chunkID, dataSize, listType; byte[] standardIndex; header = StructHelper <AVISUPERINDEX> .FromBytes(data, 0, false); dataPos += StructHelper <AVISUPERINDEX> .SizeOf; while (dataPos <= (data.Length - 16)) { if (header.nEntriesInUse == 0) { break; } entry.qwOffset = BitConverterLE.ToUInt64(data, dataPos); entry.dwSize = BitConverterLE.ToUInt32(data, dataPos + 8); entry.dwDuration = BitConverterLE.ToUInt32(data, dataPos + 12); dataPos += 16; Seek((long)entry.qwOffset); if (ReadChunkHeader(out chunkID, out dataSize, out listType) == -1) { return(false); } standardIndex = ReadChunkData(dataSize); if (standardIndex.Length < dataSize) { return(false); } ParseOpenDMLStandardIndex(standardIndex); header.nEntriesInUse--; } Seek(oldOffset); return(true); }
private void ParseOpenDMLStandardIndex(byte[] data) { AVISTDINDEX header; AVISTDINDEXENTRY entry; int dataPos = 0; int streamID; List <StreamChunkInfo> chunkList; StreamChunkInfo ci = new StreamChunkInfo(); header = StructHelper <AVISTDINDEX> .FromBytes(data, 0, false); dataPos += StructHelper <AVISTDINDEX> .SizeOf; streamID = AVIHelper.StreamID(header.dwChunkID, false); if ((streamID == -1) || (streamID >= _streamList.Count)) { throw new Exception("Invalid chunk ID in OpenDML standard index."); } if (_streamList[streamID].FourCC == 0) { _streamList[streamID].FourCC = header.dwChunkID; } chunkList = _streamList[streamID].ChunkList; while (dataPos <= (data.Length - 8)) { if (header.nEntriesInUse == 0) { break; } entry.dwOffset = BitConverterLE.ToUInt32(data, dataPos); entry.dwSize = BitConverterLE.ToUInt32(data, dataPos + 4); dataPos += 8; ci.Offset = (long)(header.qwBaseOffset + entry.dwOffset); ci.Size = entry.dwSize & 0x7FFFFFFF; ci.IsKeyFrame = ((entry.dwSize & 0x80000000) == 0); chunkList.Add(ci); header.nEntriesInUse--; } }
private long ReadChunkHeader(out uint chunkID, out uint dataSize, out uint listType) { long offset = _fileOffset; long remaining = _fileLength - _fileOffset; byte[] hdr = new byte[8]; chunkID = 0; dataSize = 0; listType = 0; if (remaining < 8) { return(-1); } _fs.Read(hdr, 0, 8); _fileOffset += 8; chunkID = BitConverterLE.ToUInt32(hdr, 0); dataSize = BitConverterLE.ToUInt32(hdr, 4); if ((chunkID == ckIDLIST) || (chunkID == ckIDRIFF)) { if (remaining < 12) { return(-1); } _fs.Read(hdr, 0, 4); _fileOffset += 4; listType = BitConverterLE.ToUInt32(hdr, 0); dataSize -= 4; } else { listType = 0; } return(offset); }
public static uint FourCC(string fourCC) { byte[] bytes = Encoding.ASCII.GetBytes(fourCC); return((bytes.Length == 4) ? BitConverterLE.ToUInt32(bytes, 0) : 0x20202020); }