diff options
Diffstat (limited to 'xrdp/xrdp_encoder.c')
| -rw-r--r-- | xrdp/xrdp_encoder.c | 188 |
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); |
