summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2015-03-28 18:34:25 -0700
committerJay Sorg <jay.sorg@gmail.com>2015-03-28 18:34:25 -0700
commit33167a7c746de49e735e76c5662d1e6c36bd10ed (patch)
tree936ed6150bf276d850a1f350823fb85bee296768
parent7f8ec757de53dbe2f4a19b5bf0a3edccbf31a0ef (diff)
downloadxrdp-proprietary-33167a7c746de49e735e76c5662d1e6c36bd10ed.tar.gz
xrdp-proprietary-33167a7c746de49e735e76c5662d1e6c36bd10ed.zip
add frame acks and h264 codec mode basics
-rw-r--r--common/xrdp_client_info.h8
-rw-r--r--common/xrdp_constants.h4
-rw-r--r--libxrdp/libxrdp.c39
-rw-r--r--libxrdp/libxrdpinc.h3
-rw-r--r--libxrdp/xrdp_caps.c29
-rw-r--r--libxrdp/xrdp_fastpath.c25
-rw-r--r--libxrdp/xrdp_rdp.c21
-rw-r--r--xrdp/xrdp.h2
-rw-r--r--xrdp/xrdp_encoder.c202
-rw-r--r--xrdp/xrdp_encoder.h62
-rw-r--r--xrdp/xrdp_mm.c159
-rw-r--r--xrdp/xrdp_types.h49
-rw-r--r--xrdp/xrdp_wm.c8
13 files changed, 400 insertions, 211 deletions
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index 8313d0ae..d1ce1e1e 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -134,6 +134,14 @@ struct xrdp_client_info
char variant[16];
char options[256];
+ /* codec */
+ int h264_codec_id;
+ int h264_prop_len;
+ char h264_prop[64];
+
+ int use_frame_acks;
+ int max_unacknowledged_frame_count;
+
};
#endif
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index 25d9495f..b8739b2b 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -557,6 +557,10 @@
#define XR_CODEC_GUID_PNG \
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
+/* MFVideoFormat_H264 ({34363248-0000-0010-8000-00AA00389B71}) */
+#define XR_CODEC_GUID_H264 \
+ "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
+
#define RDP_CAPSET_SURFCMDS 0x1c
#define RDP_CAPLEN_SURFCMDS 0x0c
#define RDP_CAPSET_BMPCODECS 0x1d
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 594fcc73..32ee2098 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -1312,7 +1312,7 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
int max_bytes;
int cmd_bytes;
- LLOGLN(10, ("libxrdp_fastpath_init:"));
+ LLOGLN(10, ("libxrdp_fastpath_send_surface:"));
if ((session->client_info->use_fast_path & 1) == 0)
{
return 1;
@@ -1362,3 +1362,40 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
}
return 0;
}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
+ int frame_action, int frame_id)
+{
+ struct stream *s;
+ struct xrdp_rdp *rdp;
+
+ LLOGLN(10, ("libxrdp_fastpath_send_frame_marker:"));
+ if ((session->client_info->use_fast_path & 1) == 0)
+ {
+ return 1;
+ }
+ if (session->client_info->use_frame_acks == 0)
+ {
+ return 1;
+ }
+ rdp = (struct xrdp_rdp *) (session->rdp);
+ make_stream(s);
+ init_stream(s, 8192);
+ xrdp_rdp_init_fastpath(rdp, s);
+ out_uint16_le(s, 0x0004); /* CMDTYPE_FRAME_MARKER */
+ out_uint16_le(s, frame_action);
+ out_uint32_le(s, frame_id);
+ s_mark_end(s);
+ /* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
+ if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ free_stream(s);
+ return 0;
+
+}
+
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index 2262f66f..8d99814c 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -242,5 +242,8 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
int destLeft, int dst_Top,
int destRight, int destBottom, int bpp,
int codecID, int width, int height);
+int EXPORT_CC
+libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
+ int frame_action, int frame_id);
#endif
diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c
index a5883a01..98ab03fa 100644
--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -486,6 +486,15 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]);
}
+ else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0)
+ {
+ g_writeln("xrdp_caps_process_codecs: h264 codec id %d prop len %d",
+ codec_id, codec_properties_length);
+ self->client_info.h264_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.h264_prop, s->p, i1);
+ self->client_info.h264_prop_len = i1;
+ }
else
{
g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id);
@@ -509,6 +518,17 @@ xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s,
return 0;
}
+ /*****************************************************************************/
+static int APP_CC
+xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
+{
+ g_writeln("xrdp_caps_process_frame_ack:");
+ self->client_info.use_frame_acks = 1;
+ in_uint32_le(s, self->client_info.max_unacknowledged_frame_count);
+ g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
+ return 0;
+}
+
/*****************************************************************************/
int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
@@ -626,6 +646,9 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
xrdp_caps_process_codecs(self, s, len);
break;
+ case 0x001E: /* CAPSSETTYPE_FRAME_ACKNOWLEDGE */
+ xrdp_caps_process_frame_ack(self, s, len);
+ break;
default:
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
break;
@@ -880,6 +903,12 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */
}
+ /* frame acks */
+ caps_count++;
+ out_uint16_le(s, 0x001E); /* CAPSETTYPE_FRAME_ACKNOWLEDGE */
+ out_uint16_le(s, 8);
+ out_uint32_le(s, 2); /* 2 frames in flight */
+
out_uint8s(s, 4); /* pad */
s_mark_end(s);
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 6a4eb78e..5bf63b29 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -113,18 +113,6 @@ xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
}
/*****************************************************************************/
-/* no fragmenation */
-int APP_CC
-xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
-{
- if (trans_force_write_s(self->trans, s) != 0)
- {
- return 1;
- }
- return 0;
-}
-
-/*****************************************************************************/
static int APP_CC
xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
long param1, long param2,
@@ -145,6 +133,19 @@ xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
}
/*****************************************************************************/
+/* no fragmenation */
+int APP_CC
+xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
+{
+ if (trans_force_write_s(self->trans, s) != 0)
+ {
+ return 1;
+ }
+ xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
+ return 0;
+}
+
+/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */
static int APP_CC
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 34842533..72562022 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -1107,6 +1107,24 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
#endif
/*****************************************************************************/
+static int APP_CC
+xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
+{
+ int frame_id;
+
+ //g_writeln("xrdp_rdp_process_frame_ack:");
+ in_uint32_le(s, frame_id);
+ //g_writeln(" frame_id %d", frame_id);
+ if (self->session->callback != 0)
+ {
+ /* call to xrdp_wm.c : callback */
+ self->session->callback(self->session->id, 0x5557, frame_id, 0,
+ 0, 0);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
/* RDP_PDU_DATA */
int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
@@ -1155,6 +1173,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
case RDP_DATA_PDU_FONT2: /* 39(0x27) */
xrdp_rdp_process_data_font(self, s);
break;
+ case 56: /* PDUTYPE2_FRAME_ACKNOWLEDGE 0x38 */
+ xrdp_rdp_process_frame_ack(self, s);
+ break;
default:
g_writeln("unknown in xrdp_rdp_process_data %d", data_type);
break;
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 67488a60..b23cdaf0 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -378,6 +378,8 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self,
tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int APP_CC
+xrdp_mm_check_chan(struct xrdp_mm *self);
+int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm* self);
int DEFAULT_CC
server_begin_update(struct xrdp_mod* mod);
diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c
index 78d1b52e..2b96d803 100644
--- a/xrdp/xrdp_encoder.c
+++ b/xrdp/xrdp_encoder.c
@@ -39,30 +39,76 @@
} \
while (0)
-#define JPG_CODEC 0
-#define RFX_CODEC 1
-
/*****************************************************************************/
static int
-process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc);
+static int
+process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc);
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+process_enc_h264(struct xrdp_encoder *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)
+/*****************************************************************************/
+struct xrdp_encoder *APP_CC
+xrdp_encoder_create(struct xrdp_mm *mm)
{
+ struct xrdp_encoder *self;
char buf[1024];
int pid;
- if (self == 0)
+ if (mm->wm->client_info->mcs_connection_type != 6) /* LAN */
+ {
+ return 0;
+ }
+
+ if (mm->wm->client_info->bpp < 24)
{
- return -1;
+ return 0;
+ }
+
+ self = (struct xrdp_encoder *)g_malloc(sizeof(struct xrdp_encoder), 1);
+ self->mm = mm;
+
+ if (mm->wm->client_info->jpeg_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting jpeg codec session"));
+ self->codec_id = mm->wm->client_info->jpeg_codec_id;
+ self->in_codec_mode = 1;
+ self->codec_quality = mm->wm->client_info->jpeg_prop[0];
+ mm->wm->client_info->capture_code = 0;
+ mm->wm->client_info->capture_format =
+ /* XRDP_a8b8g8r8 */
+ (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
+ self->process_enc = process_enc_jpg;
+ }
+ else if (mm->wm->client_info->rfx_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting rfx codec session"));
+ self->codec_id = mm->wm->client_info->rfx_codec_id;
+ self->in_codec_mode = 1;
+ mm->wm->client_info->capture_code = 2;
+ self->process_enc = process_enc_rfx;
+#ifdef XRDP_RFXCODEC
+ self->codec_handle =
+ rfxcodec_encode_create(mm->wm->screen->width,
+ mm->wm->screen->height,
+ RFX_FORMAT_YUV, 0);
+#endif
+ }
+ else if (mm->wm->client_info->h264_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting h264 codec session"));
+ self->codec_id = mm->wm->client_info->h264_codec_id;
+ self->in_codec_mode = 1;
+ mm->wm->client_info->capture_code = 3;
+ mm->wm->client_info->capture_format =
+ /* XRDP_nv12 */
+ (12 << 24) | (64 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0;
+ self->process_enc = process_enc_h264;
+ }
+ else
+ {
+ g_free(self);
+ return 0;
}
LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id));
@@ -81,52 +127,25 @@ 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);
- return 0;
+ return self;
}
-/**
- * Deinit xrdp encoder
- *****************************************************************************/
-/* called from main thread */
+/*****************************************************************************/
void APP_CC
-deinit_xrdp_encoder(struct xrdp_mm *self)
+xrdp_encoder_delete(struct xrdp_encoder *self)
{
XRDP_ENC_DATA *enc;
XRDP_ENC_DATA_DONE *enc_done;
- FIFO *fifo;
-
- LLOGLN(0, ("deinit_xrdp_encoder: deiniting encoder"));
+ FIFO *fifo;
+ LLOGLN(0, ("xrdp_encoder_delete:"));
if (self == 0)
{
return;
}
-
if (self->in_codec_mode == 0)
{
return;
@@ -135,12 +154,7 @@ 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
- }
+ /* todo delete specific encoder */
/* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc);
@@ -162,7 +176,6 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_free(enc->crects);
g_free(enc);
}
-
fifo_delete(fifo);
}
@@ -173,7 +186,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
while (!fifo_is_empty(fifo))
{
enc_done = fifo_remove_item(fifo);
- if (enc == 0)
+ if (enc_done == 0)
{
continue;
}
@@ -182,27 +195,28 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
}
fifo_delete(fifo);
}
+ g_free(self);
}
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
- int index;
- int x;
- int y;
- int cx;
- int cy;
- int quality;
- int error;
- int out_data_bytes;
- int count;
- char *out_data;
- XRDP_ENC_DATA_DONE *enc_done;
- FIFO *fifo_processed;
- tbus mutex;
- tbus event_processed;
+ int index;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int quality;
+ int error;
+ int out_data_bytes;
+ int count;
+ char *out_data;
+ XRDP_ENC_DATA_DONE *enc_done;
+ FIFO *fifo_processed;
+ tbus mutex;
+ tbus event_processed;
LLOGLN(10, ("process_enc_jpg:"));
quality = self->codec_quality;
@@ -236,9 +250,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
LLOGLN(0, ("process_enc_jpg: error 3"));
return 1;
}
+
out_data[256] = 0; /* header bytes */
out_data[257] = 0;
- error = libxrdp_codec_jpeg_compress(self->wm->session, 0, enc->data,
+ error = libxrdp_codec_jpeg_compress(self->mm->wm->session, 0, enc->data,
enc->width, enc->height,
enc->width * 4, x, y, cx, cy,
quality,
@@ -278,7 +293,7 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
@@ -364,8 +379,8 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
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;
+ enc_done->cx = self->mm->wm->screen->width;
+ enc_done->cy = self->mm->wm->screen->height;
/* done with msg */
/* inform main thread done */
@@ -383,36 +398,45 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
return 0;
}
#endif
+/*****************************************************************************/
+/* called from encoder thread */
+static int
+process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
+{
+ LLOGLN(0, ("process_enc_x264:"));
+ return 0;
+}
+
/**
* Encoder thread main loop
*****************************************************************************/
THREAD_RV THREAD_CC
proc_enc_msg(void *arg)
{
- XRDP_ENC_DATA *enc;
- FIFO *fifo_to_proc;
- tbus mutex;
- tbus event_to_proc;
- tbus term_obj;
- tbus lterm_obj;
- int robjs_count;
- int wobjs_count;
- int cont;
- int timeout;
- tbus robjs[32];
- tbus wobjs[32];
- struct xrdp_mm *self;
+ XRDP_ENC_DATA *enc;
+ FIFO *fifo_to_proc;
+ tbus mutex;
+ tbus event_to_proc;
+ tbus term_obj;
+ tbus lterm_obj;
+ int robjs_count;
+ int wobjs_count;
+ int cont;
+ int timeout;
+ tbus robjs[32];
+ tbus wobjs[32];
+ struct xrdp_encoder *self;
LLOGLN(0, ("proc_enc_msg: thread is running"));
- self = (struct xrdp_mm *) arg;
+ self = (struct xrdp_encoder *) arg;
if (self == 0)
{
LLOGLN(0, ("proc_enc_msg: self nil"));
diff --git a/xrdp/xrdp_encoder.h b/xrdp/xrdp_encoder.h
index 1d525f12..f138d749 100644
--- a/xrdp/xrdp_encoder.h
+++ b/xrdp/xrdp_encoder.h
@@ -3,13 +3,67 @@
#define _XRDP_ENCODER_H
#include "arch.h"
+#include "fifo.h"
-struct xrdp_mm;
+struct xrdp_enc_data;
-int APP_CC
-init_xrdp_encoder(struct xrdp_mm *self);
+/* for codec mode operations */
+struct xrdp_encoder
+{
+ struct xrdp_mm *mm;
+ int in_codec_mode;
+ int codec_id;
+ int codec_quality;
+ tbus xrdp_encoder_event_to_proc;
+ tbus xrdp_encoder_event_processed;
+ tbus xrdp_encoder_term;
+ FIFO *fifo_to_proc;
+ FIFO *fifo_processed;
+ tbus mutex;
+ int (*process_enc)(struct xrdp_encoder *self, struct xrdp_enc_data *enc);
+ void *codec_handle;
+ int frame_id_client; /* last frame id received from client */
+ int frame_id_server; /* last frame id received from Xorg */
+ int frame_id_server_sent;
+};
+
+/* used when scheduling tasks in xrdp_encoder.c */
+struct xrdp_enc_data
+{
+ struct xrdp_mod *mod;
+ int num_drects;
+ short *drects; /* 4 * num_drects */
+ int num_crects;
+ short *crects; /* 4 * num_crects */
+ char *data;
+ int width;
+ int height;
+ int flags;
+ int frame_id;
+};
+
+typedef struct xrdp_enc_data XRDP_ENC_DATA;
+
+/* used when scheduling tasks from xrdp_encoder.c */
+struct xrdp_enc_data_done
+{
+ int comp_bytes;
+ int pad_bytes;
+ char *comp_pad_data;
+ struct xrdp_enc_data *enc;
+ int last; /* true is this is last message for enc */
+ int x;
+ int y;
+ int cx;
+ int cy;
+};
+
+typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;
+
+struct xrdp_encoder *APP_CC
+xrdp_encoder_create(struct xrdp_mm *mm);
void APP_CC
-deinit_xrdp_encoder(struct xrdp_mm *self);
+xrdp_encoder_delete(struct xrdp_encoder *self);
THREAD_RV THREAD_CC
proc_enc_msg(void *arg);
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 76957ad6..8d67016b 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -58,46 +58,16 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->login_values->auto_free = 1;
LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d "
- "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d",
+ "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d "
+ "h264_codec_id %d",
self->wm->client_info->bpp,
self->wm->client_info->mcs_connection_type,
self->wm->client_info->jpeg_codec_id,
self->wm->client_info->v3_codec_id,
- self->wm->client_info->rfx_codec_id));
- /* go into jpeg codec mode if jpeg set, lan set */
- if (self->wm->client_info->mcs_connection_type == 6) /* LAN */
- {
- if (self->wm->client_info->jpeg_codec_id == 2) /* JPEG */
- {
- if (self->wm->client_info->bpp > 16)
- {
- LLOGLN(0, ("xrdp_mm_create: starting jpeg codec session"));
- self->codec_id = 2;
- self->in_codec_mode = 1;
- self->codec_quality = self->wm->client_info->jpeg_prop[0];
- self->wm->client_info->capture_code = 0;
- self->wm->client_info->capture_format =
- /* PIXMAN_a8b8g8r8 */
- (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
- }
- }
- else if (self->wm->client_info->rfx_codec_id == 3) /* RFX */
- {
- if (self->wm->client_info->bpp > 16)
- {
- LLOGLN(0, ("xrdp_mm_create: starting rfx codec session"));
- self->codec_id = 3;
- self->in_codec_mode = 1;
- self->wm->client_info->capture_code = 2;
- }
- }
- }
+ self->wm->client_info->rfx_codec_id,
+ self->wm->client_info->h264_codec_id));
- if (self->in_codec_mode)
- {
- /* setup thread to handle codec mode messages */
- init_xrdp_encoder(self);
- }
+ self->encoder = xrdp_encoder_create(self);
return self;
}
@@ -174,7 +144,7 @@ xrdp_mm_delete(struct xrdp_mm *self)
xrdp_mm_module_cleanup(self);
/* shutdown thread */
- deinit_xrdp_encoder(self);
+ xrdp_encoder_delete(self->encoder);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
@@ -1956,9 +1926,9 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
}
}
- if (self->in_codec_mode)
+ if (self->encoder != 0)
{
- read_objs[(*rcount)++] = self->xrdp_encoder_event_processed;
+ read_objs[(*rcount)++] = self->encoder->xrdp_encoder_event_processed;
}
return rv;
@@ -2021,6 +1991,28 @@ xrdp_mm_dump_jpeg(struct xrdp_mm *self, XRDP_ENC_DATA_DONE *enc_done)
/*****************************************************************************/
int APP_CC
+xrdp_mm_check_chan(struct xrdp_mm *self)
+{
+ //g_writeln("xrdp_mm_check_chan:");
+ if ((self->chan_trans != 0) && self->chan_trans_up)
+ {
+ if (trans_check_wait_objs(self->chan_trans) != 0)
+ {
+ self->delete_chan_trans = 1;
+ }
+ }
+ if (self->delete_chan_trans)
+ {
+ trans_delete(self->chan_trans);
+ self->chan_trans = 0;
+ self->chan_trans_up = 0;
+ self->delete_chan_trans = 0;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm *self)
{
XRDP_ENC_DATA_DONE *enc_done;
@@ -2029,6 +2021,8 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
int y;
int cx;
int cy;
+ int use_frame_acks;
+ int ex;
if (self == 0)
{
@@ -2077,15 +2071,18 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->delete_chan_trans = 0;
}
- if (self->in_codec_mode)
+ if (self->encoder != 0)
{
- if (g_is_wait_obj_set(self->xrdp_encoder_event_processed))
+
+ use_frame_acks = self->wm->client_info->use_frame_acks;
+
+ if (g_is_wait_obj_set(self->encoder->xrdp_encoder_event_processed))
{
- g_reset_wait_obj(self->xrdp_encoder_event_processed);
- tc_mutex_lock(self->mutex);
+ g_reset_wait_obj(self->encoder->xrdp_encoder_event_processed);
+ tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
- fifo_remove_item(self->fifo_processed);
- tc_mutex_unlock(self->mutex);
+ fifo_remove_item(self->encoder->fifo_processed);
+ tc_mutex_unlock(self->encoder->mutex);
while (enc_done != 0)
{
/* do something with msg */
@@ -2103,36 +2100,85 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
if (enc_done->comp_bytes > 0)
{
+ libxrdp_fastpath_send_frame_marker(self->wm->session, 0,
+ enc_done->enc->frame_id);
libxrdp_fastpath_send_surface(self->wm->session,
enc_done->comp_pad_data,
enc_done->pad_bytes,
enc_done->comp_bytes,
x, y, x + cx, y + cy,
- 32, self->codec_id, cx, cy);
+ 32, self->encoder->codec_id, cx, cy);
+ libxrdp_fastpath_send_frame_marker(self->wm->session, 1,
+ enc_done->enc->frame_id);
}
/* free enc_done */
if (enc_done->last)
{
LLOGLN(10, ("xrdp_mm_check_wait_objs: last set"));
- self->mod->mod_frame_ack(self->mod,
- enc_done->enc->flags, enc_done->enc->frame_id);
+ if (use_frame_acks == 0)
+ {
+ self->mod->mod_frame_ack(self->mod,
+ enc_done->enc->flags,
+ enc_done->enc->frame_id);
+ }
+ else
+ {
+#if 1
+ ex = self->wm->client_info->max_unacknowledged_frame_count;
+ if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server)
+ {
+ if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent)
+ {
+ LLOGLN(10, ("xrdp_mm_check_wait_objs: 1 -- %d", self->encoder->frame_id_server));
+ self->encoder->frame_id_server_sent = self->encoder->frame_id_server;
+ self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server);
+ }
+ }
+#endif
+ }
g_free(enc_done->enc->drects);
g_free(enc_done->enc->crects);
g_free(enc_done->enc);
}
g_free(enc_done->comp_pad_data);
g_free(enc_done);
- tc_mutex_lock(self->mutex);
+ tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
- fifo_remove_item(self->fifo_processed);
- tc_mutex_unlock(self->mutex);
+ fifo_remove_item(self->encoder->fifo_processed);
+ tc_mutex_unlock(self->encoder->mutex);
}
}
}
return rv;
}
+/*****************************************************************************/
+/* frame ack from client */
+int APP_CC
+xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id)
+{
+ int ex;
+
+ LLOGLN(0, ("xrdp_mm_frame_ack:"));
+ self->encoder->frame_id_client = frame_id;
+ if (self->wm->client_info->use_frame_acks == 0)
+ {
+ return 1;
+ }
+ ex = self->wm->client_info->max_unacknowledged_frame_count;
+ if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server)
+ {
+ if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent)
+ {
+ LLOGLN(10, ("xrdp_mm_frame_ack: frame_id_server %d", self->encoder->frame_id_server));
+ self->encoder->frame_id_server_sent = self->encoder->frame_id_server;
+ self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server);
+ }
+ }
+ return 0;
+}
+
#if 0
/*****************************************************************************/
struct xrdp_painter *APP_CC
@@ -2354,9 +2400,9 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
mm = wm->mm;
LLOGLN(10, ("server_paint_rects:"));
- LLOGLN(10, ("server_paint_rects: %d", mm->in_codec_mode));
+ LLOGLN(10, ("server_paint_rects: %p", mm->encoder));
- if (mm->in_codec_mode)
+ if (mm->encoder != 0)
{
/* copy formal params to XRDP_ENC_DATA */
enc_data = (XRDP_ENC_DATA *) g_malloc(sizeof(XRDP_ENC_DATA), 1);
@@ -2393,18 +2439,19 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
enc_data->height = height;
enc_data->flags = flags;
enc_data->frame_id = frame_id;
+ mm->encoder->frame_id_server = frame_id;
if (width == 0 || height == 0)
{
LLOGLN(10, ("server_paint_rects: error"));
}
/* insert into fifo for encoder thread to process */
- tc_mutex_lock(mm->mutex);
- fifo_add_item(mm->fifo_to_proc, (void *) enc_data);
- tc_mutex_unlock(mm->mutex);
+ tc_mutex_lock(mm->encoder->mutex);
+ fifo_add_item(mm->encoder->fifo_to_proc, (void *) enc_data);
+ tc_mutex_unlock(mm->encoder->mutex);
/* signal xrdp_encoder thread */
- g_set_wait_obj(mm->xrdp_encoder_event_to_proc);
+ g_set_wait_obj(mm->encoder->xrdp_encoder_event_to_proc);
return 0;
}
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 29aaac84..21d00e9a 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -292,19 +292,7 @@ struct xrdp_mm
int chan_trans_up; /* true once connected to chansrv */
int delete_chan_trans; /* boolean set when done with channel connection */
int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
-
- /* for codec mode operations */
- int in_codec_mode;
- int codec_id;
- int codec_quality;
- tbus xrdp_encoder_event_to_proc;
- tbus xrdp_encoder_event_processed;
- tbus xrdp_encoder_term;
- FIFO *fifo_to_proc;
- FIFO *fifo_processed;
- tbus mutex;
- int (*process_enc)(struct xrdp_mm *self, struct xrdp_enc_data *enc);
- void *codec_handle;
+ struct xrdp_encoder *encoder;
};
struct xrdp_key_info
@@ -624,39 +612,4 @@ struct xrdp_config
struct xrdp_cfg_channels cfg_channels;
};
-/* used when scheduling tasks in xrdp_encoder.c */
-struct xrdp_enc_data
-{
- struct xrdp_mod *mod;
- int num_drects;
- short *drects; /* 4 * num_drects */
- int num_crects;
- short *crects; /* 4 * num_crects */
- char *data;
- int width;
- int height;
- int flags;
- int frame_id;
-};
-
-typedef struct xrdp_enc_data XRDP_ENC_DATA;
-
-/* used when scheduling tasks from xrdp_encoder.c */
-struct xrdp_enc_data_done
-{
- int comp_bytes;
- int pad_bytes;
- char *comp_pad_data;
- struct xrdp_enc_data *enc;
- int last; /* true is this is last message for enc */
- int x;
- int y;
- int cx;
- int cy;
-};
-
-typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;
-
-
-
#endif
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 591c8a51..e3af0f05 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -1733,8 +1733,14 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
pass it to module if there is one */
rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4);
break;
+ case 0x5556:
+ rv = xrdp_mm_check_chan(wm->mm);
+ break;
+ case 0x5557:
+ //g_writeln("callback: frame ack %d", param1);
+ xrdp_mm_frame_ack(wm->mm, param1);
+ break;
}
-
return rv;
}