From c8b85e19a4f5e80e1f1fde6228e9a571580ed651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 13 Aug 2013 14:13:05 -0400 Subject: [PATCH] libfreerdp-codec: separate tile encoding from writing --- libfreerdp/codec/rfx.c | 124 +++++++++++++++------------------- libfreerdp/codec/rfx_encode.c | 19 +----- libfreerdp/codec/rfx_encode.h | 2 +- libfreerdp/codec/rfx_types.h | 1 - 4 files changed, 58 insertions(+), 88 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index c0e165e3d..39e048daf 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -265,8 +265,6 @@ RFX_CONTEXT* rfx_context_new(void) SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount); } - 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); @@ -299,7 +297,6 @@ void rfx_context_free(RFX_CONTEXT* context) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); - StreamPool_Free(context->priv->EncoderStreamPool); #ifdef WITH_PROFILER fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); #endif @@ -1000,53 +997,39 @@ 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) +static void rfx_write_tile(RFX_CONTEXT* context, wStream* s, RFX_TILE* tile) { - int start_pos, end_pos; + UINT32 blockLen; - Stream_EnsureRemainingCapacity(s, 19); - start_pos = Stream_GetPosition(s); + blockLen = 19 + tile->YLen + tile->CbLen + tile->CrLen; + Stream_EnsureRemainingCapacity(s, blockLen); - Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType */ - Stream_Seek_UINT32(s); /* set BlockT.blockLen later */ - Stream_Write_UINT8(s, tile->quantIdxY); - Stream_Write_UINT8(s, tile->quantIdxCb); - Stream_Write_UINT8(s, tile->quantIdxCr); - Stream_Write_UINT16(s, tile->xIdx); - Stream_Write_UINT16(s, tile->yIdx); - - Stream_Seek(s, 6); /* YLen, CbLen, CrLen */ - - 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); - - end_pos = Stream_GetPosition(s); - - Stream_SetPosition(s, start_pos + 2); - Stream_Write_UINT32(s, 19 + tile->YLen + tile->CbLen + tile->CrLen); /* BlockT.blockLen */ - Stream_SetPosition(s, start_pos + 13); - Stream_Write_UINT16(s, tile->YLen); - Stream_Write_UINT16(s, tile->CbLen); - Stream_Write_UINT16(s, tile->CrLen); - - Stream_SetPosition(s, end_pos); + Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType (2 bytes) */ + Stream_Write_UINT32(s, blockLen); /* BlockT.blockLen (4 bytes) */ + Stream_Write_UINT8(s, tile->quantIdxY); /* quantIdxY (1 byte) */ + Stream_Write_UINT8(s, tile->quantIdxCb); /* quantIdxCb (1 byte) */ + Stream_Write_UINT8(s, tile->quantIdxCr); /* quantIdxCr (1 byte) */ + Stream_Write_UINT16(s, tile->xIdx); /* xIdx (2 bytes) */ + Stream_Write_UINT16(s, tile->yIdx); /* yIdx (2 bytes) */ + Stream_Write_UINT16(s, tile->YLen); /* YLen (2 bytes) */ + Stream_Write_UINT16(s, tile->CbLen); /* CbLen (2 bytes) */ + Stream_Write_UINT16(s, tile->CrLen); /* CrLen (2 bytes) */ + Stream_Write(s, tile->YData, tile->YLen); /* YData */ + Stream_Write(s, tile->CbData, tile->CbLen); /* CbData */ + Stream_Write(s, tile->CrData, tile->CrLen); /* CrData */ } - struct _RFX_TILE_COMPOSE_WORK_PARAM { RFX_TILE* tile; RFX_CONTEXT* context; - wStream* s; }; 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; - rfx_compose_message_tile(param->context, param->s, param->tile); + rfx_encode_rgb(param->context, param->tile); } static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, @@ -1054,16 +1037,16 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, { int i; int size; + int xIdx; + int yIdx; + int numTiles; + int numTilesX; + int numTilesY; RFX_TILE* tile; int start_pos, end_pos; int numQuants; const UINT32* quantVals; const UINT32* quantValsPtr; - int numTiles; - int numTilesX; - int numTilesY; - int xIdx; - int yIdx; int tilesDataSize; PTP_WORK* work_objects = NULL; RFX_TILE_COMPOSE_WORK_PARAM* params = NULL; @@ -1107,15 +1090,14 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, quantValsPtr += 2; } - DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, scanline); + DEBUG_RFX("width:%d height:%d scanline:%d", width, height, scanline); end_pos = Stream_GetPosition(s); if (context->priv->UseThreads) - { work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * 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) * numTiles); for (yIdx = 0; yIdx < numTilesY; yIdx++) { @@ -1138,14 +1120,13 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, tile->YLen = 0; tile->CbLen = 0; tile->CrLen = 0; - tile->YData = NULL; - tile->CbData = NULL; - tile->CrData = NULL; + 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); if (context->priv->UseThreads) { params[i].context = context; - params[i].s = StreamPool_Take(context->priv->EncoderStreamPool, 0); work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback, (void*) ¶ms[i], &context->priv->ThreadPoolEnv); @@ -1154,32 +1135,39 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, wStream* s, } else { - rfx_compose_message_tile(context, s, tile); + rfx_encode_rgb(context, tile); } } } + for (yIdx = 0; yIdx < numTilesY; yIdx++) + { + for (xIdx = 0; xIdx < numTilesX; xIdx++) + { + i = yIdx * numTilesX + xIdx; + + 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); + } + } + if (context->priv->UseThreads) - { - for (yIdx = 0; yIdx < numTilesY; yIdx++) - { - for (xIdx = 0; xIdx < numTilesX; xIdx++) - { - i = yIdx * numTilesX + xIdx; - - WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); - CloseThreadpoolWork(work_objects[i]); - - Stream_EnsureRemainingCapacity(s, Stream_GetPosition(params[i].s)); - Stream_Write(s, Stream_Buffer(params[i].s), Stream_GetPosition(params[i].s)); - ObjectPool_Return(context->priv->TilePool, (void*) params[i].tile); - Stream_Release(params[i].s); - } - } - free(work_objects); - free(params); - } + + free(params); tilesDataSize = Stream_GetPosition(s) - end_pos; size += tilesDataSize; diff --git a/libfreerdp/codec/rfx_encode.c b/libfreerdp/codec/rfx_encode.c index 61d994e1a..f484e58fd 100644 --- a/libfreerdp/codec/rfx_encode.c +++ b/libfreerdp/codec/rfx_encode.c @@ -217,7 +217,7 @@ 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, wStream* s) +void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile) { INT16* pSrcDst[3]; int YLen, CbLen, CrLen; @@ -230,10 +230,6 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, wStream* s) 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 */ pSrcDst[2] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cr_b_buffer */ @@ -267,22 +263,9 @@ void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, wStream* s) 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 90e484988..28bc96651 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, wStream* s); +void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile); #endif diff --git a/libfreerdp/codec/rfx_types.h b/libfreerdp/codec/rfx_types.h index 2675d35ad..fbb4df837 100644 --- a/libfreerdp/codec/rfx_types.h +++ b/libfreerdp/codec/rfx_types.h @@ -49,7 +49,6 @@ struct _RFX_CONTEXT_PRIV TP_CALLBACK_ENVIRON ThreadPoolEnv; wBufferPool* BufferPool; - wStreamPool* EncoderStreamPool; /* profilers */ PROFILER_DEFINE(prof_rfx_decode_rgb);