libfreerdp-codec: initial support for RemoteFX fragmented encoding

This commit is contained in:
Marc-André Moreau 2013-08-14 13:19:01 -04:00
parent 5e6325d62c
commit 2d3d5acf1e
2 changed files with 63 additions and 1 deletions

View File

@ -95,6 +95,8 @@ struct _RFX_MESSAGE
UINT32* quantVals;
UINT32 tilesDataSize;
BOOL freeArray;
};
typedef struct _RFX_MESSAGE RFX_MESSAGE;
@ -168,6 +170,8 @@ FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s,
FREERDP_API RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
int numRects, BYTE* data, int width, int height, int scanline);
FREERDP_API RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize);
FREERDP_API void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message);
#ifdef __cplusplus

View File

@ -916,7 +916,8 @@ void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message)
free(message->tiles);
}
free(message);
if (!message->freeArray)
free(message);
}
}
@ -1151,6 +1152,63 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
return message;
}
RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message, int* numMessages, int maxDataSize)
{
int i, j;
UINT32 tileDataSize;
RFX_MESSAGE* messages;
maxDataSize -= 1024; /* reserve enough space for headers */
*numMessages = ((message->tilesDataSize + maxDataSize) / maxDataSize) * 4;
messages = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE) * (*numMessages));
ZeroMemory(messages, sizeof(RFX_MESSAGE) * (*numMessages));
j = 0;
for (i = 0; i < message->numTiles; i++)
{
tileDataSize = rfx_tile_length(message->tiles[i]);
if ((messages[j].tilesDataSize + tileDataSize) > maxDataSize)
j++;
if (!messages[j].numTiles)
{
messages[j].frameIdx = message->frameIdx + j;
messages[j].numQuant = message->numQuant;
messages[j].quantVals = message->quantVals;
messages[j].numRects = message->numRects;
messages[j].rects = message->rects;
messages[j].tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->numTiles);
messages[j].freeArray = TRUE;
}
messages[j].tilesDataSize += tileDataSize;
messages[j].tiles[messages[j].numTiles++] = message->tiles[i];
message->tiles[i] = NULL;
}
*numMessages = j + 1;
message->numTiles = 0;
return messages;
}
RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize)
{
RFX_MESSAGE* message;
RFX_MESSAGE* messages;
message = rfx_encode_message(context, rects, numRects, data, width, height, scanline);
messages = rfx_split_message(context, message, numMessages, maxDataSize);
rfx_message_free(context, message);
return messages;
}
static void rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message)
{
int i;