Beispiel #1
0
        public static IEnumerable <eBoxType> readChildren(this Mp4Reader reader)
        {
            int lvl = reader.level;

            Debug.Assert(lvl > 0);
            Debug.Assert(reader.currentBox.isContainer());
            lvl--;

            while (true)
            {
                eBoxType boxType = reader.readBox();
                // Console.WriteLine( "{0}:   {1}", reader.currentBoxNames, boxType );
                if (boxType == eBoxType.ChildContainerEnd)
                {
                    if (reader.level == lvl)
                    {
                        yield break;
                    }
                }
                else
                {
                    yield return(boxType);
                }
            }
        }
Beispiel #2
0
 public static string print(this eBoxType box)
 {
     if (Enum.IsDefined(typeof(eBoxType), box))
     {
         return(box.ToString());
     }
     byte[] bytes = BitConverter.GetBytes((uint)box);
     return($"\"{ Encoding.ASCII.GetString( bytes ) }\"");
 }
Beispiel #3
0
        public eBoxType readBox()
        {
            dbgVerifyOffset();

            if (stack.Count > 0 && !stack.Peek().type.isContainer())
            {
                skipCurrentBox();
            }

            if (stack.Count > 0)
            {
                Debug.Assert(stack.Peek().type.isContainer());
                if (!skipToNextBox())
                {
                    return(eBoxType.ChildContainerEnd);
                }
            }

            long startOffset = currentOffset;

            Span <byte> first8bytes = stackalloc byte[8];

            if (!tryReadBytes(first8bytes))
            {
                return(eBoxType.Empty);
            }

            ReadOnlySpan <uint> header = first8bytes.cast <uint>();

            // Damn byte order. Pretty much all big endian platforms died decades ago, yet we still suffer from that BS in 2020.
            uint     size = BinaryPrimitives.ReverseEndianness(header[0]);
            eBoxType bt   = (eBoxType)header[1];

            if (size == 0)
            {
                throw new NotImplementedException("Boxes without size are valid according to the spec, but not currently supported by this library.");
            }
            if (size != 1)
            {
                currentBoxEnd = startOffset + size;
            }
            else
            {
                // 64-bit size version
                Span <byte> sizeExt = stackalloc byte[8];
                readBytes(sizeExt);

                ulong val = sizeExt.cast <ulong>()[0];
                val           = BinaryPrimitives.ReverseEndianness(val);
                currentBoxEnd = startOffset + (long)val;
            }
            stack.Push(new sCurrentBox(bt, currentBoxEnd));
            return(bt);
        }
Beispiel #4
0
 public static void moveToBox(this Mp4Reader reader, eBoxType boxType)
 {
     while (true)
     {
         var bt = reader.readBox();
         if (bt == boxType)
         {
             return;
         }
         if (bt == eBoxType.Empty)
         {
             throw new EndOfStreamException();
         }
     }
 }
Beispiel #5
0
 public sCurrentBox(eBoxType type, long endOffset)
 {
     this.type      = type;
     this.endOffset = endOffset;
 }
Beispiel #6
0
 public static bool isContainer(this eBoxType box)
 {
     return(containerBoxes.Contains(box));
 }