예제 #1
0
파일: Block.cs 프로젝트: VoidXH/Cavern
        /// <summary>
        /// Parse the metadata of a data block.
        /// </summary>
        public Block(Stream reader, MatroskaTree source)
        {
            source.Position(reader);
            this.reader = reader;
            long start = reader.Position;

            Track     = VarInt.ReadValue(reader);
            TimeStamp = reader.ReadInt16BE();
            flags     = (byte)reader.ReadByte();

            Lacing lacing = LacingType;

            if (lacing != Lacing.None)
            {
                int x = reader.ReadByte();
                frameCount = x + 1;
                frameSizes = new int[frameCount];
                firstFrame = reader.Position;
                switch (lacing)
                {
                case Lacing.Xiph:
                    byte frame     = 0;
                    long totalSize = 0;
                    while (frame < frameCount - 1)
                    {
                        byte value;
                        int  sum = 0;
                        do
                        {
                            value = (byte)reader.ReadByte();
                            sum  += value;
                        } while (value == 255);
                        totalSize          += sum;
                        frameSizes[frame++] = sum;
                    }
                    frameSizes[frame] = (int)(source.Length - (reader.Position - start) - totalSize);
                    break;

                case Lacing.FixedSize:
                    int step = (int)((source.Length - (firstFrame - start)) / frameCount);
                    for (byte i = 0; i < frameCount; ++i)
                    {
                        frameSizes[i] = step;
                    }
                    break;

                case Lacing.EBML:
                    frameSizes[0] = (int)VarInt.ReadValue(reader);
                    long last = -frameSizes[0];
                    for (int i = 1; i < frameCount - 1; ++i)
                    {
                        frameSizes[i] = frameSizes[i - 1] + (int)VarInt.ReadSignedValue(reader);
                        last         -= frameSizes[i];
                    }
                    frameSizes[frameCount - 1] = (int)(last + source.Length - (reader.Position - start));
                    break;

                default:
                    break;
                }
            }
            else
            {
                firstFrame = reader.Position;
                frameCount = 1;
                frameSizes = new int[1] {
                    (int)(source.Length - (firstFrame - start))
                };
            }
        }