summaryrefslogtreecommitdiffstats
path: root/xrdp/xrdp_encoder.c
diff options
context:
space:
mode:
authorIdan Freiberg <speidy@gmail.com>2014-07-23 16:44:59 +0300
committerIdan Freiberg <speidy@gmail.com>2014-07-23 16:44:59 +0300
commit16929efb059e1e29c826388e5d57be82014d241b (patch)
treef8661e7495a82a4a73e68825f1a1ff44a9e100f1 /xrdp/xrdp_encoder.c
parent0795400fe260652f6ae3788325e2a4c8ee05fe3a (diff)
parent0c63a8feb3c52de98a5da51a0a0f743450c34645 (diff)
downloadxrdp-proprietary-16929efb059e1e29c826388e5d57be82014d241b.tar.gz
xrdp-proprietary-16929efb059e1e29c826388e5d57be82014d241b.zip
Merge branch 'devel' of https://github.com/neutrinolabs/xrdp into
devel Conflicts: libxrdp/xrdp_sec.c
Diffstat (limited to 'xrdp/xrdp_encoder.c')
-rw-r--r--xrdp/xrdp_encoder.c188
1 files changed, 174 insertions, 14 deletions
diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c
index 5ed1a5c0..78d1b52e 100644
--- a/xrdp/xrdp_encoder.c
+++ b/xrdp/xrdp_encoder.c
@@ -39,25 +39,34 @@
} \
while (0)
+#define JPG_CODEC 0
+#define RFX_CODEC 1
+
+/*****************************************************************************/
+static int
+process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+static int
+process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+
/**
* Init encoder
*
* @return 0 on success, -1 on failure
*****************************************************************************/
-
+/* called from main thread */
int APP_CC
init_xrdp_encoder(struct xrdp_mm *self)
{
char buf[1024];
int pid;
- LLOGLN(0, ("init_xrdp_encoder: initing encoder"));
-
if (self == 0)
{
return -1;
}
+ LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id));
+
/* setup required FIFOs */
self->fifo_to_proc = fifo_create();
self->fifo_processed = fifo_create();
@@ -72,6 +81,28 @@ init_xrdp_encoder(struct xrdp_mm *self)
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid);
self->xrdp_encoder_term = g_create_wait_obj(buf);
+ switch (self->codec_id)
+ {
+ case 2:
+ self->process_enc = process_enc_jpg;
+ break;
+ case 3:
+ self->process_enc = process_enc_rfx;
+#ifdef XRDP_RFXCODEC
+ self->codec_handle =
+ rfxcodec_encode_create(self->wm->screen->width,
+ self->wm->screen->height,
+ RFX_FORMAT_YUV, 0);
+ //RFX_FORMAT_BGRA, 0);
+#endif
+ break;
+ default:
+ LLOGLN(0, ("init_xrdp_encoder: unknown codec_id %d",
+ self->codec_id));
+ break;
+
+ }
+
/* create thread to process messages */
tc_thread_create(proc_enc_msg, self);
@@ -104,6 +135,13 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_set_wait_obj(self->xrdp_encoder_term);
g_sleep(1000);
+ if (self->codec_id == 3)
+ {
+#ifdef XRDP_RFXCODEC
+ rfxcodec_encode_destroy(self->codec_handle);
+#endif
+ }
+
/* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc);
g_delete_wait_obj(self->xrdp_encoder_event_processed);
@@ -147,8 +185,9 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
}
/*****************************************************************************/
+/* called from encoder thread */
static int
-process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
@@ -165,7 +204,7 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
tbus mutex;
tbus event_processed;
- LLOGLN(10, ("process_enc:"));
+ LLOGLN(10, ("process_enc_jpg:"));
quality = self->codec_quality;
fifo_processed = self->fifo_processed;
mutex = self->mutex;
@@ -179,19 +218,22 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
cy = enc->crects[index * 4 + 3];
if (cx < 1 || cy < 1)
{
- LLOGLN(0, ("process_enc: error 1"));
+ LLOGLN(0, ("process_enc_jpg: error 1"));
continue;
}
+
+ LLOGLN(10, ("process_enc_jpg: x %d y %d cx %d cy %d", x, y, cx, cy));
+
out_data_bytes = MAX((cx + 4) * cy * 4, 8192);
if ((out_data_bytes < 1) || (out_data_bytes > 16 * 1024 * 1024))
{
- LLOGLN(0, ("process_enc: error 2"));
+ LLOGLN(0, ("process_enc_jpg: error 2"));
return 1;
}
out_data = (char *) g_malloc(out_data_bytes + 256 + 2, 0);
if (out_data == 0)
{
- LLOGLN(0, ("process_enc: error 3"));
+ LLOGLN(0, ("process_enc_jpg: error 3"));
return 1;
}
out_data[256] = 0; /* header bytes */
@@ -203,7 +245,7 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
out_data + 256 + 2, &out_data_bytes);
if (error < 0)
{
- LLOGLN(0, ("process_enc: jpeg error %d bytes %d",
+ LLOGLN(0, ("process_enc_jpg: jpeg error %d bytes %d",
error, out_data_bytes));
g_free(out_data);
return 1;
@@ -216,7 +258,10 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = index == (enc->num_crects - 1);
- enc_done->index = index;
+ enc_done->x = x;
+ enc_done->y = y;
+ enc_done->cx = cx;
+ enc_done->cy = cy;
/* done with msg */
/* inform main thread done */
tc_mutex_lock(mutex);
@@ -228,10 +273,125 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
return 0;
}
+#ifdef XRDP_RFXCODEC
+
+/*****************************************************************************/
+/* called from encoder thread */
+static int
+process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+{
+ int index;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int out_data_bytes;
+ int count;
+ int error;
+ char *out_data;
+ XRDP_ENC_DATA_DONE *enc_done;
+ FIFO *fifo_processed;
+ tbus mutex;
+ tbus event_processed;
+ struct rfx_tile *tiles;
+ struct rfx_rect *rfxrects;
+
+ LLOGLN(10, ("process_enc_rfx:"));
+ LLOGLN(10, ("process_enc_rfx: num_crects %d num_drects %d",
+ enc->num_crects, enc->num_drects));
+ fifo_processed = self->fifo_processed;
+ mutex = self->mutex;
+ event_processed = self->xrdp_encoder_event_processed;
+
+ if ((enc->num_crects > 512) || (enc->num_drects > 512))
+ {
+ return 0;
+ }
+
+ out_data_bytes = 16 * 1024 * 1024;
+ index = 256 + sizeof(struct rfx_tile) * 512 +
+ sizeof(struct rfx_rect) * 512;
+ out_data = (char *) g_malloc(out_data_bytes + index, 0);
+ if (out_data == 0)
+ {
+ return 0;
+ }
+ tiles = (struct rfx_tile *) (out_data + out_data_bytes + 256);
+ rfxrects = (struct rfx_rect *) (tiles + 512);
+
+ count = enc->num_crects;
+ for (index = 0; index < count; index++)
+ {
+ x = enc->crects[index * 4 + 0];
+ y = enc->crects[index * 4 + 1];
+ cx = enc->crects[index * 4 + 2];
+ cy = enc->crects[index * 4 + 3];
+ LLOGLN(10, ("process_enc_rfx:"));
+ tiles[index].x = x;
+ tiles[index].y = y;
+ tiles[index].cx = cx;
+ tiles[index].cy = cy;
+ LLOGLN(10, ("x %d y %d cx %d cy %d", x, y, cx, cy));
+ tiles[index].quant_y = 0;
+ tiles[index].quant_cb = 0;
+ tiles[index].quant_cr = 0;
+ }
+
+ count = enc->num_drects;
+ for (index = 0; index < count; index++)
+ {
+ x = enc->drects[index * 4 + 0];
+ y = enc->drects[index * 4 + 1];
+ cx = enc->drects[index * 4 + 2];
+ cy = enc->drects[index * 4 + 3];
+ LLOGLN(10, ("process_enc_rfx:"));
+ rfxrects[index].x = x;
+ rfxrects[index].y = y;
+ rfxrects[index].cx = cx;
+ rfxrects[index].cy = cy;
+ }
+
+ error = rfxcodec_encode(self->codec_handle, out_data + 256, &out_data_bytes,
+ enc->data, enc->width, enc->height, enc->width * 4,
+ rfxrects, enc->num_drects,
+ tiles, enc->num_crects, 0, 0);
+ LLOGLN(10, ("process_enc_rfx: rfxcodec_encode rv %d", error));
+
+ enc_done = (XRDP_ENC_DATA_DONE *)
+ g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
+ enc_done->comp_bytes = out_data_bytes;
+ enc_done->pad_bytes = 256;
+ enc_done->comp_pad_data = out_data;
+ enc_done->enc = enc;
+ enc_done->last = 1;
+ enc_done->cx = self->wm->screen->width;
+ enc_done->cy = self->wm->screen->height;
+
+ /* done with msg */
+ /* inform main thread done */
+ tc_mutex_lock(mutex);
+ fifo_add_item(fifo_processed, enc_done);
+ tc_mutex_unlock(mutex);
+ /* signal completion for main thread */
+ g_set_wait_obj(event_processed);
+
+ return 0;
+}
+
+#else
+
+/*****************************************************************************/
+/* called from encoder thread */
+static int
+process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+{
+ return 0;
+}
+
+#endif
+
/**
- * Init encoder
- *
- * @return 0 on success, -1 on failure
+ * Encoder thread main loop
*****************************************************************************/
THREAD_RV THREAD_CC
proc_enc_msg(void *arg)
@@ -305,7 +465,7 @@ proc_enc_msg(void *arg)
while (enc != 0)
{
/* do work */
- process_enc(self, enc);
+ self->process_enc(self, enc);
/* get next msg */
tc_mutex_lock(mutex);
enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo_to_proc);