/// <summary> /// return an index page according to the inputs /// </summary> /// <returns></returns> public ActionResult IndexWithInputs() { dynamic obj = GetJsonObject(Request.InputStream); // retrieve the quant QuantizationFactorsArray quantArray = JsonHelper.RetrieveQuantsArray(obj.Params.QuantizationFactorsArray); EntropyAlgorithm algorithm = JsonHelper.CastTo <EntropyAlgorithm>(obj.Params.EntropyAlgorithm); _viewModel = new RFXDecodeViewModel(); // Updates parameters ((RFXDecodeViewModel)_viewModel).ProvideParam(quantArray, algorithm); Triplet <string> triplet = JsonHelper.RetrieveTriplet(obj.Inputs); ((RFXDecodeViewModel)_viewModel).ProvidePanelInputs(triplet.ToArray()); var envValues = new Dictionary <string, object>() { { ModelKey, _viewModel }, { isModelValid, true } }; SaveToSession(envValues); return(new HttpStatusCodeResult(HttpStatusCode.OK)); }
/// <summary> /// Using RDPRFX to send image whose resolution is Width x Height /// </summary> /// <param name="imagefile">Image to send</param> /// <param name="width">Width of image to send</param> /// <param name="height">Height of image to send</param> public bool RdprfxSendImage(Image image, ushort width, ushort height) { uint frameId = 0; //The index of the sending frame. OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1; ushort destLeft = 0; //the left bound of the frame. ushort destTop = 0; //the top bound of the frame. // Crop Image Bitmap bitmap = new Bitmap(width, height); Graphics graphics = Graphics.FromImage(bitmap); Rectangle section = new Rectangle(0, 0, width, height); graphics.DrawImage(image, 0, 0, section, GraphicsUnit.Pixel); //Check if the above setting is supported by the client. if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm)) { return(false); } rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId); rdprfxAdapter.SendImageToClient(bitmap, opMode, enAlgorithm, destLeft, destTop); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId); rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime); return(true); }
private bool rdprfxNegativeTest(RdprfxNegativeType negType) { StartRDPConnection(); this.rdprfxAdapter.SetTestType(negType); #region Fill parameters TS_RFX_ICAP[] clientSupportedCaps; rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps); OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3; ushort destLeft = 0; //the left bound of the frame. ushort destTop = 0; //the top bound of the frame. //Set OperationalMode/EntropyAlgorithm to valid pair. if (clientSupportedCaps != null) { opMode = (OperationalMode)clientSupportedCaps[0].flags; enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits; } #endregion this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.", opMode, enAlgorithm, destLeft, destTop); this.rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop); bool fDisconnected = this.rdpbcgrAdapter.WaitForDisconnection(waitTime); StopRDPConnection(); return(fDisconnected); }
/// <summary> /// Method to create TS_RFX_CONTEXT. /// </summary> /// <param name="isImageMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> public TS_RFX_CONTEXT CreateTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy) { TS_RFX_CONTEXT rfxContext = new TS_RFX_CONTEXT(); rfxContext.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxContext.CodecChannelT.blockType = blockType_Value.WBT_CONTEXT; rfxContext.CodecChannelT.blockLen = 13; rfxContext.CodecChannelT.codecId = 0x01; rfxContext.CodecChannelT.channelId = 0x00; rfxContext.ctxId = 0x00; rfxContext.tileSize = 0x0040; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) flags = 0x0000; ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004; ushort qt = 0x0001; ushort r = 0x0000; rfxContext.properties = 0x0000; rfxContext.properties |= flags; rfxContext.properties |= (ushort)(cct << 3); rfxContext.properties |= (ushort)(xft << 5); rfxContext.properties |= (ushort)(et << 9); rfxContext.properties |= (ushort)(qt << 13); rfxContext.properties |= (ushort)(r << 15); return rfxContext; }
public async Task <IActionResult> IndexWithInputs() { try { using (var bodyStream = new StreamReader(Request.Body)) { var bodyText = await bodyStream.ReadToEndAsync(); dynamic obj = JsonConvert.DeserializeObject(bodyText); // retrieve the quant QuantizationFactorsArray quantArray = JsonHelper.RetrieveQuantsArray(obj.Params.QuantizationFactorsArray); EntropyAlgorithm algorithm = JsonHelper.CastTo <EntropyAlgorithm>(obj.Params.EntropyAlgorithm); _viewModel = new RFXDecodeViewModel(); // Updates parameters ((RFXDecodeViewModel)_viewModel).ProvideParam(quantArray, algorithm); Triplet <string> triplet = JsonHelper.RetrieveTriplet(obj.Inputs); ((RFXDecodeViewModel)_viewModel).ProvidePanelInputs(triplet.ToArray()); var envValues = new Dictionary <string, object>() { { ModelKey, _viewModel }, { isModelValid, true } }; SaveToSession(envValues); } return(Json(ReturnResult <string> .Success("Success"))); } catch (Exception ex) { return(Json(ReturnResult <string> .Fail(ex.Message))); } }
/// <summary> /// Method to send TS_RFX_CONTEXT to client. /// </summary> /// <param name="isImageMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> public void SendTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy) { this.admEntropyAlgorithm = entropy; this.admOperationMode = opMode; TS_RFX_CONTEXT rfxContext = rdprfxServer.CreateTsRfxContext(opMode, entropy); if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCtxId) { rfxContext.ctxId = 0x01; //set to an invalid value other than 0x00. } else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidTileSize) { rfxContext.tileSize = 0x0080; //set to an invalid value other than 0x0040. } else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidCct) { rfxContext.properties &= 0xFFF7; //set "cct" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidXft) { rfxContext.properties &= 0xFE1F; //set "xft" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxContext_InvalidQt) { rfxContext.properties &= 0x9FFF; //set "qt" to an invalid value: 0x0. } AddToPendingList(rfxContext); }
public static void RLGREncode(short[] input, EntropyAlgorithm mode, out byte[] output) { var rfxMode = (Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdprfx.EntropyAlgorithm)mode.Algorithm; var RLGREncoder = new RLGREncoder(); output = RLGREncoder.Encode(input, rfxMode); }
/// <summary> /// Constructor /// </summary> /// <param name="tsRfxCodecQuant"></param> /// <param name="mode"></param> public RemoteFXCodecContext(TS_RFX_CODEC_QUANT tsRfxCodecQuant, EntropyAlgorithm mode) { this.CodecQuantVals = new TS_RFX_CODEC_QUANT[] { tsRfxCodecQuant }; this.QuantIdxY = 0; this.QuantIdxCb = 0; this.QuantIdxCr = 0; this.Mode = mode; }
public static void RLGRDecode(byte[] input, EntropyAlgorithm mode, out short[] output) { var rfxMode = (Microsoft.Protocols.TestTools.StackSdk.RemoteDesktop.Rdprfx.EntropyAlgorithm)mode.Algorithm; var RLGRDecoder = new RLGRDecoder(); int comLength = RdpegfxTileUtils.TileSize * RdpegfxTileUtils.TileSize; output = RLGRDecoder.Decode(input, rfxMode, comLength); }
/// <summary> /// ALGR decode the input data. /// </summary> /// <param name="encodedData">The input data to be decoded.</param> /// <param name="rlgrMode">The RLGR mode.</param> /// <param name="lengthToDecode">The expected decoding size.</param> /// <returns></returns> public short[] Decode(byte[] encodedData, EntropyAlgorithm rlgrMode, int lengthToDecode) { encodedBytes = encodedData; //bitsToDecode = new BitArray(encodedData); dataOffset = 0; decodedList = new List <short>(); this.RLGR_Decode(rlgrMode, lengthToDecode); return(decodedList.ToArray()); }
/// <summary> /// ALGR decode the input data. /// </summary> /// <param name="encodedData">The input data to be decoded.</param> /// <param name="rlgrMode">The RLGR mode.</param> /// <param name="lengthToDecode">The expected decoding size.</param> /// <returns></returns> public short[] Decode(byte[] encodedData, EntropyAlgorithm rlgrMode, int lengthToDecode) { encodedBytes = encodedData; //bitsToDecode = new BitArray(encodedData); dataOffset = 0; decodedList = new List<short>(); this.RLGR_Decode(rlgrMode, lengthToDecode); return decodedList.ToArray(); }
public static void RLGRDecode(Triplet <byte[]> input, EntropyAlgorithm mode, bool useReduceExtrapolate, out Triplet <short[]> output) { var outlist = new List <short[]>(); foreach (var component in input) { short[] decodedComponent; RFXDecoderWrapper.RLGRDecode(component, mode, out decodedComponent); ComputeOriginalLL3FromDeltas(decodedComponent, useReduceExtrapolate); outlist.Add(decodedComponent); } output = new Triplet <short[]>(outlist[0], outlist[1], outlist[2]); }
/// <summary> /// Method to send an image to the client. /// </summary> /// <param name="image">The image to be sent.</param> /// <param name="destLeft">The left bound of the frame.</param> /// <param name="destTop">The top bound of the frame.</param> /// <param name="frameId">The index of the sending frame.</param> public static void SendImageToClient(Image image, ushort destLeft, ushort destTop, uint frameId) { OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1; Site.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId); Site.Log.Add(LogEntryKind.Comment, "Sending encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.", opMode, enAlgorithm, destLeft, destTop); rdprfxAdapter.SendImageToClient(image, opMode, enAlgorithm, destLeft, destTop); Site.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId); }
/// <summary> /// Do ALGR encode to the input data. /// </summary> /// <param name="inputArr">Input data to be encoded.</param> /// <param name="mode">The ALGR mode, can be RLGR1 or RLGR3.</param> /// <returns>The encoded data.</returns> public byte[] Encode(short[] inputArr, EntropyAlgorithm mode) { inputData = inputArr; nextInputIdx = 0; bufferOffset = 0; //offset&0xFFFFFFF8 = byte offset, offset&0x7 = bit offset pBuffer = new byte[inputArr.Length]; RLGR_Encode(mode); int numbytes = bufferOffset >> 3; int bitOffset = bufferOffset & 7; if (bitOffset != 0) numbytes++; byte[] encodedBytes = new byte[numbytes]; Array.Copy(pBuffer, encodedBytes, encodedBytes.Length); return encodedBytes; }
public ActionResult IndexWithInputs() { dynamic obj = GetJsonObject(Request.InputStream); foreach (var input in obj) { // TODO: refine this if (input != null && input.Inputs != null) { int layer = JsonHelper.CastTo <int>(input.Layer); if (layer == 0) { // TODO: refine this // retrieve the quant var quantArray = JsonHelper.RetrieveQuantsArray(input.Params.QuantizationFactorsArray); // retrive the progressive quants var progQuantList = new List <QuantizationFactorsArray>(); foreach (var layerQuant in input.Params.ProgQuantizationArray) { var layerQuants = JsonHelper.RetrieveQuantsArray(layerQuant); progQuantList.Add(layerQuants); } var progQuantarray = new ProgressiveQuantizationFactors { ProgQuants = progQuantList }; EntropyAlgorithm algorithm = JsonHelper.CastTo <EntropyAlgorithm>(input.Params.EntropyAlgorithm); UseDifferenceTile useDifferenceTile = JsonHelper.CastTo <UseDifferenceTile>(input.Params.UseDifferenceTile); UseReduceExtrapolate useReduceExtrapolate = JsonHelper.CastTo <UseReduceExtrapolate>(input.Params.UseReduceExtrapolate); _viewModel = new RFXPDecodeViewModel(0); ((RFXPDecodeViewModel)_viewModel).ProvideParam(quantArray, progQuantarray, algorithm, useDifferenceTile, useReduceExtrapolate); ((RFXPDecodeViewModel)_viewModel).ProvidePanelInputs(layer, input.Inputs[0], input.Inputs[1], input.Inputs[2]); Session[ModelKey] = _viewModel; Session[isPreFrameValid] = true; } Decode(input); // Updates Decode Status UpdateDecodeStatus(layer); } } Session[IsValid] = true; return(new HttpStatusCodeResult(HttpStatusCode.OK)); }
/// <summary> /// Method to send TS_RFX_TILESET to client. /// </summary> /// <param name="opMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="tileImages">The image array for tiles to be sent. The width and height must be less than or equals with 64.</param> /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param> /// <param name="codecQuantVals">Quant values array</param> /// <param name="quantIdxYs">Index array of Y component in Quant value array</param> /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param> /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param> public void SendTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, Image[] tileImages, TILE_POSITION[] positions, TS_RFX_CODEC_QUANT[] codecQuantVals = null, byte[] quantIdxYs = null, byte[] quantIdxCbs = null, byte[] quantIdxCrs = null) { this.admEntropyAlgorithm = entropy; this.admOperationMode = opMode; TS_RFX_TILESET rfxTileSet = rdprfxServer.CreateTsRfxTileSet(opMode, entropy, tileImages, positions, codecQuantVals, quantIdxYs, quantIdxCbs, quantIdxCrs); if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidIdx) { rfxTileSet.idx = 0x0001; //set to an invalid value other than 0x0000. } else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidLt) { rfxTileSet.properties &= 0xFFFE; //set "lt" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidCct) { rfxTileSet.properties &= 0xFFCF; //set "cct" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidXft) { rfxTileSet.properties &= 0xFC3F; //set "xft" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidQt) { rfxTileSet.properties &= 0x3FFF; //set "xft" to an invalid value: 0x0. } else if (this.currentTestType == RdprfxNegativeType.TsRfxTileSet_InvalidTileSize) { rfxTileSet.tileSize = 0x80; //set to an invalid value other than 0x40. } if (this.rdpbcgrAdapter.SimulatedScreen != null) { this.rdpbcgrAdapter.SimulatedScreen.SetRemoteFXTileSet(rfxTileSet, entropy); } AddToPendingList(rfxTileSet); if (!CheckIfClientSupports(opMode, entropy)) { Site.Log.Add(LogEntryKind.Debug, "The client Cap is not supported: OperationalMode = {0}, EntropyAlgorithm = {1}", opMode.ToString(), entropy.ToString()); } }
/// <summary> /// Constructor /// </summary> /// <param name="tsRfxCodecQuantVals"></param> /// <param name="quantIdxY"></param> /// <param name="quantIdxCb"></param> /// <param name="quantIdxCr"></param> /// <param name="mode"></param> public RemoteFXCodecContext(TS_RFX_CODEC_QUANT[] tsRfxCodecQuantVals, byte quantIdxY, byte quantIdxCb, byte quantIdxCr, EntropyAlgorithm mode) { if (tsRfxCodecQuantVals == null || tsRfxCodecQuantVals.Length == 0) { throw new ArgumentException("Parameter tsRfxCodecQuantVals cannot be null and its length must larger than 0."); } int maxIndex = tsRfxCodecQuantVals.Length - 1; if (quantIdxY > maxIndex || quantIdxCb > maxIndex || quantIdxCr > maxIndex) { throw new ArgumentException("Quant index for Y , Cb or Cr is/are larger than the size of tsRfxCodecQuantVals."); } this.CodecQuantVals = tsRfxCodecQuantVals; this.QuantIdxY = quantIdxY; this.QuantIdxCb = quantIdxCb; this.QuantIdxCr = quantIdxCr; this.Mode = mode; }
/// <summary> /// Copy from RDPRFX test suite code /// </summary> private void receiveAndLogClientRfxCapabilites() { uint maxRequestSize = 38055; // MS-RDPBCGR section 2.2.7.2.7 TS_RFX_ICAP[] clientRfxCaps; this.TestSite.Log.Add(LogEntryKind.Comment, "Receive and check client capabilities..."); rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientRfxCaps); if (clientRfxCaps != null) { foreach (TS_RFX_ICAP iCap in clientRfxCaps) { OperationalMode opMode = (OperationalMode)iCap.flags; EntropyAlgorithm enAlg = (EntropyAlgorithm)iCap.entropyBits; this.TestSite.Log.Add(LogEntryKind.Comment, "Client supports ({0}, {1}).", opMode, enAlg); } } }
/// <summary> /// Do ALGR encode to the input data. /// </summary> /// <param name="inputArr">Input data to be encoded.</param> /// <param name="mode">The ALGR mode, can be RLGR1 or RLGR3.</param> /// <returns>The encoded data.</returns> public byte[] Encode(short[] inputArr, EntropyAlgorithm mode) { inputData = inputArr; nextInputIdx = 0; bufferOffset = 0; //offset&0xFFFFFFF8 = byte offset, offset&0x7 = bit offset pBuffer = new byte[inputArr.Length]; RLGR_Encode(mode); int numbytes = bufferOffset >> 3; int bitOffset = bufferOffset & 7; if (bitOffset != 0) { numbytes++; } byte[] encodedBytes = new byte[numbytes]; Array.Copy(pBuffer, encodedBytes, encodedBytes.Length); return(encodedBytes); }
/// <summary> /// Method to check if the input pair of the operation mode and entropy algorithm is supported by the client. /// </summary> /// <param name="opMode">The operation mode.</param> /// <param name="entropy">The entropy algorithm.</param> /// <returns></returns> public bool CheckIfClientSupports(OperationalMode opMode, EntropyAlgorithm entropy) { TS_RFX_ICAP[] iCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData; foreach (TS_RFX_ICAP icap in iCaps) { if ((icap.flags & (byte)OperationalMode.ImageMode) == (byte)0 && ((byte)icap.entropyBits == (byte)entropy)) { //OperationalMode.ImageMode is not set, both the image mode and the video mode of the codec are supported return(true); } else if ((byte)icap.entropyBits == (byte)entropy) { //OperationalMode.ImageMode is set, only image mode is supported if (opMode == OperationalMode.ImageMode) { return(true); } } } return(false); }
/// <summary> /// Method to create TS_RFX_CONTEXT. /// </summary> /// <param name="isImageMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> public TS_RFX_CONTEXT CreateTsRfxContext(OperationalMode opMode, EntropyAlgorithm entropy) { TS_RFX_CONTEXT rfxContext = new TS_RFX_CONTEXT(); rfxContext.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxContext.CodecChannelT.blockType = blockType_Value.WBT_CONTEXT; rfxContext.CodecChannelT.blockLen = 13; rfxContext.CodecChannelT.codecId = 0x01; rfxContext.CodecChannelT.channelId = 0xFF; rfxContext.ctxId = 0x00; rfxContext.tileSize = 0x0040; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) { flags = 0x0000; } ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) { et = 0x0004; } ushort qt = 0x0001; ushort r = 0x0000; rfxContext.properties = 0x0000; rfxContext.properties |= flags; rfxContext.properties |= (ushort)(cct << 3); rfxContext.properties |= (ushort)(xft << 5); rfxContext.properties |= (ushort)(et << 9); rfxContext.properties |= (ushort)(qt << 13); rfxContext.properties |= (ushort)(r << 15); return(rfxContext); }
public void Rdprfx_HeaderMessage_PositiveTest_OrderTest_VersionsContextChannels() { #region Test Description /* Step 1: [RDPBCGR] establishing the connection. Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT. Step 3: [RDPRFX] Send Encode Header Messages to SUT in order of TS_RFX_SYNC -> TS_RFX_VERSIONS -> TS_RFX_CONTEXT -> TS_RFX_CHANNELS. Step 4: [RDPRFX] Send one frame of Encode Data Messages to SUT. Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT. Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol); #endregion #region RDPBCGR Connection //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability."); setServerCapabilitiesWithRemoteFxSupported(); //Waiting for the RDP connection sequence. this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection."); this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on."); this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER); #endregion //Initial the RDPRFX adapter context. rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); TS_RFX_ICAP[] clientSupportedCaps; rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps); uint frameId = 0; //The index of the sending frame. OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3; ushort destLeft = 0; //the left bound of the frame. ushort destTop = 0; //the top bound of the frame. //Set OperationalMode/EntropyAlgorithm to valid pair. if (clientSupportedCaps != null) { opMode = (OperationalMode)clientSupportedCaps[0].flags; enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits; } this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.", opMode, enAlgorithm, destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending the encode header messages in the order of TS_RFX_SYNC -> TS_RFX_VERSIONS -> TS_RFX_CONTEXT -> TS_RFX_CHANNELS."); rdprfxAdapter.SendTsRfxSync(); rdprfxAdapter.SendTsRfxCodecVersions(); rdprfxAdapter.SendTsRfxContext(opMode, enAlgorithm); rdprfxAdapter.SendTsRfxChannels(); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending the encode data messages to client."); rdprfxAdapter.SendTsRfxFrameBegin(0); rdprfxAdapter.SendTsRfxRegion(); rdprfxAdapter.SendTsRfxTileSet(opMode, enAlgorithm, image_64X64); rdprfxAdapter.SendTsRfxFrameEnd(); rdprfxAdapter.FlushEncodedData(destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU."); rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime); #endregion }
public void Rdprfx_HeaderMessage_NegativeTest_UnspecifiedMessage() { #region Test Description /* Step 1: [RDPBCGR] establish the RDP connection. Step 2: [RDPRFX] send one unspecified message to client. Step 3: [RDPRFX] expect SUT terminate the RDP connectioin. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol); #endregion #region RDPBCGR Connection //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability."); setServerCapabilitiesWithRemoteFxSupported(); //Waiting for the RDP connection sequence. this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection."); this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on."); this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER); #endregion //Initial the RDPRFX adapter context. rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); #region Fill parameters TS_RFX_ICAP[] clientSupportedCaps; rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out clientSupportedCaps); OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3; ushort destLeft = 0; //the left bound of the frame. ushort destTop = 0; //the top bound of the frame. //Set OperationalMode/EntropyAlgorithm to valid pair. if (clientSupportedCaps != null) { opMode = (OperationalMode)clientSupportedCaps[0].flags; enAlgorithm = (EntropyAlgorithm)clientSupportedCaps[0].entropyBits; } #endregion this.TestSite.Log.Add(LogEntryKind.Comment, "Set the test type to {0}.", RdprfxNegativeType.UnspecifiedBlockType); rdprfxAdapter.SetTestType(RdprfxNegativeType.UnspecifiedBlockType); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Encode Header/Data Messages to client."); rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the client terminates the RDP connection."); bool bDisconnected = rdpbcgrAdapter.WaitForDisconnection(waitTime); this.TestSite.Assert.IsTrue(bDisconnected, "Client is expected to drop the connection when received an invalid message."); #endregion }
public void Rdprfx_VerifyClientCapabilities() { #region Test Description /* * Step 1: trigger SUT initial a connection request. * Step 2: continue the connection until Capabilities Exchange phase. * Step 3: server sends Demand Active PDU to SUT. * Step 4: Expect SUT responds a Confirm Active PDU and verify this PDU. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol); #endregion #region Connection initialization phase //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); #region Connection Initiation phase //Expect SUT send a Client X.224 Connection Request PDU. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client X.224 Connection Request PDU"); this.rdpbcgrAdapter.ExpectPacket <Client_X_224_Connection_Request_Pdu>(waitTime); //Respond a Server X.224 Connection Confirm PDU and set the EXTENDED_CLIENT_DATA_SUPPORTED flag. this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server X.224 Connection Confirm PDU to SUT. Selected protocol: {0}; Extended Client Data supported: true", selectedProtocol.ToString()); this.rdpbcgrAdapter.Server_X_224_Connection_Confirm(selectedProtocol, true, true, NegativeType.None); #endregion #region Basic Setting Exchange phase //Expect SUT send Client MCS Connect Initial PDU. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Connect Initial PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request>(waitTime); //Respond a Server MCS Connect Response PDU with GCC Conference Create Response. this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server MCS Connect Response PDU to SUT. Encryption Method {0}; Encryption Level: {1}; RDP Version Code: {2}.", enMethod.ToString(), enLevel.ToString(), TS_UD_SC_CORE_version_Values.V2.ToString()); this.rdpbcgrAdapter.Server_MCS_Connect_Response(enMethod, enLevel, TS_UD_SC_CORE_version_Values.V2, NegativeType.None); #endregion #region Channel Connection phase //Expect a Client MCS Erect Domain Request PDU. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Erect Domain Request PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Erect_Domain_Request>(waitTime); //Expect a Client MCS Attach User Request PDU this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client MCS Attach User Request PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_MCS_Attach_User_Request>(waitTime); //Respond a Server MCS Channel Join Confirm PDU. this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server MCS Channel Join Confirm PDU to SUT."); this.rdpbcgrAdapter.MCSAttachUserConfirm(NegativeType.None); //Expect SUT start a channel join sequence this.TestSite.Log.Add(LogEntryKind.Comment, "Expect SUT to start the channel join sequence."); this.rdpbcgrAdapter.ChannelJoinRequestAndConfirm(NegativeType.None); #endregion #region RDP Security Commencement phase //Expects SUT continue the connection by sending a Client Security Exchange PDU //(if Standard RDP Security mechanisms are being employed) or a Client Info PDU. if (transportProtocol == EncryptedProtocol.Rdp) { this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send Client a Security Exchange PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_Security_Exchange_Pdu>(waitTime); } #endregion #region Secure Setting Exchange phase //Expect a Client Info PDU. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send Client a Client Info PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_Info_Pdu>(waitTime); #endregion #region Licensing phase //Send SUT a Server License Error Pdu - Valid Client. this.TestSite.Log.Add(LogEntryKind.Comment, "Sending a Server License Error Pdu - Valid Client to SUT."); this.rdpbcgrAdapter.Server_License_Error_Pdu_Valid_Client(NegativeType.None); #endregion #region Capabilities Exchange phase //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability. Server advertises the support for MS-RDPRFX."); setServerCapabilitiesWithRemoteFxSupported(); //Send a Server Demand Active PDU to SUT. this.TestSite.Log.Add(LogEntryKind.Comment, "Sending a Server Demand Active PDU to SUT."); this.rdpbcgrAdapter.Server_Demand_Active(NegativeType.None); //Expect SUT respond a Client Confirm Active PDU. //Once the Confirm Active PDU has been sent, the client can start sending input PDUs (see section 2.2.8) to the server. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting SUT to send a Client Confirm Active PDU."); this.rdpbcgrAdapter.ExpectPacket <Client_Confirm_Active_Pdu>(waitTime); #endregion //Initial the RDPRFX adapter context. this.rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); //Verify the Client capabilites. TS_RFX_ICAP[] supportedRfxCaps; this.rdprfxAdapter.ReceiveAndCheckClientCapabilities(maxRequestSize, out supportedRfxCaps); if (supportedRfxCaps != null) { foreach (TS_RFX_ICAP iCap in supportedRfxCaps) { OperationalMode opMode = (OperationalMode)iCap.flags; EntropyAlgorithm enAlg = (EntropyAlgorithm)iCap.entropyBits; this.TestSite.Log.Add(LogEntryKind.Comment, "Client supports ({0}, {1}).", opMode, enAlg); } } #endregion #endregion }
// The output format is // firstPass [X, Y, Z] // ProgressivePass1 [encodedX, encodedY, encodedZ] // ProgressivePass1 [rawX, rawY, rawZ] // ... public static void RLGR_SRLEncode(List <Triplet <short[]> > input, ProgressiveQuantizationFactors proQuants, EntropyAlgorithm mode, bool UseReduceExtrapolate, out List <Triplet <byte[]> > output) { output = new List <Triplet <byte[]> >(); byte[] x, y, z; // fisrt pass Triplet <short[]> firstPass = input[0]; ComputeLL3Deltas(firstPass, UseReduceExtrapolate); RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.X, mode, out x); RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.Y, mode, out y); RFXEncode.RFXEncoderWrapper.RLGREncode(firstPass.Z, mode, out z); output.Add(new Triplet <byte[]>(x, y, z)); // fake encodingContext used for SRL encode var encodingContext = new RfxProgressiveCodecContext(new [] { RdpegfxTileUtils.GetCodecQuant(ImageQuality_Values.Midium) }, 0, 0, 0, UseReduceExtrapolate); encodingContext.DAS = new DwtTile(firstPass.X, firstPass.Y, firstPass.Z); var progQuantList = new List <RFX_PROGRESSIVE_CODEC_QUANT>(); foreach (var quant in proQuants.ProgQuants) { progQuantList.Add(Utility.ConvertProgQuant(quant)); } // progressive pass for (int i = 1; i < input.Count; i++) { Triplet <short[]> progressivePass = input[i]; encodingContext.ProgQ = new DwtTile(progressivePass.X, progressivePass.Y, progressivePass.Z); encodingContext.prevProgQuant = progQuantList[i - 1]; EncodedTile encodedTile = SRLEncode(encodingContext, progQuantList[i]); output.Add(new Triplet <byte[]>(encodedTile.YEncodedData, encodedTile.CbEncodedData, encodedTile.CrEncodedData)); output.Add(new Triplet <byte[]>(encodedTile.YRawData, encodedTile.CbRawData, encodedTile.CrRawData)); encodingContext.DAS.Add(new DwtTile(progressivePass.X, progressivePass.Y, progressivePass.Z)); encodingContext.prevProgQuant = progQuantList[i]; } }
/// <summary> /// Method to create TS_RFX_TILESET. /// </summary> /// <param name="opMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="tileImages">An array of bitmaps in Image type for a tile. The width and heigth must be less than or equals with 64.</param> /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param> /// <param name="codecQuantVals">Quant values array</param> /// <param name="quantIdxYs">Index array of Y component in Quant value array</param> /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param> /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param> /// <returns></returns> public TS_RFX_TILESET CreateTsRfxTileSet( OperationalMode opMode, EntropyAlgorithm entropy, Image[] tileImages, TILE_POSITION[] positions, TS_RFX_CODEC_QUANT[] codecQuantVals = null, byte[] quantIdxYs = null, byte[] quantIdxCbs = null, byte[] quantIdxCrs = null ) { if (codecQuantVals == null) { codecQuantVals = new TS_RFX_CODEC_QUANT[1]; codecQuantVals[0] = codecQuant; } TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET(); rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION; rfxTileSet.CodecChannelT.blockLen = 22 + 5; rfxTileSet.CodecChannelT.codecId = 0x01; rfxTileSet.CodecChannelT.channelId = 0x00; rfxTileSet.subtype = 0xCAC2; rfxTileSet.idx = 0x0000; ushort lt = 0x0001; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) flags = 0x0000; ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004; ushort qt = 0x0001; rfxTileSet.properties = lt; rfxTileSet.properties |= (ushort)(flags << 1); rfxTileSet.properties |= (ushort)(cct << 4); rfxTileSet.properties |= (ushort)(xft << 6); rfxTileSet.properties |= (ushort)(et << 10); rfxTileSet.properties |= (ushort)(qt << 14); rfxTileSet.numQuant = (byte)codecQuantVals.Length; rfxTileSet.tileSize = RdprfxServer.TileSize; rfxTileSet.numTiles = 1; rfxTileSet.quantVals = codecQuantVals; byte[] yData, cbData, crData; rfxTileSet.tiles = new TS_RFX_TILE[tileImages.Length]; rfxTileSet.numTiles = (ushort) rfxTileSet.tiles.Length; for (int i = 0; i < tileImages.Length; i++) { byte quantIdxY = quantIdxYs == null ? (byte)0 : (quantIdxYs.Length > i ? quantIdxYs[i] : (byte)0); byte quantIdxCb = quantIdxCbs == null ? (byte)0 : (quantIdxCbs.Length > i ? quantIdxCbs[i] : (byte)0); byte quantIdxCr = quantIdxCrs == null ? (byte)0 : (quantIdxCrs.Length > i ? quantIdxCrs[i] : (byte)0); RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuantVals, quantIdxY, quantIdxCb, quantIdxCr, entropy); RemoteFXEncoder.EncodeTile(tileImages[i], 0, 0, encodingContext); yData = encodingContext.YData; cbData = encodingContext.CbData; crData = encodingContext.CrData; rfxTileSet.tiles[i].BlockT.blockType = blockType_Value.CBT_TILE; rfxTileSet.tiles[i].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length); rfxTileSet.tiles[i].quantIdxY = quantIdxY; rfxTileSet.tiles[i].quantIdxCb = quantIdxCb; rfxTileSet.tiles[i].quantIdxCr = quantIdxCr; rfxTileSet.tiles[i].xIdx = positions[i].xIdx; rfxTileSet.tiles[i].yIdx = positions[i].yIdx; rfxTileSet.tiles[i].YLen = (ushort)yData.Length; rfxTileSet.tiles[i].CbLen = (ushort)cbData.Length; rfxTileSet.tiles[i].CrLen = (ushort)crData.Length; rfxTileSet.tiles[i].YData = yData; rfxTileSet.tiles[i].CbData = cbData; rfxTileSet.tiles[i].CrData = crData; rfxTileSet.tilesDataSize += rfxTileSet.tiles[i].BlockT.blockLen; rfxTileSet.CodecChannelT.blockLen = (uint)(22 + 5 * rfxTileSet.numQuant + rfxTileSet.tilesDataSize); } return rfxTileSet; }
/// <summary> /// Pack a Rdprfx message for a tile image. /// </summary> /// <param name="index"> Frame index in frame begin block.</param> /// <param name="opMode"> Indicate Operational Mode.</param> /// <param name="entropy"> Indicate Entropy Algorithm.</param> /// <param name="tileImage"> The image to be encoded as RFX codec.</param> /// <return> A byte array of image encoded as RFX codec.</return> private byte[] PackRfxTileImage(uint index, OperationalMode opMode, EntropyAlgorithm entropy, System.Drawing.Image tileImage) { lock (syncLocker) { pendingRfxBuffer.Clear(); } if (index == 0 || opMode == OperationalMode.ImageMode) { TS_RFX_SYNC rfxSync = rdprfxServer.CreateTsRfxSync(); AddToPendingList(rfxSync); TS_RFX_CODEC_VERSIONS rfxVersions = rdprfxServer.CreateTsRfxCodecVersions(); AddToPendingList(rfxVersions); TS_RFX_CHANNELS rfxChannels = rdprfxServer.CreateTsRfxChannels(); AddToPendingList(rfxChannels); TS_RFX_CONTEXT rfxContext = rdprfxServer.CreateTsRfxContext(opMode, entropy); AddToPendingList(rfxContext); } TS_RFX_FRAME_BEGIN rfxBegin = rdprfxServer.CreateTsRfxFrameBegin(index); AddToPendingList(rfxBegin); TS_RFX_REGION rfxRegion = rdprfxServer.CreateTsRfxRegion(); AddToPendingList(rfxRegion); TS_RFX_TILESET rfxTileSet = rdprfxServer.CreateTsRfxTileSet(opMode, entropy, tileImage); AddToPendingList(rfxTileSet); TS_RFX_FRAME_END rfxEnd = rdprfxServer.CreateTsRfxFrameEnd(); AddToPendingList(rfxEnd); if (this.bcgrAdapter.SimulatedScreen != null) { this.bcgrAdapter.SimulatedScreen.SetRemoteFXRegion(rfxRegion); this.bcgrAdapter.SimulatedScreen.SetRemoteFXTileSet(rfxTileSet, entropy); } lock (syncLocker) { return pendingRfxBuffer.ToArray(); } }
// // Routine that outputs a stream of RLGR1/RLGR3-encoded bits // void RLGR_Encode( EntropyAlgorithm rlgrMode // RLGR1 || RLGR3 ) { // initialize the parameters int k = 1; int kp = 1 << LSGR; //int kr = 1; int krp = 1 << LSGR; // process all the input coefficients while (hasMoreData()) { int input; if (k != 0) { // RUN-LENGTH MODE // collect the run of zeros in the input stream int numZeros = 0; while ((input = GetNextInput()) == 0) { ++numZeros; if (!hasMoreData()) break; } // emit output zebros int runmax = 1 << k; while (numZeros >= runmax) { OutputBit(1, 0); // output a zero bit numZeros -= runmax; k = UpdateParam(ref kp, UP_GR); // update kp, k runmax = 1 << k; } // output a 1 to terminate runs OutputBit(1, 1); // output the remaining run length using k bits OutputBits(k, numZeros); if (input != 0) { // encode the nonzero value using GR coding int mag = Math.Abs(input); // absolute value of input coefficient int sign = (input < 0 ? 1 : 0); // sign of input coefficient OutputBit(1, sign); // output the sign bit CodeGR(ref krp, (uint)(mag - 1)); // output GR code for (mag - 1) k = UpdateParam(ref kp, -DN_GR); } } else { // GOLOMB-RICE MODE if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1) { // RLGR1 variant // convert input to (2*magnitude - sign), encode using GR code uint twoMs = Get2MagSign(GetNextInput()); CodeGR(ref krp, twoMs); // update k, kp if (twoMs == 0) { k = UpdateParam(ref kp, UQ_GR); } else { k = UpdateParam(ref kp, -DQ_GR); } } else // rlgrMode == RLGR3 { // RLGR3 variant // convert the next two input values to (2*magnitude - sign) and // encode their sum using GR code uint twoMs1 = Get2MagSign(GetNextInput()); uint twoMs2 = 0; if (hasMoreData()) { twoMs2 = Get2MagSign(GetNextInput()); } uint sum2Ms = twoMs1 + twoMs2; CodeGR(ref krp, sum2Ms); // encode binary representation of the first input (twoMs1). OutputBits((int)GetMinBits((int)sum2Ms), (int)twoMs1); // update k,kp for the two input values if (twoMs1 != 0 && twoMs2 != 0) { k = UpdateParam(ref kp, -2 * DQ_GR); } else if (twoMs1 == 0 && twoMs2 == 0) { k = UpdateParam(ref kp, 2 * UQ_GR); } } } } }
/// <summary> /// Method to send one frame of encoded data message to client. /// </summary> /// <param name="image">The image to be sent.</param> /// <param name="opMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="destLeft">Left bound of the frame.</param> /// <param name="destTop">Left bound of the frame.</param> public void SendImageToClient(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy, ushort destLeft, ushort destTop) { if (image == null) { Site.Log.Add(LogEntryKind.Debug, "[In iRdprfxAdapter.SendImageToClient Method] The image to be send is null."); return; } TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize); for (int idx = 0; idx < tileImageArr.Length; idx++) { if (idx == 0 || opMode == OperationalMode.ImageMode) { SendTsRfxSync(); SendTsRfxCodecVersions(); SendTsRfxChannels(); SendTsRfxContext(opMode, entropy); } SendTsRfxFrameBegin((uint)idx); SendTsRfxRegion(); SendTsRfxTileSet(opMode, entropy, tileImageArr[idx].image); SendTsRfxFrameEnd(); FlushEncodedData((ushort)(destLeft + tileImageArr[idx].x), (ushort)(destTop + tileImageArr[idx].y)); if (currentTestType != RdprfxNegativeType.None) { // Only send one message if it is in a negative test case. break; } } }
/// <summary> /// Constructor /// </summary> /// <param name="tsRfxCodecQuantVals"></param> /// <param name="quantIdxY"></param> /// <param name="quantIdxCb"></param> /// <param name="quantIdxCr"></param> /// <param name="mode"></param> public RemoteFXCodecContext(TS_RFX_CODEC_QUANT[] tsRfxCodecQuantVals, byte quantIdxY, byte quantIdxCb, byte quantIdxCr, EntropyAlgorithm mode) { if(tsRfxCodecQuantVals == null || tsRfxCodecQuantVals.Length == 0) { throw new ArgumentException("Parameter tsRfxCodecQuantVals cannot be null and its length must larger than 0."); } int maxIndex = tsRfxCodecQuantVals.Length -1; if (quantIdxY > maxIndex || quantIdxCb > maxIndex || quantIdxCr > maxIndex) { throw new ArgumentException("Quant index for Y , Cb or Cr is/are larger than the size of tsRfxCodecQuantVals."); } this.CodecQuantVals = tsRfxCodecQuantVals; this.QuantIdxY = quantIdxY; this.QuantIdxCb = quantIdxCb; this.QuantIdxCr = quantIdxCr; this.Mode = mode; }
public void Rdprfx_ImageMode_PositiveTest_RLGR3() { #region Test Description /* * Step 1: [RDPBCGR] establishing the connection. * Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT. * Step 3: [RDPRFX] Send Encode Header Messages to SUT. * Step 4: [RDPRFX] Send one frame of Encode Data Messages (encoded with RLGR3) to SUT. * Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT. * Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol, true); #endregion #region RDPBCGR Connection //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability."); setServerCapabilitiesWithRemoteFxSupported(); //Waiting for the RDP connection sequence. this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection."); this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on."); this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER); #endregion //Initial the RDPRFX adapter context. rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); receiveAndLogClientRfxCapabilites(); uint frameId = 0; //The index of the sending frame. OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3; ushort destLeft = 64; //the left bound of the frame. ushort destTop = 64; //the top bound of the frame. //Check if the above setting is supported by the client. if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm)) { this.TestSite.Log.Add(LogEntryKind.Comment, "the input pair of Operational Mode ({0}) / Entropy Algorithm ({1}) is not supported by the client, so stop running this test case.", opMode, enAlgorithm); return; } this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending one frame of encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.", opMode, enAlgorithm, destLeft, destTop); rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU."); rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime); this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true."); Rectangle compareRect = new Rectangle(destLeft, destTop, image_64X64.Width, image_64X64.Height); this.VerifySUTDisplay(true, compareRect); #endregion }
// // Routine that outputs a stream of RLGR1/RLGR3-encoded bits // void RLGR_Encode( EntropyAlgorithm rlgrMode // RLGR1 || RLGR3 ) { // initialize the parameters int k = 1; int kp = 1 << LSGR; //int kr = 1; int krp = 1 << LSGR; // process all the input coefficients while (hasMoreData()) { int input; if (k != 0) { // RUN-LENGTH MODE // collect the run of zeros in the input stream int numZeros = 0; while ((input = GetNextInput()) == 0) { ++numZeros; if (!hasMoreData()) { break; } } // emit output zebros int runmax = 1 << k; while (numZeros >= runmax) { OutputBit(1, 0); // output a zero bit numZeros -= runmax; k = UpdateParam(ref kp, UP_GR); // update kp, k runmax = 1 << k; } // output a 1 to terminate runs OutputBit(1, 1); // output the remaining run length using k bits OutputBits(k, numZeros); if (input != 0) { // encode the nonzero value using GR coding int mag = Math.Abs(input); // absolute value of input coefficient int sign = (input < 0 ? 1 : 0); // sign of input coefficient OutputBit(1, sign); // output the sign bit CodeGR(ref krp, (uint)(mag - 1)); // output GR code for (mag - 1) k = UpdateParam(ref kp, -DN_GR); } } else { // GOLOMB-RICE MODE if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1) { // RLGR1 variant // convert input to (2*magnitude - sign), encode using GR code uint twoMs = Get2MagSign(GetNextInput()); CodeGR(ref krp, twoMs); // update k, kp if (twoMs == 0) { k = UpdateParam(ref kp, UQ_GR); } else { k = UpdateParam(ref kp, -DQ_GR); } } else // rlgrMode == RLGR3 { // RLGR3 variant // convert the next two input values to (2*magnitude - sign) and // encode their sum using GR code uint twoMs1 = Get2MagSign(GetNextInput()); uint twoMs2 = 0; if (hasMoreData()) { twoMs2 = Get2MagSign(GetNextInput()); } uint sum2Ms = twoMs1 + twoMs2; CodeGR(ref krp, sum2Ms); // encode binary representation of the first input (twoMs1). OutputBits((int)GetMinBits((int)sum2Ms), (int)twoMs1); // update k,kp for the two input values if (twoMs1 != 0 && twoMs2 != 0) { k = UpdateParam(ref kp, -2 * DQ_GR); } else if (twoMs1 == 0 && twoMs2 == 0) { k = UpdateParam(ref kp, 2 * UQ_GR); } } } } }
// // Routine that reads and decodes stream of RLGR data // void RLGR_Decode( EntropyAlgorithm rlgrMode, // RLGR1 || RLGR3 int lenToDecode ) { int termsToDecode = lenToDecode; // initialize the parameters int k = 1; int kp = k << LSGR; int kr = 1; int krp = kr << LSGR; while (termsToDecode > 0) { int run; if (k != 0) { // RL MODE while (GetBits(1) == 0) { if (termsToDecode > 0) { // we have an RL escape "0", which translates to a run (1<<k) of zeros WriteZeroes((uint)(1 << k), ref termsToDecode); k = UpdateParam(ref kp, UP_GR); // raise k and kp up because of zero run } else { break; } } if (termsToDecode > 0) { // next k bits will contain remaining run of zeros run = (int)GetBits((uint)k); WriteZeroes((uint)run, ref termsToDecode); } if (termsToDecode > 0) { // get nonzero value, starting with sign bit and // then GRCode for magnitude - 1 uint sign = GetBits(1); // magnitude - 1 was coded (because it was nonzero) int mag = (int)GetGRCode(ref krp, ref kr) + 1; WriteValue(sign != 0 ? -mag : mag, ref termsToDecode); k = UpdateParam(ref kp, -DN_GR); // lower k and kp because of nonzero term } } else { // GR (GOLOMB-RICE) MODE uint mag = GetGRCode(ref krp, ref kr); // values coded are 2*magnitude - sign if (rlgrMode == EntropyAlgorithm.CLW_ENTROPY_RLGR1) { if (mag == 0) { WriteValue(0, ref termsToDecode); k = UpdateParam(ref kp, UQ_GR); // raise k and kp due to zero } else { WriteValue(GetIntFrom2MagSign(mag), ref termsToDecode); k = UpdateParam(ref kp, -DQ_GR); // lower k and kp due to nonzero } } else // rlgrMode == RLGR3 { // In GR mode FOR RLGR3, we have encoded the // sum of two (2*mag - sign) values // maximum possible bits for first term uint nIdx = GetMinBits(mag); // decode val1 is first term's (2*mag - sign) value uint val1 = GetBits(nIdx); // val2 is second term's (2*mag - sign) value uint val2 = mag - val1; if (val1 != 0 && val2 != 0) { // raise k and kp if both terms nonzero k = UpdateParam(ref kp, -2 * DQ_GR); } else if (val1 == 0 && val2 == 0) { // lower k and kp if both terms zero k = UpdateParam(ref kp, 2 * UQ_GR); } WriteValue(GetIntFrom2MagSign(val1), ref termsToDecode); if (termsToDecode > 0) { WriteValue(GetIntFrom2MagSign(val2), ref termsToDecode); } } } } }
/// <summary> /// Method to create TS_RFX_TILESET. /// </summary> /// <param name="isImageMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="tileImage">A RgbTile. The width and heigth must be less than or equals with 64.</param> public TS_RFX_TILESET CreateTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, RgbTile tileImage) { TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET(); rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION; rfxTileSet.CodecChannelT.blockLen = 22 + 5; rfxTileSet.CodecChannelT.codecId = 0x01; rfxTileSet.CodecChannelT.channelId = 0x00; rfxTileSet.subtype = 0xCAC2; rfxTileSet.idx = 0x0000; ushort lt = 0x0001; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) { flags = 0x0000; } ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) { et = 0x0004; } ushort qt = 0x0001; rfxTileSet.properties = lt; rfxTileSet.properties |= (ushort)(flags << 1); rfxTileSet.properties |= (ushort)(cct << 4); rfxTileSet.properties |= (ushort)(xft << 6); rfxTileSet.properties |= (ushort)(et << 10); rfxTileSet.properties |= (ushort)(qt << 14); rfxTileSet.numQuant = 1; rfxTileSet.tileSize = RdprfxServer.TileSize; rfxTileSet.numTiles = 1; rfxTileSet.quantVals = new TS_RFX_CODEC_QUANT[1]; rfxTileSet.quantVals[0] = codecQuant; byte[] yData, cbData, crData; RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuant, entropy); RemoteFXEncoder.EncodeTile(tileImage, 0, 0, encodingContext); yData = encodingContext.YData; cbData = encodingContext.CbData; crData = encodingContext.CrData; rfxTileSet.tiles = new TS_RFX_TILE[1]; rfxTileSet.tiles[0].BlockT.blockType = blockType_Value.CBT_TILE; rfxTileSet.tiles[0].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length); rfxTileSet.tiles[0].quantIdxY = 0; rfxTileSet.tiles[0].quantIdxCb = 0; rfxTileSet.tiles[0].quantIdxCr = 0; rfxTileSet.tiles[0].xIdx = 0; rfxTileSet.tiles[0].yIdx = 0; rfxTileSet.tiles[0].YLen = (ushort)yData.Length; rfxTileSet.tiles[0].CbLen = (ushort)cbData.Length; rfxTileSet.tiles[0].CrLen = (ushort)crData.Length; rfxTileSet.tiles[0].YData = yData; rfxTileSet.tiles[0].CbData = cbData; rfxTileSet.tiles[0].CrData = crData; rfxTileSet.tilesDataSize = rfxTileSet.tiles[0].BlockT.blockLen; rfxTileSet.CodecChannelT.blockLen = 22 + 5 + rfxTileSet.tilesDataSize; return(rfxTileSet); }
/// <summary> /// Method to create TS_RFX_TILESET. /// </summary> /// <param name="opMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="tileImages">An array of bitmaps in Image type for a tile. The width and heigth must be less than or equals with 64.</param> /// <param name="positions">A TILE_POSITION array indicating the positions of each tile images</param> /// <param name="codecQuantVals">Quant values array</param> /// <param name="quantIdxYs">Index array of Y component in Quant value array</param> /// <param name="quantIdxCbs">Index array of Cb component in Quant value array</param> /// <param name="quantIdxCrs">Index array of Cr component in Quant value array</param> /// <returns></returns> public TS_RFX_TILESET CreateTsRfxTileSet( OperationalMode opMode, EntropyAlgorithm entropy, Image[] tileImages, TILE_POSITION[] positions, TS_RFX_CODEC_QUANT[] codecQuantVals = null, byte[] quantIdxYs = null, byte[] quantIdxCbs = null, byte[] quantIdxCrs = null ) { if (codecQuantVals == null) { codecQuantVals = new TS_RFX_CODEC_QUANT[1]; codecQuantVals[0] = codecQuant; } TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET(); rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION; rfxTileSet.CodecChannelT.blockLen = 22 + 5; rfxTileSet.CodecChannelT.codecId = 0x01; rfxTileSet.CodecChannelT.channelId = 0x00; rfxTileSet.subtype = 0xCAC2; rfxTileSet.idx = 0x0000; ushort lt = 0x0001; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) { flags = 0x0000; } ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) { et = 0x0004; } ushort qt = 0x0001; rfxTileSet.properties = lt; rfxTileSet.properties |= (ushort)(flags << 1); rfxTileSet.properties |= (ushort)(cct << 4); rfxTileSet.properties |= (ushort)(xft << 6); rfxTileSet.properties |= (ushort)(et << 10); rfxTileSet.properties |= (ushort)(qt << 14); rfxTileSet.numQuant = (byte)codecQuantVals.Length; rfxTileSet.tileSize = RdprfxServer.TileSize; rfxTileSet.numTiles = 1; rfxTileSet.quantVals = codecQuantVals; byte[] yData, cbData, crData; rfxTileSet.tiles = new TS_RFX_TILE[tileImages.Length]; rfxTileSet.numTiles = (ushort)rfxTileSet.tiles.Length; for (int i = 0; i < tileImages.Length; i++) { byte quantIdxY = quantIdxYs == null ? (byte)0 : (quantIdxYs.Length > i ? quantIdxYs[i] : (byte)0); byte quantIdxCb = quantIdxCbs == null ? (byte)0 : (quantIdxCbs.Length > i ? quantIdxCbs[i] : (byte)0); byte quantIdxCr = quantIdxCrs == null ? (byte)0 : (quantIdxCrs.Length > i ? quantIdxCrs[i] : (byte)0); RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuantVals, quantIdxY, quantIdxCb, quantIdxCr, entropy); RemoteFXEncoder.EncodeTile(tileImages[i], 0, 0, encodingContext); yData = encodingContext.YData; cbData = encodingContext.CbData; crData = encodingContext.CrData; rfxTileSet.tiles[i].BlockT.blockType = blockType_Value.CBT_TILE; rfxTileSet.tiles[i].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length); rfxTileSet.tiles[i].quantIdxY = quantIdxY; rfxTileSet.tiles[i].quantIdxCb = quantIdxCb; rfxTileSet.tiles[i].quantIdxCr = quantIdxCr; rfxTileSet.tiles[i].xIdx = positions[i].xIdx; rfxTileSet.tiles[i].yIdx = positions[i].yIdx; rfxTileSet.tiles[i].YLen = (ushort)yData.Length; rfxTileSet.tiles[i].CbLen = (ushort)cbData.Length; rfxTileSet.tiles[i].CrLen = (ushort)crData.Length; rfxTileSet.tiles[i].YData = yData; rfxTileSet.tiles[i].CbData = cbData; rfxTileSet.tiles[i].CrData = crData; rfxTileSet.tilesDataSize += rfxTileSet.tiles[i].BlockT.blockLen; rfxTileSet.CodecChannelT.blockLen = (uint)(22 + 5 * rfxTileSet.numQuant + rfxTileSet.tilesDataSize); } return(rfxTileSet); }
/// <summary> /// Set TS_RFX_TILESET for RemoteFX codec image /// </summary> /// <param name="rfxTileSet"></param> /// <param name="entropy"></param> public void SetRemoteFXTileSet(TS_RFX_TILESET rfxTileSet, EntropyAlgorithm entropy) { remoteFXContext.TileSet = rfxTileSet; remoteFXContext.Entropy = entropy; }
/// <summary> /// Method to create TS_RFX_TILESET. /// </summary> /// <param name="isImageMode">Indicates the operational mode.</param> /// <param name="entropy">Indicates the entropy algorithm.</param> /// <param name="tileImage">A RgbTile. The width and heigth must be less than or equals with 64.</param> public TS_RFX_TILESET CreateTsRfxTileSet(OperationalMode opMode, EntropyAlgorithm entropy, RgbTile tileImage) { TS_RFX_TILESET rfxTileSet = new TS_RFX_TILESET(); rfxTileSet.CodecChannelT = new TS_RFX_CODEC_CHANNELT(); rfxTileSet.CodecChannelT.blockType = blockType_Value.WBT_EXTENSION; rfxTileSet.CodecChannelT.blockLen = 22 + 5; rfxTileSet.CodecChannelT.codecId = 0x01; rfxTileSet.CodecChannelT.channelId = 0x00; rfxTileSet.subtype = 0xCAC2; rfxTileSet.idx = 0x0000; ushort lt = 0x0001; ushort flags = 0x0002; if (opMode == OperationalMode.VideoMode) flags = 0x0000; ushort cct = 0x0001; ushort xft = 0x0001; ushort et = 0x0001; if (entropy == EntropyAlgorithm.CLW_ENTROPY_RLGR3) et = 0x0004; ushort qt = 0x0001; rfxTileSet.properties = lt; rfxTileSet.properties |= (ushort)(flags << 1); rfxTileSet.properties |= (ushort)(cct << 4); rfxTileSet.properties |= (ushort)(xft << 6); rfxTileSet.properties |= (ushort)(et << 10); rfxTileSet.properties |= (ushort)(qt << 14); rfxTileSet.numQuant = 1; rfxTileSet.tileSize = RdprfxServer.TileSize; rfxTileSet.numTiles = 1; rfxTileSet.quantVals = new TS_RFX_CODEC_QUANT[1]; rfxTileSet.quantVals[0] = codecQuant; byte[] yData, cbData, crData; RemoteFXCodecContext encodingContext = new RemoteFXCodecContext(codecQuant, entropy); RemoteFXEncoder.EncodeTile(tileImage, 0, 0, encodingContext); yData = encodingContext.YData; cbData = encodingContext.CbData; crData = encodingContext.CrData; rfxTileSet.tiles = new TS_RFX_TILE[1]; rfxTileSet.tiles[0].BlockT.blockType = blockType_Value.CBT_TILE; rfxTileSet.tiles[0].BlockT.blockLen = (uint)(19 + yData.Length + cbData.Length + crData.Length); rfxTileSet.tiles[0].quantIdxY = 0; rfxTileSet.tiles[0].quantIdxCb = 0; rfxTileSet.tiles[0].quantIdxCr = 0; rfxTileSet.tiles[0].xIdx = 0; rfxTileSet.tiles[0].yIdx = 0; rfxTileSet.tiles[0].YLen = (ushort)yData.Length; rfxTileSet.tiles[0].CbLen = (ushort)cbData.Length; rfxTileSet.tiles[0].CrLen = (ushort)crData.Length; rfxTileSet.tiles[0].YData = yData; rfxTileSet.tiles[0].CbData = cbData; rfxTileSet.tiles[0].CrData = crData; rfxTileSet.tilesDataSize = rfxTileSet.tiles[0].BlockT.blockLen; rfxTileSet.CodecChannelT.blockLen = 22 + 5 + rfxTileSet.tilesDataSize; return rfxTileSet; }
public void Rdprfx_ImageMode_PositiveTest_MultiQuantVals() { #region Test Description /* * Step 1: [RDPBCGR] establishing the connection. * Step 2: [RDPBCGR] send Frame Maker Command (Begin) to SUT. * Step 3: [RDPRFX] Send Encode Header Messages to SUT. * Step 4: [RDPRFX] Send one frame of Encode Data Messages (encoded with RLGR1) to SUT, each component use different quantization value. * Step 5: [RDPBCGR] send Frame Maker Command (End) to SUT. * Step 6: [RDPRFX] Expect SUT sends a TS_FRAME_ACKNOWLEDGE_PDU. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol, true); #endregion #region RDPBCGR Connection //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability."); setServerCapabilitiesWithRemoteFxSupported(); //Waiting for the RDP connection sequence. this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection."); this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on."); this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER); #endregion //Initial the RDPRFX adapter context. rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); receiveAndLogClientRfxCapabilites(); uint frameId = 0; //The index of the sending frame. OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1; ushort destLeft = 64; //the left bound of the frame. ushort destTop = 64; //the top bound of the frame. //Check if the above setting is supported by the client. if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm)) { this.TestSite.Log.Add(LogEntryKind.Comment, "the input pair of Operational Mode ({0}) / Entropy Algorithm ({1}) is not supported by the client, so stop running this test case.", opMode, enAlgorithm); return; } this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (Begin) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_BEGIN, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Start to send encoded bitmap data to client. Operational Mode = {0}, Entropy Algorithm = {1}, destLeft = {2}, destTop = {3}.", opMode, enAlgorithm, destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Generate Quantization value, each component has different quant index."); TS_RFX_CODEC_QUANT[] quantVals = this.GenerateCodecQuantVals(); byte quantIdxY = 0; byte quantIdxCb = 1; byte quantIdxCr = 2; TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image_64X64, RdprfxServer.TileSize, RdprfxServer.TileSize); for (int idx = 0; idx < tileImageArr.Length; idx++) { if (idx == 0) { rdprfxAdapter.SendTsRfxSync(); rdprfxAdapter.SendTsRfxCodecVersions(); rdprfxAdapter.SendTsRfxChannels(); rdprfxAdapter.SendTsRfxContext(opMode, enAlgorithm); } rdprfxAdapter.SendTsRfxFrameBegin((uint)idx); rdprfxAdapter.SendTsRfxRegion(); rdprfxAdapter.SendTsRfxTileSet(opMode, enAlgorithm, tileImageArr[idx].image, quantVals, quantIdxY, quantIdxCb, quantIdxCr); rdprfxAdapter.SendTsRfxFrameEnd(); rdprfxAdapter.FlushEncodedData((ushort)(destLeft + tileImageArr[idx].x), (ushort)(destTop + tileImageArr[idx].y)); } this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Frame Marker Command (End) with frameID: {0}.", frameId); rdpbcgrAdapter.SendFrameMarkerCommand(frameAction_Values.SURFACECMD_FRAMEACTION_END, frameId); this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting TS_FRAME_ACKNOWLEDGE_PDU."); rdprfxAdapter.ExpectTsFrameAcknowledgePdu(frameId, waitTime); this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true."); Rectangle compareRect = new Rectangle(destLeft, destTop, image_64X64.Width, image_64X64.Height); this.VerifySUTDisplay(true, compareRect); #endregion }
/// <summary> /// Method to check if the input pair of the operation mode and entropy algorithm is supported by the client. /// </summary> /// <param name="opMode">The operation mode.</param> /// <param name="entropy">The entropy algorithm.</param> /// <returns></returns> public bool CheckIfClientSupports(OperationalMode opMode, EntropyAlgorithm entropy) { TS_RFX_ICAP[] iCaps = this.client_RFX_Caps_Container.capsData.capsetsData[0].icapsData; foreach (TS_RFX_ICAP icap in iCaps) { if ((icap.flags & (byte)OperationalMode.ImageMode) == (byte)0 && ((byte)icap.entropyBits == (byte)entropy)) { //OperationalMode.ImageMode is not set, both the image mode and the video mode of the codec are supported return true; } else if ((byte)icap.entropyBits == (byte)entropy) { //OperationalMode.ImageMode is set, only image mode is supported if (opMode == OperationalMode.ImageMode) return true; } } return false; }
public void Rdprfx_ImageMode_NegativeTest_TsRfxFrameBegin_InvalidBlockLen() { #region Test Description /* * Step 1: [RDPBCGR] establishing the connection. * Step 2: [RDPRFX] send one frame of Encode Header and Data Messages to client, set the blockLen field of TS_RFX_FRAME_BEGIN to an invalid value (less than the actual). * Step 3: [RDPRFX] expect the client terminates the RDP connection. */ #endregion #region Test Sequence //Start RDP listening. this.TestSite.Log.Add(LogEntryKind.Comment, "Starting RDP listening."); this.rdpbcgrAdapter.StartRDPListening(transportProtocol); #region Trigger client to connect //Trigger client to connect. this.TestSite.Log.Add(LogEntryKind.Comment, "Triggering SUT to initiate a RDP connection to server."); triggerClientRDPConnect(transportProtocol); #endregion #region RDPBCGR Connection //Waiting for the transport level connection request. this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the transport layer connection request."); this.rdpbcgrAdapter.ExpectTransportConnection(RDPSessionType.Normal); //Set Server Capability with RomoteFX codec supported. this.TestSite.Log.Add(LogEntryKind.Comment, "Setting Server Capability."); setServerCapabilitiesWithRemoteFxSupported(); //Waiting for the RDP connection sequence. this.TestSite.Log.Add(LogEntryKind.Comment, "Establishing RDP connection."); this.rdpbcgrAdapter.EstablishRDPConnection(selectedProtocol, enMethod, enLevel, true, false, rdpServerVersion); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Server Save Session Info PDU to SUT to notify user has logged on."); this.rdpbcgrAdapter.ServerSaveSessionInfo(LogonNotificationType.UserLoggedOn, ErrorNotificationType_Values.LOGON_FAILED_OTHER); #endregion //Initial the RDPRFX adapter context. rdprfxAdapter.Accept(this.rdpbcgrAdapter.ServerStack, this.rdpbcgrAdapter.SessionContext); receiveAndLogClientRfxCapabilites(); OperationalMode opMode = OperationalMode.ImageMode; EntropyAlgorithm enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR3; ushort destLeft = 0; //the left bound of the frame. ushort destTop = 0; //the top bound of the frame. //Check if the above setting is supported by the client. if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm)) { enAlgorithm = EntropyAlgorithm.CLW_ENTROPY_RLGR1; if (!this.rdprfxAdapter.CheckIfClientSupports(opMode, enAlgorithm)) { this.TestSite.Log.Add(LogEntryKind.Comment, "Client does not support Image Mode, so stop running this test case."); return; } } this.TestSite.Log.Add(LogEntryKind.Comment, "Set the test type to {0}.", RdprfxNegativeType.TsRfxFrameBegin_InvalidBlockLen); rdprfxAdapter.SetTestType(RdprfxNegativeType.TsRfxFrameBegin_InvalidBlockLen); this.TestSite.Log.Add(LogEntryKind.Comment, "Sending Encode Header/Data Messages to client."); rdprfxAdapter.SendImageToClient(image_64X64, opMode, enAlgorithm, destLeft, destTop); this.TestSite.Log.Add(LogEntryKind.Comment, "Expecting the client terminates the RDP connection."); bool bDisconnected = rdpbcgrAdapter.WaitForDisconnection(waitTime); this.TestSite.Assert.IsTrue(bDisconnected, "Client is expected to drop the connection if received encode data in Video Mode when Image Mode is in effect."); #endregion }
/// <summary> /// Encode a bitmap data by RemoteFX codec. /// </summary> /// <param name="image"> The bitmap image to be sent </param> /// <param name="opMode"> Indicate Operational Mode.</param> /// <param name="entropy"> Indicate Entropy Algorithm.</param> /// <param name="imgPos"> The top-left position of bitmap image relative to surface</param> /// <param name="sId"> The surface Id that bitmap image is sent to </param> /// <returns> A dictionary with frameId and byte stream frame pair </returns> public Dictionary<uint, byte[]> RemoteFXCodecEncode(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy, RDPGFX_POINT16 imgPos, ushort sId, PixelFormat pixFormat) { if (image == null) return null; Dictionary<uint, byte[]> frDict = new Dictionary<uint, byte[]>(); // Save encoded frames for one tile TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize); for (uint index = 0; index < tileImageArr.Length; index++) { byte[] tileBitmap = this.PackRfxTileImage(index, opMode, entropy, tileImageArr[index].image); ushort tileLeft = (ushort)(imgPos.x + tileImageArr[index].x); ushort tileTop = (ushort)(imgPos.y + tileImageArr[index].y); RDPGFX_RECT16 tileRect = new RDPGFX_RECT16(tileLeft, tileTop, (ushort)(tileLeft + tileImageArr[index].image.Width), (ushort)(tileTop + tileImageArr[index].image.Height)); uint fid = MakeStartFramePdu(); MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_CAVIDEO, pixFormat, tileRect, tileBitmap); MakeEndFramePdu(fid); if (this.bcgrAdapter.SimulatedScreen != null) { this.bcgrAdapter.SimulatedScreen.RenderRemoteFXTile(sId, tileRect); } frDict.Add(fid, EncodePdusToSent()); } return frDict; }