mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
gdkpixbufdec: port to 0.11
This commit is contained in:
parent
9c789aa434
commit
606a88f197
2 changed files with 161 additions and 67 deletions
|
@ -67,7 +67,8 @@ static GstStaticPadTemplate gst_gdk_pixbuf_src_template =
|
|||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB "; " GST_VIDEO_CAPS_RGBA)
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB") "; "
|
||||
GST_VIDEO_CAPS_MAKE ("RGBA"))
|
||||
);
|
||||
|
||||
static void gst_gdk_pixbuf_set_property (GObject * object, guint prop_id,
|
||||
|
@ -77,23 +78,24 @@ static void gst_gdk_pixbuf_get_property (GObject * object, guint prop_id,
|
|||
|
||||
static GstStateChangeReturn
|
||||
gst_gdk_pixbuf_change_state (GstElement * element, GstStateChange transition);
|
||||
static GstFlowReturn gst_gdk_pixbuf_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event);
|
||||
static GstFlowReturn gst_gdk_pixbuf_chain (GstPad * pad, GstObject * parent,
|
||||
GstBuffer * buffer);
|
||||
static gboolean gst_gdk_pixbuf_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event);
|
||||
|
||||
#ifdef enable_typefind
|
||||
static void gst_gdk_pixbuf_type_find (GstTypeFind * tf, gpointer ignore);
|
||||
#endif
|
||||
|
||||
GST_BOILERPLATE (GstGdkPixbuf, gst_gdk_pixbuf, GstElement, GST_TYPE_ELEMENT);
|
||||
#define gst_gdk_pixbuf_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGdkPixbuf, gst_gdk_pixbuf, GST_TYPE_ELEMENT);
|
||||
|
||||
static gboolean
|
||||
gst_gdk_pixbuf_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
gst_gdk_pixbuf_sink_setcaps (GstGdkPixbuf * filter, GstCaps * caps)
|
||||
{
|
||||
GstGdkPixbuf *filter;
|
||||
const GValue *framerate;
|
||||
GstStructure *s;
|
||||
|
||||
filter = GST_GDK_PIXBUF (GST_PAD_PARENT (pad));
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
|
||||
|
@ -112,7 +114,7 @@ gst_gdk_pixbuf_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_gdk_pixbuf_get_capslist (void)
|
||||
gst_gdk_pixbuf_get_capslist (GstCaps * filter)
|
||||
{
|
||||
GSList *slist;
|
||||
GSList *slist0;
|
||||
|
@ -132,7 +134,7 @@ gst_gdk_pixbuf_get_capslist (void)
|
|||
mimetypes = gdk_pixbuf_format_get_mime_types (pixbuf_format);
|
||||
|
||||
for (mimetype = mimetypes; *mimetype; mimetype++) {
|
||||
gst_caps_append_structure (capslist, gst_structure_new (*mimetype, NULL));
|
||||
gst_caps_append_structure (capslist, gst_structure_new_empty (*mimetype));
|
||||
}
|
||||
g_strfreev (mimetypes);
|
||||
}
|
||||
|
@ -143,29 +145,43 @@ gst_gdk_pixbuf_get_capslist (void)
|
|||
|
||||
gst_caps_unref (tmpl_caps);
|
||||
gst_caps_unref (capslist);
|
||||
|
||||
if (filter && return_caps) {
|
||||
GstCaps *temp;
|
||||
|
||||
temp = gst_caps_intersect (return_caps, filter);
|
||||
gst_caps_unref (return_caps);
|
||||
return_caps = temp;
|
||||
}
|
||||
|
||||
return return_caps;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_gdk_pixbuf_sink_getcaps (GstPad * pad)
|
||||
static gboolean
|
||||
gst_gdk_pixbuf_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||
{
|
||||
return gst_gdk_pixbuf_get_capslist ();
|
||||
gboolean res;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
GstCaps *filter, *caps;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = gst_gdk_pixbuf_get_capslist (filter);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, parent, query);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gdk_pixbuf_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_gdk_pixbuf_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_gdk_pixbuf_sink_template));
|
||||
gst_element_class_set_details_simple (element_class,
|
||||
"GdkPixbuf image decoder", "Codec/Decoder/Image",
|
||||
"Decodes images in a video stream using GdkPixbuf",
|
||||
"David A. Schleef <ds@schleef.org>, Renato Filho <renato.filho@indt.org.br>");
|
||||
}
|
||||
|
||||
/* initialize the plugin's class */
|
||||
static void
|
||||
|
@ -187,17 +203,24 @@ gst_gdk_pixbuf_class_init (GstGdkPixbufClass * klass)
|
|||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_change_state);
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_gdk_pixbuf_src_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_gdk_pixbuf_sink_template));
|
||||
gst_element_class_set_details_simple (gstelement_class,
|
||||
"GdkPixbuf image decoder", "Codec/Decoder/Image",
|
||||
"Decodes images in a video stream using GdkPixbuf",
|
||||
"David A. Schleef <ds@schleef.org>, Renato Filho <renato.filho@indt.org.br>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gdk_pixbuf_init (GstGdkPixbuf * filter, GstGdkPixbufClass * klass)
|
||||
gst_gdk_pixbuf_init (GstGdkPixbuf * filter)
|
||||
{
|
||||
filter->sinkpad =
|
||||
gst_pad_new_from_static_template (&gst_gdk_pixbuf_sink_template, "sink");
|
||||
gst_pad_set_setcaps_function (filter->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_setcaps));
|
||||
gst_pad_set_getcaps_function (filter->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_getcaps));
|
||||
gst_pad_set_query_function (filter->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_query));
|
||||
gst_pad_set_chain_function (filter->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_chain));
|
||||
gst_pad_set_event_function (filter->sinkpad,
|
||||
|
@ -213,6 +236,55 @@ gst_gdk_pixbuf_init (GstGdkPixbuf * filter, GstGdkPixbufClass * klass)
|
|||
filter->pixbuf_loader = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gdk_pixbuf_setup_pool (GstGdkPixbuf * filter, GstVideoInfo * info)
|
||||
{
|
||||
GstCaps *target;
|
||||
GstQuery *query;
|
||||
GstBufferPool *pool = NULL;
|
||||
guint size, min, max, prefix, alignment;
|
||||
|
||||
target = gst_pad_get_current_caps (filter->srcpad);
|
||||
|
||||
/* try to get a bufferpool now */
|
||||
/* find a pool for the negotiated caps now */
|
||||
query = gst_query_new_allocation (target, TRUE);
|
||||
|
||||
if (gst_pad_peer_query (filter->srcpad, query)) {
|
||||
/* we got configuration from our peer, parse them */
|
||||
gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
|
||||
&alignment, &pool);
|
||||
} else {
|
||||
size = info->size;
|
||||
min = max = 0;
|
||||
prefix = 0;
|
||||
alignment = 0;
|
||||
}
|
||||
|
||||
if (pool == NULL) {
|
||||
GstStructure *config;
|
||||
|
||||
/* we did not get a pool, make one ourselves then */
|
||||
pool = gst_buffer_pool_new ();
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set (config, target, size, min, max, prefix,
|
||||
alignment);
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
}
|
||||
|
||||
if (filter->pool)
|
||||
gst_object_unref (filter->pool);
|
||||
filter->pool = pool;
|
||||
|
||||
/* and activate */
|
||||
gst_buffer_pool_set_active (filter->pool, TRUE);
|
||||
|
||||
gst_caps_unref (target);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_gdk_pixbuf_flush (GstGdkPixbuf * filter)
|
||||
{
|
||||
|
@ -225,44 +297,50 @@ gst_gdk_pixbuf_flush (GstGdkPixbuf * filter)
|
|||
GstFlowReturn ret;
|
||||
GstCaps *caps = NULL;
|
||||
gint n_channels;
|
||||
GstVideoFrame frame;
|
||||
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (filter->pixbuf_loader);
|
||||
if (pixbuf == NULL)
|
||||
goto no_pixbuf;
|
||||
|
||||
if (filter->image_size == 0) {
|
||||
if (filter->width == 0) {
|
||||
GstVideoInfo info;
|
||||
GstVideoFormat fmt;
|
||||
|
||||
filter->width = gdk_pixbuf_get_width (pixbuf);
|
||||
filter->height = gdk_pixbuf_get_height (pixbuf);
|
||||
filter->rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
filter->image_size = filter->rowstride * filter->height;
|
||||
GST_DEBUG ("Set size to %dx%d", filter->width, filter->height);
|
||||
|
||||
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
|
||||
switch (n_channels) {
|
||||
case 3:
|
||||
caps = gst_caps_from_string (GST_VIDEO_CAPS_RGB);
|
||||
fmt = GST_VIDEO_FORMAT_RGB;
|
||||
break;
|
||||
case 4:
|
||||
caps = gst_caps_from_string (GST_VIDEO_CAPS_RGBA);
|
||||
fmt = GST_VIDEO_FORMAT_RGBA;
|
||||
break;
|
||||
default:
|
||||
goto channels_not_supported;
|
||||
}
|
||||
|
||||
gst_caps_set_simple (caps,
|
||||
"width", G_TYPE_INT, filter->width,
|
||||
"height", G_TYPE_INT, filter->height,
|
||||
"framerate", GST_TYPE_FRACTION, filter->framerate_numerator,
|
||||
filter->framerate_denominator, NULL);
|
||||
|
||||
GST_DEBUG ("Set size to %dx%d", filter->width, filter->height);
|
||||
gst_video_info_init (&info);
|
||||
gst_video_info_set_format (&info, fmt, filter->width, filter->height);
|
||||
info.fps_n = filter->framerate_numerator;
|
||||
info.fps_d = filter->framerate_denominator;
|
||||
caps = gst_video_info_to_caps (&info);
|
||||
|
||||
filter->channels = n_channels;
|
||||
filter->rowstride = GST_VIDEO_INFO_COMP_STRIDE (&info, 0);
|
||||
filter->info = info;
|
||||
|
||||
gst_pad_set_caps (filter->srcpad, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
gst_gdk_pixbuf_setup_pool (filter, &info);
|
||||
}
|
||||
|
||||
ret = gst_pad_alloc_buffer_and_set_caps (filter->srcpad,
|
||||
GST_BUFFER_OFFSET_NONE,
|
||||
filter->image_size, GST_PAD_CAPS (filter->srcpad), &outbuf);
|
||||
|
||||
ret = gst_buffer_pool_acquire_buffer (filter->pool, &outbuf, NULL);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto no_buffer;
|
||||
|
||||
|
@ -271,16 +349,19 @@ gst_gdk_pixbuf_flush (GstGdkPixbuf * filter)
|
|||
|
||||
in_pix = gdk_pixbuf_get_pixels (pixbuf);
|
||||
in_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
out_pix = GST_BUFFER_DATA (outbuf);
|
||||
|
||||
/* FIXME, last line might not have rowstride pixels */
|
||||
gst_video_frame_map (&frame, &filter->info, outbuf, GST_MAP_WRITE);
|
||||
out_pix = GST_VIDEO_FRAME_COMP_DATA (&frame, 0);
|
||||
|
||||
for (y = 0; y < filter->height; y++) {
|
||||
memcpy (out_pix, in_pix, filter->rowstride);
|
||||
memcpy (out_pix, in_pix, filter->width * filter->channels);
|
||||
in_pix += in_rowstride;
|
||||
out_pix += filter->rowstride;
|
||||
}
|
||||
|
||||
GST_DEBUG ("pushing... %d bytes", GST_BUFFER_SIZE (outbuf));
|
||||
gst_video_frame_unmap (&frame);
|
||||
|
||||
GST_DEBUG ("pushing... %d bytes", gst_buffer_get_size (outbuf));
|
||||
ret = gst_pad_push (filter->srcpad, outbuf);
|
||||
|
||||
if (ret != GST_FLOW_OK)
|
||||
|
@ -308,15 +389,24 @@ no_buffer:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event)
|
||||
gst_gdk_pixbuf_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
{
|
||||
GstFlowReturn res = GST_FLOW_OK;
|
||||
gboolean ret = TRUE;
|
||||
GstGdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = GST_GDK_PIXBUF (gst_pad_get_parent (pad));
|
||||
pixbuf = GST_GDK_PIXBUF (parent);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
res = gst_gdk_pixbuf_sink_setcaps (pixbuf, caps);
|
||||
gst_event_unref (event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_EOS:
|
||||
if (pixbuf->pixbuf_loader != NULL) {
|
||||
gdk_pixbuf_loader_close (pixbuf->pixbuf_loader, NULL);
|
||||
|
@ -332,7 +422,7 @@ gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
case GST_EVENT_SEGMENT:
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
if (pixbuf->pixbuf_loader != NULL) {
|
||||
gdk_pixbuf_loader_close (pixbuf->pixbuf_loader, NULL);
|
||||
|
@ -345,27 +435,24 @@ gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event)
|
|||
}
|
||||
|
||||
if (res == GST_FLOW_OK) {
|
||||
ret = gst_pad_event_default (pad, event);
|
||||
ret = gst_pad_event_default (pad, parent, event);
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
gst_object_unref (pixbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_gdk_pixbuf_chain (GstPad * pad, GstBuffer * buf)
|
||||
gst_gdk_pixbuf_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||
{
|
||||
GstGdkPixbuf *filter;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GError *error = NULL;
|
||||
GstClockTime timestamp;
|
||||
guint8 *data;
|
||||
guint size;
|
||||
GstMapInfo map;
|
||||
|
||||
filter = GST_GDK_PIXBUF (gst_pad_get_parent (pad));
|
||||
filter = GST_GDK_PIXBUF (parent);
|
||||
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
|
@ -378,11 +465,11 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstBuffer * buf)
|
|||
if (filter->pixbuf_loader == NULL)
|
||||
filter->pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
size = GST_BUFFER_SIZE (buf);
|
||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||
|
||||
GST_LOG_OBJECT (filter, "Writing buffer size %d", size);
|
||||
if (!gdk_pixbuf_loader_write (filter->pixbuf_loader, data, size, &error))
|
||||
GST_LOG_OBJECT (filter, "Writing buffer size %d", (gint) map.size);
|
||||
if (!gdk_pixbuf_loader_write (filter->pixbuf_loader, map.data, map.size,
|
||||
&error))
|
||||
goto error;
|
||||
|
||||
/* packetised mode? */
|
||||
|
@ -393,8 +480,8 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstBuffer * buf)
|
|||
filter->pixbuf_loader = NULL;
|
||||
}
|
||||
|
||||
gst_buffer_unmap (buf, &map);
|
||||
gst_buffer_unref (buf);
|
||||
gst_object_unref (filter);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -404,8 +491,8 @@ error:
|
|||
GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL),
|
||||
("gdk_pixbuf_loader_write error: %s", error->message));
|
||||
g_error_free (error);
|
||||
gst_buffer_unmap (buf, &map);
|
||||
gst_buffer_unref (buf);
|
||||
gst_object_unref (filter);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -462,6 +549,10 @@ gst_gdk_pixbuf_change_state (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
dec->framerate_numerator = 0;
|
||||
dec->framerate_denominator = 0;
|
||||
if (dec->pool) {
|
||||
gst_buffer_pool_set_active (dec->pool, FALSE);
|
||||
gst_object_replace ((GstObject **) & dec->pool, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -52,7 +52,10 @@ struct _GstGdkPixbuf
|
|||
int width;
|
||||
int height;
|
||||
int rowstride;
|
||||
unsigned int image_size;
|
||||
int channels;
|
||||
|
||||
GstVideoInfo info;
|
||||
GstBufferPool *pool;
|
||||
|
||||
gint framerate_numerator;
|
||||
gint framerate_denominator;
|
||||
|
|
Loading…
Reference in a new issue