static private bool ParseReferencePictureResampling(Mpeg4Parser parser, H263PictureTypeCode pictureCodingType)
        {
            // Warping Displacement Accuracy (WDA) (2 bits)
            /*byte warpingDisplacementAccuracy = (byte)*/ parser.GetBits(2);

            FillModeH263 fillMode = FillModeH263.Invalid;

            // Warping parameters (Variable length)
            if (pictureCodingType == H263PictureTypeCode.P_Picture ||
                pictureCodingType == H263PictureTypeCode.B_Picture ||
                pictureCodingType == H263PictureTypeCode.ImprovedPBFrame)
            {
                // VLC-coded warping parameters
                // TODO


                // Fill Mode (FILL_MODE) (2 bits)
                fillMode = (FillModeH263)parser.GetBits(2);
            }
            else if (pictureCodingType == H263PictureTypeCode.EP_Picture)
            {
                // For an EP-picture, the fill-mode action is the same as that for
                // the reference layer, and the two fill-mode bits are not sent.
                // TODO
            }
            //TODO else if(pictureCodingType == H263VopType.

            // Fill Color Specification (Y_FILL, CB_EPB, CB_FILL, CR_EPB, CR_FILL) (26 bits)
            if (pictureCodingType != H263PictureTypeCode.EP_Picture && fillMode == FillModeH263.Color)
            {
                // Y_FILL
                parser.FlushBits(8);
                // CB_EPB
                bool cbepb = parser.GetBit();
                if (cbepb == false)
                {
                    return(false);
                }
                // CB_FILL
                parser.FlushBits(8);
                // CR_EPB
                bool crepb = parser.GetBit();
                if (crepb == false)
                {
                    return(false);
                }
                // CR_FILL
                parser.FlushBits(8);
            }

            //Resampling algorithm
            // TODO

            return(true);
        }
        public override bool Parse(Mpeg4Parser parser)
        {
            if (!base.Parse(parser))
            {
                return(false);
            }

            VideoObjectLayer VOL = new VideoObjectLayer(Parent as Mpeg4Header, true);

            VOL.Parse(parser);

            _fcodeForward = 1;

            Attributes.Add(new FormattedAttribute <Attribute, bool>(Attribute.ShortVideoHeader, true));

            // Get the Temporal Reference (TR)
            this.TemporalReference = (byte)parser.GetBits(8, Attribute.TemporalReference);

            // Get the Type Information (PTYPE) (Variable Length)
            if (!parser.GetMarkerBit())                 // PTYPE, bit 1. First bit must always be '1',
            {                                           // in order to avoid start code emulation.
#if DEBUG
                //long offset = parser.GetDataPacket(parser._dataReader.BytePosition, 1).StartOffset;
                //string message = string.Format(CultureInfo.CurrentCulture, "Offset: 0x{0}; First bit of PTYPE is '0', it must always be '1'.", offset.ToString("X", CultureInfo.CurrentCulture));
                //Debug.WriteLineIf(_mpeg4H263DebugInfo, message, Mpeg4H263);
#endif // DEBUG
                return(false);
            }
            // The second bit must always be '0', for distinction with ITU-T Rec. H.261.
            if (!parser.GetZeroBit())             // PTYPE, bit 2
            {
#if DEBUG
                Debug.WriteLineIf(_mpeg4H263DebugInfo, "Second bit of PTYPE is '1', it must always be '0'.", Mpeg4H263);
#endif // DEBUG
                return(false);
            }
            /*bool splitScreenIndicator = */ parser.GetBit();           // PTYPE, bit 3
            /*bool documentCameraIndicator = */ parser.GetBit();        // PTYPE, bit 4
            /*bool fullPictureFreezeRelease = */ parser.GetBit();       // PTYPE, bit 5
            byte sourceFormat = (byte)parser.GetBits(3);                // PTYPE, bit 6-8
            Attributes.Add(new FormattedAttribute <Attribute, string>(Attribute.PTypeSourceFormat, Enum.GetName(typeof(PTypeSourceFormat), sourceFormat)));

            bool extendedPType = (sourceFormat == (byte)PTypeSourceFormat.ExtendedPType);
            if (sourceFormat == (byte)PTypeSourceFormat.Forbidden)
            {
#if DEBUG
                Debug.WriteLineIf(_mpeg4H263DebugInfo, "The source format has the forbidden value of '0'.", Mpeg4H263);
#endif // DEBUG
                return(false);
            }
            H263PictureTypeCode pictureCodingType    = H263PictureTypeCode.Invalid;
            bool optionalPBFramesMode                = false;
            bool optionalCustomPictureClockFrequency = false;
            bool cpm = false;

            CustomPictureFormat customPictureFormat = null;

            if (!extendedPType)
            {
                pictureCodingType = parser.GetBit() ? H263PictureTypeCode.P_Picture : H263PictureTypeCode.I_Picture;                    // PTYPE, bit 9
                _codingType       = (byte)pictureCodingType;
                Attributes.Add(new FormattedAttribute <Attribute, string>(Attribute.CodingType, Enum.GetName(typeof(H263PictureTypeCode), _codingType)));

                /*bool optionalUnrestrictedMotionVectorMode = */ parser.GetBit();    // PTYPE, bit 10
                /*bool optionalSyntaxBasedArithmeticCodingMode = */ parser.GetBit(); // PTYPE, bit 11
                /*bool optionalAdvancedPredictionMode = */ parser.GetBit();          // PTYPE, bit 12
                optionalPBFramesMode = parser.GetBit();                              // PTYPE, bit 13

                // If bit 9 is set to 0, bit 13 shall be set to 0 as well
                if (pictureCodingType == H263PictureTypeCode.I_Picture && optionalPBFramesMode)
                {
#if DEBUG
                    Debug.WriteLineIf(_mpeg4H263DebugInfo, "Bit 9 of PTYPE is '0', and bit 13 is '1', while bit 13 should be '0'.", Mpeg4H263);
#endif // DEBUG
                    return(false);
                }
            }
            else            // SourceFormat == SourceFormat.ExtendedPType
            {               // Plus PTYPE (PLUSPTYPE) (Variable Length; 12 or 30 bits)
                            // Update Full Extended PTYPE (UFEP) (3 bits)
                            // Values of UFEP other than "000" and "001" are reserved
                byte updateFullExtendedPType = (byte)parser.GetBits(3);

                //PlusPTypeSourceFormat plusPTypeSourceFormat = PlusPTypeSourceFormat.Invalid;
                bool optionalUnrestrictedMotionVector  = false;
                bool optionalSliceStructured           = false;
                bool optionalReferencePictureSelection = false;
                if (updateFullExtendedPType == 1)
                {                                           // The Optional Part of PLUSPTYPE (OPPTYPE) (18 bits)
                                                            // overwrite sourceFormat variable
                    sourceFormat = (byte)parser.GetBits(3); // bit 1-3
                    Attributes.Add(new FormattedAttribute <Attribute, string>(Attribute.PlusPTypeSourceFormat, Enum.GetName(typeof(PlusPTypeSourceFormat), (sourceFormat == 7) ? (byte)0 /* enum values 0 and 7 are both 'Reserved' */: sourceFormat)));

                    optionalCustomPictureClockFrequency = parser.GetBit();                  // bit 4 (PCF)
                    optionalUnrestrictedMotionVector    = parser.GetBit();                  // bit 5 (UMV)
                    /*bool optionalSyntaxBasedArithmeticCoding = */ parser.GetBit();        // bit 6 (SAC)
                    /*bool optionalAdvancedPrediction = */ parser.GetBit();                 // bit 7 (AP)
                    /*bool optionalAdvancedIntraCoding = */ parser.GetBit();                // bit 8 (AIC)
                    /*bool optionalDeblockingFilter = */ parser.GetBit();                   // bit 9 (DF)
                    optionalSliceStructured           = parser.GetBit();                    // bit 10 (SS)
                    optionalReferencePictureSelection = parser.GetBit();                    // bit 11 (RPS)
                    /*bool optionalIndependentSegmentDecoding = */ parser.GetBit();         // bit 12 (ISD)
                    /*bool optionalAlternativeInterVariableLengthCode = */ parser.GetBit(); // bit 13 (AIV)
                    _optionalModifiedQuantization = parser.GetBit();                        // bit 14 (MQ)

                    if (!parser.GetOneBit())                                                // bit 15 should be "1" to prevent start code emulation
                    {
#if DEBUG
                        Debug.WriteLineIf(_mpeg4H263DebugInfo, "Bit 15 of PLUSPTYPE is '0' but should be '1'.", Mpeg4H263);
#endif // DEBUG
                        return(false);
                    }

                    if (parser.GetBits(3) != 0)                         // bit 16-18 shall be equal to "0"
                    {
#if DEBUG
                        Debug.WriteLineIf(_mpeg4H263DebugInfo, "Bit 16-18 of PLUSPTYPE are != '0' but shall be equal to '0'.", Mpeg4H263);
#endif // DEBUG
                        return(false);
                    }
                }

                // The mandatory part of PLUSPTYPE (MPPTYPE) (9 bits)
                pictureCodingType = (H263PictureTypeCode)parser.GetBits(3);                 // bits 1-3
                _codingType       = (byte)pictureCodingType;
                Attributes.Add(new FormattedAttribute <Attribute, string>(Attribute.CodingType, Enum.GetName(typeof(H263PictureTypeCode), (_codingType == 7) ? (byte)6 /* enum values 6 and 7 are both 'Reserved' */: _codingType)));

                bool optionalReferencePictureResamplingMode = parser.GetBit(); // bit 4 (RPR)
                bool optionalReducedResolutionUpdateMode    = parser.GetBit(); // bit 5 (RRU)

                bool roundingType = parser.GetBit();                           // bit 6 (RTYPE)

                // bit 6 can be set to "1" only when bits 1-3 indicate P-picture, Improved PB-frame or EP-frame
                if (roundingType &&
                    !(pictureCodingType == H263PictureTypeCode.P_Picture ||
                      pictureCodingType == H263PictureTypeCode.ImprovedPBFrame ||
                      pictureCodingType == H263PictureTypeCode.EP_Picture))
                {
#if DEBUG
                    Debug.WriteLineIf(_mpeg4H263DebugInfo, "Bit 6 of PLUSPTYPE can only be set to '1' when bits 1-3 indicate P-picture, Improved PB-frame or EP-frame.", Mpeg4H263);
#endif // DEBUG
                    return(false);
                }

                // Read two reserved bits
                // Shall be equal to "0"
                if (parser.GetBits(2) != 0)                     // bit 7 and 8
                {
#if DEBUG
                    Debug.WriteLineIf(_mpeg4H263DebugInfo, "The reserved bits 7 and 8 of PLUSPTYPE are != '0', but should be '0'.", Mpeg4H263);
#endif // DEBUG
                    return(false);
                }

                // Bit 9 must be equal to "1" to prevent start code emulation
                if (!parser.GetOneBit())                        // bit 9
                {
#if DEBUG
                    Debug.WriteLineIf(_mpeg4H263DebugInfo, "Bit 9 of PLUSPTYPE is '0' but must be '1'.", Mpeg4H263);
#endif // DEBUG
                    return(false);
                }

                // If the picture type is INTRA or EI, updateFullExtendedPType shall be set to "001".
                if ((pictureCodingType == H263PictureTypeCode.I_Picture || pictureCodingType == H263PictureTypeCode.EI_Picture) &&
                    updateFullExtendedPType != 1)
                {
#if DEBUG
                    Debug.WriteLineIf(_mpeg4H263DebugInfo, "If the picture type is INTRA or EI, updateFullExtendedPType shall be set to '001'", Mpeg4H263);
#endif // DEBUG
                    return(false);
                }

                // Continuous Presence Multipoint and Video Multiplex (CPM) (1 bit)
                // CPM follows immediately after PLUSPTYPE if PLUSPTYPE is present,
                // but follows PQUANT in the picture header if PLUSPTYPE is not present.
                // - This is the case where PLUSPTYPE is present
                cpm = ReadCpmAndPsbi(parser);

                // Custom Picture Format (CPFMT) (23 bits)
                // A fixed length codeword of 23 bits that is present only if the use of a
                // custom picture format is signalled in PLUSPTYPE and UFEP is '001'
                if (sourceFormat == (int)PlusPTypeSourceFormat.CustomSourceFormat && updateFullExtendedPType == 1)
                {
                    customPictureFormat = new CustomPictureFormat(optionalReducedResolutionUpdateMode);
                    if (!customPictureFormat.Parse(parser))
                    {
                        return(false);
                    }

                    // Extended Pixel Aspect Ratio (EPAR) (16 bits)
                    if (customPictureFormat.PixelAspectRatioCode == 15 /*Extended PAR*/)
                    {
                        // The natural binary representation of the PAR width
                        byte parWidth = (byte)parser.GetBits(8);                                // bit 1-8
                        // PAR Width: "0" is forbidden.
                        if (parWidth == 0)
                        {
                            return(false);
                        }
                        // The natural binary representation of the PAR height.
                        byte parHeight = (byte)parser.GetBits(8);                               // bit 9-16
                        // PAR Height: "0" is forbidden.
                        if (parHeight == 0)
                        {
                            return(false);
                        }
                    }
                }

                // Custom Picture Clock Frequency Code (CPCFC) (8 bits)
                // A fixed length codeword of 8 bits that is present only if PLUSPTYPE is present
                // and UFEP is 001 and a custom picture clock frequency is signalled in PLUSPTYPE.
                if (updateFullExtendedPType == 1 && optionalCustomPictureClockFrequency)
                {
                    // Clock Conversion Code: "0" indicates a clock conversion factor of 1000 and
                    // "1" indicates 1001
                    /*bool clockConversionCode = */ parser.GetBit();                    // bit 1

                    // Bits 2-8
                    // Clock Divisor: "0" is forbidden. The natural binary representation of the value
                    // of the clock divisor.
                    byte clockDivisor = (byte)parser.GetBits(7);                        // bit 2-8
                    if (clockDivisor == 0)
                    {
                        return(false);
                    }
                }

                // Extended Temporal Reference (ETR) (2 bits)
                // A fixed length codeword of 2 bits which is present only if a custom picture clock frequency is in
                // use (regardless of the value of UFEP). It is the two MSBs of the 10-bit Temporal Reference (TR).
                if (optionalCustomPictureClockFrequency)
                {
                    /*byte extendedTemporalReference = (byte)*/ parser.GetBits(2);                      // bit 1-2
                }

                // Unlimited Unrestricted Motion Vectors Indicator (UUI) (Variable length)
                // A variable length codeword of 1 or 2 bits that is present only if the
                // optional Unrestricted Motion Vector mode is indicated in PLUSPTYPE and UFEP is 001.
                if (updateFullExtendedPType == 1 && optionalUnrestrictedMotionVector)
                {
                    bool unlimitedUnrestrictedMotionVectorsIndicator = parser.GetBit();

                    if (!unlimitedUnrestrictedMotionVectorsIndicator)
                    {
                        // UUI = "01" The motion vector range is not limited except by the picture size.
                        unlimitedUnrestrictedMotionVectorsIndicator = parser.GetBit();
                        if (!unlimitedUnrestrictedMotionVectorsIndicator)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        // UUI = "1" The motion vector range is limited according to Tables D.1 and D.2.
                    }
                }

                // Slice Structured Submode bits (SSS) (2 bits)
                // A fixed length codeword of 2 bits which is present only if the optional Slice Structured mode
                // (see Annex K) is indicated in PLUSPTYPE and UFEP is 001. If the Slice Structured mode is in use
                // but UFEP is not 001, the last values sent for SSS shall remain in effect.
                if (updateFullExtendedPType == 1 && optionalSliceStructured)
                {
                    // Bit 1; "0" indicates free-running slices, "1" indicates rectangular slices
                    /*bool rectangularSlices = */ parser.GetBit();
                    // Bit 2 "0" indicates sequential order, "1" indicates arbitrary order
                    /*bool arbitrarySliceOrdering = */ parser.GetBit();
                }

                if (pictureCodingType == H263PictureTypeCode.B_Picture ||
                    pictureCodingType == H263PictureTypeCode.EI_Picture ||
                    pictureCodingType == H263PictureTypeCode.EP_Picture)
                {
                    // Enhancement Layer Number (ELNUM) (4 bits)
                    // A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR,
                    // and Spatial Scalability mode is in use (regardless of the value of UFEP)
                    /*byte enhancementLayerNumber = (byte)*/ parser.GetBits(4);

                    // Reference Layer Number (RLNUM) (4 bits)
                    // A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR,
                    // and Spatial Scalability mode is in use (see Annex O) and UFEP is 001.
                    if (updateFullExtendedPType == 1)
                    {
                        /*byte referenceLayerNumber = (byte)*/ parser.GetBits(4);

                        // Note that for B-pictures in an enhancement layer having temporally surrounding EI- or EP-pictures
                        // which are present in the same enhancement layer, RLNUM shall be equal to ELNUM
                        //if (pictureCodingType == H263VopType.BPicture && updateFullExtendedPType != referenceLayerNumber) return false;
                    }
                }

                // Reference Picture Selection Mode Flags (RPSMF) (3 bits)
                if (updateFullExtendedPType == 1 && optionalReferencePictureSelection)
                {
                    /*byte referencePictureSelectionModeFlags = (byte)*/ parser.GetBits(3);
                }

                if (optionalReferencePictureSelection)
                {
                    // Temporal Reference for Prediction Indication (TRPI) (1 bit)
                    // A fixed length codeword of 1 bit that is present only if the optional Reference Picture Selection
                    // mode is in use (regardless of the value of UFEP).
                    bool temporalReferenceForPredictionIndication = parser.GetBit();

                    if (temporalReferenceForPredictionIndication)
                    {
                        if (pictureCodingType == H263PictureTypeCode.I_Picture || pictureCodingType == H263PictureTypeCode.EI_Picture)
                        {
                            // TRPI shall be 0 whenever the picture header indicates an I- or EI-picture.
                            return(false);
                        }

                        // Temporal Reference for Prediction (TRP) (10 bits)
                        parser.FlushBits(10);
                    }

                    // Back-Channel message Indication (BCI) (Variable length)
                    while (parser.GetBit() == true)
                    {
                        // Back-Channel Message (BCM) (Variable length)
                        // Structure: BT URF TR ELNUMI ELNUM BCPM BSBI BEPB1 GN/MBA BEPB2 RTR BSTUF

                        // Back-channel message Type (BT) (2 bits)
                        parser.FlushBits(2);

                        // Unreliable Flag (URF) (1 bit)
                        // 0: Reliable; 1: Unreliable.
                        parser.FlushBits(1);

                        // Temporal Reference (TR) (10 bits)
                        parser.FlushBits(10);

                        // Enhancement Layer Number Indication (ELNUMI) (1 bit)
                        bool enhancementLayerNumberIndication = parser.GetBit();

                        // Enhancement Layer Number (ELNUM) (4 bits)
                        if (enhancementLayerNumberIndication)
                        {
                            parser.FlushBits(4);
                        }

                        // BCPM (1 bit)
                        bool bcpm = parser.GetBit();

                        // Back-channel Sub-Bitstream Indicator (BSBI) (2 bits)
                        if (bcpm)
                        {
                            parser.FlushBits(2);
                        }

                        // Back-channel Emulation Prevention Bit 1 (BEPB1) (1 bit)
                        // A field which is present if and only if the videomux mode is in use.
                        //if(videomux mode is in use) TODO
                        //{
                        // This field is always set to "1" to prevent a start code emulation.
                        if (!parser.GetOneBit())
                        {
                            return(false);
                        }
                        //}
                    }
                    bool bit2 = parser.GetBit();
                    if (bit2 == false)
                    {
                        return(false);                                   // If bit1 == 0, bit2 must be 1.
                    }
                }

                // Reference Picture Resampling Parameters (RPRP) (Variable length)
                if (optionalReferencePictureResamplingMode)
                {
                    ParseReferencePictureResampling(parser, pictureCodingType);
                }
            }            // SourceFormat == SourceFormat.ExtendedPType

            // Quantizer Information (PQUANT) (5 bits)
            _pQuant = parser.GetBits(5);

            // Continuous Presence Multipoint and Video Multiplex (CPM) (1 bit)
            // CPM follows immediately after PLUSPTYPE if PLUSPTYPE is present,
            // but follows PQUANT in the picture header if PLUSPTYPE is not present.
            // - This is the case where PLUSPTYPE is not present.
            if (!extendedPType)
            {
                cpm = ReadCpmAndPsbi(parser);
            }

            if (optionalPBFramesMode ||                                   // PTYPE indicates "PB-frame"
                pictureCodingType == H263PictureTypeCode.ImprovedPBFrame) //PLUSPTYPE indicates "Improved PB-frame"
            {
                // Temporal Reference for B-pictures in PB-frames (TRB) (3/5 bits)
                // TRB is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame"
                //
                // The codeword is the natural binary representation of the number of nontransmitted
                // pictures plus one. It is 3 bits long for standard CIF picture clock frequency and is
                // extended to 5 bits when a custom picture clock frequency is in use. The maximum number
                // of nontransmitted pictures is 6 for the standard CIF picture clock frequency and 30 when
                // a custom picture clock frequency is used.
                byte trb = (byte)parser.GetBits((short)(optionalCustomPictureClockFrequency ? 5 : 3));
                if (trb == 0)
                {
                    return(false);
                }

                // Quantization information for B-pictures in PB-frames (DBQUANT) (2 bits)
                // DBQUANT is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame"
                /*byte dbQuant = (byte)*/ parser.GetBits(2);
            }

            // PEI (1 bit) and PSUPP (0/8/16 ... bits)
            for (; ;)
            {
                // Extra Insertion Information (PEI) (1 bit)
                // A bit which when set to "1" signals the presence of the following optional data field.
                bool extraInsertionInformation = parser.GetBit();                 // 1 bit (PEI)
                // If PEI is set to "1", then 9 bits follow consisting of 8 bits of data (PSUPP)
                // and then another PEI bit to indicate if a further 9 bits follow and so on.
                if (!extraInsertionInformation)
                {
                    break;
                }
                /*byte supplementalEnhancementInformation = (byte)*/ parser.GetBits(8);                // 8 bit (PSUPP)
            }

            // Group of Blocks Layer (GOB)
            // Structure: GSTUF GBSC GN GSBI GFID GQUANT Macroblock Data

            uint numGobsInVop;
            uint numRowsInGob;

            if (customPictureFormat != null)
            {
                _vopWidth            = customPictureFormat.PixelsPerLine;
                _vopHeight           = customPictureFormat.NumberOfLines;
                numGobsInVop         = customPictureFormat.GobsInVopCount;
                _numMacroblocksInGob = customPictureFormat.MacroblocksInGobCount;
                numRowsInGob         = customPictureFormat.RowsInGobCount;
            }
            else
            {
                int sourceFormatIndex = sourceFormat - 1;

                if (sourceFormatIndex < 0 || sourceFormatIndex >= MP4H263Width.Length)
                {
                    return(false);
                }

                _vopWidth            = (uint)MP4H263Width[sourceFormatIndex];
                _vopHeight           = (uint)MP4H263Height[sourceFormatIndex];
                numGobsInVop         = (uint)MP4H263GobVop[sourceFormatIndex];
                _numMacroblocksInGob = (uint)MP4H263MbGob[sourceFormatIndex];
                numRowsInGob         = (uint)MP4H263RowGob[sourceFormatIndex];
            }

            int  gob_number = 0;
            uint rowNum     = 0;
            uint colNum     = 0;

            for (int i = 0; i < numGobsInVop; i++)
            {
                if (!GobLayer(parser, VOL, ref gob_number, ref rowNum, ref colNum, cpm, numRowsInGob, numGobsInVop))
                {
                    return(false);
                }
            }

            // Stuffing (ESTUF) (Variable length)
            // A codeword of variable length consisting of less than 8 zero-bits.
            // TODO 5.1.26

            // End Of Sequence (EOS) (22 bits)
            if (parser.ShowBits(22) == ShortVideoEndMarker)
            {
                parser.FlushBits(22);
            }

            // Stuffing (PSTUF) (Variable length)
            // A codeword of variable length consisting of less than 8 zero-bits.
            while (!parser.ByteAligned)
            {
                if (!parser.GetZeroBit())
                {
                    return(false);
                }
            }

            return(true);
        }