From 5e6325d62c7a838d289bd75a822243f9456a582d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 14 Aug 2013 10:14:47 -0400 Subject: [PATCH] libfreerdp-codec: start exporting split encode/write rfx api --- include/freerdp/codec/rfx.h | 5 ++ libfreerdp/codec/rfx.c | 134 ++++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 60 deletions(-) diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index 891f65a97..d1ee72d3a 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -80,6 +80,7 @@ struct _RFX_MESSAGE */ UINT16 numRects; RFX_RECT* rects; + BOOL freeRects; /** * The tiles array represents the actual frame data. Each tile is always @@ -165,6 +166,10 @@ FREERDP_API void rfx_compose_message_header(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); +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 void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message); + #ifdef __cplusplus } #endif diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index db4cfb09b..1a465f0db 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -777,6 +777,8 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); + message->freeRects = TRUE; + s = Stream_New(data, length); while (Stream_GetRemainingLength(s) > 6) @@ -888,7 +890,7 @@ void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) if (message) { - if (message->rects) + if ((message->rects) && (message->freeRects)) { free(message->rects); } @@ -918,52 +920,10 @@ void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) } } -static void rfx_compose_message_sync(RFX_CONTEXT* context, wStream* s) -{ - Stream_Write_UINT16(s, WBT_SYNC); /* BlockT.blockType */ - Stream_Write_UINT32(s, 12); /* BlockT.blockLen */ - Stream_Write_UINT32(s, WF_MAGIC); /* magic */ - Stream_Write_UINT16(s, WF_VERSION_1_0); /* version */ -} - -static void rfx_compose_message_codec_versions(RFX_CONTEXT* context, wStream* s) -{ - Stream_Write_UINT16(s, WBT_CODEC_VERSIONS); /* BlockT.blockType */ - Stream_Write_UINT32(s, 10); /* BlockT.blockLen */ - Stream_Write_UINT8(s, 1); /* numCodecs */ - Stream_Write_UINT8(s, 1); /* codecs.codecId */ - Stream_Write_UINT16(s, WF_VERSION_1_0); /* codecs.version */ -} - -static void rfx_compose_message_channels(RFX_CONTEXT* context, wStream* s) -{ - Stream_Write_UINT16(s, WBT_CHANNELS); /* BlockT.blockType */ - Stream_Write_UINT32(s, 12); /* BlockT.blockLen */ - Stream_Write_UINT8(s, 1); /* numChannels */ - Stream_Write_UINT8(s, 0); /* Channel.channelId */ - Stream_Write_UINT16(s, context->width); /* Channel.width */ - Stream_Write_UINT16(s, context->height); /* Channel.height */ -} - -static void rfx_compose_message_context(RFX_CONTEXT* context, wStream* s) +static void rfx_update_context_properties(RFX_CONTEXT* context) { UINT16 properties; - Stream_Write_UINT16(s, WBT_CONTEXT); /* CodecChannelT.blockType */ - Stream_Write_UINT32(s, 13); /* CodecChannelT.blockLen */ - Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId */ - Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ - Stream_Write_UINT8(s, 0); /* ctxId */ - Stream_Write_UINT16(s, CT_TILE_64x64); /* tileSize */ - - /* properties */ - properties = context->flags; /* flags */ - properties |= (COL_CONV_ICT << 3); /* cct */ - properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */ - properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 9); /* et */ - properties |= (SCALAR_QUANTIZATION << 13); /* qt */ - Stream_Write_UINT16(s, properties); - /* properties in tilesets: note that this has different format from the one in TS_RFX_CONTEXT */ properties = 1; /* lt */ properties |= (context->flags << 1); /* flags */ @@ -971,17 +931,67 @@ static void rfx_compose_message_context(RFX_CONTEXT* context, wStream* s) properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */ properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 10); /* et */ properties |= (SCALAR_QUANTIZATION << 14); /* qt */ + context->properties = properties; } +static void rfx_write_message_sync(RFX_CONTEXT* context, wStream* s) +{ + Stream_Write_UINT16(s, WBT_SYNC); /* BlockT.blockType (2 bytes) */ + Stream_Write_UINT32(s, 12); /* BlockT.blockLen (4 bytes) */ + Stream_Write_UINT32(s, WF_MAGIC); /* magic (4 bytes) */ + Stream_Write_UINT16(s, WF_VERSION_1_0); /* version (2 bytes) */ +} + +static void rfx_write_message_codec_versions(RFX_CONTEXT* context, wStream* s) +{ + Stream_Write_UINT16(s, WBT_CODEC_VERSIONS); /* BlockT.blockType (2 bytes) */ + Stream_Write_UINT32(s, 10); /* BlockT.blockLen (4 bytes) */ + Stream_Write_UINT8(s, 1); /* numCodecs (1 byte) */ + Stream_Write_UINT8(s, 1); /* codecs.codecId (1 byte) */ + Stream_Write_UINT16(s, WF_VERSION_1_0); /* codecs.version (2 bytes) */ +} + +static void rfx_write_message_channels(RFX_CONTEXT* context, wStream* s) +{ + Stream_Write_UINT16(s, WBT_CHANNELS); /* BlockT.blockType (2 bytes) */ + Stream_Write_UINT32(s, 12); /* BlockT.blockLen (4 bytes) */ + Stream_Write_UINT8(s, 1); /* numChannels (1 byte) */ + Stream_Write_UINT8(s, 0); /* Channel.channelId (1 byte) */ + Stream_Write_UINT16(s, context->width); /* Channel.width (2 bytes) */ + Stream_Write_UINT16(s, context->height); /* Channel.height (2 bytes) */ +} + +static void rfx_write_message_context(RFX_CONTEXT* context, wStream* s) +{ + UINT16 properties; + + Stream_Write_UINT16(s, WBT_CONTEXT); /* CodecChannelT.blockType (2 bytes) */ + Stream_Write_UINT32(s, 13); /* CodecChannelT.blockLen (4 bytes) */ + Stream_Write_UINT8(s, 1); /* CodecChannelT.codecId (1 byte) */ + Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId (1 byte) */ + Stream_Write_UINT8(s, 0); /* ctxId (1 byte) */ + Stream_Write_UINT16(s, CT_TILE_64x64); /* tileSize (2 bytes) */ + + /* properties */ + properties = context->flags; /* flags */ + properties |= (COL_CONV_ICT << 3); /* cct */ + properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */ + properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 9); /* et */ + properties |= (SCALAR_QUANTIZATION << 13); /* qt */ + Stream_Write_UINT16(s, properties); /* properties (2 bytes) */ + + rfx_update_context_properties(context); +} + void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s) { Stream_EnsureRemainingCapacity(s, 12 + 10 + 12 + 13); - rfx_compose_message_sync(context, s); - rfx_compose_message_context(context, s); - rfx_compose_message_codec_versions(context, s); - rfx_compose_message_channels(context, s); + rfx_write_message_sync(context, s); + rfx_write_message_context(context, s); + rfx_write_message_codec_versions(context, s); + rfx_write_message_channels(context, s); } static int rfx_tile_length(RFX_TILE* tile) @@ -1024,7 +1034,7 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta rfx_encode_rgb(param->context, param->tile); } -RFX_MESSAGE* rfx_compose_message_full(RFX_CONTEXT* context, const RFX_RECT* rects, +RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline) { int i; @@ -1040,6 +1050,9 @@ RFX_MESSAGE* rfx_compose_message_full(RFX_CONTEXT* context, const RFX_RECT* rect message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); + if (context->state == RFX_STATE_SEND_HEADERS) + rfx_update_context_properties(context); + message->frameIdx = context->frameIdx++; message->numRects = numRects; @@ -1158,7 +1171,7 @@ static void rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, RFX_MESS 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 */ + Stream_Write_UINT32(s, message->tilesDataSize); /* tilesDataSize (4 bytes) */ quantVals = message->quantVals; @@ -1227,27 +1240,28 @@ void rfx_write_message_frame_end(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* Stream_Write_UINT8(s, 0); /* CodecChannelT.channelId */ } -FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s, - const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline) +void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message) { - RFX_MESSAGE* message; - - if ((context->frameIdx == 0) && (context->state == RFX_STATE_SEND_HEADERS)) + if (context->state == RFX_STATE_SEND_HEADERS) { rfx_compose_message_header(context, s); context->state = RFX_STATE_SEND_FRAME_DATA; } - message = rfx_compose_message_full(context, rects, numRects, data, width, height, scanline); - rfx_write_message_frame_begin(context, s, message); rfx_write_message_region(context, s, message); rfx_write_message_tileset(context, s, message); rfx_write_message_frame_end(context, s, message); +} - message->rects = NULL; - message->numRects = 0; +void rfx_compose_message(RFX_CONTEXT* context, wStream* s, + const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline) +{ + RFX_MESSAGE* message; + + message = rfx_encode_message(context, rects, numRects, data, width, height, scanline); + + rfx_write_message(context, s, message); rfx_message_free(context, message); } -