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,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -45,6 +45,7 @@ typedef struct xf_info xfInfo;
|
||||
struct xf_info
|
||||
{
|
||||
int bpp;
|
||||
int xfds;
|
||||
int depth;
|
||||
int width;
|
||||
int height;
|
||||
|
Loading…
Reference in New Issue
Block a user