示例#1
0
        private bool GetNextBox(out MpegBox mpegBox, long endPosition, MpegBox parentBox)
        {
            // return empty object when we reach data endPosition.  If endPosition is set
            // to zero, return empty object if we reach EOF.
            if (this.br.BaseStream.Position == (0 == endPosition ? this.br.BaseStream.Length : endPosition))
            {
                mpegBox = null;
                return(false);
            }

            // create new box, fill in the byte offset
            MpegBox ma = new MpegBox(parentBox, null, MpegBox.BoxType.Unknown, this.br.BaseStream.Position, 0);

            // now get the size and type
            ma.Size = BU.ReverseToUInt32(this.br.ReadBytes(4));  // size
            // special size values aren't handled yet
            if (ma.Size < 2)
            {
                throw new MsvDecoderException("Special MPEG box size values are not yet supported.");
            }
            // type
            try
            {
                ma.Type = (MpegBox.BoxType)BU.ReverseToInt32(this.br.ReadBytes(4));
            }
            catch
            {
                ma.Type = MpegBox.BoxType.Unknown;
            }

            // check the type to see if it has data or child boxes that we care about
            switch (ma.Type)
            {
            case MpegBox.BoxType.moov:
            {
                // now that we've picked up the moov box, leave br's pointer
                // at the start of the moov data and read in all its child boxes
                ma.Children = GetBoxes(br, ma.Offset + ma.Size, ma);
                break;
            }

            case MpegBox.BoxType.trak:
            {
                // read in all its child boxes
                ma.Children = GetBoxes(br, ma.Offset + ma.Size, ma);
                break;
            }

            case MpegBox.BoxType.mdia:
            {
                // read in all its child boxes
                ma.Children = GetBoxes(br, ma.Offset + ma.Size, ma);
                break;
            }

            case MpegBox.BoxType.minf:
            {
                // read in all its child boxes
                ma.Children = GetBoxes(br, ma.Offset + ma.Size, ma);
                break;
            }

            case MpegBox.BoxType.stbl:
            {
                // read in all its child boxes
                ma.Children = GetBoxes(br, ma.Offset + ma.Size, ma);
                break;
            }

            case MpegBox.BoxType.uuid:      // may have data we want
            {
                // note current br pointer location
                long dataStartPos = this.br.BaseStream.Position;
                // get the 16 byte UUID value from the start of data
                ma.UuidType = GetUuidType(this.br.ReadBytes(16));
                // return pointer to previous location
                this.br.BaseStream.Position = dataStartPos;
                // if this is a uuid we care about, copy its data into the box
                if (!(MpegBox.BoxUuidType.Unknown == ma.UuidType ||
                      MpegBox.BoxUuidType.None == ma.UuidType))
                {
                    // TODO: throw exception if ma.Size is bigger than an Int32 can hold
                    // read data into ma, then leave br's pointer at the end of this data/box
                    ma.Data = br.ReadBytes((int)ma.Size - 8);      // box size, less size/tag bytes
                }
                else
                {
                    // don't care about this uuid, move br's pointer to the end of this box
                    this.br.BaseStream.Seek(ma.Size - 8, SeekOrigin.Current);
                    break;
                }
                break;
            }

            case MpegBox.BoxType.stco:      // contains list of mdat data chunk offsets
            {
                // read data into ma, then leave br's pointer at the end of this data/box
                ma.Data = br.ReadBytes((int)ma.Size - 8);      // box size, less size/tag bytes
                break;
            }

            default:      // unrecognized, don't read any data from this box
            {
                // just move br's pointer to the end of this box
                this.br.BaseStream.Seek(ma.Size - 8, SeekOrigin.Current);
                break;
            }
            }

            // all done, verify br's pointer is where it should be

            // return finished box
            mpegBox = ma;
            return(true);
        }
示例#2
0
        private bool GetNextAtom(out MpegAtom mpegAtom, long endPosition, MpegAtom parentAtom)
        {
            // return empty object when we reach data endPosition.  If endPosition is set
            // to zero, return empty object if we reach EOF.
            if (this.br.BaseStream.Position == (0 == endPosition ? this.br.BaseStream.Length : endPosition))
            {
                mpegAtom = null;
                return(false);
            }

            // create new atom, fill in the byte offset
            MpegAtom ma = new MpegAtom(null, null, MpegAtom.AtomType.Unknown, this.br.BaseStream.Position, 0);

            // now get the size and type
            ma.Size = BU.ReverseToUInt32(this.br.ReadBytes(4));  // size
            // type
            try
            {
                ma.Type = (MpegAtom.AtomType)BU.ReverseToInt32(this.br.ReadBytes(4));
            }
            catch
            {
                ma.Type = MpegAtom.AtomType.Unknown;
            }

            /*
             * switch (BU.ReverseToInt32(this.br.ReadBytes(4)))  // type
             * {
             *  case 0x6D6F6F76:    ma.Type = MpegAtom.AtomType.moov;     break;   // "moov"
             *  case 0x75756964:    ma.Type = MpegAtom.AtomType.uuid;     break;   // "uuid"
             *  default:            ma.Type = MpegAtom.AtomType.Unknown;  break;   // uninteresting to us
             * }
             */

            // check the type to see if it has data or child atoms that we care about
            switch (ma.Type)
            {
            case MpegAtom.AtomType.moov:
            {
                // now that we've picked up the moov atom, leave br's pointer
                // at the start of the moov data and read in all its child atoms
                ma.Children = GetAtoms(br, ma.Offset + ma.Size);
                // TODO: verify br's pointer is now at end of moov data
                break;
            }

            case MpegAtom.AtomType.trak:
            {
                // now that we've picked up the moov atom, leave br's pointer
                // at the start of the moov data and read in all its child atoms
                ma.Children = GetAtoms(br, ma.Offset + ma.Size);
                // TODO: verify br's pointer is now at end of moov data
                break;
            }

            case MpegAtom.AtomType.uuid:      // may have data we want
            {
                // note current br pointer location
                long dataStartPos = this.br.BaseStream.Position;
                // get the 16 byte UUID value from the start of data
                ma.UuidType = GetUuidType(this.br.ReadBytes(16));
                // return pointer to previous location
                this.br.BaseStream.Position = dataStartPos;
                // if this is a uuid we care about, copy its data into the atom
                if (!(MpegAtom.AtomUuidType.Unknown == ma.UuidType ||
                      MpegAtom.AtomUuidType.None == ma.UuidType))
                {
                    // TODO: throw exception if ma.Size is bigger than an Int32 can hold
                    // read data into ma, then leave br's pointer at the end of this data/atom
                    ma.Data = br.ReadBytes((int)ma.Size - 8);      // atom size, less size/tag bytes
                }
                else
                {
                    // don't care about this uuid, move br's pointer to the end of this atom
                    this.br.BaseStream.Seek(ma.Size - 8, SeekOrigin.Current);
                    break;
                }
                break;
            }

            default:      // unrecognized, don't read any data from this atom
            {
                // just move br's pointer to the end of this atom
                this.br.BaseStream.Seek(ma.Size - 8, SeekOrigin.Current);
                break;
            }
            }

            // all done, verify br's pointer is where it should be

            // return finished atom
            mpegAtom = ma;
            return(true);
        }