예제 #1
0
        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));
        }
예제 #2
0
        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());
        }
예제 #3
0
        internal byte[] ReadAtom([NotNull] AtomInfo atom)
        {
            _stream.Position = atom.Start;

            using (var reader = new Mp4Reader(_stream))
                return(reader.ReadBytes((int)atom.Size));
        }
예제 #4
0
        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);
        }