123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.IO;
- using MatrixIO.IO.Bmff;
- namespace MatrixIO.IO.Bmff
- {
- public class BmffReader : ISuperBox, IEnumerable<Box>
- {
- private readonly Stream _baseStream;
- public Stream BaseStream { get { return _baseStream; } }
- private IList<Box> _rootBoxes;
- public IList<Box> RootBoxes
- {
- get
- {
- #pragma warning disable 612,618
- if (_rootBoxes == null) return _rootBoxes = Portability.CreateList<Box>(GetBoxes());
- #pragma warning restore 612,618
- return _rootBoxes;
- }
- }
- public bool RandomAccess { get { return _baseStream.CanSeek; } }
- #region Navigation
- private readonly Stack<Box> _boxStack = new Stack<Box>();
- public int Depth
- {
- get
- {
- return _boxStack.Count;
- }
- }
- public Box CurrentBox
- {
- get
- {
- return _boxStack.Peek();
- }
- }
- public bool HasChildren
- {
- get
- {
- if (CurrentBox is ISuperBox) return true;
- else return false;
- }
- }
- #endregion
- public BmffReader(Stream stream)
- {
- if (stream.CanSeek && stream.Position!=0) stream.Seek(0, SeekOrigin.Begin);
- _baseStream = stream;
- }
- [Obsolete("Use the BaseMedia class instead.")]
- public void Scan()
- {
- GetBoxes();
- }
- /// <summary>
- /// Traverses the tree of Boxes in file order (depth-first)
- /// </summary>
- /// <returns>IEnumerable collection of Box types in file order.</returns>
- [Obsolete("Use the BaseMedia class instead.")]
- public IEnumerable<Box> GetBoxes()
- {
- Box box = null;
- do
- {
- box = Box.FromStream(_baseStream);
- if (box != null) yield return box;
- } while (box != null);
- }
- /// <summary>
- /// Seeks to the beginning of the file and reads the "ftyp" Box.
- /// </summary>
- /// <returns>FileTypeBox</returns>
- [Obsolete]
- public Boxes.FileTypeBox GetFileTypeBox()
- {
- if (_baseStream.CanSeek && _baseStream.Position!=0) _baseStream.Seek(0, SeekOrigin.Begin);
- // TODO: Support files where "ftyp" is not the first FourCC like JPEG2000.
- return Box.FromStream<Boxes.FileTypeBox>(_baseStream);
- }
- /// <summary>
- /// Seek to the end of the file and returns the "mfro" Box for a Microsoft Smooth Streaming PIFF format file that gives
- /// you the chunk offsets within the file.
- /// </summary>
- /// <returns>MovieFragmentRandomAccessBox</returns>
- // TODO: Move to a new MatrixIO.IO.Piff.??? class
- public Boxes.MovieFragmentRandomAccessBox GetMovieFragmentRandomAccessBox()
- {
- _baseStream.Seek(-24, SeekOrigin.End);
- byte[] mfrobuf = _baseStream.ReadBytes(24);
- uint mfraOffset;
- if (BitConverter.ToUInt32(mfrobuf, 12).NetworkToHostOrder() == 0x6d66726f ||
- BitConverter.ToUInt32(mfrobuf, 4).NetworkToHostOrder() == 0x6d66726f) // 'mfro'
- {
- mfraOffset = BitConverter.ToUInt32(mfrobuf, 20).NetworkToHostOrder();
- }
- else return null;
- _baseStream.Seek(-mfraOffset, SeekOrigin.End);
- return new Boxes.MovieFragmentRandomAccessBox(_baseStream);
- }
- [Obsolete("Use the BaseMedia class instead.")]
- IList<Box> ISuperBox.Children
- {
- get { return RootBoxes; }
- }
- [Obsolete("Use the BaseMedia class instead.")]
- IEnumerator<Box> IEnumerable<Box>.GetEnumerator()
- {
- return RootBoxes.GetEnumerator();
- }
- [Obsolete("Use the BaseMedia class instead.")]
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return RootBoxes.GetEnumerator();
- }
- }
- }
|