niimaqdx: add back in set_caps/get_caps, and improve caps handling

This commit is contained in:
Joshua M. Doe 2013-06-03 11:33:53 -04:00
parent fca5b782ec
commit 2e485ee44e
2 changed files with 115 additions and 75 deletions

View File

@ -72,7 +72,7 @@ static GParamSpec *properties[PROP_LAST];
/* the capabilities of the inputs and outputs */ /* the capabilities of the inputs and outputs */
static GstStaticPadTemplate gst_videolevels_src_template = static GstStaticPadTemplate gst_videolevels_src_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw, " GST_STATIC_CAPS ("video/x-raw, "
@ -81,13 +81,20 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"width = " GST_VIDEO_SIZE_RANGE ", " "width = " GST_VIDEO_SIZE_RANGE ", "
"height = " GST_VIDEO_SIZE_RANGE ", " "height = " GST_VIDEO_SIZE_RANGE ", "
"framerate = " GST_VIDEO_FPS_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 = static GstStaticPadTemplate gst_videolevels_sink_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("GRAY8")) 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()) #define GST_TYPE_VIDEOLEVELS_AUTO (gst_videolevels_auto_get_type())

View File

@ -60,12 +60,6 @@ enum
#define DEFAULT_PROP_RING_BUFFER_COUNT 3 #define DEFAULT_PROP_RING_BUFFER_COUNT 3
#define DEFAULT_PROP_ATTRIBUTES "" #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); static void gst_niimaqdxsrc_init_interfaces (GType type);
G_DEFINE_TYPE (GstNiImaqDxSrc, gst_niimaqdxsrc, GST_TYPE_PUSH_SRC); 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_start (GstBaseSrc * src);
static gboolean gst_niimaqdxsrc_stop (GstBaseSrc * src); static gboolean gst_niimaqdxsrc_stop (GstBaseSrc * src);
static gboolean gst_niimaqdxsrc_query (GstBaseSrc * src, GstQuery * query); 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 */ /* GstPushSrc virtual methods */
static GstFlowReturn gst_niimaqdxsrc_fill (GstPushSrc * src, GstBuffer * buf); static GstFlowReturn gst_niimaqdxsrc_fill (GstPushSrc * src, GstBuffer * buf);
/* GstNiImaqDx methods */ /* GstNiImaqDx methods */
static gboolean gst_niimaqdxsrc_set_caps (GstNiImaqDxSrc * niimaqdxsrc);
static GstCaps *gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * src); static GstCaps *gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * src);
static gboolean gst_niimaqdxsrc_close_interface (GstNiImaqDxSrc * niimaqdxsrc); static gboolean gst_niimaqdxsrc_close_interface (GstNiImaqDxSrc * niimaqdxsrc);
static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc); static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc);
@ -142,9 +138,18 @@ gst_niimaqdxsrc_frame_done_callback (IMAQdxSession session, uInt32 bufferNumber,
return 1; return 1;
} }
#define GST_VIDEO_CAPS_BAYER(format) \ #define VIDEO_CAPS_MAKE_BAYER8(format) \
"video/x-bayer, " \ "video/x-bayer, " \
"format = " format "," \ "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 ", " \ "width = " GST_VIDEO_SIZE_RANGE ", " \
"height = " GST_VIDEO_SIZE_RANGE ", " \ "height = " GST_VIDEO_SIZE_RANGE ", " \
"framerate = " GST_VIDEO_FPS_RANGE "framerate = " GST_VIDEO_FPS_RANGE
@ -161,10 +166,10 @@ ImaqDxCapsInfo imaq_dx_caps_infos[] = {
, ,
{"YUV 422 Packed", 0, GST_VIDEO_CAPS_MAKE ("UYVY"), 16, 16, 4} {"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 //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 * static ImaqDxCapsInfo *
@ -379,8 +384,17 @@ gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass)
"Attributes", "Initial attributes to set", DEFAULT_PROP_ATTRIBUTES, "Attributes", "Initial attributes to set", DEFAULT_PROP_ATTRIBUTES,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
{
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_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&src_factory)); gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps));
}
gst_element_class_set_static_metadata (gstelement_class, gst_element_class_set_static_metadata (gstelement_class,
"NI-IMAQdx Video Source", "Source/Video", "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->start = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_stop); gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_stop);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_query); 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 */ /* install GstPushSrc vmethod implementations */
gstpushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_fill); 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 static void
gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc) gst_niimaqdxsrc_reset (GstNiImaqDxSrc * niimaqdxsrc)
{ {
@ -912,7 +884,6 @@ gst_niimaqdxsrc_start (GstBaseSrc * src)
GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (src); GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (src);
IMAQdxError rval; IMAQdxError rval;
gint i; gint i;
gboolean ret;
gst_niimaqdxsrc_reset (niimaqdxsrc); gst_niimaqdxsrc_reset (niimaqdxsrc);
@ -964,9 +935,7 @@ gst_niimaqdxsrc_start (GstBaseSrc * src)
gst_niimaqdxsrc_set_dx_attributes (niimaqdxsrc); gst_niimaqdxsrc_set_dx_attributes (niimaqdxsrc);
ret = gst_niimaqdxsrc_set_caps (niimaqdxsrc); return TRUE;
return ret;
error: error:
gst_niimaqdxsrc_close_interface (niimaqdxsrc); gst_niimaqdxsrc_close_interface (niimaqdxsrc);
@ -1011,24 +980,23 @@ gst_niimaqdxsrc_stop (GstBaseSrc * src)
} }
static gboolean 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; gboolean res;
switch (GST_QUERY_TYPE (query)) { switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_LATENCY:{ case GST_QUERY_LATENCY:{
if (!niimaqdxsrc->session_started) { if (!src->session_started) {
GST_WARNING_OBJECT (niimaqdxsrc, GST_WARNING_OBJECT (src, "Can't give latency since device isn't open!");
"Can't give latency since device isn't open!");
res = FALSE; res = FALSE;
} else { } else {
GstClockTime min_latency, max_latency; GstClockTime min_latency, max_latency;
/* TODO: this is a ballpark figure, estimate from FVAL times */ /* TODO: this is a ballpark figure, estimate from FVAL times */
min_latency = 33 * GST_MSECOND; 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, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
@ -1038,13 +1006,78 @@ gst_niimaqdxsrc_query (GstBaseSrc * src, GstQuery * query)
} }
} }
default: default:
res = FALSE; res =
GST_BASE_SRC_CLASS (gst_niimaqdxsrc_parent_class)->query (bsrc,
query);
break; break;
} }
return res; 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: * gst_niimaqdxsrc_close_interface:
* niimaqdxsrc: #GstNiImaqDxSrc instance * niimaqdxsrc: #GstNiImaqDxSrc instance