xfreerdp-server: improve XShm encoding
This commit is contained in:
parent
9c81ff8022
commit
66cd849229
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user