From aac84ad1c721c8db84b729d2b265aa62c3f1b5c9 Mon Sep 17 00:00:00 2001 From: Thijs Vermeir Date: Wed, 31 Oct 2007 14:09:25 +0000 Subject: gst/librfb/: Added copyrect encoding Original commit message from CVS: * gst/librfb/d3des.h: * gst/librfb/gstrfbsrc.c: * gst/librfb/gstrfbsrc.h: * gst/librfb/rfbbuffer.h: * gst/librfb/rfbcontext.h: * gst/librfb/rfbdecoder.c: * gst/librfb/rfbdecoder.h: * gst/librfb/rfbutil.h: * gst/librfb/vncauth.h: Added copyrect encoding --- gst/librfb/d3des.h | 17 +++++--- gst/librfb/gstrfbsrc.c | 59 +++++++++----------------- gst/librfb/gstrfbsrc.h | 4 -- gst/librfb/rfbbuffer.h | 11 ++--- gst/librfb/rfbcontext.h | 5 +-- gst/librfb/rfbdecoder.c | 110 ++++++++++++++++++++++++++++++++++++++++-------- gst/librfb/rfbdecoder.h | 59 +++++++++++--------------- gst/librfb/rfbutil.h | 5 +-- gst/librfb/vncauth.h | 9 ++-- 9 files changed, 156 insertions(+), 123 deletions(-) (limited to 'gst') diff --git a/gst/librfb/d3des.h b/gst/librfb/d3des.h index e647fc12..7988eef3 100644 --- a/gst/librfb/d3des.h +++ b/gst/librfb/d3des.h @@ -19,28 +19,32 @@ * (GEnie : OUTER; CIS : [71755,204]) */ -#define EN0 0 /* MODE == encrypt */ -#define DE1 1 /* MODE == decrypt */ +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +extern void deskey (unsigned char *, int); -extern void deskey(unsigned char *, int); /* hexkey[8] MODE * Sets the internal key register according to the hexadecimal * key contained in the 8 bytes of hexkey, according to the DES, * for encryption or decryption according to MODE. */ -extern void usekey(unsigned long *); +extern void usekey (unsigned long *); + /* cookedkey[32] * Loads the internal key register with the data in cookedkey. */ -extern void cpkey(unsigned long *); +extern void cpkey (unsigned long *); + /* cookedkey[32] * Copies the contents of the internal key register into the storage * located at &cookedkey[0]. */ -extern void des(unsigned char *, unsigned char *); +extern void des (unsigned char *, unsigned char *); + /* from[8] to[8] * Encrypts/Decrypts (according to the key currently loaded in the * internal key register) one block of eight bytes at address 'from' @@ -49,4 +53,3 @@ extern void des(unsigned char *, unsigned char *); /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery ********************************************************************/ - diff --git a/gst/librfb/gstrfbsrc.c b/gst/librfb/gstrfbsrc.c index 626a5ff6..37757156 100644 --- a/gst/librfb/gstrfbsrc.c +++ b/gst/librfb/gstrfbsrc.c @@ -84,8 +84,6 @@ static gboolean gst_rfb_src_stop (GstBaseSrc * bsrc); static gboolean gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event); static GstFlowReturn gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); -static void gst_rfb_src_paint_rect (RfbDecoder * decoder, gint x, gint y, - gint w, gint h, guint8 * data); GST_BOILERPLATE (GstRfbSrc, gst_rfb_src, GstPushSrc, GST_TYPE_PUSH_SRC); @@ -327,11 +325,16 @@ gst_rfb_src_start (GstBaseSrc * bsrc) rfb_decoder_iterate (decoder); } + decoder->rect_width = + (decoder->rect_width ? decoder->rect_width : decoder->width); + decoder->rect_height = + (decoder->rect_height ? decoder->rect_height : decoder->height); + g_object_set (bsrc, "blocksize", src->decoder->width * src->decoder->height * (decoder->bpp / 8), NULL); - src->frame = g_malloc (bsrc->blocksize); - decoder->paint_rect = gst_rfb_src_paint_rect; + decoder->frame = g_malloc (bsrc->blocksize); + decoder->prev_frame = g_malloc (bsrc->blocksize); decoder->decoder_private = src; GST_DEBUG_OBJECT (src, "setting caps width to %d and height to %d", @@ -356,9 +359,14 @@ gst_rfb_src_stop (GstBaseSrc * bsrc) src->decoder->fd = -1; - if (src->frame) { - g_free (src->frame); - src->frame = NULL; + if (src->decoder->frame) { + g_free (src->decoder->frame); + src->decoder->frame = NULL; + } + + if (src->decoder->prev_frame) { + g_free (src->decoder->prev_frame); + src->decoder->prev_frame = NULL; } return TRUE; @@ -373,13 +381,10 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) GstFlowReturn ret; rfb_decoder_send_update_request (decoder, src->incremental_update, - decoder->offset_x, decoder->offset_y, - (decoder->rect_width ? decoder->rect_width : decoder->width), - (decoder->rect_height ? decoder->rect_height : decoder->height)); - // src->inter = TRUE; + decoder->offset_x, decoder->offset_y, decoder->rect_width, + decoder->rect_height); - src->go = TRUE; - while (src->go) { + while (decoder->state != NULL) { rfb_decoder_iterate (decoder); } @@ -394,7 +399,7 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) return GST_FLOW_ERROR; } - memcpy (GST_BUFFER_DATA (*outbuf), src->frame, newsize); + memcpy (GST_BUFFER_DATA (*outbuf), decoder->frame, newsize); GST_BUFFER_SIZE (*outbuf) = newsize; return GST_FLOW_OK; @@ -449,32 +454,6 @@ gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event) return TRUE; } -static void -gst_rfb_src_paint_rect (RfbDecoder * decoder, gint start_x, gint start_y, - gint rect_w, gint rect_h, guint8 * data) -{ - gint pos_y; - guint8 *frame; - GstRfbSrc *src; - gint width; - guint32 src_offset; - guint32 dst_offset; - - //printf ("painting %d,%d (%dx%d)\n", start_x, start_y, rect_w, rect_h); - src = GST_RFB_SRC (decoder->decoder_private); - - frame = src->frame; - width = decoder->width; - - for (pos_y = start_y; pos_y < (start_y + rect_h); pos_y++) { - src_offset = (pos_y - start_y) * rect_w * decoder->bpp / 8; - dst_offset = ((pos_y * width) + start_x) * decoder->bpp / 8; - memcpy (frame + dst_offset, data + src_offset, rect_w * decoder->bpp / 8); - } - - src->go = FALSE; -} - static gboolean plugin_init (GstPlugin * plugin) { diff --git a/gst/librfb/gstrfbsrc.h b/gst/librfb/gstrfbsrc.h index 13f79287..72af58cb 100644 --- a/gst/librfb/gstrfbsrc.h +++ b/gst/librfb/gstrfbsrc.h @@ -27,7 +27,6 @@ #include G_BEGIN_DECLS - #define GST_TYPE_RFB_SRC \ (gst_rfb_src_get_type()) #define GST_RFB_SRC(obj) \ @@ -38,7 +37,6 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RFB_SRC)) #define GST_IS_RFB_SRC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RFB_SRC)) - typedef struct _GstRfbSrc GstRfbSrc; typedef struct _GstRfbSrcClass GstRfbSrcClass; @@ -55,7 +53,6 @@ struct _GstRfbSrc gint port; RfbDecoder *decoder; - guint8 *frame; gboolean go; gboolean incremental_update; @@ -70,5 +67,4 @@ struct _GstRfbSrc GType gst_rfb_src_get_type (void); G_END_DECLS - #endif diff --git a/gst/librfb/rfbbuffer.h b/gst/librfb/rfbbuffer.h index 5c09c77c..6250ad46 100644 --- a/gst/librfb/rfbbuffer.h +++ b/gst/librfb/rfbbuffer.h @@ -3,10 +3,8 @@ #include -G_BEGIN_DECLS - -typedef struct _RfbBuffer RfbBuffer; -typedef void(*RfbBufferFreeFunc)(guint8 *data, gpointer priv); +G_BEGIN_DECLS typedef struct _RfbBuffer RfbBuffer; +typedef void (*RfbBufferFreeFunc) (guint8 * data, gpointer priv); struct _RfbBuffer { @@ -17,10 +15,9 @@ struct _RfbBuffer gint length; }; -RfbBuffer *rfb_buffer_new (void); +RfbBuffer *rfb_buffer_new (void); RfbBuffer *rfb_buffer_new_and_alloc (gint len); -void rfb_buffer_free (RfbBuffer *buffer); +void rfb_buffer_free (RfbBuffer * buffer); G_END_DECLS - #endif diff --git a/gst/librfb/rfbcontext.h b/gst/librfb/rfbcontext.h index fb41aa0c..4c72bc65 100644 --- a/gst/librfb/rfbcontext.h +++ b/gst/librfb/rfbcontext.h @@ -3,9 +3,7 @@ #include -G_BEGIN_DECLS - -typedef struct _RfbContext +G_BEGIN_DECLS typedef struct _RfbContext { RfbConnection *connection; @@ -34,5 +32,4 @@ typedef struct _RfbRect } RfbRect; G_END_DECLS - #endif diff --git a/gst/librfb/rfbdecoder.c b/gst/librfb/rfbdecoder.c index 85658bd4..bd13569b 100644 --- a/gst/librfb/rfbdecoder.c +++ b/gst/librfb/rfbdecoder.c @@ -48,6 +48,10 @@ static gboolean rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder); static gboolean rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder); static gboolean rfb_decoder_state_server_cut_text (RfbDecoder * decoder); +static void rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x, + gint start_y, gint rect_w, gint rect_h); +static void rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, + gint start_y, gint rect_w, gint rect_h); RfbDecoder * rfb_decoder_new (void) @@ -181,6 +185,12 @@ rfb_decoder_send_update_request (RfbDecoder * decoder, RFB_SET_UINT16 (data + 8, height); rfb_decoder_send (decoder, data, 10); + + /* create a backup of the prev frame for copyrect encoding */ + memcpy (decoder->prev_frame, decoder->frame, + decoder->rect_width * decoder->rect_height * decoder->bpp / 8); + + decoder->state = rfb_decoder_state_normal; } void @@ -388,18 +398,24 @@ rfb_decoder_state_security_result (RfbDecoder * decoder) static gboolean rfb_decoder_state_set_encodings (RfbDecoder * decoder) { - guint8 *buffer = g_malloc0 (8); // 4 + 4 * nr_of_encodings + guint8 *buffer = g_malloc0 (12); // 4 + 4 * nr_of_encodings + + GST_DEBUG ("Sending encoding types to server"); buffer[0] = 2; // message-type - buffer[3] = 1; // number of encodings + buffer[3] = 2; // number of encodings /* RAW encoding (0) */ - rfb_decoder_send (decoder, buffer, 8); + /* CopyRect encoding (1) */ + buffer[11] = 1; + + rfb_decoder_send (decoder, buffer, 12); g_free (buffer); decoder->state = rfb_decoder_state_normal; + decoder->inited = TRUE; return TRUE; } @@ -492,8 +508,6 @@ rfb_decoder_state_wait_for_server_initialisation (RfbDecoder * decoder) } decoder->state = rfb_decoder_state_set_encodings; - decoder->inited = TRUE; - return TRUE; } @@ -503,11 +517,13 @@ rfb_decoder_state_normal (RfbDecoder * decoder) guint8 *buffer; gint message_type; + GST_DEBUG ("decoder_state_normal"); + buffer = rfb_decoder_read (decoder, 1); message_type = RFB_GET_UINT8 (buffer); switch (message_type) { - case 0: + case MESSAGE_TYPE_FRAMEBUFFER_UPDATE: GST_DEBUG ("Receiving framebuffer update"); decoder->state = rfb_decoder_state_framebuffer_update; break; @@ -584,7 +600,6 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder) guint8 *buffer; gint x, y, w, h; gint encoding; - gint size; buffer = rfb_decoder_read (decoder, 12); @@ -599,26 +614,85 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder) GST_DEBUG ("w:%d h:%d", w, h); GST_DEBUG ("encoding: %d", encoding); - if (encoding != 0) - g_critical ("unimplemented encoding\n"); - + switch (encoding) { + case ENCODING_TYPE_RAW: + rfb_decoder_raw_encoding (decoder, x, y, w, h); + break; + case ENCODING_TYPE_COPYRECT: + rfb_decoder_copyrect_encoding (decoder, x, y, w, h); + break; + default: + g_critical ("unimplemented encoding\n"); + break; + } g_free (buffer); + decoder->n_rects--; + if (decoder->n_rects == 0) { + decoder->state = NULL; + } else { + decoder->state = rfb_decoder_state_framebuffer_update_rectangle; + } + return TRUE; +} - size = w * h * decoder->bpp / 8; +static void +rfb_decoder_raw_encoding (RfbDecoder * decoder, gint start_x, gint start_y, + gint rect_w, gint rect_h) +{ + gint pos_y, size; + guint8 *frame, *buffer; + gint width; + guint32 src_offset; + guint32 dst_offset; + + /* read the data */ + size = rect_h * rect_w * decoder->bpp / 8; GST_DEBUG ("Reading %d bytes", size); buffer = rfb_decoder_read (decoder, size); - GST_DEBUG ("Reading %d bytes", size); - if (decoder->paint_rect) { - decoder->paint_rect (decoder, x, y, w, h, buffer); + frame = decoder->frame; + width = decoder->rect_width; + + for (pos_y = start_y; pos_y < (start_y + rect_h); pos_y++) { + src_offset = (pos_y - start_y) * rect_w * decoder->bpp / 8; + dst_offset = ((pos_y * width) + start_x) * decoder->bpp / 8; + memcpy (frame + dst_offset, buffer + src_offset, rect_w * decoder->bpp / 8); } g_free (buffer); - decoder->n_rects--; - if (decoder->n_rects == 0) { - decoder->state = rfb_decoder_state_normal; +} + +static void +rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y, + gint rect_w, gint rect_h) +{ + guint16 src_x, src_y; + guint32 src_offset; + guint32 dst_offset; + gint pos_y, max_y, line_width, copyrect_width; + guint8 *buffer; + + buffer = rfb_decoder_read (decoder, 4); + max_y = start_y + rect_h; + + src_x = RFB_GET_UINT16 (buffer); + src_y = RFB_GET_UINT16 (buffer + 2); + GST_DEBUG ("Copyrect from %d %d", src_x, src_y); + + dst_offset = + (((start_y - 1) * decoder->rect_width) + start_x) * decoder->bpp / 8; + src_offset = (((src_y - 1) * decoder->rect_width) + src_x) * decoder->bpp / 8; + line_width = decoder->rect_width * decoder->bpp / 8; + copyrect_width = rect_w * decoder->bpp / 8; + + for (pos_y = start_y; pos_y < max_y; pos_y++) { + dst_offset += line_width; + src_offset += line_width; + memcpy (decoder->frame + dst_offset, decoder->prev_frame + src_offset, + copyrect_width); } - return TRUE; + + g_free (buffer); } static gboolean diff --git a/gst/librfb/rfbdecoder.h b/gst/librfb/rfbdecoder.h index 5d7d983e..8ec94bd2 100644 --- a/gst/librfb/rfbdecoder.h +++ b/gst/librfb/rfbdecoder.h @@ -3,12 +3,11 @@ #include -G_BEGIN_DECLS - -enum { - SECURITY_FAIL = 0, - SECURITY_NONE, - SECURITY_VNC, +G_BEGIN_DECLS enum +{ + SECURITY_FAIL = 0, + SECURITY_NONE, + SECURITY_VNC, }; #define IS_VERSION(x, ma, mi) ((x->protocol_major == ma) && (x->protocol_minor == mi)) @@ -16,23 +15,25 @@ enum { #define IS_VERSION_3_7(x) IS_VERSION(x, 3, 7) #define IS_VERSION_3_8(x) IS_VERSION(x, 3, 8) +#define MESSAGE_TYPE_FRAMEBUFFER_UPDATE 0 + +#define ENCODING_TYPE_RAW 0 +#define ENCODING_TYPE_COPYRECT 1 + typedef struct _RfbDecoder RfbDecoder; struct _RfbDecoder { /* callbacks */ - gint (*send_data) (guint8 *buffer, gint length, gpointer user_data); - void (*paint_rect) (RfbDecoder *decoder, gint x, gint y, gint w, gint h, - guint8 *data); - void (*copy_rect) (RfbDecoder *decoder, gint x, gint y, gint w, gint h, - gint src_x, gint src_y); - gboolean (*state) (RfbDecoder *decoder); + gboolean (*state) (RfbDecoder * decoder); gpointer buffer_handler_data; gint fd; gpointer decoder_private; + guint8 *frame; + guint8 *prev_frame; /* settable properties */ gboolean shared_flag; @@ -85,28 +86,18 @@ typedef struct _RfbRect } RfbRect; #endif -RfbDecoder *rfb_decoder_new (void); -void rfb_decoder_free (RfbDecoder * decoder); -void rfb_decoder_use_file_descriptor (RfbDecoder * decoder, - gint fd); -gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder, - gchar * addr, - guint port); -gboolean rfb_decoder_iterate (RfbDecoder * decoder); -void rfb_decoder_send_update_request (RfbDecoder * decoder, - gboolean incremental, - gint x, - gint y, - gint width, - gint height); -void rfb_decoder_send_key_event (RfbDecoder * decoder, - guint key, - gboolean down_flag); -void rfb_decoder_send_pointer_event (RfbDecoder * decoder, - gint button_mask, - gint x, - gint y); +RfbDecoder *rfb_decoder_new (void); +void rfb_decoder_free (RfbDecoder * decoder); +void rfb_decoder_use_file_descriptor (RfbDecoder * decoder, gint fd); +gboolean rfb_decoder_connect_tcp (RfbDecoder * decoder, + gchar * addr, guint port); +gboolean rfb_decoder_iterate (RfbDecoder * decoder); +void rfb_decoder_send_update_request (RfbDecoder * decoder, + gboolean incremental, gint x, gint y, gint width, gint height); +void rfb_decoder_send_key_event (RfbDecoder * decoder, + guint key, gboolean down_flag); +void rfb_decoder_send_pointer_event (RfbDecoder * decoder, + gint button_mask, gint x, gint y); G_END_DECLS - #endif diff --git a/gst/librfb/rfbutil.h b/gst/librfb/rfbutil.h index c816bcd4..b1ac9462 100644 --- a/gst/librfb/rfbutil.h +++ b/gst/librfb/rfbutil.h @@ -3,8 +3,5 @@ #include -G_BEGIN_DECLS - -G_END_DECLS - +G_BEGIN_DECLS G_END_DECLS #endif diff --git a/gst/librfb/vncauth.h b/gst/librfb/vncauth.h index 2a4deaeb..6420dbc8 100644 --- a/gst/librfb/vncauth.h +++ b/gst/librfb/vncauth.h @@ -24,8 +24,7 @@ #define MAXPWLEN 8 #define CHALLENGESIZE 16 -extern int vncEncryptAndStorePasswd(char *passwd, char *fname); -extern char *vncDecryptPasswdFromFile(char *fname); -extern void vncRandomBytes(unsigned char *bytes); -extern void vncEncryptBytes(unsigned char *bytes, char *passwd); - +extern int vncEncryptAndStorePasswd (char *passwd, char *fname); +extern char *vncDecryptPasswdFromFile (char *fname); +extern void vncRandomBytes (unsigned char *bytes); +extern void vncEncryptBytes (unsigned char *bytes, char *passwd); -- cgit v1.2.1