public static Box FromStream(Stream stream, BaseMediaOptions options = BaseMediaOptions.LoadChildren) { Box box = null; try { ulong offset = (ulong)stream.Position; uint size = stream.ReadBEUInt32(); uint type = stream.ReadBEUInt32(); ulong?largeSize = null; if (size == 1) { largeSize = stream.ReadBEUInt64(); } BoxType boxType = (type == uuidType) ? new BoxType(new Guid(stream.ReadBytes(16))) : new BoxType(type); AvailableBoxTypes.TryGetValue(boxType, out Type t); box = t != null ? (Box)Activator.CreateInstance(t) : new Boxes.UnknownBox(boxType); box.Size = size; box.LargeSize = largeSize; box.Offset = offset; box.Initialize(ConstrainedStream.WrapStream(stream), options); } catch (EndOfStreamException) { } return(box); }
public Stream GetContentStream() { Stream source = ConstrainedStream.UnwrapStream(_SourceStream); if (!source.CanSeek) { throw new FileNotFoundException("Invalid Source Stream in Box.GetContentStream()"); } source.Seek((long)ContentOffset, SeekOrigin.Begin); ConstrainedStream contentStream = ConstrainedStream.WrapStream(source); contentStream.PushConstraint((long)ContentOffset, (long)ContentSize); return(contentStream); }
internal void Initialize(Stream stream, BaseMediaOptions options = BaseMediaOptions.LoadChildren) { Trace.WriteLine(Type, "Loading"); _SourceStream = stream; ConstrainedStream constrainedStream = ConstrainedStream.WrapStream(stream); constrainedStream.PushConstraint((long)Offset.Value, (long)EffectiveSize); LoadFromStream(stream); ContentOffset = (ulong)stream.Position; if (((options & BaseMediaOptions.LoadChildren) == BaseMediaOptions.LoadChildren) && this is ISuperBox) { LoadChildrenFromStream(stream); } Sync(stream, !(this is IContentBox)); constrainedStream.PopConstraint(); }
public void ToStream(Stream stream) { Trace.WriteLine(Type, "Saving"); ConstrainedStream constrainedStream = ConstrainedStream.WrapStream(stream); long offset = constrainedStream.Position; ulong calculatedLength = CalculateSize() + (ulong)(Size == 1 ? 0 : 8); uint size = 1; ulong largeSize = 0; if (calculatedLength > uint.MaxValue) { largeSize = (ulong)calculatedLength; } else { size = (uint)calculatedLength - 8; } constrainedStream.PushConstraint(size); constrainedStream.WriteBEUInt32(size); constrainedStream.WriteBEUInt32(Type.FourCC); if (Size == 1) { constrainedStream.WriteBEUInt64(largeSize); } if (Type.FourCC == uuidType) { constrainedStream.WriteBytes(Type.UserType.ToByteArray()); } SaveToStream(constrainedStream); if (this is ISuperBox) { SaveChildrenToStream(constrainedStream); } // TODO: Handle IContentBox properly if (this is IContentBox && this.HasContent) { // TODO: Support unseekable streams for the case of Size=0 if (_sourceStream != null && _sourceStream.CanSeek) { ConstrainedStream source = new ConstrainedStream(_sourceStream); source.PushConstraint((long)this.ContentOffset.Value, (long)this.ContentSize.Value); source.Seek((long)this.ContentOffset.Value, SeekOrigin.Begin); ulong remaining = this.ContentSize.Value; byte[] buffer = ArrayPool <byte> .Shared.Rent(4096); int len = 0; do { len = source.Read(buffer, 0, (ulong)buffer.Length < remaining ? buffer.Length : (int)remaining); remaining -= (ulong)len; constrainedStream.Write(buffer, 0, len); }while (len == buffer.Length); ArrayPool <byte> .Shared.Return(buffer); } } long remainder = offset + (size == 1 ? (long)largeSize : size) - constrainedStream.Position; if (remainder > 0) { Trace.WriteLine("Undershot by " + remainder + " bytes. Padding with 0s.", "WARNING"); for (long i = 0; i < remainder; i++) { constrainedStream.WriteByte(0); } } constrainedStream.PopConstraint(); }