summaryrefslogtreecommitdiff
path: root/gst/librfb/gstrfbsrc.c
diff options
context:
space:
mode:
authorAleix Conchillo Flaque <aleix@oblong.com>2013-05-09 16:41:32 -0700
committerTim-Philipp Müller <tim@centricular.net>2013-05-10 20:43:16 +0100
commit42783e676e34de906491df97bc13012766d7d108 (patch)
treec77cb3c7bc658fb9ecb5fa1b3d80d00226e01d01 /gst/librfb/gstrfbsrc.c
parent275e104be637325ac005062817a7d6a48914776d (diff)
downloadgstreamer-plugins-bad-42783e676e34de906491df97bc13012766d7d108.tar.gz
rfbsrc: port to 1.0
https://bugzilla.gnome.org/show_bug.cgi?id=700038
Diffstat (limited to 'gst/librfb/gstrfbsrc.c')
-rw-r--r--gst/librfb/gstrfbsrc.c185
1 files changed, 134 insertions, 51 deletions
diff --git a/gst/librfb/gstrfbsrc.c b/gst/librfb/gstrfbsrc.c
index dc18e45ca..563f35974 100644
--- a/gst/librfb/gstrfbsrc.c
+++ b/gst/librfb/gstrfbsrc.c
@@ -60,19 +60,15 @@ GST_DEBUG_CATEGORY (rfbdecoder_debug);
#define GST_CAT_DEFAULT rfbsrc_debug
static GstStaticPadTemplate gst_rfb_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
+ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-rgb, "
- "bpp = (int) [1, 255], "
- "depth = (int) [1, 255], "
- "endianness = (int) [1234, 4321], "
- "red_mask = (int) [min, max], "
- "green_mask = (int) [min, max], "
- "blue_mask = (int) [min, max], "
- "width = (int) [ 16, 4096 ], "
- "height = (int) [ 16, 4096 ], " "framerate = (fraction) 0/1")
- );
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")
+ "; " GST_VIDEO_CAPS_MAKE ("BGR")
+ "; " GST_VIDEO_CAPS_MAKE ("RGBx")
+ "; " GST_VIDEO_CAPS_MAKE ("BGRx")
+ "; " GST_VIDEO_CAPS_MAKE ("xRGB")
+ "; " GST_VIDEO_CAPS_MAKE ("xBGR")));
static void gst_rfb_src_finalize (GObject * object);
static void gst_rfb_src_set_property (GObject * object, guint prop_id,
@@ -80,37 +76,25 @@ static void gst_rfb_src_set_property (GObject * object, guint prop_id,
static void gst_rfb_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
+static GstCaps *gst_rfb_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);
static gboolean gst_rfb_src_start (GstBaseSrc * bsrc);
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);
-GST_BOILERPLATE (GstRfbSrc, gst_rfb_src, GstPushSrc, GST_TYPE_PUSH_SRC);
-
-static void
-gst_rfb_src_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rfb_src_template));
-
- gst_element_class_set_static_metadata (element_class, "Rfb source",
- "Source/Video",
- "Creates a rfb video stream",
- "David A. Schleef <ds@schleef.org>, "
- "Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>, "
- "Thijs Vermeir <thijsvermeir@gmail.com>");
-}
+#define gst_rfb_src_parent_class parent_class
+G_DEFINE_TYPE (GstRfbSrc, gst_rfb_src, GST_TYPE_PUSH_SRC);
static void
gst_rfb_src_class_init (GstRfbSrcClass * klass)
{
GObjectClass *gobject_class;
GstBaseSrcClass *gstbasesrc_class;
+ GstElementClass *gstelement_class;
GstPushSrcClass *gstpushsrc_class;
+
GST_DEBUG_CATEGORY_INIT (rfbsrc_debug, "rfbsrc", 0, "rfb src element");
GST_DEBUG_CATEGORY_INIT (rfbdecoder_debug, "rfbdecoder", 0, "rfb decoder");
@@ -166,14 +150,27 @@ gst_rfb_src_class_init (GstRfbSrcClass * klass)
g_param_spec_boolean ("view-only", "Only view the desktop",
"only view the desktop", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_rfb_src_fixate);
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);
gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_rfb_src_create);
+
+ gstelement_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rfb_src_template));
+
+ gst_element_class_set_static_metadata (gstelement_class, "Rfb source",
+ "Source/Video",
+ "Creates a rfb video stream",
+ "David A. Schleef <ds@schleef.org>, "
+ "Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>, "
+ "Thijs Vermeir <thijsvermeir@gmail.com>");
}
static void
-gst_rfb_src_init (GstRfbSrc * src, GstRfbSrcClass * klass)
+gst_rfb_src_init (GstRfbSrc * src)
{
GstBaseSrc *bsrc = GST_BASE_SRC (src);
@@ -190,6 +187,8 @@ gst_rfb_src_init (GstRfbSrc * src, GstRfbSrcClass * klass)
src->view_only = FALSE;
+ src->pool = NULL;
+
src->decoder = rfb_decoder_new ();
#ifdef G_OS_WIN32
@@ -209,6 +208,10 @@ gst_rfb_src_finalize (GObject * object)
GstRfbSrc *src = GST_RFB_SRC (object);
g_free (src->host);
+ if (src->pool) {
+ gst_object_unref (src->pool);
+ src->pool = NULL;
+ }
if (src->decoder) {
rfb_decoder_free (src->decoder);
g_free (src->decoder);
@@ -354,12 +357,90 @@ gst_rfb_src_get_property (GObject * object, guint prop_id,
}
}
+static GstCaps *
+gst_rfb_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
+{
+ GstRfbSrc *src = GST_RFB_SRC (bsrc);
+ RfbDecoder *decoder;
+ GstStructure *structure;
+ guint i;
+
+ decoder = src->decoder;
+
+ GST_DEBUG_OBJECT (src, "fixating caps %" GST_PTR_FORMAT, caps);
+
+ caps = gst_caps_make_writable (caps);
+
+ for (i = 0; i < gst_caps_get_size (caps); ++i) {
+ structure = gst_caps_get_structure (caps, i);
+
+ gst_structure_fixate_field_nearest_int (structure,
+ "width", decoder->rect_width);
+ gst_structure_fixate_field_nearest_int (structure,
+ "height", decoder->rect_height);
+ gst_structure_fixate_field (structure, "format");
+ }
+
+ GST_DEBUG_OBJECT (src, "fixated caps %" GST_PTR_FORMAT, caps);
+
+ caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);
+
+ return caps;
+}
+
+static void
+gst_rfb_negotiate_pool (GstRfbSrc * src, GstCaps * caps)
+{
+ GstQuery *query;
+ GstBufferPool *pool = NULL;
+ guint size, min, max;
+ GstStructure *config;
+
+ /* find a pool for the negotiated caps now */
+ query = gst_query_new_allocation (caps, TRUE);
+
+ if (!gst_pad_peer_query (GST_BASE_SRC_PAD (src), query)) {
+ /* not a problem, we use the defaults of query */
+ GST_DEBUG_OBJECT (src, "could not get downstream ALLOCATION hints");
+ }
+
+ if (gst_query_get_n_allocation_pools (query) > 0) {
+ /* we got configuration from our peer, parse them */
+ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+ } else {
+ GST_DEBUG_OBJECT (src, "didn't get downstream pool hints");
+ size = GST_BASE_SRC (src)->blocksize;
+ min = max = 0;
+ }
+
+ if (pool == NULL) {
+ /* we did not get a pool, make one ourselves then */
+ pool = gst_video_buffer_pool_new ();
+ }
+
+ if (src->pool)
+ gst_object_unref (src->pool);
+ src->pool = pool;
+
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set_params (config, caps, size, min, max);
+ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+
+ gst_buffer_pool_set_config (pool, config);
+ // and activate
+ gst_buffer_pool_set_active (pool, TRUE);
+
+ gst_query_unref (query);
+}
+
static gboolean
gst_rfb_src_start (GstBaseSrc * bsrc)
{
GstRfbSrc *src = GST_RFB_SRC (bsrc);
RfbDecoder *decoder;
GstCaps *caps;
+ GstVideoInfo vinfo;
+ GstVideoFormat vformat;
guint32 red_mask, green_mask, blue_mask;
decoder = src->decoder;
@@ -398,23 +479,25 @@ gst_rfb_src_start (GstBaseSrc * bsrc)
GST_DEBUG_OBJECT (src, "setting caps width to %d and height to %d",
decoder->rect_width, decoder->rect_height);
- caps =
- gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc)));
-
red_mask = decoder->red_max << decoder->red_shift;
green_mask = decoder->green_max << decoder->green_shift;
blue_mask = decoder->blue_max << decoder->blue_shift;
- gst_caps_set_simple (caps, "width", G_TYPE_INT, decoder->rect_width,
- "height", G_TYPE_INT, decoder->rect_height,
- "bpp", G_TYPE_INT, decoder->bpp,
- "depth", G_TYPE_INT, decoder->depth,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, GST_READ_UINT32_BE (&red_mask),
- "green_mask", G_TYPE_INT, GST_READ_UINT32_BE (&green_mask),
- "blue_mask", G_TYPE_INT, GST_READ_UINT32_BE (&blue_mask), NULL);
+ vformat = gst_video_format_from_masks (decoder->depth, decoder->bpp,
+ decoder->big_endian ? G_BIG_ENDIAN : G_LITTLE_ENDIAN,
+ red_mask, green_mask, blue_mask, 0);
+
+ gst_video_info_init (&vinfo);
+
+ gst_video_info_set_format (&vinfo, vformat, decoder->rect_width,
+ decoder->rect_height);
+
+ caps = gst_video_info_to_caps (&vinfo);
gst_pad_set_caps (GST_BASE_SRC_PAD (bsrc), caps);
+
+ gst_rfb_negotiate_pool (src, caps);
+
gst_caps_unref (caps);
return TRUE;
@@ -445,7 +528,7 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
GstRfbSrc *src = GST_RFB_SRC (psrc);
RfbDecoder *decoder = src->decoder;
- gulong newsize;
+ GstMapInfo info;
GstFlowReturn ret;
rfb_decoder_send_update_request (decoder, src->incremental_update,
@@ -456,23 +539,23 @@ gst_rfb_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
rfb_decoder_iterate (decoder);
}
- newsize = GST_BASE_SRC (psrc)->blocksize;
-
/* Create the buffer. */
- ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
- GST_BUFFER_OFFSET_NONE, newsize,
- GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf);
+ ret = gst_buffer_pool_acquire_buffer (src->pool, outbuf, NULL);
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
return GST_FLOW_ERROR;
}
- memcpy (GST_BUFFER_DATA (*outbuf), decoder->frame, newsize);
- GST_BUFFER_SIZE (*outbuf) = newsize;
- GST_BUFFER_TIMESTAMP (*outbuf) =
+ gst_buffer_map (*outbuf, &info, GST_MAP_WRITE);
+
+ memcpy (info.data, decoder->frame, info.size);
+
+ GST_BUFFER_PTS (*outbuf) =
gst_clock_get_time (GST_ELEMENT_CLOCK (src)) -
GST_ELEMENT_CAST (src)->base_time;
+ gst_buffer_unmap (*outbuf, &info);
+
return GST_FLOW_OK;
}
@@ -482,7 +565,7 @@ gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event)
GstRfbSrc *src = GST_RFB_SRC (bsrc);
gdouble x, y;
gint button;
- GstStructure *structure;
+ const GstStructure *structure;
const gchar *event_type;
gboolean key_event, key_press;
@@ -495,7 +578,7 @@ gst_rfb_src_event (GstBaseSrc * bsrc, GstEvent * event)
if (src->view_only)
break;
- structure = event->structure;
+ structure = gst_event_get_structure (event);
event_type = gst_structure_get_string (structure, "event");
if (strcmp (event_type, "key-press") == 0) {