/**
         * Transform a RTP packet into a SRTP packet. This method is called when a
         * normal RTP packet ready to be sent.
         *
         * Operations done by the transformation may include: encryption, using
         * either Counter Mode encryption, or F8 Mode encryption, adding
         * authentication tag, currently HMC SHA1 method.
         *
         * Both encryption and authentication functionality can be turned off as
         * long as the SRTPPolicy used in this SRTPCryptoContext is requires no
         * encryption and no authentication. Then the packet will be sent out
         * untouched. However this is not encouraged. If no SRTP feature is enabled,
         * then we shall not use SRTP TransformConnector. We should use the original
         * method (RTPManager managed transportation) instead.
         *
         * @param pkt
         *            the RTP packet that is going to be sent out
         */
        public void TransformPacket(RawPacket pkt)
        {
            /* Encrypt the packet using Counter Mode encryption */
            if (policy.EncType == SrtpPolicy.AESCM_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISH_ENCRYPTION)
            {
                ProcessPacketAESCM(pkt);
            }
            else if (policy.EncType == SrtpPolicy.AESF8_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISHF8_ENCRYPTION)
            {
                /* Encrypt the packet using F8 Mode encryption */
                ProcessPacketAESF8(pkt);
            }

            /* Authenticate the packet */
            if (policy.AuthType != SrtpPolicy.NULL_AUTHENTICATION)
            {
                AuthenticatePacketHMCSHA1(pkt, roc);
                pkt.Append(tagStore, policy.AuthTagLength);
            }

            /* Update the ROC if necessary */
            int seqNo = pkt.GetSequenceNumber();

            if (seqNo == 0xFFFF)
            {
                roc++;
            }
        }
        /**
         * Transform a RTP packet into a SRTP packet.
         * This method is called when a normal RTP packet ready to be sent.
         *
         * Operations done by the transformation may include: encryption, using
         * either Counter Mode encryption, or F8 Mode encryption, adding
         * authentication tag, currently HMC SHA1 method.
         *
         * Both encryption and authentication functionality can be turned off
         * as long as the SRTPPolicy used in this SRTPCryptoContext is requires no
         * encryption and no authentication. Then the packet will be sent out
         * untouched. However this is not encouraged. If no SRTP feature is enabled,
         * then we shall not use SRTP TransformConnector. We should use the original
         * method (RTPManager managed transportation) instead.
         *
         * @param pkt the RTP packet that is going to be sent out
         */
        public void TransformPacket(RawPacket pkt)
        {
            bool encrypt = false;

            // Encrypt the packet using Counter Mode encryption
            if (policy.EncType == SrtpPolicy.AESCM_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISH_ENCRYPTION)
            {
                ProcessPacketAESCM(pkt, sentIndex);
                encrypt = true;
            }

            // Encrypt the packet using F8 Mode encryption
            else if (policy.EncType == SrtpPolicy.AESF8_ENCRYPTION || policy.EncType == SrtpPolicy.TWOFISHF8_ENCRYPTION)
            {
                ProcessPacketAESF8(pkt, sentIndex);
                encrypt = true;
            }

            int index = 0;

            if (encrypt)
            {
                index = (int)(sentIndex | 0x80000000);
            }

            // Authenticate the packet
            // The authenticate method gets the index via parameter and stores
            // it in network order in rbStore variable.
            if (policy.AuthType != SrtpPolicy.NULL_AUTHENTICATION)
            {
                AuthenticatePacket(pkt, index);
                pkt.Append(rbStore, 4);
                pkt.Append(tagStore, policy.AuthTagLength);
            }

            sentIndex++;
            sentIndex &= (int)(~0x80000000);  // clear possible overflow
        }