mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-codec: internal refactoring
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
free(message->rects);
|
if (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*) ¶ms[i], &context->priv->ThreadPoolEnv);
|
(void*) ¶ms[i], &context->priv->ThreadPoolEnv);
|
||||||
@@ -1140,45 +1150,68 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (yIdx = 0; yIdx < numTilesY; yIdx++)
|
message->tilesDataSize = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < message->numTiles; i++)
|
||||||
{
|
{
|
||||||
for (xIdx = 0; xIdx < numTilesX; xIdx++)
|
tile = message->tiles[i];
|
||||||
|
|
||||||
|
if (context->priv->UseThreads)
|
||||||
{
|
{
|
||||||
i = yIdx * numTilesX + xIdx;
|
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
|
||||||
|
CloseThreadpoolWork(work_objects[i]);
|
||||||
tile = params[i].tile;
|
|
||||||
|
|
||||||
if (context->priv->UseThreads)
|
|
||||||
{
|
|
||||||
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
|
|
||||||
CloseThreadpoolWork(work_objects[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rfx_write_tile(context, s, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message->tilesDataSize += rfx_tile_length(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->priv->UseThreads)
|
if (context->priv->UseThreads)
|
||||||
|
{
|
||||||
free(work_objects);
|
free(work_objects);
|
||||||
|
free(params);
|
||||||
|
}
|
||||||
|
|
||||||
free(params);
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
tilesDataSize = Stream_GetPosition(s) - end_pos;
|
static void rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message)
|
||||||
size += tilesDataSize;
|
{
|
||||||
end_pos = Stream_GetPosition(s);
|
int i;
|
||||||
|
RFX_TILE* tile;
|
||||||
|
UINT32 blockLen;
|
||||||
|
UINT32* quantVals;
|
||||||
|
|
||||||
Stream_SetPosition(s, start_pos + 2);
|
blockLen = 22 + (message->numQuant * 5) + message->tilesDataSize;
|
||||||
Stream_Write_UINT32(s, size); /* CodecChannelT.blockLen */
|
Stream_EnsureRemainingCapacity(s, blockLen);
|
||||||
Stream_SetPosition(s, start_pos + 18);
|
|
||||||
Stream_Write_UINT32(s, tilesDataSize);
|
|
||||||
|
|
||||||
Stream_SetPosition(s, end_pos);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user