mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
17cd697aa0
commit
f17a78668e
4 changed files with 122 additions and 48 deletions
|
@ -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>
|
2007-11-29 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
Patch by: Wouter Cloetens <wouter at mind dot be>
|
Patch by: Wouter Cloetens <wouter at mind dot be>
|
||||||
|
|
|
@ -43,6 +43,7 @@ enum
|
||||||
ARG_WIDTH,
|
ARG_WIDTH,
|
||||||
ARG_HEIGHT,
|
ARG_HEIGHT,
|
||||||
ARG_INCREMENTAL,
|
ARG_INCREMENTAL,
|
||||||
|
ARG_USE_COPYRECT
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (rfbsrc_debug);
|
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_object_class_install_property (gobject_class, ARG_INCREMENTAL,
|
||||||
g_param_spec_boolean ("incremental", "Incremental updates",
|
g_param_spec_boolean ("incremental", "Incremental updates",
|
||||||
"Incremental updates", TRUE, G_PARAM_READWRITE));
|
"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->start = GST_DEBUG_FUNCPTR (gst_rfb_src_start);
|
||||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_rfb_src_stop);
|
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_rfb_src_stop);
|
||||||
gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_rfb_src_event);
|
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:
|
case ARG_INCREMENTAL:
|
||||||
src->incremental_update = g_value_get_boolean (value);
|
src->incremental_update = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case ARG_USE_COPYRECT:
|
||||||
|
src->decoder->use_copyrect = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +303,9 @@ gst_rfb_src_get_property (GObject * object, guint prop_id,
|
||||||
case ARG_INCREMENTAL:
|
case ARG_INCREMENTAL:
|
||||||
g_value_set_boolean (value, src->incremental_update);
|
g_value_set_boolean (value, src->incremental_update);
|
||||||
break;
|
break;
|
||||||
|
case ARG_USE_COPYRECT:
|
||||||
|
g_value_set_boolean (value, src->decoder->use_copyrect);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -334,7 +343,9 @@ gst_rfb_src_start (GstBaseSrc * bsrc)
|
||||||
src->decoder->width * src->decoder->height * (decoder->bpp / 8), NULL);
|
src->decoder->width * src->decoder->height * (decoder->bpp / 8), NULL);
|
||||||
|
|
||||||
decoder->frame = g_malloc (bsrc->blocksize);
|
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;
|
decoder->decoder_private = src;
|
||||||
|
|
||||||
/* calculate some many used values */
|
/* calculate some many used values */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
|
||||||
#include "vncauth.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);
|
gint start_y, gint rect_w, gint rect_h);
|
||||||
static void rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x,
|
static void rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x,
|
||||||
gint start_y, gint rect_w, gint rect_h);
|
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 *
|
RfbDecoder *
|
||||||
rfb_decoder_new (void)
|
rfb_decoder_new (void)
|
||||||
|
@ -62,6 +65,8 @@ rfb_decoder_new (void)
|
||||||
|
|
||||||
decoder->password = NULL;
|
decoder->password = NULL;
|
||||||
|
|
||||||
|
decoder->use_copyrect = FALSE;
|
||||||
|
|
||||||
decoder->offset_x = 0;
|
decoder->offset_x = 0;
|
||||||
decoder->offset_y = 0;
|
decoder->offset_y = 0;
|
||||||
decoder->rect_width = 0;
|
decoder->rect_width = 0;
|
||||||
|
@ -187,8 +192,10 @@ rfb_decoder_send_update_request (RfbDecoder * decoder,
|
||||||
rfb_decoder_send (decoder, data, 10);
|
rfb_decoder_send (decoder, data, 10);
|
||||||
|
|
||||||
/* create a backup of the prev frame for copyrect encoding */
|
/* create a backup of the prev frame for copyrect encoding */
|
||||||
memcpy (decoder->prev_frame, decoder->frame,
|
if (decoder->use_copyrect) {
|
||||||
decoder->rect_width * decoder->rect_height * decoder->bpp / 8);
|
memcpy (decoder->prev_frame, decoder->frame,
|
||||||
|
decoder->rect_width * decoder->rect_height * decoder->bpp / 8);
|
||||||
|
}
|
||||||
|
|
||||||
decoder->state = rfb_decoder_state_normal;
|
decoder->state = rfb_decoder_state_normal;
|
||||||
}
|
}
|
||||||
|
@ -387,6 +394,27 @@ rfb_decoder_state_security_result (RfbDecoder * decoder)
|
||||||
return TRUE;
|
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:
|
* rfb_decoder_state_set_encodings:
|
||||||
* @decoder: The rfb context
|
* @decoder: The rfb context
|
||||||
|
@ -398,21 +426,22 @@ rfb_decoder_state_security_result (RfbDecoder * decoder)
|
||||||
static gboolean
|
static gboolean
|
||||||
rfb_decoder_state_set_encodings (RfbDecoder * decoder)
|
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
|
encoder_list = g_slist_append (encoder_list, (guint32 *) ENCODING_TYPE_RRE);
|
||||||
buffer[3] = 2; // number of encodings
|
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) */
|
rfb_decoder_send (decoder, message, 4 + 4 * g_slist_length (encoder_list));
|
||||||
buffer[11] = 1;
|
|
||||||
|
|
||||||
rfb_decoder_send (decoder, buffer, 12);
|
g_free (message);
|
||||||
|
|
||||||
g_free (buffer);
|
|
||||||
|
|
||||||
decoder->state = rfb_decoder_state_normal;
|
decoder->state = rfb_decoder_state_normal;
|
||||||
decoder->inited = TRUE;
|
decoder->inited = TRUE;
|
||||||
|
@ -560,40 +589,6 @@ rfb_decoder_state_framebuffer_update (RfbDecoder * decoder)
|
||||||
return TRUE;
|
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
|
static gboolean
|
||||||
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||||
{
|
{
|
||||||
|
@ -621,6 +616,9 @@ rfb_decoder_state_framebuffer_update_rectangle (RfbDecoder * decoder)
|
||||||
case ENCODING_TYPE_COPYRECT:
|
case ENCODING_TYPE_COPYRECT:
|
||||||
rfb_decoder_copyrect_encoding (decoder, x, y, w, h);
|
rfb_decoder_copyrect_encoding (decoder, x, y, w, h);
|
||||||
break;
|
break;
|
||||||
|
case ENCODING_TYPE_RRE:
|
||||||
|
rfb_decoder_rre_encoding (decoder, x, y, w, h);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_critical ("unimplemented encoding\n");
|
g_critical ("unimplemented encoding\n");
|
||||||
break;
|
break;
|
||||||
|
@ -696,6 +694,59 @@ rfb_decoder_copyrect_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
|
||||||
g_free (buffer);
|
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
|
static gboolean
|
||||||
rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder)
|
rfb_decoder_state_set_colour_map_entries (RfbDecoder * decoder)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ G_BEGIN_DECLS enum
|
||||||
|
|
||||||
#define ENCODING_TYPE_RAW 0
|
#define ENCODING_TYPE_RAW 0
|
||||||
#define ENCODING_TYPE_COPYRECT 1
|
#define ENCODING_TYPE_COPYRECT 1
|
||||||
|
#define ENCODING_TYPE_RRE 2
|
||||||
|
|
||||||
typedef struct _RfbDecoder RfbDecoder;
|
typedef struct _RfbDecoder RfbDecoder;
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ struct _RfbDecoder
|
||||||
guint security_type;
|
guint security_type;
|
||||||
|
|
||||||
gchar *password;
|
gchar *password;
|
||||||
|
gboolean use_copyrect;
|
||||||
|
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
|
@ -102,6 +104,8 @@ void rfb_decoder_send_key_event (RfbDecoder * decoder,
|
||||||
guint key, gboolean down_flag);
|
guint key, gboolean down_flag);
|
||||||
void rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
void rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
||||||
gint button_mask, gint x, gint y);
|
gint button_mask, gint x, gint y);
|
||||||
|
guint8 *
|
||||||
|
rfb_decoder_message_set_encodings ( GSList *encodings_list);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue