Extract Rectangle Information from RemoteFX Display Data (Compact 7)
3/12/2014
In full-screen mode, the ESCAPE_COPY2_BMP escape sequence is not sent to the display driver. Therefore, the display driver must extract the destination rectangle information from the RemoteFX-encoded display data. The destination rectangle information is present before the start of each frame in the RemoteFX-encoded data stream. The destination rectangle information is also present before the sync message, which is the first message in a RemoteFX-encoded data stream.
The following code example demonstrates how the destination rectangle information can be extracted from the RemoteFX-encoded display data.
Important
For readability, the following code example does not contain security or error handling. Do not use the following code in a production environment.
const int WF_MAGIC = 0xCACCACCA;
enum cmdType
{
CMDTYPE_FRAME_MARKER = 0x04,
CMDTYPE_STREAM_SURFACE_BITS = 0x06
};
enum BlockType
{
WBT_SYNC = 0xCCC0,
WBT_CODEC_VERSIONS = 0xCCC1,
WBT_CHANNELS = 0xCCC2,
WBT_CONTEXT = 0xCCC3,
WBT_FRAME_BEG = 0xCCC4,
WBT_FRAME_END = 0xCCC5,
WBT_REGION = 0xCCC6,
WBT_EXTENSION = 0xCCC7,
WBT_LAST = 0xCCC8
};
typedef struct tagTS_DEST_RECT
{
UINT16 destLeft;
UINT16 destTop;
UINT16 destRight;
UINT16 destBottom;
}TS_DEST_RECT, *PTS_DEST_RECT;
typedef struct tagTS_BITMAP_DATA_EX
{
UINT8 Bpp;
UINT8 reserved1;
UINT8 reserved2;
UINT8 CodecID;
UINT16 Width;
UINT16 Height;
UINT32 bitmapDataLength;
}TS_BITMAP_DATA_EX , *PTS_BITMAP_DATA_EX;
typedef struct tagTS_SURFCMD_SET_SURF_BITS
{
UINT16 CmdType;
TS_DEST_RECT destRect;
TS_BITMAP_DATA_EX bitmapHeader;
} TS_SURFCMD_SET_SURF_BITS;
typedef struct TAGTS_RFX_BLOCKT
{
USHORT blockType;
UINT blockLen;
} TS_RFX_BLOCKT;
typedef struct TagTS_RFX_SYNC
{
TS_RFX_BLOCKT block;
UINT magic;
USHORT version;
} TS_RFX_SYNC;
typedef struct TagTS_RFX_FRAME_BEGIN
{
TS_RFX_BLOCKT block;
BYTE codecId;
BYTE channelId;
UINT frameIdx;
USHORT numRegions;
} TS_RFX_FRAME_BEGIN;
typedef struct TagTS_RFX_CHANNELS
{
TS_RFX_BLOCKT block;
BYTE numChannels;
BYTE channelId;
USHORT width;
USHORT height;
} TS_RFX_CHANNELS;
// The function GetDestRectangle fills in the pDestFrame structure from
// destination rectangle information.
void GetDestRectangle( BYTE *mDataBuf)
{
BYTE *dataBuf = mDataBuf;
dataBuf = dataBuf - sizeof(TS_SURFCMD_SET_SURF_BITS) + sizeof(short);
PTS_DEST_RECT Rect =(PTS_DEST_RECT)(dataBuf);
pDestFrame->left = Rect->destLeft;
pDestFrame->top = Rect->destTop;
pDestFrame->right = Rect->destRight;
pDestFrame->bottom = Rect->destBottom;
}
// The function ScanSyncFrameBeginBlock extracts destination rectangle information
// present before the start of each Frame. For the first message in any encoded
// stream, this information is present before sync message.
void ScanSyncFrameBeginBlock(BYTE *mDataBuf )
{
BYTE *dataBuf = mDataBuf;
for (int i=0;
(*dataBuf != CMDTYPE_STREAM_SURFACE_BITS) &&
(*(dataBuf - 2* sizeof(int)) != CMDTYPE_FRAME_MARKER); i++,dataBuf--)
{
TS_RFX_BLOCKT *block = (TS_RFX_BLOCKT*)dataBuf;
switch (block->blockType)
{
case WBT_SYNC:
{
TS_RFX_SYNC *ss = (TS_RFX_SYNC*)dataBuf;
if (ss->block.blockType == WBT_SYNC &&
ss->magic == WF_MAGIC)
{
GetDestRectangle(dataBuf);
}
}
break;
case WBT_FRAME_BEG:
{
TS_RFX_FRAME_BEGIN *fb = (TS_RFX_FRAME_BEGIN*)dataBuf;
BYTE *mBuf = dataBuf - sizeof (TS_RFX_CHANNELS);
TS_RFX_CHANNELS *ch = (TS_RFX_CHANNELS*)mBuf;
if (fb->block.blockType == WBT_FRAME_BEG &&
ch->block.blockType != WBT_CHANNELS )
{
GetDestRectangle(dataBuf);
}
}
break;
}
}
}
// The _cOutRects and _pOutRects out params of decode call provide the number
// of rects and co-ordinates of each rect, for example, _pOutRects can
// be 0,0, 34, 26. To calculate the dirty, or changed, region after decoding is
// done, combine the decoder output with the destination rectangle information as
// follows to place the decoded bitmap on the screen.
for (int i = 0; i < _cOutRects; i++)
{
TS_GFX_RECT DirtyRect = {
pDestFrame->left + _pOutRects-> llX,
pDestFrame->top + _pOutRects-> llY,
pDestFrame->left + _pOutRects-> urX,
pDestFrame->top + _pOutRects-> urY,
};
}