From 4e6f1f5a4b511caeee8806350e38c19c46b46430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 13 Aug 2013 13:45:28 -0400 Subject: [PATCH] libfreerdp-codec: use pooled buffers for channel encoding --- include/freerdp/codec/rfx.h | 1 + libfreerdp/codec/rfx.c | 29 +++++++------------ libfreerdp/codec/rfx_encode.c | 53 ++++++++++++++++++++++------------- libfreerdp/codec/rfx_encode.h | 2 +- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index d735adaa4..d2ecfd204 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -54,6 +54,7 @@ struct _RFX_TILE int width; int height; BYTE* data; + int scanline; BYTE quantIdxY; BYTE quantIdxCb; diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index bd744ee7f..c0e165e3d 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -263,10 +263,10 @@ RFX_CONTEXT* rfx_context_new(void) if (context->priv->MaxThreadCount) SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount); - - context->priv->EncoderStreamPool = StreamPool_New(TRUE, 64*64*3+19); } + context->priv->EncoderStreamPool = StreamPool_New(TRUE, 64*64*3+19); + /* initialize the default pixel format */ rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_B8G8R8A8); @@ -1000,7 +1000,7 @@ static void rfx_compose_message_region(RFX_CONTEXT* context, wStream* s, Stream_Write_UINT16(s, 1); /* numTilesets */ } -static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* tile, int rowstride) +static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* tile) { int start_pos, end_pos; @@ -1017,7 +1017,7 @@ static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* Stream_Seek(s, 6); /* YLen, CbLen, CrLen */ - rfx_encode_rgb(context, tile, rowstride, s); + rfx_encode_rgb(context, tile, s); DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d", tile->xIdx, tile->yIdx, tile->width, tile->height, tile->YLen, tile->CbLen, tile->CrLen); @@ -1039,27 +1039,18 @@ struct _RFX_TILE_COMPOSE_WORK_PARAM { RFX_TILE* tile; RFX_CONTEXT* context; - wStream* s; - int rowstride; }; typedef struct _RFX_TILE_COMPOSE_WORK_PARAM RFX_TILE_COMPOSE_WORK_PARAM; void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work) { RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context; - - /** - * We need to clear the stream as the RLGR encoder expects it to be initialized to zero. - * This allows simplifying and improving the performance of the encoding process. - */ - Stream_Clear(param->s); - - rfx_compose_message_tile(param->context, param->s, param->tile, param->rowstride); + rfx_compose_message_tile(param->context, param->s, param->tile); } static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, - BYTE* image_data, int width, int height, int rowstride) + BYTE* image_data, int width, int height, int scanline) { int i; int size; @@ -1116,7 +1107,7 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, quantValsPtr += 2; } - DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride); + DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, scanline); end_pos = Stream_GetPosition(s); @@ -1134,7 +1125,8 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, tile = params[i].tile = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); - tile->data = image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel; + tile->scanline = scanline; + tile->data = image_data + yIdx * 64 * scanline + xIdx * 8 * context->bits_per_pixel; tile->width = (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64; tile->height = (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64; @@ -1154,7 +1146,6 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, { params[i].context = context; params[i].s = StreamPool_Take(context->priv->EncoderStreamPool, 0); - params[i].rowstride = rowstride; work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback, (void*) ¶ms[i], &context->priv->ThreadPoolEnv); @@ -1163,7 +1154,7 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, } else { - rfx_compose_message_tile(context, s, tile, rowstride); + rfx_compose_message_tile(context, s, tile); } } } diff --git a/libfreerdp/codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c index a97215deb..61d994e1a 100644 --- a/libfreerdp/codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -217,18 +217,22 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio BufferPool_Return(context->priv->BufferPool, dwt_buffer); } -void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, int rowstride, wStream* s) +void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, wStream* s) { INT16* pSrcDst[3]; int YLen, CbLen, CrLen; - UINT32 *y_quants, *cb_quants, *cr_quants; + UINT32 *YQuant, *CbQuant, *CrQuant; primitives_t* prims = primitives_get(); static const prim_size_t roi_64x64 = { 64, 64 }; YLen = CbLen = CrLen = 0; - y_quants = context->quants + (tile->quantIdxY * 10); - cb_quants = context->quants + (tile->quantIdxCb * 10); - cr_quants = context->quants + (tile->quantIdxCr * 10); + YQuant = context->quants + (tile->quantIdxY * 10); + CbQuant = context->quants + (tile->quantIdxCb * 10); + CrQuant = context->quants + (tile->quantIdxCr * 10); + + tile->YData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + tile->CbData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + tile->CrData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); pSrcDst[0] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* y_r_buffer */ pSrcDst[1] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cb_g_buffer */ @@ -237,7 +241,7 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, int rowstride, wStream PROFILER_ENTER(context->priv->prof_rfx_encode_rgb); PROFILER_ENTER(context->priv->prof_rfx_encode_format_rgb); - rfx_encode_format_rgb(tile->data, tile->width, tile->height, rowstride, + rfx_encode_format_rgb(tile->data, tile->width, tile->height, tile->scanline, context->pixel_format, context->palette, pSrcDst[0], pSrcDst[1], pSrcDst[2]); PROFILER_EXIT(context->priv->prof_rfx_encode_format_rgb); @@ -246,30 +250,39 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, int rowstride, wStream pSrcDst, 64 * sizeof(INT16), &roi_64x64); PROFILER_EXIT(context->priv->prof_rfx_rgb_to_ycbcr); - /* Ensure the buffer is reasonably large enough */ - Stream_EnsureRemainingCapacity(s, 4096); + /** + * We need to clear the buffers as the RLGR encoder expects it to be initialized to zero. + * This allows simplifying and improving the performance of the encoding process. + */ - rfx_encode_component(context, y_quants, pSrcDst[0], - Stream_Pointer(s), Stream_GetRemainingLength(s), &YLen); - Stream_Seek(s, YLen); + ZeroMemory(tile->YData, 4096); + ZeroMemory(tile->CbData, 4096); + ZeroMemory(tile->CrData, 4096); - Stream_EnsureRemainingCapacity(s, 4096); - rfx_encode_component(context, cb_quants, pSrcDst[1], - Stream_Pointer(s), Stream_GetRemainingLength(s), &CbLen); - Stream_Seek(s, CbLen); - - Stream_EnsureRemainingCapacity(s, 4096); - rfx_encode_component(context, cr_quants, pSrcDst[2], - Stream_Pointer(s), Stream_GetRemainingLength(s), &CrLen); - Stream_Seek(s, CrLen); + rfx_encode_component(context, YQuant, pSrcDst[0], tile->YData, 4096, &YLen); + rfx_encode_component(context, CbQuant, pSrcDst[1], tile->CbData, 4096, &CbLen); + rfx_encode_component(context, CrQuant, pSrcDst[2], tile->CrData, 4096, &CrLen); tile->YLen = (UINT16) YLen; tile->CbLen = (UINT16) CbLen; tile->CrLen = (UINT16) CrLen; + Stream_EnsureRemainingCapacity(s, tile->YLen); + Stream_Write(s, tile->YData, tile->YLen); + + Stream_EnsureRemainingCapacity(s, tile->CbLen); + Stream_Write(s, tile->CbData, tile->CbLen); + + Stream_EnsureRemainingCapacity(s, tile->CrLen); + Stream_Write(s, tile->CrData, tile->CrLen); + PROFILER_EXIT(context->priv->prof_rfx_encode_rgb); BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[0] - 16); BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[1] - 16); BufferPool_Return(context->priv->BufferPool, (BYTE*)pSrcDst[2] - 16); + + BufferPool_Return(context->priv->BufferPool, tile->YData); + BufferPool_Return(context->priv->BufferPool, tile->CbData); + BufferPool_Return(context->priv->BufferPool, tile->CrData); } diff --git a/libfreerdp/codec/rfx_encode.h b/libfreerdp/codec/rfx_encode.h index ff1197b7f..90e484988 100644 --- a/libfreerdp/codec/rfx_encode.h +++ b/libfreerdp/codec/rfx_encode.h @@ -22,7 +22,7 @@ #include -void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, int rowstride, wStream* s); +void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, wStream* s); #endif