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, rfx_compose_message_tile(context, s,
image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel, image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel,
xIdx < numTilesX - 1 ? 64 : width - xIdx * 64, (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64,
yIdx < numTilesY - 1 ? 64 : height - yIdx * 64, (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64,
rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); 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; x_exceed = 64 - width;
y_exceed = 64 - height; y_exceed = 64 - height;
for (y = 0; y < height; y++) for (y = 0; y < height; y++)
{ {
src = rgb_data + y * rowstride; 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); r = *(r_buf - 1);
g = *(g_buf - 1); g = *(g_buf - 1);
b = *(b_buf - 1); b = *(b_buf - 1);
for (x = 0; x < x_exceed; x++) for (x = 0; x < x_exceed; x++)
{ {
*r_buf++ = r; *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; r_last = r_buf - 64;
g_last = g_buf - 64; g_last = g_buf - 64;
b_last = b_buf - 64; b_last = b_buf - 64;
while (y_exceed > 0) while (y_exceed > 0)
{ {
memcpy(r_buf, r_last, 64 * sizeof(sint16)); 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) 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 is used intentionally because we calculate with shifted factors! */
sint32 y, cb, cr;
sint32 r, g, b;
int i; 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 * 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]. * 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. * It will be scaled down to original during the quantization phase.
*/ */
for (i = 0; i < 4096; i++) 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 * Cr: 0.499813 << 15 = 16377, 0.418531 << 15 = 13714, 0.081282 << 15 = 2663
*/ */
y = (r*9798 + g*19235 + b*3735)>>10; y = (r * 9798 + g * 19235 + b * 3735) >> 10;
cb = (r*-5535 + g*-10868 + b*16403)>>10; cb = (r * -5535 + g * -10868 + b * 16403) >> 10;
cr = (r*16377 + g*-13714 + b*-2663)>>10; cr = (r * 16377 + g * -13714 + b * -2663) >> 10;
y_r_buf[i] = MINMAX(y - 4096, -4096, 4095); y_r_buf[i] = MINMAX(y - 4096, -4096, 4095);
cb_g_buf[i] = MINMAX(cb, -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; XImage* image;
xfInfo* xfi = xfp->info; xfInfo* xfi = xfp->info;
pthread_mutex_lock(&(xfp->mutex));
if (xfi->use_xshm) if (xfi->use_xshm)
{ {
pthread_mutex_lock(&(xfp->mutex));
XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap, XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap,
xfi->xdamage_gc, x, y, width, height, x, y); xfi->xdamage_gc, x, y, width, height, x, y);
XSync(xfi->display, False); XSync(xfi->display, False);
image = xfi->fb_image; image = xfi->fb_image;
pthread_mutex_unlock(&(xfp->mutex));
} }
else else
{ {
pthread_mutex_lock(&(xfp->mutex));
image = XGetImage(xfi->display, xfi->root_window, image = XGetImage(xfi->display, xfi->root_window,
x, y, width, height, AllPlanes, ZPixmap); x, y, width, height, AllPlanes, ZPixmap);
}
pthread_mutex_unlock(&(xfp->mutex)); pthread_mutex_unlock(&(xfp->mutex));
}
return image; return image;
} }
@ -91,12 +95,16 @@ void* xf_frame_rate_thread(void* param)
void* xf_monitor_updates(void* param) void* xf_monitor_updates(void* param)
{ {
int fds;
xfInfo* xfi; xfInfo* xfi;
XEvent xevent; XEvent xevent;
fd_set rfds_set;
int select_status;
int pending_events;
xfPeerContext* xfp; xfPeerContext* xfp;
freerdp_peer* client; freerdp_peer* client;
uint32 wait_interval; uint32 wait_interval;
int pending_events = 0; struct timeval timeout;
int x, y, width, height; int x, y, width, height;
XDamageNotifyEvent* notify; XDamageNotifyEvent* notify;
xfEventRegion* event_region; xfEventRegion* event_region;
@ -105,14 +113,32 @@ void* xf_monitor_updates(void* param)
xfp = (xfPeerContext*) client->context; xfp = (xfPeerContext*) client->context;
xfi = xfp->info; 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_create(&(xfp->frame_rate_thread), 0, xf_frame_rate_thread, (void*) client);
pthread_detach(pthread_self()); pthread_detach(pthread_self());
wait_interval = (1000000 / 2500);
while (1) 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)); pthread_mutex_lock(&(xfp->mutex));
pending_events = XPending(xfi->display); pending_events = XPending(xfi->display);
pthread_mutex_unlock(&(xfp->mutex)); pthread_mutex_unlock(&(xfp->mutex));
@ -139,8 +165,6 @@ void* xf_monitor_updates(void* param)
xf_event_push(xfp->event_queue, (xfEvent*) event_region); xf_event_push(xfp->event_queue, (xfEvent*) event_region);
} }
} }
freerdp_usleep(wait_interval);
} }
return NULL; return NULL;

View File

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

View File

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