public Trak(Stream fs, ulong maximumLength, TreeNode root) { Position = (ulong)fs.Position; while (fs.Position < (long)maximumLength) { if (!InitializeSizeAndName(fs)) { return; } if (Name == "mdia") { var mdiaNode = new TreeNode(Name) { Tag = "Element: " + Name + " - " + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }; Mdia = new Mdia(fs, Position, mdiaNode); root.Nodes.Add(mdiaNode); } else if (Name == "tkhd") { Tkhd = new Tkhd(fs); root.Nodes.Add(new TreeNode(Name) { Tag = "Element: " + Name + " - " + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }); } fs.Seek((long)Position, SeekOrigin.Begin); } }
public Minf(Stream fs, ulong maximumLength, ulong timeScale, string handlerType, Mdia mdia, TreeNode root) { Position = (ulong)fs.Position; while (fs.Position < (long)maximumLength) { if (!InitializeSizeAndName(fs)) { return; } if (Name == "stbl") { var stblNode = new TreeNode(Name) { Tag = "Element: " + Name + " - Sample Table" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }; Stbl = new Stbl(fs, Position, timeScale, handlerType, mdia, stblNode); root.Nodes.Add(stblNode); } else if (Name == "sthd") { var stblNode = new TreeNode(Name) { Tag = "Element: " + Name + " - Subtitle Media Header" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }; root.Nodes.Add(stblNode); } fs.Seek((long)Position, SeekOrigin.Begin); } }
public Stbl(Stream fs, ulong maximumLength, ulong timeScale, string handlerType, Mdia mdia, TreeNode root) { _mdia = mdia; Position = (ulong)fs.Position; while (fs.Position < (long)maximumLength) { if (!InitializeSizeAndName(fs)) { return; } if (Name == "stco") // 32-bit - chunk offset { Buffer = new byte[Size - 4]; fs.Read(Buffer, 0, Buffer.Length); int version = Buffer[0]; uint totalEntries = GetUInt(4); var sbTexts = new StringBuilder(); uint lastOffset = 0; for (int i = 0; i < totalEntries; i++) { uint offset = GetUInt(8 + i * 4); if (lastOffset + 5 < offset) { var s = ReadText(fs, offset, handlerType); sbTexts.AppendLine($" {i} - {s}"); } lastOffset = offset; } root.Nodes.Add(new TreeNode(Name) { Tag = "Element: " + Name + " - Chunk Offset" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition + Environment.NewLine + "Total entries: " + totalEntries + "Texts: " + sbTexts }); } else if (Name == "co64") // 64-bit { Buffer = new byte[Size - 4]; fs.Read(Buffer, 0, Buffer.Length); int version = Buffer[0]; uint totalEntries = GetUInt(4); ulong lastOffset = 0; for (int i = 0; i < totalEntries; i++) { ulong offset = GetUInt64(8 + i * 8); if (lastOffset + 8 < offset) { ReadText(fs, offset, handlerType); } lastOffset = offset; } var co64Node = new TreeNode(Name) { Tag = "Element: " + Name + " - " + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }; root.Nodes.Add(co64Node); } else if (Name == "stsz") // sample sizes { var sbSampleSizes = new StringBuilder(); Buffer = new byte[Size - 4]; fs.Read(Buffer, 0, Buffer.Length); int version = Buffer[0]; uint uniformSizeOfEachSample = GetUInt(4); uint numberOfSampleSizes = GetUInt(8); StszSampleCount = numberOfSampleSizes; for (int i = 0; i < numberOfSampleSizes; i++) { if (12 + i * 4 + 4 < Buffer.Length) { uint sampleSize = GetUInt(12 + i * 4); sbSampleSizes.AppendLine($" {i} - Sample size: {sampleSize}"); } } root.Nodes.Add(new TreeNode(Name) { Tag = "Element: " + Name + " - Sample Size Box" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition + Environment.NewLine + "Sample sizes:" + Environment.NewLine + sbSampleSizes }); } else if (Name == "stts") // sample table time to sample map { //https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-SW1 Buffer = new byte[Size - 4]; fs.Read(Buffer, 0, Buffer.Length); int version = Buffer[0]; uint numberOfSampleTimes = GetUInt(4); double totalTime = 0; var sbTimeToSample = new StringBuilder(); if (_mdia.IsClosedCaption) { for (int i = 0; i < numberOfSampleTimes; i++) { uint sampleCount = GetUInt(8 + i * 8); uint sampleDelta = GetUInt(12 + i * 8); sbTimeToSample.AppendLine($" {i} - {sampleCount} - {sampleDelta}"); for (int j = 0; j < sampleCount; j++) { totalTime += sampleDelta / (double)timeScale; if (StartTimeCodes.Count > 0) { EndTimeCodes[EndTimeCodes.Count - 1] = totalTime - 0.001; } StartTimeCodes.Add(totalTime); EndTimeCodes.Add(totalTime + 2.5); } } } else { for (int i = 0; i < numberOfSampleTimes; i++) { uint sampleCount = GetUInt(8 + i * 8); uint sampleDelta = GetUInt(12 + i * 8); sbTimeToSample.AppendLine($" {i} - {sampleCount} - {sampleDelta}"); totalTime += sampleDelta / (double)timeScale; if (StartTimeCodes.Count <= EndTimeCodes.Count) { StartTimeCodes.Add(totalTime); } else { EndTimeCodes.Add(totalTime); } } } root.Nodes.Add(new TreeNode(Name) { Tag = "Element: " + Name + " - Decoding, Time to Sample" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition + Environment.NewLine + "Number of samples: " + numberOfSampleTimes + Environment.NewLine + "Samples: " + Environment.NewLine + sbTimeToSample }); } else if (Name == "stsc") // sample table sample to chunk map { Buffer = new byte[Size - 4]; fs.Read(Buffer, 0, Buffer.Length); int version = Buffer[0]; uint numberOfSampleTimes = GetUInt(4); for (int i = 0; i < numberOfSampleTimes; i++) { if (16 + i * 12 + 4 < Buffer.Length) { uint firstChunk = GetUInt(8 + i * 12); uint samplesPerChunk = GetUInt(12 + i * 12); uint sampleDescriptionIndex = GetUInt(16 + i * 12); } } root.Nodes.Add(new TreeNode(Name) { Tag = "Element: " + Name + " - Sample‐to‐Chunk" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition + Environment.NewLine + "Number of samples: " + numberOfSampleTimes }); } else if (Name == "stsd") { var stsdNode = new TreeNode(Name) { Tag = "Element: " + Name + " - Sample Description Box" + Environment.NewLine + "Size: " + Size + Environment.NewLine + "Position: " + StartPosition }; var stsd = new Stsd(fs, Position, stsdNode); root.Nodes.Add(stsdNode); } fs.Seek((long)Position, SeekOrigin.Begin); } }