gst/librfb/: Disable CopyRect encoding by default

Original commit message from CVS:
* gst/librfb/gstrfbsrc.c:
* gst/librfb/rfbdecoder.c:
* gst/librfb/rfbdecoder.h:
Disable CopyRect encoding by default
Add RRE encoding
This commit is contained in:
Thijs Vermeir 2007-11-29 13:32:11 +00:00
parent 17cd697aa0
commit f17a78668e
4 changed files with 122 additions and 48 deletions

View file

@ -1,3 +1,11 @@
2007-11-29 Thijs Vermeir <thijsvermeir@gmail.com>
* gst/librfb/gstrfbsrc.c:
* gst/librfb/rfbdecoder.c:
* gst/librfb/rfbdecoder.h:
Disable CopyRect encoding by default
Add RRE encoding
2007-11-29 Wim Taymans <wim.taymans@gmail.com>
Patch by: Wouter Cloetens <wouter at mind dot be>

View file

@ -43,6 +43,7 @@ enum
ARG_WIDTH,
ARG_HEIGHT,
ARG_INCREMENTAL,
ARG_USE_COPYRECT
};
GST_DEBUG_CATEGORY_STATIC (rfbsrc_debug);
@ -140,7 +141,9 @@ gst_rfb_src_class_init (GstRfbSrcClass * klass)
g_object_class_install_property (gobject_class, ARG_INCREMENTAL,
g_param_spec_boolean ("incremental", "Incremental updates",
"Incremental updates", TRUE, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_USE_COPYRECT,
g_param_spec_boolean ("use-copyrect", "Use copyrect encoding",
"Use copyrect encoding", FALSE, G_PARAM_READWRITE));
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_rfb_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_rfb_src_stop);
gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_rfb_src_event);
@ -258,6 +261,9 @@ gst_rfb_src_set_property (GObject * object, guint prop_id,
case ARG_INCREMENTAL:
src->incremental_update = g_value_get_boolean (value);
break;
case ARG_USE_COPYRECT:
src->decoder->use_copyrect = g_value_get_boolean (value);
break;
default:
break;
}
@ -297,6 +303,9 @@ gst_rfb_src_get_property (GObject * object, guint prop_id,
case ARG_INCREMENTAL:
g_value_set_boolean (value, src->incremental_update);
break;
case ARG_USE_COPYRECT:
g_value_set_boolean (value, src->decoder->use_copyrect);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -334,7 +343,9 @@ gst_rfb_src_start (GstBaseSrc * bsrc)
src->decoder->width * src->decoder->height * (decoder->bpp / 8), NULL);
decoder->frame = g_malloc (bsrc->blocksize);
decoder->prev_frame = g_malloc (bsrc->blocksize);
if (decoder->use_copyrect) {
decoder->prev_frame = g_malloc (bsrc->blocksize);
}
decoder->decoder_private = src;
/* calculate some many used values */

View file

@ -12,6 +12,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <byteswap.h>
#include "vncauth.h"
@ -52,6 +53,8 @@ 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);
static void rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x,
gint start_y, gint rect_w, gint rect_h);
RfbDecoder *
rfb_decoder_new (void)
@ -62,6 +65,8 @@ rfb_decoder_new (void)
decoder->password = NULL;
decoder->use_copyrect = FALSE;
decoder->offset_x = 0;
decoder->offset_y = 0;
decoder->rect_width = 0;
@ -187,8 +192,10 @@ rfb_decoder_send_update_request (RfbDecoder * decoder,
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);
if (decoder->use_copyrect) {
memcpy (decoder->prev_frame, decoder->frame,
decoder->rect_width * decoder->rect_height * decoder->bpp / 8);
}
decoder->state = rfb_decoder_state_normal;
}
@ -387,6 +394,27 @@ rfb_decoder_state_security_result (RfbDecoder * decoder)
return TRUE;
}
guint8 *
rfb_decoder_message_set_encodings (GSList * encodings_list)
{
guint8 *message = g_malloc0 (4 + 4 * g_slist_length (encodings_list));
message[0] = 0x02; /* message type */
RFB_SET_UINT16 (message + 2, g_slist_length (encodings_list)); /* number of encodings */
/* write all the encoding types */
guint32 *encoding_type = (guint32 *) (message + 4);
while (encodings_list) {
RFB_SET_UINT32 (encoding_type, (guint32) encodings_list->data);
encoding_type++;
encodings_list = encodings_list->next;
}
return message;
}
/**
* rfb_decoder_state_set_encodings:
* @decoder: The rfb context
@ -398,21 +426,22 @@ rfb_decoder_state_security_result (RfbDecoder * decoder)
static gboolean
rfb_decoder_state_set_encodings (RfbDecoder * decoder)
{
guint8 *buffer = g_malloc0 (12); // 4 + 4 * nr_of_encodings
GSList *encoder_list = NULL;
GST_DEBUG ("Sending encoding types to server");
GST_DEBUG ("entered set encodings");
buffer[0] = 2; // message-type
buffer[3] = 2; // number of encodings
encoder_list = g_slist_append (encoder_list, (guint32 *) ENCODING_TYPE_RRE);
if (decoder->use_copyrect) {
encoder_list =
g_slist_append (encoder_list, (guint32 *) ENCODING_TYPE_COPYRECT);
}
encoder_list = g_slist_append (encoder_list, (guint32 *) ENCODING_TYPE_RAW);
/* RAW encoding (0) */
guint8 *message = rfb_decoder_message_set_encodings (encoder_list);
/* CopyRect encoding (1) */
buffer[11] = 1;
rfb_decoder_send (decoder, message, 4 + 4 * g_slist_length (encoder_list));
rfb_decoder_send (decoder, buffer, 12);
g_free (buffer);
g_free (message);
decoder->state = rfb_decoder_state_normal;
decoder->inited = TRUE;
@ -560,40 +589,6 @@ rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
return TRUE;
}
/*
static gboolean
rfb_decoder_state_framebuffer_update (RfbDecoder *decoder)
{
RfbBuffer *buffer;
gint ret;
gint x, y, w, h;
gint encoding;
gint size;
ret = rfb_bytestream_peek (decoder->bytestream, &buffer, 12);
if (ret < 12)
return FALSE;
x = RFB_GET_UINT16 (buffer->data + 0);
y = RFB_GET_UINT16 (buffer->data + 2);
w = RFB_GET_UINT16 (buffer->data + 4);
h = RFB_GET_UINT16 (buffer->data + 6);
encoding = RFB_GET_UINT32 (buffer->data + 8);
GST_DEBUG(" UPDATE Receiver");
GST_DEBUG("x:%d y:%d", x, y);
GST_DEBUG("w:%d h:%d", w, h);
GST_DEBUG("encoding: %d", encoding);
switch (encoding)
{
default:
GST_WARNING("encoding type(%d) is not supported", encoding);
return FALSE;
}
return TRUE;
}
*/
static gboolean
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
{
@ -621,6 +616,9 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
case ENCODING_TYPE_COPYRECT:
rfb_decoder_copyrect_encoding (decoder, x, y, w, h);
break;
case ENCODING_TYPE_RRE:
rfb_decoder_rre_encoding (decoder, x, y, w, h);
break;
default:
g_critical ("unimplemented encoding\n");
break;
@ -696,6 +694,59 @@ rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
g_free (buffer);
}
static void
rfb_decoder_fill_rectangle (RfbDecoder * decoder, gint x, gint y, gint w,
gint h, guint32 color)
{
/* fill the whole region with the same color */
guint32 *offset;
gint i, j;
for (i = 0; i < h; i++) {
offset =
(guint32 *) (decoder->frame + ((x + (y +
i) * decoder->rect_width)) * decoder->bytespp);
for (j = 0; j < w; j++) {
*(offset++) = color;
}
}
}
static void
rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
gint rect_w, gint rect_h)
{
guint8 *buffer;
guint32 number_of_rectangles, color;
guint16 x, y, w, h;
buffer = rfb_decoder_read (decoder, 4 + decoder->bytespp);
number_of_rectangles = RFB_GET_UINT32 (buffer);
color = bswap_32 (RFB_GET_UINT32 (buffer + 4));
g_free (buffer);
GST_DEBUG ("number of rectangles :%d", number_of_rectangles);
/* color the background of this rectangle */
rfb_decoder_fill_rectangle (decoder, start_x, start_y, rect_w, rect_h, color);
while (number_of_rectangles--) {
buffer = rfb_decoder_read (decoder, decoder->bytespp + 8);
color = bswap_32 (RFB_GET_UINT32 (buffer));
x = RFB_GET_UINT16 (buffer + decoder->bytespp);
y = RFB_GET_UINT16 (buffer + decoder->bytespp + 2);
w = RFB_GET_UINT16 (buffer + decoder->bytespp + 4);
h = RFB_GET_UINT16 (buffer + decoder->bytespp + 6);
/* draw the rectangle in the foreground */
rfb_decoder_fill_rectangle (decoder, start_x + x, start_y + y, w, h, color);
g_free (buffer);
}
}
static gboolean
rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder)
{

View file

@ -19,6 +19,7 @@ G_BEGIN_DECLS enum
#define ENCODING_TYPE_RAW 0
#define ENCODING_TYPE_COPYRECT 1
#define ENCODING_TYPE_RRE 2
typedef struct _RfbDecoder RfbDecoder;
@ -46,6 +47,7 @@ struct _RfbDecoder
guint security_type;
gchar *password;
gboolean use_copyrect;
guint width;
guint height;
@ -102,6 +104,8 @@ 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);
guint8 *
rfb_decoder_message_set_encodings ( GSList *encodings_list);
G_END_DECLS
#endif