From 9f49600787e99b6d1dc0c52afe1647ef3429cc7b Mon Sep 17 00:00:00 2001 From: Christian Beier Date: Mon, 24 Jan 2011 23:32:24 +0100 Subject: [PATCH] libvncserver: Make RRE, CoRRE and Ultra encodings thread-safe. This adds generic before/after encoding buffers to the rfbClient struct, so there is no need for thread local storage. Signed-off-by: Christian Beier --- libvncserver/corre.c | 88 ++++++++++++++++----------------------- libvncserver/main.c | 3 -- libvncserver/private.h | 9 ---- libvncserver/rfbserver.c | 4 ++ libvncserver/rre.c | 90 ++++++++++++++++------------------------ libvncserver/ultra.c | 61 ++++++++++----------------- rfb/rfb.h | 7 ++++ 7 files changed, 103 insertions(+), 159 deletions(-) diff --git a/libvncserver/corre.c b/libvncserver/corre.c index bb07c77..8a845ea 100755 --- a/libvncserver/corre.c +++ b/libvncserver/corre.c @@ -30,37 +30,19 @@ #include /* - * rreBeforeBuf contains pixel data in the client's format. - * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is - * larger than the raw data or if it exceeds rreAfterBufSize then + * cl->beforeEncBuf contains pixel data in the client's format. + * cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is + * larger than the raw data or if it exceeds cl->afterEncBufSize then * raw encoding is used instead. */ -static int rreBeforeBufSize = 0; -static char *rreBeforeBuf = NULL; - -static int rreAfterBufSize = 0; -static char *rreAfterBuf = NULL; -static int rreAfterBufLen = 0; - -static int subrectEncode8(uint8_t *data, int w, int h); -static int subrectEncode16(uint16_t *data, int w, int h); -static int subrectEncode32(uint32_t *data, int w, int h); +static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h); +static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h); +static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h); static uint32_t getBgColour(char *data, int size, int bpp); static rfbBool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y, int w, int h); -void rfbCoRRECleanup(rfbScreenInfoPtr screen) -{ - if (rreBeforeBufSize) { - free(rreBeforeBuf); - rreBeforeBufSize=0; - } - if (rreAfterBufSize) { - free(rreAfterBuf); - rreAfterBufSize=0; - } -} /* * rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE @@ -114,35 +96,35 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height * (cl->format.bitsPerPixel / 8)); - if (rreBeforeBufSize < maxRawSize) { - rreBeforeBufSize = maxRawSize; - if (rreBeforeBuf == NULL) - rreBeforeBuf = (char *)malloc(rreBeforeBufSize); + if (cl->beforeEncBufSize < maxRawSize) { + cl->beforeEncBufSize = maxRawSize; + if (cl->beforeEncBuf == NULL) + cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize); else - rreBeforeBuf = (char *)realloc(rreBeforeBuf, rreBeforeBufSize); + cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize); } - if (rreAfterBufSize < maxRawSize) { - rreAfterBufSize = maxRawSize; - if (rreAfterBuf == NULL) - rreAfterBuf = (char *)malloc(rreAfterBufSize); + if (cl->afterEncBufSize < maxRawSize) { + cl->afterEncBufSize = maxRawSize; + if (cl->afterEncBuf == NULL) + cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize); else - rreAfterBuf = (char *)realloc(rreAfterBuf, rreAfterBufSize); + cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize); } (*cl->translateFn)(cl->translateLookupTable,&(cl->screen->serverFormat), - &cl->format, fbptr, rreBeforeBuf, + &cl->format, fbptr, cl->beforeEncBuf, cl->scaledScreen->paddedWidthInBytes, w, h); switch (cl->format.bitsPerPixel) { case 8: - nSubrects = subrectEncode8((uint8_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h); break; case 16: - nSubrects = subrectEncode16((uint16_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h); break; case 32: - nSubrects = subrectEncode32((uint32_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h); break; default: rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); @@ -157,7 +139,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, } rfbStatRecordEncodingSent(cl,rfbEncodingCoRRE, - sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen, + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen, sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8)); if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader @@ -182,15 +164,15 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader); cl->ublen += sz_rfbRREHeader; - for (i = 0; i < rreAfterBufLen;) { + for (i = 0; i < cl->afterEncBufLen;) { int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; - if (i + bytesToCopy > rreAfterBufLen) { - bytesToCopy = rreAfterBufLen - i; + if (i + bytesToCopy > cl->afterEncBufLen) { + bytesToCopy = cl->afterEncBufLen - i; } - memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy); + memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy); cl->ublen += bytesToCopy; i += bytesToCopy; @@ -210,7 +192,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, * subrectEncode() encodes the given multicoloured rectangle as a background * colour overwritten by single-coloured rectangles. It returns the number * of subrectangles in the encoded buffer, or -1 if subrect encoding won't - * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The * single-colour rectangle partition is not optimal, but does find the biggest * horizontal or vertical rectangle top-left anchored to each consecutive * coordinate position. @@ -221,7 +203,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, #define DEFINE_SUBRECT_ENCODE(bpp) \ static int \ -subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \ +subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \ uint##bpp##_t cl; \ rfbCoRRERectangle subrect; \ int x,y; \ @@ -236,9 +218,9 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \ int newLen; \ uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \ \ - *((uint##bpp##_t*)rreAfterBuf) = bg; \ + *((uint##bpp##_t*)client->afterEncBuf) = bg; \ \ - rreAfterBufLen = (bpp/8); \ + client->afterEncBufLen = (bpp/8); \ \ for (y=0; y (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ + newLen = client->afterEncBufLen + (bpp/8) + sz_rfbCoRRERectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \ return -1; \ \ numsubs += 1; \ - *((uint##bpp##_t*)(rreAfterBuf + rreAfterBufLen)) = cl; \ - rreAfterBufLen += (bpp/8); \ - memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \ - rreAfterBufLen += sz_rfbCoRRERectangle; \ + *((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \ + client->afterEncBufLen += (bpp/8); \ + memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbCoRRERectangle); \ + client->afterEncBufLen += sz_rfbCoRRERectangle; \ \ /* \ * Now mark the subrect as done. \ diff --git a/libvncserver/main.c b/libvncserver/main.c index b128581..eab4c84 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -1003,9 +1003,6 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen) if(screen->cursor && screen->cursor->cleanup) rfbFreeCursor(screen->cursor); - rfbRRECleanup(screen); - rfbCoRRECleanup(screen); - rfbUltraCleanup(screen); #ifdef LIBVNCSERVER_HAVE_LIBZ rfbZlibCleanup(screen); #ifdef LIBVNCSERVER_HAVE_LIBJPEG diff --git a/libvncserver/private.h b/libvncserver/private.h index 71370b5..d656e39 100644 --- a/libvncserver/private.h +++ b/libvncserver/private.h @@ -29,16 +29,7 @@ void rfbFreeZrleData(rfbClientPtr cl); /* from ultra.c */ -extern void rfbUltraCleanup(rfbScreenInfoPtr screen); extern void rfbFreeUltraData(rfbClientPtr cl); -/* from rre.c */ - -extern void rfbRRECleanup(rfbScreenInfoPtr screen); - -/* from corre.c */ - -extern void rfbCoRRECleanup(rfbScreenInfoPtr screen); - #endif diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index 8d6ae0c..554c118 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -486,6 +486,10 @@ rfbClientConnectionGone(rfbClientPtr cl) rfbFreeUltraData(cl); + /* free buffers holding pixel data before and after encoding */ + free(cl->beforeEncBuf); + free(cl->afterEncBuf); + #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD if(cl->screen->backgroundLoop != FALSE) { int i; diff --git a/libvncserver/rre.c b/libvncserver/rre.c index b43561a..2103153 100755 --- a/libvncserver/rre.c +++ b/libvncserver/rre.c @@ -29,38 +29,18 @@ #include /* - * rreBeforeBuf contains pixel data in the client's format. - * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is - * larger than the raw data or if it exceeds rreAfterBufSize then + * cl->beforeEncBuf contains pixel data in the client's format. + * cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is + * larger than the raw data or if it exceeds cl->afterEncBufSize then * raw encoding is used instead. */ -static int rreBeforeBufSize = 0; -static char *rreBeforeBuf = NULL; - -static int rreAfterBufSize = 0; -static char *rreAfterBuf = NULL; -static int rreAfterBufLen=0; - -static int subrectEncode8(uint8_t *data, int w, int h); -static int subrectEncode16(uint16_t *data, int w, int h); -static int subrectEncode32(uint32_t *data, int w, int h); +static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h); +static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h); +static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h); static uint32_t getBgColour(char *data, int size, int bpp); -void rfbRRECleanup(rfbScreenInfoPtr screen) -{ - if (rreBeforeBufSize) { - free(rreBeforeBuf); - rreBeforeBufSize=0; - } - if (rreAfterBufSize) { - free(rreAfterBuf); - rreAfterBufSize=0; - } -} - - /* * rfbSendRectEncodingRRE - send a given rectangle using RRE encoding. */ @@ -82,36 +62,36 @@ rfbSendRectEncodingRRE(rfbClientPtr cl, int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height * (cl->format.bitsPerPixel / 8)); - if (rreBeforeBufSize < maxRawSize) { - rreBeforeBufSize = maxRawSize; - if (rreBeforeBuf == NULL) - rreBeforeBuf = (char *)malloc(rreBeforeBufSize); + if (cl->beforeEncBufSize < maxRawSize) { + cl->beforeEncBufSize = maxRawSize; + if (cl->beforeEncBuf == NULL) + cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize); else - rreBeforeBuf = (char *)realloc(rreBeforeBuf, rreBeforeBufSize); + cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize); } - if (rreAfterBufSize < maxRawSize) { - rreAfterBufSize = maxRawSize; - if (rreAfterBuf == NULL) - rreAfterBuf = (char *)malloc(rreAfterBufSize); + if (cl->afterEncBufSize < maxRawSize) { + cl->afterEncBufSize = maxRawSize; + if (cl->afterEncBuf == NULL) + cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize); else - rreAfterBuf = (char *)realloc(rreAfterBuf, rreAfterBufSize); + cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize); } (*cl->translateFn)(cl->translateLookupTable, &(cl->screen->serverFormat), - &cl->format, fbptr, rreBeforeBuf, + &cl->format, fbptr, cl->beforeEncBuf, cl->scaledScreen->paddedWidthInBytes, w, h); switch (cl->format.bitsPerPixel) { case 8: - nSubrects = subrectEncode8((uint8_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h); break; case 16: - nSubrects = subrectEncode16((uint16_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h); break; case 32: - nSubrects = subrectEncode32((uint32_t *)rreBeforeBuf, w, h); + nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h); break; default: rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel); @@ -126,7 +106,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl, } rfbStatRecordEncodingSent(cl, rfbEncodingRRE, - sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen, + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen, sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8)); if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader @@ -151,15 +131,15 @@ rfbSendRectEncodingRRE(rfbClientPtr cl, memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader); cl->ublen += sz_rfbRREHeader; - for (i = 0; i < rreAfterBufLen;) { + for (i = 0; i < cl->afterEncBufLen;) { int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; - if (i + bytesToCopy > rreAfterBufLen) { - bytesToCopy = rreAfterBufLen - i; + if (i + bytesToCopy > cl->afterEncBufLen) { + bytesToCopy = cl->afterEncBufLen - i; } - memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy); + memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy); cl->ublen += bytesToCopy; i += bytesToCopy; @@ -179,7 +159,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl, * subrectEncode() encodes the given multicoloured rectangle as a background * colour overwritten by single-coloured rectangles. It returns the number * of subrectangles in the encoded buffer, or -1 if subrect encoding won't - * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The * single-colour rectangle partition is not optimal, but does find the biggest * horizontal or vertical rectangle top-left anchored to each consecutive * coordinate position. @@ -190,7 +170,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl, #define DEFINE_SUBRECT_ENCODE(bpp) \ static int \ -subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \ + subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \ uint##bpp##_t cl; \ rfbRectangle subrect; \ int x,y; \ @@ -205,9 +185,9 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \ int newLen; \ uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \ \ - *((uint##bpp##_t*)rreAfterBuf) = bg; \ + *((uint##bpp##_t*)client->afterEncBuf) = bg; \ \ - rreAfterBufLen = (bpp/8); \ + client->afterEncBufLen = (bpp/8); \ \ for (y=0; y (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \ + newLen = client->afterEncBufLen + (bpp/8) + sz_rfbRectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \ return -1; \ \ numsubs += 1; \ - *((uint##bpp##_t*)(rreAfterBuf + rreAfterBufLen)) = cl; \ - rreAfterBufLen += (bpp/8); \ - memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbRectangle); \ - rreAfterBufLen += sz_rfbRectangle; \ + *((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \ + client->afterEncBufLen += (bpp/8); \ + memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbRectangle); \ + client->afterEncBufLen += sz_rfbRectangle; \ \ /* \ * Now mark the subrect as done. \ diff --git a/libvncserver/ultra.c b/libvncserver/ultra.c index a802026..9a3b14f 100644 --- a/libvncserver/ultra.c +++ b/libvncserver/ultra.c @@ -11,19 +11,13 @@ #include "minilzo.h" /* - * lzoBeforeBuf contains pixel data in the client's format. - * lzoAfterBuf contains the lzo (deflated) encoding version. + * cl->beforeEncBuf contains pixel data in the client's format. + * cl->afterEncBuf contains the lzo (deflated) encoding version. * If the lzo compressed/encoded version is - * larger than the raw data or if it exceeds lzoAfterBufSize then + * larger than the raw data or if it exceeds cl->afterEncBufSize then * raw encoding is used instead. */ -static int lzoBeforeBufSize = 0; -static char *lzoBeforeBuf = NULL; - -static int lzoAfterBufSize = 0; -static char *lzoAfterBuf = NULL; -static int lzoAfterBufLen = 0; /* * rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib @@ -32,17 +26,6 @@ static int lzoAfterBufLen = 0; #define MAX_WRKMEM ((LZO1X_1_MEM_COMPRESS) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) -void rfbUltraCleanup(rfbScreenInfoPtr screen) -{ - if (lzoBeforeBufSize) { - free(lzoBeforeBuf); - lzoBeforeBufSize=0; - } - if (lzoAfterBufSize) { - free(lzoAfterBuf); - lzoAfterBufSize=0; - } -} void rfbFreeUltraData(rfbClientPtr cl) { if (cl->compStreamInitedLZO) { @@ -71,12 +54,12 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl, maxRawSize = (w * h * (cl->format.bitsPerPixel / 8)); - if (lzoBeforeBufSize < maxRawSize) { - lzoBeforeBufSize = maxRawSize; - if (lzoBeforeBuf == NULL) - lzoBeforeBuf = (char *)malloc(lzoBeforeBufSize); + if (cl->beforeEncBufSize < maxRawSize) { + cl->beforeEncBufSize = maxRawSize; + if (cl->beforeEncBuf == NULL) + cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize); else - lzoBeforeBuf = (char *)realloc(lzoBeforeBuf, lzoBeforeBufSize); + cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize); } /* @@ -85,19 +68,19 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl, */ maxCompSize = (maxRawSize + maxRawSize / 16 + 64 + 3); - if (lzoAfterBufSize < maxCompSize) { - lzoAfterBufSize = maxCompSize; - if (lzoAfterBuf == NULL) - lzoAfterBuf = (char *)malloc(lzoAfterBufSize); + if (cl->afterEncBufSize < maxCompSize) { + cl->afterEncBufSize = maxCompSize; + if (cl->afterEncBuf == NULL) + cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize); else - lzoAfterBuf = (char *)realloc(lzoAfterBuf, lzoAfterBufSize); + cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize); } /* * Convert pixel data to client format. */ (*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat, - &cl->format, fbptr, lzoBeforeBuf, + &cl->format, fbptr, cl->beforeEncBuf, cl->scaledScreen->paddedWidthInBytes, w, h); if ( cl->compStreamInitedLZO == FALSE ) { @@ -109,11 +92,11 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl, } /* Perform the compression here. */ - deflateResult = lzo1x_1_compress((unsigned char *)lzoBeforeBuf, (lzo_uint)(w * h * (cl->format.bitsPerPixel / 8)), (unsigned char *)lzoAfterBuf, (lzo_uint *)&maxCompSize, cl->lzoWrkMem); + deflateResult = lzo1x_1_compress((unsigned char *)cl->beforeEncBuf, (lzo_uint)(w * h * (cl->format.bitsPerPixel / 8)), (unsigned char *)cl->afterEncBuf, (lzo_uint *)&maxCompSize, cl->lzoWrkMem); /* maxCompSize now contains the compressed size */ /* Find the total size of the resulting compressed data. */ - lzoAfterBufLen = maxCompSize; + cl->afterEncBufLen = maxCompSize; if ( deflateResult != LZO_E_OK ) { rfbErr("lzo deflation error: %d\n", deflateResult); @@ -121,7 +104,7 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl, } /* Update statics */ - rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + lzoAfterBufLen, maxRawSize); + rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + cl->afterEncBufLen, maxRawSize); if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader > UPDATE_BUF_SIZE) @@ -140,21 +123,21 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl, sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; - hdr.nBytes = Swap32IfLE(lzoAfterBufLen); + hdr.nBytes = Swap32IfLE(cl->afterEncBufLen); memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader); cl->ublen += sz_rfbZlibHeader; /* We might want to try sending the data directly... */ - for (i = 0; i < lzoAfterBufLen;) { + for (i = 0; i < cl->afterEncBufLen;) { int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen; - if (i + bytesToCopy > lzoAfterBufLen) { - bytesToCopy = lzoAfterBufLen - i; + if (i + bytesToCopy > cl->afterEncBufLen) { + bytesToCopy = cl->afterEncBufLen - i; } - memcpy(&cl->updateBuf[cl->ublen], &lzoAfterBuf[i], bytesToCopy); + memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy); cl->ublen += bytesToCopy; i += bytesToCopy; diff --git a/rfb/rfb.h b/rfb/rfb.h index fa530b3..7c15bd8 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -617,6 +617,13 @@ typedef struct _rfbClientRec { MUTEX(sendMutex); #endif + /* buffers to hold pixel data before and after encoding. + per-client for thread safety */ + char *beforeEncBuf; + int beforeEncBufSize; + char *afterEncBuf; + int afterEncBufSize; + int afterEncBufLen; } rfbClientRec, *rfbClientPtr; /**