mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 08:24:16 +09:00
libfreerdp-codec: use pooled buffers for channel encoding
This commit is contained in:
@@ -54,6 +54,7 @@ struct _RFX_TILE
|
||||
int width;
|
||||
int height;
|
||||
BYTE* data;
|
||||
int scanline;
|
||||
|
||||
BYTE quantIdxY;
|
||||
BYTE quantIdxCb;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <freerdp/codec/rfx.h>
|
||||
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user