From 2e485ee44e4315a8583c9a32aab47511dcda8f5d Mon Sep 17 00:00:00 2001 From: "Joshua M. Doe" Date: Mon, 3 Jun 2013 11:33:53 -0400 Subject: [PATCH] niimaqdx: add back in set_caps/get_caps, and improve caps handling --- gst/videoadjust/gstvideolevels.c | 11 +- sys/niimaqdx/gstniimaqdx.c | 179 ++++++++++++++++++------------- 2 files changed, 115 insertions(+), 75 deletions(-) diff --git a/gst/videoadjust/gstvideolevels.c b/gst/videoadjust/gstvideolevels.c index ab1d5bf..bd3a3b7 100644 --- a/gst/videoadjust/gstvideolevels.c +++ b/gst/videoadjust/gstvideolevels.c @@ -72,7 +72,7 @@ static GParamSpec *properties[PROP_LAST]; /* the capabilities of the inputs and outputs */ static GstStaticPadTemplate gst_videolevels_src_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-raw, " @@ -81,13 +81,20 @@ GST_STATIC_PAD_TEMPLATE ("sink", "width = " GST_VIDEO_SIZE_RANGE ", " "height = " GST_VIDEO_SIZE_RANGE ", " "framerate = " GST_VIDEO_FPS_RANGE) + //";" + // "video/x-bayer,format=(string){bggr16,grbg16,gbrg16,rggb16}," + // "bpp=(int){10,12,14,16},endianness={1234,4321}," + // "width=(int)[1,MAX],height=(int)[1,MAX],framerate=(fraction)[0/1,MAX]") ); static GstStaticPadTemplate gst_videolevels_sink_template = -GST_STATIC_PAD_TEMPLATE ("src", + GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8")) + //";" + // "video/x-bayer,format=(string){bggr,grbg,gbrg,rggb}," + // "width=(int)[1,MAX],height=(int)[1,MAX],framerate=(fraction)[0/1,MAX]") ); #define GST_TYPE_VIDEOLEVELS_AUTO (gst_videolevels_auto_get_type()) diff --git a/sys/niimaqdx/gstniimaqdx.c b/sys/niimaqdx/gstniimaqdx.c index 025a534..ae57c29 100644 --- a/sys/niimaqdx/gstniimaqdx.c +++ b/sys/niimaqdx/gstniimaqdx.c @@ -60,12 +60,6 @@ enum #define DEFAULT_PROP_RING_BUFFER_COUNT 3 #define DEFAULT_PROP_ATTRIBUTES "" -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("ANY") - ); - static void gst_niimaqdxsrc_init_interfaces (GType type); G_DEFINE_TYPE (GstNiImaqDxSrc, gst_niimaqdxsrc, GST_TYPE_PUSH_SRC); @@ -81,12 +75,14 @@ static void gst_niimaqdxsrc_get_property (GObject * object, guint prop_id, static gboolean gst_niimaqdxsrc_start (GstBaseSrc * src); static gboolean gst_niimaqdxsrc_stop (GstBaseSrc * src); static gboolean gst_niimaqdxsrc_query (GstBaseSrc * src, GstQuery * query); +static GstCaps *gst_niimaqdxsrc_get_caps (GstBaseSrc * bsrc, + GstCaps * caps_filter); +static gboolean gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps); /* GstPushSrc virtual methods */ static GstFlowReturn gst_niimaqdxsrc_fill (GstPushSrc * src, GstBuffer * buf); /* GstNiImaqDx methods */ -static gboolean gst_niimaqdxsrc_set_caps (GstNiImaqDxSrc * niimaqdxsrc); static GstCaps *gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * src); static gboolean gst_niimaqdxsrc_close_interface (GstNiImaqDxSrc * niimaqdxsrc); static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc); @@ -142,12 +138,21 @@ gst_niimaqdxsrc_frame_done_callback (IMAQdxSession session, uInt32 bufferNumber, return 1; } -#define GST_VIDEO_CAPS_BAYER(format) \ - "video/x-bayer, " \ - "format = " format "," \ - "width = " GST_VIDEO_SIZE_RANGE ", " \ - "height = " GST_VIDEO_SIZE_RANGE ", " \ - "framerate = " GST_VIDEO_FPS_RANGE +#define VIDEO_CAPS_MAKE_BAYER8(format) \ + "video/x-bayer, " \ + "format = (string) { " format " }, " \ + "width = " GST_VIDEO_SIZE_RANGE ", " \ + "height = " GST_VIDEO_SIZE_RANGE ", " \ + "framerate = " GST_VIDEO_FPS_RANGE + +#define VIDEO_CAPS_MAKE_BAYER16(format,endianness) \ + "video/x-bayer, " \ + "format = (string) { " format " }, " \ + "endianness = (int) { " endianness " }, " \ + "bpp = (int) {16, 14, 12, 10}, " \ + "width = " GST_VIDEO_SIZE_RANGE ", " \ + "height = " GST_VIDEO_SIZE_RANGE ", " \ + "framerate = " GST_VIDEO_FPS_RANGE ImaqDxCapsInfo imaq_dx_caps_infos[] = { {"Mono 8", 0, GST_VIDEO_CAPS_MAKE ("GRAY8"), 8, 8, 4} @@ -161,10 +166,10 @@ ImaqDxCapsInfo imaq_dx_caps_infos[] = { , {"YUV 422 Packed", 0, GST_VIDEO_CAPS_MAKE ("UYVY"), 16, 16, 4} , - {"Bayer BG 8", 0, GST_VIDEO_CAPS_BAYER ("bggr"), 8, 8, 1} + {"Bayer BG 8", 0, VIDEO_CAPS_MAKE_BAYER8 ("bggr"), 8, 8, 1} , //TODO: use a caps string that agrees with Aravis - {"Bayer BG 16", 0, GST_VIDEO_CAPS_BAYER ("bggr16"), 16, 16, 1} + {"Bayer BG 16", 0, VIDEO_CAPS_MAKE_BAYER16 ("bggr16", "1234"), 16, 16, 1} }; static ImaqDxCapsInfo * @@ -379,8 +384,17 @@ gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass) "Attributes", "Initial attributes to set", DEFAULT_PROP_ATTRIBUTES, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&src_factory)); + { + GstCaps *caps = gst_caps_new_empty (); + int i; + + for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) { + ImaqDxCapsInfo *info = &imaq_dx_caps_infos[i]; + gst_caps_append (caps, gst_caps_from_string (info->gst_caps_string)); + } + gst_element_class_add_pad_template (gstelement_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + } gst_element_class_set_static_metadata (gstelement_class, "NI-IMAQdx Video Source", "Source/Video", @@ -391,6 +405,8 @@ gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass) gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_start); gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_stop); gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_query); + gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_get_caps); + gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_set_caps); /* install GstPushSrc vmethod implementations */ gstpushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_fill); @@ -501,50 +517,6 @@ gst_niimaqdxsrc_get_property (GObject * object, guint prop_id, GValue * value, } } -gboolean -gst_niimaqdxsrc_set_caps (GstNiImaqDxSrc * niimaqdxsrc) -{ - gboolean res = TRUE; - GstStructure *structure; - const char *pixel_format; - int endianness; - GstCaps *caps; - - caps = gst_niimaqdxsrc_get_cam_caps (niimaqdxsrc); - - structure = gst_caps_get_structure (caps, 0); - - gst_structure_get_int (structure, "width", &niimaqdxsrc->width); - gst_structure_get_int (structure, "height", &niimaqdxsrc->height); - - pixel_format = gst_niimaqdxsrc_pixel_format_from_caps (caps, &endianness); - g_assert (pixel_format); - - niimaqdxsrc->caps_info = - gst_niimaqdxsrc_get_caps_info (pixel_format, endianness); - - niimaqdxsrc->dx_row_stride = - gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, endianness, - niimaqdxsrc->width); - - niimaqdxsrc->dx_framesize = niimaqdxsrc->dx_row_stride * niimaqdxsrc->height; - - if (niimaqdxsrc->temp_buffer) - g_free (niimaqdxsrc->temp_buffer); - - niimaqdxsrc->temp_buffer = g_malloc (niimaqdxsrc->dx_framesize); - - GST_DEBUG ("Size %dx%d", niimaqdxsrc->width, niimaqdxsrc->height); - - GST_LOG_OBJECT (niimaqdxsrc, "Caps set, framesize=%d", - niimaqdxsrc->dx_framesize); - - GST_LOG_OBJECT (niimaqdxsrc, "Setting srcpad caps to %" GST_PTR_FORMAT, caps); - gst_pad_set_caps (GST_BASE_SRC_PAD (niimaqdxsrc), caps); - - return res; -} - static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc) { @@ -912,7 +884,6 @@ gst_niimaqdxsrc_start (GstBaseSrc * src) GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (src); IMAQdxError rval; gint i; - gboolean ret; gst_niimaqdxsrc_reset (niimaqdxsrc); @@ -964,9 +935,7 @@ gst_niimaqdxsrc_start (GstBaseSrc * src) gst_niimaqdxsrc_set_dx_attributes (niimaqdxsrc); - ret = gst_niimaqdxsrc_set_caps (niimaqdxsrc); - - return ret; + return TRUE; error: gst_niimaqdxsrc_close_interface (niimaqdxsrc); @@ -1011,24 +980,23 @@ gst_niimaqdxsrc_stop (GstBaseSrc * src) } static gboolean -gst_niimaqdxsrc_query (GstBaseSrc * src, GstQuery * query) +gst_niimaqdxsrc_query (GstBaseSrc * bsrc, GstQuery * query) { - GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (src); + GstNiImaqDxSrc *src = GST_NIIMAQDXSRC (bsrc); gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ - if (!niimaqdxsrc->session_started) { - GST_WARNING_OBJECT (niimaqdxsrc, - "Can't give latency since device isn't open!"); + if (!src->session_started) { + GST_WARNING_OBJECT (src, "Can't give latency since device isn't open!"); res = FALSE; } else { GstClockTime min_latency, max_latency; /* TODO: this is a ballpark figure, estimate from FVAL times */ min_latency = 33 * GST_MSECOND; - max_latency = 33 * GST_MSECOND * niimaqdxsrc->ringbuffer_count; + max_latency = 33 * GST_MSECOND * src->ringbuffer_count; - GST_LOG_OBJECT (niimaqdxsrc, + GST_LOG_OBJECT (src, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); @@ -1038,13 +1006,78 @@ gst_niimaqdxsrc_query (GstBaseSrc * src, GstQuery * query) } } default: - res = FALSE; + res = + GST_BASE_SRC_CLASS (gst_niimaqdxsrc_parent_class)->query (bsrc, + query); break; } return res; } +static GstCaps * +gst_niimaqdxsrc_get_caps (GstBaseSrc * bsrc, GstCaps * filter_caps) +{ + GstNiImaqDxSrc *src = GST_NIIMAQDXSRC (bsrc); + GstCaps *caps; + + if (!src->session) { + caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (src)); + } else + caps = gst_niimaqdxsrc_get_cam_caps (src); + + GST_DEBUG_OBJECT (bsrc, "get_caps, pre-filter=%" GST_PTR_FORMAT, caps); + + if (filter_caps) { + GstCaps *tmp = gst_caps_intersect (caps, filter_caps); + gst_caps_unref (caps); + caps = tmp; + } + + GST_DEBUG_OBJECT (bsrc, + "with filter %" GST_PTR_FORMAT ", post-filter=%" GST_PTR_FORMAT, + filter_caps, caps); + + return caps; +} + +static gboolean +gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) +{ + GstNiImaqDxSrc *src = GST_NIIMAQDXSRC (bsrc); + GstStructure *structure; + const char *pixel_format; + int endianness; + + GST_DEBUG_OBJECT (src, "set_caps with caps=%" GST_PTR_FORMAT, caps); + + structure = gst_caps_get_structure (caps, 0); + + gst_structure_get_int (structure, "width", &src->width); + gst_structure_get_int (structure, "height", &src->height); + + pixel_format = gst_niimaqdxsrc_pixel_format_from_caps (caps, &endianness); + g_assert (pixel_format); + + src->caps_info = gst_niimaqdxsrc_get_caps_info (pixel_format, endianness); + + src->dx_row_stride = + gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, endianness, + src->width); + + src->dx_framesize = src->dx_row_stride * src->height; + + if (src->temp_buffer) + g_free (src->temp_buffer); + src->temp_buffer = g_malloc (src->dx_framesize); + + GST_DEBUG ("Size %dx%d", src->width, src->height); + + GST_LOG_OBJECT (src, "Caps set, framesize=%d", src->dx_framesize); + + return TRUE; +} + /** * gst_niimaqdxsrc_close_interface: * niimaqdxsrc: #GstNiImaqDxSrc instance