static void gst_gdk_pixbuf_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstGdkPixbufSink *sink; sink = GST_GDK_PIXBUF_SINK (object); switch (prop_id) { case PROP_SEND_MESSAGES: case PROP_POST_MESSAGES: GST_OBJECT_LOCK (sink); g_value_set_boolean (value, sink->post_messages); GST_OBJECT_UNLOCK (sink); break; case PROP_LAST_PIXBUF: GST_OBJECT_LOCK (sink); g_value_set_object (value, sink->last_pixbuf); GST_OBJECT_UNLOCK (sink); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstFlowReturn gst_gdk_pixbuf_sink_handle_buffer (GstBaseSink * basesink, GstBuffer * buf, const gchar * msg_name) { GstGdkPixbufSink *sink; GdkPixbuf *pixbuf; gboolean do_post; sink = GST_GDK_PIXBUF_SINK (basesink); pixbuf = gst_gdk_pixbuf_sink_get_pixbuf_from_buffer (sink, buf); GST_OBJECT_LOCK (sink); do_post = sink->post_messages; if (sink->last_pixbuf) g_object_unref (sink->last_pixbuf); sink->last_pixbuf = pixbuf; /* take ownership */ GST_OBJECT_UNLOCK (sink); if (G_UNLIKELY (pixbuf == NULL)) goto error; if (do_post) { GstStructure *s; GstMessage *msg; /* it's okay to keep using pixbuf here, we can be sure no one is going to * unref or change sink->last_pixbuf before we return from this function. * The structure will take its own ref to the pixbuf. */ s = gst_structure_new (msg_name, "pixbuf", GDK_TYPE_PIXBUF, pixbuf, "pixel-aspect-ratio", GST_TYPE_FRACTION, sink->par_d, sink->par_n, NULL); msg = gst_message_new_element (GST_OBJECT_CAST (sink), s); gst_element_post_message (GST_ELEMENT_CAST (sink), msg); } g_object_notify (G_OBJECT (sink), "last-pixbuf"); return GST_FLOW_OK; /* ERRORS */ error: { /* This shouldn't really happen */ GST_ELEMENT_ERROR (sink, LIBRARY, FAILED, ("Couldn't create pixbuf from RGB image."), ("Probably not enough free memory")); return GST_FLOW_ERROR; } }
static gboolean gst_gdk_pixbuf_sink_set_caps (GstBaseSink * basesink, GstCaps * caps) { GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink); GstVideoInfo info; GstVideoFormat fmt; gint w, h, s, par_n, par_d; GST_LOG_OBJECT (sink, "caps: %" GST_PTR_FORMAT, caps); if (!gst_video_info_from_caps (&info, caps)) { GST_WARNING_OBJECT (sink, "parse_caps failed"); return FALSE; } fmt = GST_VIDEO_INFO_FORMAT (&info); w = GST_VIDEO_INFO_WIDTH (&info); h = GST_VIDEO_INFO_HEIGHT (&info); s = GST_VIDEO_INFO_COMP_PSTRIDE (&info, 0); par_n = GST_VIDEO_INFO_PAR_N (&info); par_d = GST_VIDEO_INFO_PAR_N (&info); g_assert ((fmt == GST_VIDEO_FORMAT_RGB && s == 3) || (fmt == GST_VIDEO_FORMAT_RGBA && s == 4)); GST_VIDEO_SINK_WIDTH (sink) = w; GST_VIDEO_SINK_HEIGHT (sink) = h; sink->par_n = par_n; sink->par_d = par_d; sink->has_alpha = GST_VIDEO_INFO_HAS_ALPHA (&info); GST_INFO_OBJECT (sink, "format : %d", fmt); GST_INFO_OBJECT (sink, "width x height : %d x %d", w, h); GST_INFO_OBJECT (sink, "pixel-aspect-ratio : %d/%d", par_n, par_d); sink->info = info; return TRUE; }
static gboolean gst_gdk_pixbuf_sink_stop (GstBaseSink * basesink) { GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink); GST_VIDEO_SINK_WIDTH (sink) = 0; GST_VIDEO_SINK_HEIGHT (sink) = 0; sink->par_n = 0; sink->par_d = 0; sink->has_alpha = FALSE; if (sink->last_pixbuf) { g_object_unref (sink->last_pixbuf); sink->last_pixbuf = NULL; } GST_LOG_OBJECT (sink, "stop"); return TRUE; }
static gboolean gst_gdk_pixbuf_sink_set_caps (GstBaseSink * basesink, GstCaps * caps) { GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink); GstVideoFormat fmt; gint w, h, par_n, par_d; GST_LOG_OBJECT (sink, "caps: %" GST_PTR_FORMAT, caps); if (!gst_video_format_parse_caps (caps, &fmt, &w, &h)) { GST_WARNING_OBJECT (sink, "parse_caps failed"); return FALSE; } if (!gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d)) { GST_LOG_OBJECT (sink, "no pixel aspect ratio"); return FALSE; } g_assert ((fmt == GST_VIDEO_FORMAT_RGB && gst_video_format_get_pixel_stride (fmt, 0) == 3) || (fmt == GST_VIDEO_FORMAT_RGBA && gst_video_format_get_pixel_stride (fmt, 0) == 4)); GST_VIDEO_SINK_WIDTH (sink) = w; GST_VIDEO_SINK_HEIGHT (sink) = h; sink->rowstride = gst_video_format_get_row_stride (fmt, 0, w); sink->has_alpha = (fmt == GST_VIDEO_FORMAT_RGBA); sink->par_n = par_n; sink->par_d = par_d; GST_INFO_OBJECT (sink, "format : %d", fmt); GST_INFO_OBJECT (sink, "width x height : %d x %d", w, h); GST_INFO_OBJECT (sink, "pixel-aspect-ratio : %d/%d", par_d, par_n); return TRUE; }