/// <summary>
 /// Decode this PDU from the PduMarshaler.
 /// </summary>
 /// <param name="marshaler">This is used to encode the fields of this PDU.</param>
 public override bool Decode(PduMarshaler marshaler)
 {
     try
     {
         this.Header.cbSize      = marshaler.ReadUInt32();
         this.Header.PacketType  = (PacketTypeValues)marshaler.ReadUInt32();
         this.PresentatioinId    = marshaler.ReadByte();
         this.Version            = (RdpevorVersionValues)marshaler.ReadByte();
         this.Flags              = (TsmmVideoData_FlagsValues)marshaler.ReadByte();
         this.Reserved           = marshaler.ReadByte();
         this.HnsTimestamp       = marshaler.ReadUInt64();
         this.HnsDuration        = marshaler.ReadUInt64();
         this.CurrentPacketIndex = marshaler.ReadUInt16();
         this.PacketsInSample    = marshaler.ReadUInt16();
         this.SampleNumber       = marshaler.ReadUInt32();
         this.cbSample           = marshaler.ReadUInt32();
         this.pSample            = marshaler.ReadBytes((int)this.cbSample);
         this.Reserved2          = marshaler.ReadByte();
         return(true);
     }
     catch
     {
         marshaler.Reset();
         throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
     }
 }
        /// <summary>
        /// Method to sent a sample to client.
        /// </summary>
        /// <param name="presentationId">This is the same number as the PresentationId field in the TSMM_PRESENTATION_REQUEST message.</param>
        /// <param name="isKeyFrame">Is the sample a key frame.</param>
        /// <param name="SampleNumber">The number of sample in the video stream.</param>
        /// <param name="sampleData">The sample data in bytes which to be sent.</param>
        public void SendVideoSample(byte presentationId, bool isKeyFrame, uint SampleNumber, byte[] sampleData, ulong timeStamp)
        {
            if (sampleData == null)
            {
                return;
            }
            ushort totalPackets = (ushort)(((sampleData.Length - 1) / LargestSampleSize) + 1);

            for (ushort packetIndex = 1; packetIndex <= totalPackets; packetIndex++)
            {
                TsmmVideoData_FlagsValues flags = TsmmVideoData_FlagsValues.None;
                if (isKeyFrame)
                {
                    flags |= TsmmVideoData_FlagsValues.TSMM_VIDEO_DATA_FLAG_KEYFRAME;
                }
                int packetSize = LargestSampleSize;
                if (packetIndex == totalPackets)
                {
                    packetSize = sampleData.Length % LargestSampleSize;
                    flags     |= TsmmVideoData_FlagsValues.TSMM_VIDEO_DATA_FLAG_HAS_TIMESTAMPS;
                }
                byte[] packetData = new byte[packetSize];
                Array.Copy(sampleData, (packetIndex - 1) * LargestSampleSize, packetData, 0, packetSize);
                SendVideoPacket(presentationId, flags, packetIndex, totalPackets, SampleNumber, packetData, timeStamp);
                //System.Threading.Thread.Sleep(100);//Sleep 0.1 second to avoid this packet is merged with next one in TCP layer.
            }
        }
        /// <summary>
        /// Method to send a TSMM_VIDEO_DATA to client.
        /// </summary>
        /// <param name="presentationId">This is the same number as the PresentationId field in the TSMM_PRESENTATION_REQUEST message.</param>
        /// <param name="flags">The bits of this integer indicate attributes of this message. </param>
        /// <param name="packetIndex">This field contains the index of the current packet within the larger sample. </param>
        /// <param name="totalPacketsInSample">This field contains the number of packets that make up the current sample.</param>
        /// <param name="SampleNumber">This field contains the index of current sample in current presentation.</param>
        /// <param name="packetData">The video data in bytes which to be sent.</param>
        public void SendVideoPacket(byte presentationId, TsmmVideoData_FlagsValues flags, ushort packetIndex, ushort totalPacketsInSample, uint SampleNumber, byte[] packetData, ulong timeStamp)
        {
            TSMM_VIDEO_DATA videoDataPacket = rdpevorServer.CreateVideoDataPacket(presentationId, flags, packetIndex, totalPacketsInSample, SampleNumber, packetData, timeStamp);

            if (this.testType == RdpevorNegativeType.VideoData_InvalidPacketLength)
            {
                //Set the packet length to an invalid value.
                videoDataPacket.Header.cbSize = (uint)(videoDataPacket.Header.cbSize - 1);
            }
            else if (this.testType == RdpevorNegativeType.VideoData_InvalidVersion)
            {
                //Set version to an invalid value.
                videoDataPacket.Version = RdpevorVersionValues.InvalidValue;
            }

            rdpevorServer.SendRdpevorDataPdu(videoDataPacket);
        }
        /// <summary>
        /// Method to create a TSMM_VIDEO_DATA packet.
        /// </summary>
        /// <param name="presentationId">This is the same number as the PresentationId field in the TSMM_PRESENTATION_REQUEST message.</param>
        /// <param name="flags">The bits of this integer indicate attributes of this message. </param>
        /// <param name="packetIndex">This field contains the index of the current packet within the larger sample. </param>
        /// <param name="totalPacketsInSample">This field contains the number of packets that make up the current sample.</param>
        /// <param name="SampleNumber">The sample index in this presentation.</param>
        /// <param name="videoData">The video data to be sent.</param>
        public TSMM_VIDEO_DATA CreateVideoDataPacket(byte presentationId, TsmmVideoData_FlagsValues flags, ushort packetIndex, ushort totalPacketsInSample, uint SampleNumber, byte[] videoRawData, ulong timeStamp)
        {
            TSMM_VIDEO_DATA videoData = new TSMM_VIDEO_DATA();

            videoData.Header.PacketType = PacketTypeValues.TSMM_PACKET_TYPE_VIDEO_DATA;
            videoData.PresentatioinId   = presentationId;
            videoData.Version           = RdpevorVersionValues.RDP8;
            videoData.Flags             = flags;
            videoData.Reserved          = 0;
            if (packetIndex != totalPacketsInSample)
            {
                //HnsTimestamp and HnsDuration are only effective in the last packet of a sample.
                videoData.HnsTimestamp = 0;
                videoData.HnsDuration  = 0;
            }
            else
            {
                videoData.HnsTimestamp = timeStamp;
                videoData.HnsDuration  = timeStamp - lastPacketTimestamp;
                lastPacketTimestamp    = videoData.HnsTimestamp;
            }
            videoData.CurrentPacketIndex = packetIndex;
            videoData.PacketsInSample    = totalPacketsInSample;
            videoData.SampleNumber       = SampleNumber;
            if (videoRawData != null)
            {
                videoData.pSample = new byte[videoRawData.Length];
                Array.Copy(videoRawData, videoData.pSample, videoRawData.Length);
                videoData.Header.cbSize = (uint)(sizeOfVideoPacketFixedFields + videoData.pSample.Length);
                videoData.cbSample      = (uint)videoData.pSample.Length;
            }
            else
            {
                videoData.pSample       = null;
                videoData.Header.cbSize = sizeOfVideoPacketFixedFields;
                videoData.cbSample      = 0;
            }
            videoData.Reserved2 = 0;
            return(videoData);
        }
 /// <summary>
 /// Decode this PDU from the PduMarshaler.
 /// </summary>
 /// <param name="marshaler">This is used to encode the fields of this PDU.</param>
 public override bool Decode(PduMarshaler marshaler)
 {
     try
     {
         this.Header.cbSize = marshaler.ReadUInt32();
         this.Header.PacketType = (PacketTypeValues)marshaler.ReadUInt32();
         this.PresentatioinId = marshaler.ReadByte();
         this.Version = (RdpevorVersionValues)marshaler.ReadByte();
         this.Flags = (TsmmVideoData_FlagsValues)marshaler.ReadByte();
         this.Reserved = marshaler.ReadByte();
         this.HnsTimestamp = marshaler.ReadUInt64();
         this.HnsDuration = marshaler.ReadUInt64();
         this.CurrentPacketIndex = marshaler.ReadUInt16();
         this.PacketsInSample = marshaler.ReadUInt16();
         this.SampleNumber = marshaler.ReadUInt32();
         this.cbSample = marshaler.ReadUInt32();
         this.pSample = marshaler.ReadBytes((int)this.cbSample);
         this.Reserved2 = marshaler.ReadByte();
         return true;
     }
     catch
     {
         marshaler.Reset();
         throw new PDUDecodeException(this.GetType(), marshaler.ReadToEnd());
     }
 }
        /// <summary>
        /// Method to send a TSMM_VIDEO_DATA to client.
        /// </summary>
        /// <param name="presentationId">This is the same number as the PresentationId field in the TSMM_PRESENTATION_REQUEST message.</param>
        /// <param name="flags">The bits of this integer indicate attributes of this message. </param>
        /// <param name="packetIndex">This field contains the index of the current packet within the larger sample. </param>
        /// <param name="totalPacketsInSample">This field contains the number of packets that make up the current sample.</param>
        /// <param name="SampleNumber">This field contains the index of current sample in current presentation.</param>
        /// <param name="packetData">The video data in bytes which to be sent.</param>
        public void SendVideoPacket(byte presentationId, TsmmVideoData_FlagsValues flags, ushort packetIndex, ushort totalPacketsInSample, uint SampleNumber, byte[] packetData, ulong timeStamp)
        {
            TSMM_VIDEO_DATA videoDataPacket = rdpevorServer.CreateVideoDataPacket(presentationId, flags, packetIndex, totalPacketsInSample, SampleNumber, packetData, timeStamp);
            if (this.testType == RdpevorNegativeType.VideoData_InvalidPacketLength)
            {
                //Set the packet length to an invalid value.
                videoDataPacket.Header.cbSize = (uint)(videoDataPacket.Header.cbSize - 1);
            }
            else if (this.testType == RdpevorNegativeType.VideoData_InvalidVersion)
            {
                //Set version to an invalid value.
                videoDataPacket.Version = RdpevorVersionValues.InvalidValue;
            }

            rdpevorServer.SendRdpevorDataPdu(videoDataPacket);
        }