public override void Read(BoxReader reader)
        {
            using (new SizeChecker(this, reader)) {
            long pos = reader.BaseStream.Position;

            base.Read(reader);
            for (int i = 0; i < 2; i++) reader.ReadUInt32();  // unsigned int(32)[2] reserved = 0
            ChannelCount = reader.ReadUInt16();
            SampleSize = reader.ReadUInt16();
            PreDefined = reader.ReadUInt16(); // unsigned int(16) pre_defined = 0
            reader.ReadUInt16(); // unsigned int(16) reserved = 0
            SampleRate = reader.ReadUInt32() >> 16;

              // read esds or avcc boxes
            BoxType bt = reader.PeekNextBoxType();
            switch (bt.ToString().ToLower())
            {
            case "esds": // AudioSampleEntry type is mp4a (denotes AAC encoding)
            case "avcc":
                PrivDataFullBox = new AnyPrivFullBox(bt, string.Empty);
                PrivDataFullBox.Read(reader);
                break;
            case "wfex": // AudioSampleEntry type is wma
                PrivDataBox = new AnyPrivBox(bt, string.Empty);
                PrivDataBox.Read(reader);
                break;
               case "damr": // 3gpp sound
                PrivDataFullBox = new AnyPrivFullBox(bt, string.Empty);
                PrivDataFullBox.Read(reader);
                break;
            default:
                throw new Exception(string.Format("AudioSampleEntry has unknown contents: {0}", bt.ToString()));
            }
              }
        }
        public override void Read(BoxReader reader)
        {
            using (new SizeChecker(this, reader)) {
            long startpos = reader.BaseStream.Position;

            base.Read(reader);
            reader.ReadUInt16(); // pre_defined = 0;
            reader.ReadUInt16(); // reserved = 0;
            for (int i = 0; i < 3; i++) reader.ReadUInt32();  // unsigned int(32)[3] pre_defined = 0
            Width = reader.ReadUInt16();
            Height = reader.ReadUInt16();
            HorizResolution = reader.ReadUInt32(); // = 0x0048000 = 72 dpi
            VertResolution = reader.ReadUInt32(); // = 0x0048000 = 72 dpi
            reader.ReadUInt32(); // reserved = 0
            FrameCount = reader.ReadUInt16(); // frame_count = 1

            // Compressor name has first 2 bytes which is the readable length, the rest are char's or null bytes
            CompressorName = "";
            ushort len = reader.ReadUInt16();
            // NOTE: Some encoders use only one byte for count of compressor name, so here
            // we test for whether the length is valid. If not valid, only the first byte is
            // used as the length.
            if (len > 30)
            {
              byte[] b = BitConverter.GetBytes(len);
              if (BitConverter.IsLittleEndian)
              {
            len = (ushort)b[1];
            CompressorName += (char)b[0];
              }
              else
              {
            len = (ushort)b[0];
            CompressorName += (char)b[1];
              }
            }
            for (int i=0; i<30; i++) {
              if (i < len)
            CompressorName += reader.ReadChar();
              else
            reader.ReadChar();
            }
            CompressorName = CompressorName.Trim().Replace("\0","");
            Depth = reader.ReadUInt16(); // depth = 0x0018
            reader.ReadUInt16();  // pre_defined = -1

            bool bOptionalBoxFound = true;
            while (bOptionalBoxFound) {
              bOptionalBoxFound = false;
              long pos = reader.BaseStream.Position;
              Box test = new Box(BoxTypes.Any);
              test.Read(reader);
              reader.BaseStream.Position = pos;

              if (test.Type == BoxTypes.CleanApertureBox) {
            CleanApertureBox = new CleanApertureBox();
            CleanApertureBox.Read(reader);
            bOptionalBoxFound = true;
              } else

              if (test.Type == BoxTypes.PixelAspectRatio) {
            PixelAspectRatioBox = new PixelAspectRatioBox();
            PixelAspectRatioBox.Read(reader);
            bOptionalBoxFound = true;
              } else

              // retrieve CodecPrivateData from avcC
              if (test.Type == BoxTypes.AvcC) {
            AvcCBox = new AvcCBox();
            AvcCBox.Read(reader);

            //if ((ulong) (reader.BaseStream.Position - pos) < this.Size) {
            //  // klude to work around Expression problem (missing uuid, but box size large enough for it)
            //  pos = reader.BaseStream.Position;
            //  test = new Box(BoxTypes.Any);
            //  test.Read(reader);
            //  reader.BaseStream.Position = pos;

            //  if (test.Type == BoxTypes.UUID) {
            //    Uuid = new UuidBox();
            //    Uuid.Read(reader);
            //  }
            //}
            bOptionalBoxFound = true;
              } else

              if (test.Type == BoxTypes.UUID) {
            Uuid = new UuidBox();
            Uuid.Read(reader);
              } else

              if (test.Type == BoxTypes.Mp4v) {
            PrivDataFullBox = new AnyPrivFullBox();
            PrivDataFullBox.Read(reader);
            bOptionalBoxFound = true;
              } else

              if (test.Type == BoxTypes.Vc1) {
            PrivDataBox = new AnyPrivBox();
            PrivDataBox.Read(reader);
            bOptionalBoxFound = true;
              }
            }
              }
        }
        public AudioSampleEntry(BoxType inType, RawAudioTrackInfo audioInfo)
            : base(inType)
        {
            ChannelCount = (ushort)audioInfo.ChannelCount;
              SampleSize = (ushort)audioInfo.SampleSize;
              SampleRate = (uint)audioInfo.SampleRate;

              this.Size += 20UL;

              switch (audioInfo.PayloadType)
              {
            case AudioPayloadType.aac:
            case AudioPayloadType.mp4a:
              PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Esds, audioInfo.CodecPrivateData); // AAC encoding
              this.Size += PrivDataFullBox.Size;
              break;
            case AudioPayloadType.wma:
              PrivDataBox = new AnyPrivBox(BoxTypes.Wfex, audioInfo.CodecPrivateData);
              this.Size += PrivDataBox.Size;
              break;
            case AudioPayloadType.samr: // 3gp audio
              PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Damr, audioInfo.CodecPrivateData);
              this.Size += PrivDataFullBox.Size;
              break;
            default:
              throw new Exception(string.Format("Unknown audio track payload type: {0}", audioInfo.PayloadType));
              }
        }
        public VisualSampleEntry(BoxType inType, RawVideoTrackInfo trackInfo)
            : base(inType)
        {
            Width = (ushort)trackInfo.Width;
              Height = (ushort)trackInfo.Height;
              HorizResolution = (uint)0x00480000; // 72 dpi
              VertResolution = (uint)0x00480000;
              FrameCount = (ushort)1;

              this.Size += 34UL;

              CompressorName = ""; // "Orions Digital MP4 Recoding";
              Depth = (ushort)0x18; // images in color with no alpha

              this.Size += 36UL; // compressor name is 30 bytes plus 2 for length, 2 for depth, 2 for reserved

              if (trackInfo.PayloadType == VideoPayloadType.avc1)
              {
            AvcCBox = new AvcCBox();
            AvcCBox.CodecPrivateData = trackInfo.CodecPrivateData;
            this.Size += AvcCBox.Size;
              }
              else if (trackInfo.PayloadType == VideoPayloadType.vc1)
              {
            PrivDataBox = new AnyPrivBox(BoxTypes.Dvc1, trackInfo.CodecPrivateData); // MS ISMV
            this.Size += PrivDataBox.Size;
              }
              else if (trackInfo.PayloadType == VideoPayloadType.mp4v)
              {
            //CleanApertureBox = new CleanApertureBox();  // We won't be putting a CleanApertureBox for now

            PrivDataFullBox = new AnyPrivFullBox(BoxTypes.Esds, trackInfo.CodecPrivateData); // 3gp mp4v --> esds
            this.Size += PrivDataFullBox.Size;
              }

              if (trackInfo.AspectRatioX != trackInfo.AspectRatioY)
              {
            PixelAspectRatioBox = new PixelAspectRatioBox();
            PixelAspectRatioBox.hSpacing = (uint)trackInfo.AspectRatioX;
            PixelAspectRatioBox.vSpacing = (uint)trackInfo.AspectRatioY;
            this.Size += PixelAspectRatioBox.Size;
              }
        }