xfreerdp-server: improve XShm encoding

This commit is contained in:
Marc-André Moreau 2012-02-04 18:18:46 -05:00
parent 9c81ff8022
commit 66cd849229
5 changed files with 61 additions and 24 deletions

View File

@ -846,8 +846,8 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* s,
{
rfx_compose_message_tile(context, s,
image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel,
xIdx < numTilesX - 1 ? 64 : width - xIdx * 64,
yIdx < numTilesY - 1 ? 64 : height - yIdx * 64,
(xIdx < numTilesX - 1) ? 64 : width - xIdx * 64,
(yIdx < numTilesY - 1) ? 64 : height - yIdx * 64,
rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx);
}
}

View File

@ -43,6 +43,7 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height,
x_exceed = 64 - width;
y_exceed = 64 - height;
for (y = 0; y < height; y++)
{
src = rgb_data + y * rowstride;
@ -144,6 +145,7 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height,
r = *(r_buf - 1);
g = *(g_buf - 1);
b = *(b_buf - 1);
for (x = 0; x < x_exceed; x++)
{
*r_buf++ = r;
@ -159,6 +161,7 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height,
r_last = r_buf - 64;
g_last = g_buf - 64;
b_last = b_buf - 64;
while (y_exceed > 0)
{
memcpy(r_buf, r_last, 64 * sizeof(sint16));
@ -174,18 +177,18 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height,
void rfx_encode_rgb_to_ycbcr(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf)
{
// sint32 is used intentionally because we calculate with shifted factors!
sint32 y, cb, cr;
sint32 r, g, b;
/* sint32 is used intentionally because we calculate with shifted factors! */
int i;
sint32 r, g, b;
sint32 y, cb, cr;
/**
* The encoded YCbCr coeffectients are represented as 11.5 fixed-point numbers:
* The encoded YCbCr coefficients are represented as 11.5 fixed-point numbers:
*
* 1 sign bit + 10 integer bits + 5 fractional bits
*
* However only 7 integer bits will be actually used since the value range is [-128.0, 127.0].
* In other words, the encoded coeffectients is scaled by << 5 when intepreted as sint16.
* In other words, the encoded coefficients is scaled by << 5 when interpreted as sint16.
* It will be scaled down to original during the quantization phase.
*/
for (i = 0; i < 4096; i++)
@ -204,9 +207,9 @@ void rfx_encode_rgb_to_ycbcr(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf
* Cr: 0.499813 << 15 = 16377, 0.418531 << 15 = 13714, 0.081282 << 15 = 2663
*/
y = (r*9798 + g*19235 + b*3735)>>10;
cb = (r*-5535 + g*-10868 + b*16403)>>10;
cr = (r*16377 + g*-13714 + b*-2663)>>10;
y = (r * 9798 + g * 19235 + b * 3735) >> 10;
cb = (r * -5535 + g * -10868 + b * 16403) >> 10;
cr = (r * 16377 + g * -13714 + b * -2663) >> 10;
y_r_buf[i] = MINMAX(y - 4096, -4096, 4095);
cb_g_buf[i] = MINMAX(cb, -4096, 4095);

View File

@ -27,24 +27,28 @@ XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height)
XImage* image;
xfInfo* xfi = xfp->info;
pthread_mutex_lock(&(xfp->mutex));
if (xfi->use_xshm)
{
pthread_mutex_lock(&(xfp->mutex));
XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap,
xfi->xdamage_gc, x, y, width, height, x, y);
XSync(xfi->display, False);
image = xfi->fb_image;
pthread_mutex_unlock(&(xfp->mutex));
}
else
{
pthread_mutex_lock(&(xfp->mutex));
image = XGetImage(xfi->display, xfi->root_window,
x, y, width, height, AllPlanes, ZPixmap);
}
pthread_mutex_unlock(&(xfp->mutex));
pthread_mutex_unlock(&(xfp->mutex));
}
return image;
}
@ -91,12 +95,16 @@ void* xf_frame_rate_thread(void* param)
void* xf_monitor_updates(void* param)
{
int fds;
xfInfo* xfi;
XEvent xevent;
fd_set rfds_set;
int select_status;
int pending_events;
xfPeerContext* xfp;
freerdp_peer* client;
uint32 wait_interval;
int pending_events = 0;
struct timeval timeout;
int x, y, width, height;
XDamageNotifyEvent* notify;
xfEventRegion* event_region;
@ -105,14 +113,32 @@ void* xf_monitor_updates(void* param)
xfp = (xfPeerContext*) client->context;
xfi = xfp->info;
fds = xfi->xfds;
wait_interval = (1000000 / 2500);
memset(&timeout, 0, sizeof(struct timeval));
pthread_create(&(xfp->frame_rate_thread), 0, xf_frame_rate_thread, (void*) client);
pthread_detach(pthread_self());
wait_interval = (1000000 / 2500);
while (1)
{
FD_ZERO(&rfds_set);
FD_SET(fds, &rfds_set);
timeout.tv_sec = 0;
timeout.tv_usec = wait_interval;
select_status = select(fds + 1, &rfds_set, NULL, NULL, &timeout);
if (select_status == -1)
{
printf("select failed\n");
}
else if (select_status == 0)
{
//printf("select timeout\n");
}
pthread_mutex_lock(&(xfp->mutex));
pending_events = XPending(xfi->display);
pthread_mutex_unlock(&(xfp->mutex));
@ -139,8 +165,6 @@ void* xf_monitor_updates(void* param)
xf_event_push(xfp->event_queue, (xfEvent*) event_region);
}
}
freerdp_usleep(wait_interval);
}
return NULL;

View File

@ -111,13 +111,13 @@ void xf_xdamage_init(xfInfo* xfi)
values.subwindow_mode = IncludeInferiors;
xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values);
XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy);
}
#endif
void xf_xshm_init(xfInfo* xfi)
{
xfi->use_xshm = false;
xfi->fb_shm_info.shmid = -1;
xfi->fb_shm_info.shmaddr = (char*) -1;
@ -157,8 +157,6 @@ void xf_xshm_init(xfInfo* xfi)
xfi->fb_pixmap = XShmCreatePixmap(xfi->display,
xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info),
xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);
//xfi->use_xshm = true;
}
xfInfo* xf_info_init()
@ -175,6 +173,7 @@ xfInfo* xf_info_init()
xfi = xnew(xfInfo);
//xfi->use_xshm = true;
xfi->display = XOpenDisplay(NULL);
XInitThreads();
@ -185,6 +184,7 @@ xfInfo* xf_info_init()
exit(1);
}
xfi->xfds = ConnectionNumber(xfi->display);
xfi->number = DefaultScreen(xfi->display);
xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
xfi->depth = DefaultDepthOfScreen(xfi->screen);
@ -393,6 +393,7 @@ void xf_peer_dump_rfx(freerdp_peer* client)
void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height)
{
STREAM* s;
uint8* data;
xfInfo* xfi;
RFX_RECT rect;
XImage* image;
@ -412,6 +413,11 @@ void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
if (xfi->use_xshm)
{
width = x + width;
height = y + height;
x = 0;
y = 0;
rect.x = x;
rect.y = y;
rect.width = width;
@ -419,8 +425,11 @@ void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
image = xf_snapshot(xfp, x, y, width, height);
rfx_compose_message(xfp->rfx_context, s, &rect, 1,
(uint8*) image->data, xfi->width, xfi->height, image->bytes_per_line);
data = (uint8*) image->data;
data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel)];
rfx_compose_message(xfp->rfx_context, s, &rect, 1, data,
width, height, image->bytes_per_line);
cmd->destLeft = x;
cmd->destTop = y;

View File

@ -45,6 +45,7 @@ typedef struct xf_info xfInfo;
struct xf_info
{
int bpp;
int xfds;
int depth;
int width;
int height;