internal bool DescendToAtom([NotNull, ItemNotNull] params string[] hierarchy) { Reset(); using (var reader = new Mp4Reader(_stream)) { foreach (var fourCc in hierarchy) { do { var subAtom = new AtomInfo((uint)_stream.Position, reader.ReadUInt32BigEndian(), reader.ReadFourCc()); if (subAtom.End > _stream.Length) { throw new EndOfStreamException($"{fourCc} atom is missing."); } if (fourCc.Equals(subAtom.FourCc, StringComparison.Ordinal)) { _atomInfoStack.Push(subAtom); _stream.Seek(GetDataLength(fourCc), SeekOrigin.Current); break; } _stream.Position = subAtom.End; } while (_stream.Position < (_atomInfoStack.Count == 0 ? _stream.Length : _atomInfoStack.Peek().End)); } } return(hierarchy.Last().Equals(_atomInfoStack.Peek().FourCc, StringComparison.Ordinal)); }
internal AtomInfo[] GetChildAtomInfo() { var result = new List <AtomInfo>(); using (var reader = new Mp4Reader(_stream)) { _stream.Position = _atomInfoStack.Count == 0 ? 0 : _atomInfoStack.Peek().Start + 8 + GetDataLength(_atomInfoStack.Peek().FourCc); while (_stream.Position < (_atomInfoStack.Count == 0 ? _stream.Length : _atomInfoStack.Peek().End)) { var childAtom = new AtomInfo( (uint)_stream.Position, reader.ReadUInt32BigEndian(), reader.ReadFourCc()); // The stream might be padded with empty space if (childAtom.FourCc.Equals("\0\0\0\0", StringComparison.Ordinal)) { _stream.Position = result.Count > 0 ? result.Last().End : 0; break; } result.Add(childAtom); _stream.Position = childAtom.End; } } return(result.ToArray()); }
internal byte[] ReadAtom([NotNull] AtomInfo atom) { _stream.Position = atom.Start; using (var reader = new Mp4Reader(_stream)) return(reader.ReadBytes((int)atom.Size)); }
internal void CopyAtom([NotNull] AtomInfo atom, [NotNull] Stream output) { _stream.Position = atom.Start; var count = (int)atom.Size; var buffer = new byte[1024]; do { var read = _stream.Read(buffer, 0, Math.Min(buffer.Length, count)); output.Write(buffer, 0, read); count -= read; } while (count > 0); }