libfreerdp-codec: internal refactoring

This commit is contained in:
Marc-André Moreau 2013-08-13 17:18:59 -04:00
parent c8b85e19a4
commit fe25303656
7 changed files with 195 additions and 142 deletions

View File

@ -575,14 +575,14 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
/* blit each tile */ /* blit each tile */
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
tx = message->tiles[i]->x + surface_bits_command->destLeft; tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop; ty = message->tiles[i]->y + surface_bits_command->destTop;
freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv); freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);
for (j = 0; j < message->num_rects; j++) for (j = 0; j < message->numRects; j++)
{ {
wf_set_clip_rgn(wfc, wf_set_clip_rgn(wfc,
surface_bits_command->destLeft + message->rects[j].x, surface_bits_command->destLeft + message->rects[j].x,
@ -596,7 +596,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
wf_set_null_clip_rgn(wfc); wf_set_null_clip_rgn(wfc);
/* invalidate regions */ /* invalidate regions */
for (i = 0; i < message->num_rects; i++) for (i = 0; i < message->numRects; i++)
{ {
tx = surface_bits_command->destLeft + message->rects[i].x; tx = surface_bits_command->destLeft + message->rects[i].x;
ty = surface_bits_command->destTop + message->rects[i].y; ty = surface_bits_command->destTop + message->rects[i].y;

View File

@ -950,10 +950,10 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
XSetClipRectangles(xfc->display, xfc->gc, XSetClipRectangles(xfc->display, xfc->gc,
surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->destLeft, surface_bits_command->destTop,
(XRectangle*) message->rects, message->num_rects, YXBanded); (XRectangle*) message->rects, message->numRects, YXBanded);
/* Draw the tiles to primary surface, each is 64x64. */ /* Draw the tiles to primary surface, each is 64x64. */
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0, image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) message->tiles[i]->data, 64, 64, 32, 0); (char*) message->tiles[i]->data, 64, 64, 32, 0);
@ -966,7 +966,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
} }
/* Copy the updated region from backstore to the window. */ /* Copy the updated region from backstore to the window. */
for (i = 0; i < message->num_rects; i++) for (i = 0; i < message->numRects; i++)
{ {
tx = message->rects[i].x + surface_bits_command->destLeft; tx = message->rects[i].x + surface_bits_command->destLeft;
ty = message->rects[i].y + surface_bits_command->destTop; ty = message->rects[i].y + surface_bits_command->destTop;

View File

@ -404,7 +404,7 @@ void test_message(void)
message = rfx_process_message(context, s->pointer, s->capacity); message = rfx_process_message(context, s->pointer, s->capacity);
if (i == 0) if (i == 0)
{ {
for (j = 0; j < message->num_tiles; j++) for (j = 0; j < message->numTiles; j++)
{ {
dump_ppm_image(message->tiles[j]->data); dump_ppm_image(message->tiles[j]->data);
} }

View File

@ -76,7 +76,7 @@ struct _RFX_MESSAGE
* The rects array represents the updated region of the frame. The UI * The rects array represents the updated region of the frame. The UI
* requires to clip drawing destination base on the union of the rects. * requires to clip drawing destination base on the union of the rects.
*/ */
UINT16 num_rects; UINT16 numRects;
RFX_RECT* rects; RFX_RECT* rects;
/** /**
@ -85,15 +85,33 @@ struct _RFX_MESSAGE
* rects described above) are valid. Pixels outside of the region may * rects described above) are valid. Pixels outside of the region may
* contain arbitrary data. * contain arbitrary data.
*/ */
UINT16 num_tiles; UINT16 numTiles;
RFX_TILE** tiles; RFX_TILE** tiles;
UINT16 numQuant;
UINT32* quantVals;
UINT32 tilesDataSize;
}; };
typedef struct _RFX_MESSAGE RFX_MESSAGE; typedef struct _RFX_MESSAGE RFX_MESSAGE;
typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV; typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV;
enum _RFX_STATE
{
RFX_STATE_INITIAL,
RFX_STATE_SERVER_UNINITIALIZED,
RFX_STATE_SEND_HEADERS,
RFX_STATE_SEND_FRAME_DATA,
RFX_STATE_FRAME_DATA_SENT,
RFX_STATE_FINAL
};
typedef enum _RFX_STATE RFX_STATE;
struct _RFX_CONTEXT struct _RFX_CONTEXT
{ {
RFX_STATE state;
UINT16 flags; UINT16 flags;
UINT16 properties; UINT16 properties;
UINT16 width; UINT16 width;
@ -109,8 +127,7 @@ struct _RFX_CONTEXT
const BYTE* palette; const BYTE* palette;
/* temporary data within a frame */ /* temporary data within a frame */
UINT32 frame_idx; UINT32 frameIdx;
BOOL header_processed;
BYTE numQuant; BYTE numQuant;
UINT32* quants; UINT32* quants;
BYTE quantIdxY; BYTE quantIdxY;

View File

@ -144,6 +144,12 @@ void rfx_tile_init(RFX_TILE* tile)
{ {
tile->x = 0; tile->x = 0;
tile->y = 0; tile->y = 0;
tile->YLen = 0;
tile->YData = NULL;
tile->CbLen = 0;
tile->CbData = NULL;
tile->CrLen = 0;
tile->CrData = NULL;
} }
} }
@ -281,6 +287,8 @@ RFX_CONTEXT* rfx_context_new(void)
RFX_INIT_SIMD(context); RFX_INIT_SIMD(context);
context->state = RFX_STATE_SEND_HEADERS;
return context; return context;
} }
@ -340,8 +348,8 @@ void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_f
void rfx_context_reset(RFX_CONTEXT* context) void rfx_context_reset(RFX_CONTEXT* context)
{ {
context->header_processed = FALSE; context->state = RFX_STATE_SEND_HEADERS;
context->frame_idx = 0; context->frameIdx = 0;
} }
static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s) static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s)
@ -524,27 +532,27 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag
} }
Stream_Seek_UINT8(s); /* regionFlags (1 byte) */ Stream_Seek_UINT8(s); /* regionFlags (1 byte) */
Stream_Read_UINT16(s, message->num_rects); /* numRects (2 bytes) */ Stream_Read_UINT16(s, message->numRects); /* numRects (2 bytes) */
if (message->num_rects < 1) if (message->numRects < 1)
{ {
DEBUG_WARN("no rects."); DEBUG_WARN("no rects.");
return TRUE; return TRUE;
} }
if (Stream_GetRemainingLength(s) < 8 * message->num_rects) if (Stream_GetRemainingLength(s) < 8 * message->numRects)
{ {
DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->num_rects); DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->numRects);
return FALSE; return FALSE;
} }
if (message->rects != NULL) if (message->rects != NULL)
message->rects = (RFX_RECT*) realloc(message->rects, message->num_rects * sizeof(RFX_RECT)); message->rects = (RFX_RECT*) realloc(message->rects, message->numRects * sizeof(RFX_RECT));
else else
message->rects = (RFX_RECT*) malloc(message->num_rects * sizeof(RFX_RECT)); message->rects = (RFX_RECT*) malloc(message->numRects * sizeof(RFX_RECT));
/* rects */ /* rects */
for (i = 0; i < message->num_rects; i++) for (i = 0; i < message->numRects; i++)
{ {
/* RFX_RECT */ /* RFX_RECT */
Stream_Read_UINT16(s, message->rects[i].x); /* x (2 bytes) */ Stream_Read_UINT16(s, message->rects[i].x); /* x (2 bytes) */
@ -611,9 +619,9 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
return TRUE; return TRUE;
} }
Stream_Read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */ Stream_Read_UINT16(s, message->numTiles); /* numTiles (2 bytes) */
if (message->num_tiles < 1) if (message->numTiles < 1)
{ {
DEBUG_WARN("no tiles."); DEBUG_WARN("no tiles.");
return TRUE; return TRUE;
@ -661,24 +669,24 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
context->quants[i * 10 + 8], context->quants[i * 10 + 9]); context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
} }
message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->num_tiles); message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->numTiles);
ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->num_tiles); ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->numTiles);
if (context->priv->UseThreads) if (context->priv->UseThreads)
{ {
work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->num_tiles); work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles);
params = (RFX_TILE_PROCESS_WORK_PARAM*) malloc(sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->num_tiles); params = (RFX_TILE_PROCESS_WORK_PARAM*) malloc(sizeof(RFX_TILE_PROCESS_WORK_PARAM) * message->numTiles);
} }
/* tiles */ /* tiles */
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool);
/* RFX_TILE */ /* RFX_TILE */
if (Stream_GetRemainingLength(s) < 6) if (Stream_GetRemainingLength(s) < 6)
{ {
DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles); DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->numTiles);
return FALSE; return FALSE;
} }
@ -687,7 +695,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
if (Stream_GetRemainingLength(s) < blockLen - 6) if (Stream_GetRemainingLength(s) < blockLen - 6)
{ {
DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen); DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->numTiles, blockLen);
return FALSE; return FALSE;
} }
@ -738,7 +746,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
if (context->priv->UseThreads) if (context->priv->UseThreads)
{ {
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
CloseThreadpoolWork(work_objects[i]); CloseThreadpoolWork(work_objects[i]);
@ -747,6 +755,14 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
free(work_objects); free(work_objects);
free(params); free(params);
} }
for (i = 0; i < message->numTiles; i++)
{
tile = message->tiles[i];
tile->YLen = tile->CbLen = tile->CrLen = 0;
tile->YData = tile->CbData = tile->CrData = NULL;
}
return TRUE; return TRUE;
} }
@ -847,7 +863,7 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length
UINT16 rfx_message_get_tile_count(RFX_MESSAGE* message) UINT16 rfx_message_get_tile_count(RFX_MESSAGE* message)
{ {
return message->num_tiles; return message->numTiles;
} }
RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index) RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index)
@ -857,7 +873,7 @@ RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index)
UINT16 rfx_message_get_rect_count(RFX_MESSAGE* message) UINT16 rfx_message_get_rect_count(RFX_MESSAGE* message)
{ {
return message->num_rects; return message->numRects;
} }
RFX_RECT* rfx_message_get_rect(RFX_MESSAGE* message, int index) RFX_RECT* rfx_message_get_rect(RFX_MESSAGE* message, int index)
@ -868,16 +884,31 @@ RFX_RECT* rfx_message_get_rect(RFX_MESSAGE* message, int index)
void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message)
{ {
int i; int i;
RFX_TILE* tile;
if (message != NULL) if (message)
{
if (message->rects)
{ {
free(message->rects); free(message->rects);
}
if (message->tiles) if (message->tiles)
{ {
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
ObjectPool_Return(context->priv->TilePool, (void*) message->tiles[i]); tile = message->tiles[i];
if (tile->YData)
BufferPool_Return(context->priv->BufferPool, tile->YData);
if (tile->CbData)
BufferPool_Return(context->priv->BufferPool, tile->CbData);
if (tile->CrData)
BufferPool_Return(context->priv->BufferPool, tile->CrData);
ObjectPool_Return(context->priv->TilePool, (void*) tile);
} }
free(message->tiles); free(message->tiles);
@ -951,8 +982,6 @@ void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s)
rfx_compose_message_context(context, s); rfx_compose_message_context(context, s);
rfx_compose_message_codec_versions(context, s); rfx_compose_message_codec_versions(context, s);
rfx_compose_message_channels(context, s); rfx_compose_message_channels(context, s);
context->header_processed = TRUE;
} }
static void rfx_compose_message_frame_begin(RFX_CONTEXT* context, wStream* s) static void rfx_compose_message_frame_begin(RFX_CONTEXT* context, wStream* s)
@ -963,29 +992,29 @@ static void rfx_compose_message_frame_begin(RFX_CONTEXT* context, wStream* s)
Stream_Write_UINT32(s, 14); /* CodecChannelT.blockLen */ Stream_Write_UINT32(s, 14); /* CodecChannelT.blockLen */
Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */
Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */
Stream_Write_UINT32(s, context->frame_idx); /* frameIdx */ Stream_Write_UINT32(s, context->frameIdx); /* frameIdx */
Stream_Write_UINT16(s, 1); /* numRegions */ Stream_Write_UINT16(s, 1); /* numRegions */
context->frame_idx++; context->frameIdx++;
} }
static void rfx_compose_message_region(RFX_CONTEXT* context, wStream* s, static void rfx_compose_message_region(RFX_CONTEXT* context, wStream* s,
const RFX_RECT* rects, int num_rects) const RFX_RECT* rects, int numRects)
{ {
int size;
int i; int i;
UINT32 blockLen;
size = 15 + num_rects * 8; blockLen = 15 + (numRects * 8);
Stream_EnsureRemainingCapacity(s, size); Stream_EnsureRemainingCapacity(s, blockLen);
Stream_Write_UINT16(s, WBT_REGION); /* CodecChannelT.blockType */ Stream_Write_UINT16(s, WBT_REGION); /* CodecChannelT.blockType (2 bytes) */
Stream_Write_UINT32(s, size); /* set CodecChannelT.blockLen later */ Stream_Write_UINT32(s, blockLen); /* set CodecChannelT.blockLen (4 bytes) */
Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId (1 byte) */
Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId (1 byte) */
Stream_Write_UINT8(s, 1); /* regionFlags */ Stream_Write_UINT8(s, 1); /* regionFlags (1 byte) */
Stream_Write_UINT16(s, num_rects); /* numRects */ Stream_Write_UINT16(s, numRects); /* numRects (2 bytes) */
for (i = 0; i < num_rects; i++) for (i = 0; i < numRects; i++)
{ {
Stream_Write_UINT16(s, rects[i].x); Stream_Write_UINT16(s, rects[i].x);
Stream_Write_UINT16(s, rects[i].y); Stream_Write_UINT16(s, rects[i].y);
@ -993,15 +1022,20 @@ static void rfx_compose_message_region(RFX_CONTEXT* context, wStream* s,
Stream_Write_UINT16(s, rects[i].height); Stream_Write_UINT16(s, rects[i].height);
} }
Stream_Write_UINT16(s, CBT_REGION); /* regionType */ Stream_Write_UINT16(s, CBT_REGION); /* regionType (2 bytes) */
Stream_Write_UINT16(s, 1); /* numTilesets */ Stream_Write_UINT16(s, 1); /* numTilesets (2 bytes) */
}
static int rfx_tile_length(RFX_TILE* tile)
{
return 19 + tile->YLen + tile->CbLen + tile->CrLen;
} }
static void rfx_write_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* tile) static void rfx_write_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* tile)
{ {
UINT32 blockLen; UINT32 blockLen;
blockLen = 19 + tile->YLen + tile->CbLen + tile->CrLen; blockLen = rfx_tile_length(tile);
Stream_EnsureRemainingCapacity(s, blockLen); Stream_EnsureRemainingCapacity(s, blockLen);
Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType (2 bytes) */ Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType (2 bytes) */
@ -1032,25 +1066,21 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta
rfx_encode_rgb(param->context, param->tile); rfx_encode_rgb(param->context, param->tile);
} }
static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* rfx_compose_message_full(RFX_CONTEXT* context, BYTE* data, int width, int height, int scanline)
BYTE* image_data, int width, int height, int scanline)
{ {
int i; int i;
int size;
int xIdx; int xIdx;
int yIdx; int yIdx;
int numTiles;
int numTilesX; int numTilesX;
int numTilesY; int numTilesY;
RFX_TILE* tile; RFX_TILE* tile;
int start_pos, end_pos; RFX_MESSAGE* message = NULL;
int numQuants;
const UINT32* quantVals;
const UINT32* quantValsPtr;
int tilesDataSize;
PTP_WORK* work_objects = NULL; PTP_WORK* work_objects = NULL;
RFX_TILE_COMPOSE_WORK_PARAM* params = NULL; RFX_TILE_COMPOSE_WORK_PARAM* params = NULL;
message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE));
ZeroMemory(message, sizeof(RFX_MESSAGE));
if (!context->numQuant) if (!context->numQuant)
{ {
context->numQuant = 1; context->numQuant = 1;
@ -1060,44 +1090,23 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
context->quantIdxCr = 0; context->quantIdxCr = 0;
} }
numQuants = context->numQuant; message->numQuant = context->numQuant;
quantVals = context->quants; message->quantVals = context->quants;
numTilesX = (width + 63) / 64; numTilesX = (width + 63) / 64;
numTilesY = (height + 63) / 64; numTilesY = (height + 63) / 64;
numTiles = numTilesX * numTilesY;
size = 22 + numQuants * 5; message->numTiles = numTilesX * numTilesY;
Stream_EnsureRemainingCapacity(s, size); message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE) * message->numTiles);
start_pos = Stream_GetPosition(s); ZeroMemory(message->tiles, sizeof(RFX_TILE) * message->numTiles);
Stream_Write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ DEBUG_RFX("width: %d height: %d scanline: %d", width, height, scanline);
Stream_Seek_UINT32(s); /* set CodecChannelT.blockLen later */
Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */
Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */
Stream_Write_UINT16(s, CBT_TILESET); /* subtype */
Stream_Write_UINT16(s, 0); /* idx */
Stream_Write_UINT16(s, context->properties); /* properties */
Stream_Write_UINT8(s, numQuants); /* numQuants */
Stream_Write_UINT8(s, 0x40); /* tileSize */
Stream_Write_UINT16(s, numTiles); /* numTiles */
Stream_Seek_UINT32(s); /* set tilesDataSize later */
quantValsPtr = quantVals;
for (i = 0; i < numQuants * 5; i++)
{
Stream_Write_UINT8(s, quantValsPtr[0] + (quantValsPtr[1] << 4));
quantValsPtr += 2;
}
DEBUG_RFX("width:%d height:%d scanline:%d", width, height, scanline);
end_pos = Stream_GetPosition(s);
if (context->priv->UseThreads) if (context->priv->UseThreads)
work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * numTiles); {
work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles);
params = (RFX_TILE_COMPOSE_WORK_PARAM*) malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * numTiles); params = (RFX_TILE_COMPOSE_WORK_PARAM*) malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles);
}
for (yIdx = 0; yIdx < numTilesY; yIdx++) for (yIdx = 0; yIdx < numTilesY; yIdx++)
{ {
@ -1105,10 +1114,10 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
{ {
i = yIdx * numTilesX + xIdx; i = yIdx * numTilesX + xIdx;
tile = params[i].tile = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool);
tile->scanline = scanline; tile->scanline = scanline;
tile->data = image_data + yIdx * 64 * scanline + xIdx * 8 * context->bits_per_pixel; tile->data = data + yIdx * 64 * scanline + xIdx * 8 * context->bits_per_pixel;
tile->width = (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64; tile->width = (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64;
tile->height = (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64; tile->height = (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64;
@ -1127,6 +1136,7 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
if (context->priv->UseThreads) if (context->priv->UseThreads)
{ {
params[i].context = context; params[i].context = context;
params[i].tile = tile;
work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback, work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback,
(void*) &params[i], &context->priv->ThreadPoolEnv); (void*) &params[i], &context->priv->ThreadPoolEnv);
@ -1140,13 +1150,11 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
} }
} }
for (yIdx = 0; yIdx < numTilesY; yIdx++) message->tilesDataSize = 0;
{
for (xIdx = 0; xIdx < numTilesX; xIdx++)
{
i = yIdx * numTilesX + xIdx;
tile = params[i].tile; for (i = 0; i < message->numTiles; i++)
{
tile = message->tiles[i];
if (context->priv->UseThreads) if (context->priv->UseThreads)
{ {
@ -1154,31 +1162,56 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
CloseThreadpoolWork(work_objects[i]); CloseThreadpoolWork(work_objects[i]);
} }
rfx_write_tile(context, s, tile); message->tilesDataSize += rfx_tile_length(tile);
BufferPool_Return(context->priv->BufferPool, tile->YData);
BufferPool_Return(context->priv->BufferPool, tile->CbData);
BufferPool_Return(context->priv->BufferPool, tile->CrData);
ObjectPool_Return(context->priv->TilePool, (void*) params[i].tile);
}
} }
if (context->priv->UseThreads) if (context->priv->UseThreads)
{
free(work_objects); free(work_objects);
free(params); free(params);
}
tilesDataSize = Stream_GetPosition(s) - end_pos; return message;
size += tilesDataSize; }
end_pos = Stream_GetPosition(s);
Stream_SetPosition(s, start_pos + 2); static void rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message)
Stream_Write_UINT32(s, size); /* CodecChannelT.blockLen */ {
Stream_SetPosition(s, start_pos + 18); int i;
Stream_Write_UINT32(s, tilesDataSize); RFX_TILE* tile;
UINT32 blockLen;
UINT32* quantVals;
Stream_SetPosition(s, end_pos); blockLen = 22 + (message->numQuant * 5) + message->tilesDataSize;
Stream_EnsureRemainingCapacity(s, blockLen);
Stream_Write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType (2 bytes) */
Stream_Write_UINT32(s, blockLen); /* set CodecChannelT.blockLen (4 bytes) */
Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId (1 byte) */
Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId (1 byte) */
Stream_Write_UINT16(s, CBT_TILESET); /* subtype (2 bytes) */
Stream_Write_UINT16(s, 0); /* idx (2 bytes) */
Stream_Write_UINT16(s, context->properties); /* properties (2 bytes) */
Stream_Write_UINT8(s, message->numQuant); /* numQuant (1 byte) */
Stream_Write_UINT8(s, 0x40); /* tileSize (1 byte) */
Stream_Write_UINT16(s, message->numTiles); /* numTiles (2 bytes) */
Stream_Write_UINT32(s, message->tilesDataSize); /* set tilesDataSize later */
quantVals = message->quantVals;
for (i = 0; i < message->numQuant * 5; i++)
{
Stream_Write_UINT8(s, quantVals[0] + (quantVals[1] << 4));
quantVals += 2;
}
for (i = 0; i < message->numTiles; i++)
{
tile = message->tiles[i];
rfx_write_tile(context, s, tile);
}
DEBUG_RFX("numQuant: %d numTiles: %d tilesDataSize: %d",
message->numQuant, message->numTiles, message->tilesDataSize);
} }
static void rfx_compose_message_frame_end(RFX_CONTEXT* context, wStream* s) static void rfx_compose_message_frame_end(RFX_CONTEXT* context, wStream* s)
@ -1191,22 +1224,25 @@ static void rfx_compose_message_frame_end(RFX_CONTEXT* context, wStream* s)
Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */
} }
static void rfx_compose_message_data(RFX_CONTEXT* context, wStream* s,
const RFX_RECT* rects, int num_rects, BYTE* image_data, int width, int height, int rowstride)
{
rfx_compose_message_frame_begin(context, s);
rfx_compose_message_region(context, s, rects, num_rects);
rfx_compose_message_tileset(context, s, image_data, width, height, rowstride);
rfx_compose_message_frame_end(context, s);
}
FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s, FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s,
const RFX_RECT* rects, int num_rects, BYTE* image_data, int width, int height, int rowstride) const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline)
{ {
/* Only the first frame should send the RemoteFX header */ RFX_MESSAGE* message;
if (context->frame_idx == 0 && !context->header_processed)
rfx_compose_message_header(context, s);
rfx_compose_message_data(context, s, rects, num_rects, image_data, width, height, rowstride); if ((context->frameIdx == 0) && (context->state == RFX_STATE_SEND_HEADERS))
{
rfx_compose_message_header(context, s);
context->state = RFX_STATE_SEND_FRAME_DATA;
}
rfx_compose_message_frame_begin(context, s);
rfx_compose_message_region(context, s, rects, numRects);
message = rfx_compose_message_full(context, data, width, height, scanline);
rfx_write_message_tileset(context, s, message);
rfx_compose_message_frame_end(context, s);
rfx_message_free(context, message);
} }

View File

@ -789,10 +789,10 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
message = rfx_process_message(rfx_context, message = rfx_process_message(rfx_context,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
DEBUG_GDI("num_rects %d num_tiles %d", message->num_rects, message->num_tiles); DEBUG_GDI("num_rects %d num_tiles %d", message->numRects, message->numTiles);
/* blit each tile */ /* blit each tile */
for (i = 0; i < message->num_tiles; i++) for (i = 0; i < message->numTiles; i++)
{ {
tx = message->tiles[i]->x + surface_bits_command->destLeft; tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop; ty = message->tiles[i]->y + surface_bits_command->destTop;
@ -805,7 +805,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
#endif #endif
for (j = 0; j < message->num_rects; j++) for (j = 0; j < message->numRects; j++)
{ {
gdi_SetClipRgn(gdi->primary->hdc, gdi_SetClipRgn(gdi->primary->hdc,
surface_bits_command->destLeft + message->rects[j].x, surface_bits_command->destLeft + message->rects[j].x,

View File

@ -138,7 +138,7 @@ void wf_update_encode(wfInfo* wfi)
rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1, rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1,
pDataBits, width, height, stride); pDataBits, width, height, stride);
wfi->frame_idx = wfi->rfx_context->frame_idx; wfi->frame_idx = wfi->rfx_context->frameIdx;
cmd->destLeft = wfi->invalid.left; cmd->destLeft = wfi->invalid.left;
cmd->destTop = wfi->invalid.top; cmd->destTop = wfi->invalid.top;