add frame acks and h264 codec mode basics

ulab-next-nosound
Jay Sorg 10 years ago
parent 7f8ec757de
commit 33167a7c74

@ -134,6 +134,14 @@ struct xrdp_client_info
char variant[16]; char variant[16];
char options[256]; 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 #endif

@ -557,6 +557,10 @@
#define XR_CODEC_GUID_PNG \ #define XR_CODEC_GUID_PNG \
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60" "\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_CAPSET_SURFCMDS 0x1c
#define RDP_CAPLEN_SURFCMDS 0x0c #define RDP_CAPLEN_SURFCMDS 0x0c
#define RDP_CAPSET_BMPCODECS 0x1d #define RDP_CAPSET_BMPCODECS 0x1d

@ -1312,7 +1312,7 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
int max_bytes; int max_bytes;
int cmd_bytes; int cmd_bytes;
LLOGLN(10, ("libxrdp_fastpath_init:")); LLOGLN(10, ("libxrdp_fastpath_send_surface:"));
if ((session->client_info->use_fast_path & 1) == 0) if ((session->client_info->use_fast_path & 1) == 0)
{ {
return 1; return 1;
@ -1362,3 +1362,40 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
} }
return 0; 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;
}

@ -242,5 +242,8 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
int destLeft, int dst_Top, int destLeft, int dst_Top,
int destRight, int destBottom, int bpp, int destRight, int destBottom, int bpp,
int codecID, int width, int height); 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 #endif

@ -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]); 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 else
{ {
g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id); 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; 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 int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s) 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) */ case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
xrdp_caps_process_codecs(self, s, len); xrdp_caps_process_codecs(self, s, len);
break; break;
case 0x001E: /* CAPSSETTYPE_FRAME_ACKNOWLEDGE */
xrdp_caps_process_frame_ack(self, s, len);
break;
default: default:
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
break; break;
@ -880,6 +903,12 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */ 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 */ out_uint8s(s, 4); /* pad */
s_mark_end(s); s_mark_end(s);

@ -112,18 +112,6 @@ xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
return 0; return 0;
} }
/*****************************************************************************/
/* 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 static int APP_CC
xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg, xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
@ -144,6 +132,19 @@ xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
return 0; return 0;
} }
/*****************************************************************************/
/* 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 */ /* FASTPATH_INPUT_EVENT_SCANCODE */
static int APP_CC static int APP_CC

@ -1106,6 +1106,24 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
} }
#endif #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 */ /* RDP_PDU_DATA */
int APP_CC int APP_CC
@ -1155,6 +1173,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
case RDP_DATA_PDU_FONT2: /* 39(0x27) */ case RDP_DATA_PDU_FONT2: /* 39(0x27) */
xrdp_rdp_process_data_font(self, s); xrdp_rdp_process_data_font(self, s);
break; break;
case 56: /* PDUTYPE2_FRAME_ACKNOWLEDGE 0x38 */
xrdp_rdp_process_frame_ack(self, s);
break;
default: default:
g_writeln("unknown in xrdp_rdp_process_data %d", data_type); g_writeln("unknown in xrdp_rdp_process_data %d", data_type);
break; break;

@ -378,6 +378,8 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self,
tbus* read_objs, int* rcount, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout); tbus* write_objs, int* wcount, int* timeout);
int APP_CC int APP_CC
xrdp_mm_check_chan(struct xrdp_mm *self);
int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm* self); xrdp_mm_check_wait_objs(struct xrdp_mm* self);
int DEFAULT_CC int DEFAULT_CC
server_begin_update(struct xrdp_mod* mod); server_begin_update(struct xrdp_mod* mod);

@ -39,30 +39,76 @@
} \ } \
while (0) while (0)
#define JPG_CODEC 0
#define RFX_CODEC 1
/*****************************************************************************/ /*****************************************************************************/
static int 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 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 struct xrdp_encoder *APP_CC
* xrdp_encoder_create(struct xrdp_mm *mm)
* @return 0 on success, -1 on failure
*****************************************************************************/
/* called from main thread */
int APP_CC
init_xrdp_encoder(struct xrdp_mm *self)
{ {
struct xrdp_encoder *self;
char buf[1024]; char buf[1024];
int pid; 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)); 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); g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid);
self->xrdp_encoder_term = g_create_wait_obj(buf); 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 */ /* create thread to process messages */
tc_thread_create(proc_enc_msg, self); tc_thread_create(proc_enc_msg, self);
return 0; return self;
} }
/** /*****************************************************************************/
* Deinit xrdp encoder
*****************************************************************************/
/* called from main thread */
void APP_CC void APP_CC
deinit_xrdp_encoder(struct xrdp_mm *self) xrdp_encoder_delete(struct xrdp_encoder *self)
{ {
XRDP_ENC_DATA *enc; XRDP_ENC_DATA *enc;
XRDP_ENC_DATA_DONE *enc_done; XRDP_ENC_DATA_DONE *enc_done;
FIFO *fifo; FIFO *fifo;
LLOGLN(0, ("deinit_xrdp_encoder: deiniting encoder")); LLOGLN(0, ("xrdp_encoder_delete:"));
if (self == 0) if (self == 0)
{ {
return; return;
} }
if (self->in_codec_mode == 0) if (self->in_codec_mode == 0)
{ {
return; return;
@ -135,12 +154,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_set_wait_obj(self->xrdp_encoder_term); g_set_wait_obj(self->xrdp_encoder_term);
g_sleep(1000); g_sleep(1000);
if (self->codec_id == 3) /* todo delete specific encoder */
{
#ifdef XRDP_RFXCODEC
rfxcodec_encode_destroy(self->codec_handle);
#endif
}
/* destroy wait objects used for signalling */ /* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc); 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->crects);
g_free(enc); g_free(enc);
} }
fifo_delete(fifo); fifo_delete(fifo);
} }
@ -173,7 +186,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
while (!fifo_is_empty(fifo)) while (!fifo_is_empty(fifo))
{ {
enc_done = fifo_remove_item(fifo); enc_done = fifo_remove_item(fifo);
if (enc == 0) if (enc_done == 0)
{ {
continue; continue;
} }
@ -182,12 +195,13 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
} }
fifo_delete(fifo); fifo_delete(fifo);
} }
g_free(self);
} }
/*****************************************************************************/ /*****************************************************************************/
/* called from encoder thread */ /* called from encoder thread */
static int 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 index;
int x; int x;
@ -236,9 +250,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
LLOGLN(0, ("process_enc_jpg: error 3")); LLOGLN(0, ("process_enc_jpg: error 3"));
return 1; return 1;
} }
out_data[256] = 0; /* header bytes */ out_data[256] = 0; /* header bytes */
out_data[257] = 0; 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, enc->height,
enc->width * 4, x, y, cx, cy, enc->width * 4, x, y, cx, cy,
quality, quality,
@ -278,7 +293,7 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
/*****************************************************************************/ /*****************************************************************************/
/* called from encoder thread */ /* called from encoder thread */
static int 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 index;
int x; 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->comp_pad_data = out_data;
enc_done->enc = enc; enc_done->enc = enc;
enc_done->last = 1; enc_done->last = 1;
enc_done->cx = self->wm->screen->width; enc_done->cx = self->mm->wm->screen->width;
enc_done->cy = self->wm->screen->height; enc_done->cy = self->mm->wm->screen->height;
/* done with msg */ /* done with msg */
/* inform main thread done */ /* inform main thread done */
@ -383,13 +398,22 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
/*****************************************************************************/ /*****************************************************************************/
/* called from encoder thread */ /* called from encoder thread */
static int 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; return 0;
} }
#endif #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 * Encoder thread main loop
*****************************************************************************/ *****************************************************************************/
@ -408,11 +432,11 @@ proc_enc_msg(void *arg)
int timeout; int timeout;
tbus robjs[32]; tbus robjs[32];
tbus wobjs[32]; tbus wobjs[32];
struct xrdp_mm *self; struct xrdp_encoder *self;
LLOGLN(0, ("proc_enc_msg: thread is running")); LLOGLN(0, ("proc_enc_msg: thread is running"));
self = (struct xrdp_mm *) arg; self = (struct xrdp_encoder *) arg;
if (self == 0) if (self == 0)
{ {
LLOGLN(0, ("proc_enc_msg: self nil")); LLOGLN(0, ("proc_enc_msg: self nil"));

@ -3,13 +3,67 @@
#define _XRDP_ENCODER_H #define _XRDP_ENCODER_H
#include "arch.h" #include "arch.h"
#include "fifo.h"
struct xrdp_mm; struct xrdp_enc_data;
int APP_CC /* for codec mode operations */
init_xrdp_encoder(struct xrdp_mm *self); 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 void APP_CC
deinit_xrdp_encoder(struct xrdp_mm *self); xrdp_encoder_delete(struct xrdp_encoder *self);
THREAD_RV THREAD_CC THREAD_RV THREAD_CC
proc_enc_msg(void *arg); proc_enc_msg(void *arg);

@ -58,46 +58,16 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->login_values->auto_free = 1; self->login_values->auto_free = 1;
LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d " 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->bpp,
self->wm->client_info->mcs_connection_type, self->wm->client_info->mcs_connection_type,
self->wm->client_info->jpeg_codec_id, self->wm->client_info->jpeg_codec_id,
self->wm->client_info->v3_codec_id, self->wm->client_info->v3_codec_id,
self->wm->client_info->rfx_codec_id)); self->wm->client_info->rfx_codec_id,
/* go into jpeg codec mode if jpeg set, lan set */ self->wm->client_info->h264_codec_id));
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;
}
}
}
if (self->in_codec_mode) self->encoder = xrdp_encoder_create(self);
{
/* setup thread to handle codec mode messages */
init_xrdp_encoder(self);
}
return self; return self;
} }
@ -174,7 +144,7 @@ xrdp_mm_delete(struct xrdp_mm *self)
xrdp_mm_module_cleanup(self); xrdp_mm_module_cleanup(self);
/* shutdown thread */ /* shutdown thread */
deinit_xrdp_encoder(self); xrdp_encoder_delete(self->encoder);
trans_delete(self->sesman_trans); trans_delete(self->sesman_trans);
self->sesman_trans = 0; 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; return rv;
@ -2019,6 +1989,28 @@ xrdp_mm_dump_jpeg(struct xrdp_mm *self, XRDP_ENC_DATA_DONE *enc_done)
#endif #endif
/*****************************************************************************/
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 int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm *self) xrdp_mm_check_wait_objs(struct xrdp_mm *self)
@ -2029,6 +2021,8 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
int y; int y;
int cx; int cx;
int cy; int cy;
int use_frame_acks;
int ex;
if (self == 0) if (self == 0)
{ {
@ -2077,15 +2071,18 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->delete_chan_trans = 0; 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); g_reset_wait_obj(self->encoder->xrdp_encoder_event_processed);
tc_mutex_lock(self->mutex); tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*) enc_done = (XRDP_ENC_DATA_DONE*)
fifo_remove_item(self->fifo_processed); fifo_remove_item(self->encoder->fifo_processed);
tc_mutex_unlock(self->mutex); tc_mutex_unlock(self->encoder->mutex);
while (enc_done != 0) while (enc_done != 0)
{ {
/* do something with msg */ /* do something with msg */
@ -2103,36 +2100,85 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
if (enc_done->comp_bytes > 0) 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, libxrdp_fastpath_send_surface(self->wm->session,
enc_done->comp_pad_data, enc_done->comp_pad_data,
enc_done->pad_bytes, enc_done->pad_bytes,
enc_done->comp_bytes, enc_done->comp_bytes,
x, y, x + cx, y + cy, 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 */ /* free enc_done */
if (enc_done->last) if (enc_done->last)
{ {
LLOGLN(10, ("xrdp_mm_check_wait_objs: last set")); LLOGLN(10, ("xrdp_mm_check_wait_objs: last set"));
if (use_frame_acks == 0)
{
self->mod->mod_frame_ack(self->mod, self->mod->mod_frame_ack(self->mod,
enc_done->enc->flags, enc_done->enc->frame_id); 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->drects);
g_free(enc_done->enc->crects); g_free(enc_done->enc->crects);
g_free(enc_done->enc); g_free(enc_done->enc);
} }
g_free(enc_done->comp_pad_data); g_free(enc_done->comp_pad_data);
g_free(enc_done); g_free(enc_done);
tc_mutex_lock(self->mutex); tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*) enc_done = (XRDP_ENC_DATA_DONE*)
fifo_remove_item(self->fifo_processed); fifo_remove_item(self->encoder->fifo_processed);
tc_mutex_unlock(self->mutex); tc_mutex_unlock(self->encoder->mutex);
} }
} }
} }
return rv; 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 #if 0
/*****************************************************************************/ /*****************************************************************************/
struct xrdp_painter *APP_CC struct xrdp_painter *APP_CC
@ -2354,9 +2400,9 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
mm = wm->mm; mm = wm->mm;
LLOGLN(10, ("server_paint_rects:")); 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 */ /* copy formal params to XRDP_ENC_DATA */
enc_data = (XRDP_ENC_DATA *) g_malloc(sizeof(XRDP_ENC_DATA), 1); 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->height = height;
enc_data->flags = flags; enc_data->flags = flags;
enc_data->frame_id = frame_id; enc_data->frame_id = frame_id;
mm->encoder->frame_id_server = frame_id;
if (width == 0 || height == 0) if (width == 0 || height == 0)
{ {
LLOGLN(10, ("server_paint_rects: error")); LLOGLN(10, ("server_paint_rects: error"));
} }
/* insert into fifo for encoder thread to process */ /* insert into fifo for encoder thread to process */
tc_mutex_lock(mm->mutex); tc_mutex_lock(mm->encoder->mutex);
fifo_add_item(mm->fifo_to_proc, (void *) enc_data); fifo_add_item(mm->encoder->fifo_to_proc, (void *) enc_data);
tc_mutex_unlock(mm->mutex); tc_mutex_unlock(mm->encoder->mutex);
/* signal xrdp_encoder thread */ /* 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; return 0;
} }

@ -292,19 +292,7 @@ struct xrdp_mm
int chan_trans_up; /* true once connected to chansrv */ int chan_trans_up; /* true once connected to chansrv */
int delete_chan_trans; /* boolean set when done with channel connection */ int delete_chan_trans; /* boolean set when done with channel connection */
int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */ int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
struct xrdp_encoder *encoder;
/* 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_key_info struct xrdp_key_info
@ -624,39 +612,4 @@ struct xrdp_config
struct xrdp_cfg_channels cfg_channels; 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 #endif

@ -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 */ pass it to module if there is one */
rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4); rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4);
break; 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; return rv;
} }

Loading…
Cancel
Save