Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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();
        }