From 549a4ddc8f6bcf7b7cf44b91efab3b5b57d1a0d8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 15 Jul 2011 11:30:25 +0200 Subject: [PATCH] v4l2: add ALLOCATION query to the sink --- sys/v4l2/gstv4l2sink.c | 77 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c index 1ec96bdddb..14a0f31a93 100644 --- a/sys/v4l2/gstv4l2sink.c +++ b/sys/v4l2/gstv4l2sink.c @@ -53,6 +53,7 @@ #include #endif +#include "gst/video/gstmetavideo.h" #include "gstv4l2colorbalance.h" #include "gstv4l2tuner.h" @@ -133,11 +134,12 @@ static void gst_v4l2sink_set_property (GObject * object, guint prop_id, static void gst_v4l2sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); - /* GstElement methods: */ static GstStateChangeReturn gst_v4l2sink_change_state (GstElement * element, GstStateChange transition); +static gboolean gst_v4l2sink_sink_query (GstPad * sinkpad, GstQuery * query); + /* GstBaseSink methods: */ static GstCaps *gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter); static gboolean gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps); @@ -234,6 +236,10 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass) static void gst_v4l2sink_init (GstV4l2Sink * v4l2sink) { + /* for the ALLOCATION query */ + gst_pad_set_query_function (GST_BASE_SINK (v4l2sink)->sinkpad, + gst_v4l2sink_sink_query); + v4l2sink->v4l2object = gst_v4l2_object_new (GST_ELEMENT (v4l2sink), V4L2_BUF_TYPE_VIDEO_OUTPUT, DEFAULT_PROP_DEVICE, gst_v4l2_get_output, gst_v4l2_set_output, NULL); @@ -662,6 +668,75 @@ invalid_format: } } +static gboolean +gst_v4l2sink_sink_query (GstPad * sinkpad, GstQuery * query) +{ + GstV4l2Sink *v4l2sink = GST_V4L2SINK (GST_PAD_PARENT (sinkpad)); + GstV4l2Object *obj = v4l2sink->v4l2object; + gboolean res = TRUE; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ALLOCATION: + { + GstBufferPool *pool; + GstStructure *config; + GstCaps *caps; + guint size = 0; + gboolean need_pool; + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (caps == NULL) + goto no_caps; + + if ((pool = obj->pool)) + gst_object_ref (pool); + + if (pool != NULL) { + const GstCaps *pcaps; + + /* we had a pool, check caps */ + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_get (config, &pcaps, &size, NULL, NULL, NULL, + NULL); + + GST_DEBUG_OBJECT (v4l2sink, + "we had a pool with caps %" GST_PTR_FORMAT, pcaps); + if (!gst_caps_is_equal (caps, pcaps)) { + gst_object_unref (pool); + goto different_caps; + } + } + gst_query_set_allocation_params (query, size, 0, 0, 0, 15, pool); + + /* we also support various metadata */ + gst_query_add_allocation_meta (query, GST_META_API_VIDEO); + gst_query_add_allocation_meta (query, GST_META_API_VIDEO_CROP); + + if (pool) + gst_object_unref (pool); + break; + } + default: + res = FALSE; + break; + } + return res; + + /* ERRORS */ +no_caps: + { + GST_DEBUG_OBJECT (sinkpad, "no caps specified"); + return FALSE; + } +different_caps: + { + /* different caps, we can't use this pool */ + GST_DEBUG_OBJECT (v4l2sink, "pool has different caps"); + return FALSE; + } +} + /* called after A/V sync to render frame */ static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)