niimaqdxsrc: port to 1.0

This commit is contained in:
Joshua M. Doe 2013-05-15 09:48:06 -04:00
parent f995ed9987
commit 2388d2ccd6
3 changed files with 84 additions and 291 deletions

View File

@ -43,18 +43,11 @@
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <gst/interfaces/propertyprobe.h>
#include <gst/video/video.h> #include <gst/video/video.h>
GST_DEBUG_CATEGORY (niimaqdxsrc_debug); GST_DEBUG_CATEGORY (niimaqdxsrc_debug);
#define GST_CAT_DEFAULT niimaqdxsrc_debug #define GST_CAT_DEFAULT niimaqdxsrc_debug
static GstElementDetails niimaqdxsrc_details =
GST_ELEMENT_DETAILS ("NI-IMAQdx Video Source",
"Source/Video",
"National Instruments IMAQdx source, supports FireWire, USB, and GigE Vision cameras",
"Joshua M. Doe <oss@nvl.army.mil>");
enum enum
{ {
PROP_0, PROP_0,
@ -75,8 +68,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
static void gst_niimaqdxsrc_init_interfaces (GType type); static void gst_niimaqdxsrc_init_interfaces (GType type);
GST_BOILERPLATE_FULL (GstNiImaqDxSrc, gst_niimaqdxsrc, GstPushSrc, G_DEFINE_TYPE (GstNiImaqDxSrc, gst_niimaqdxsrc, GST_TYPE_PUSH_SRC);
GST_TYPE_PUSH_SRC, gst_niimaqdxsrc_init_interfaces);
/* GObject virtual methods */ /* GObject virtual methods */
static void gst_niimaqdxsrc_dispose (GObject * object); static void gst_niimaqdxsrc_dispose (GObject * object);
@ -86,17 +78,15 @@ static void gst_niimaqdxsrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
/* GstBaseSrc virtual methods */ /* GstBaseSrc virtual methods */
static GstCaps *gst_niimaqdxsrc_get_caps (GstBaseSrc * bsrc);
static gboolean gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps);
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);
/* GstPushSrc virtual methods */ /* GstPushSrc virtual methods */
static GstFlowReturn gst_niimaqdxsrc_create (GstPushSrc * psrc, static GstFlowReturn gst_niimaqdxsrc_fill (GstPushSrc * src, GstBuffer * buf);
GstBuffer ** buffer);
/* 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);
@ -125,11 +115,11 @@ gst_niimaqdxsrc_frame_done_callback (IMAQdxSession session, uInt32 bufferNumber,
GstClockTime abstime; GstClockTime abstime;
static guint32 index = 0; static guint32 index = 0;
g_mutex_lock (niimaqdxsrc->mutex); g_mutex_lock (&niimaqdxsrc->mutex);
/* time hasn't been read yet, this frame will be dropped */ /* time hasn't been read yet, this frame will be dropped */
if (niimaqdxsrc->times[index] != GST_CLOCK_TIME_NONE) { if (niimaqdxsrc->times[index] != GST_CLOCK_TIME_NONE) {
g_mutex_unlock (niimaqdxsrc->mutex); g_mutex_unlock (&niimaqdxsrc->mutex);
return 1; return 1;
} }
@ -146,30 +136,30 @@ gst_niimaqdxsrc_frame_done_callback (IMAQdxSession session, uInt32 bufferNumber,
index = (index + 1) % niimaqdxsrc->ringbuffer_count; index = (index + 1) % niimaqdxsrc->ringbuffer_count;
g_mutex_unlock (niimaqdxsrc->mutex); g_mutex_unlock (&niimaqdxsrc->mutex);
/* return 1 to rearm the callback */ /* return 1 to rearm the callback */
return 1; return 1;
} }
#define GST_VIDEO_CAPS_BAYER(format) \ #define GST_VIDEO_CAPS_BAYER(format) \
"video/x-raw-bayer, " \ "video/x-bayer, " \
"format = " format "," \ "format = " format "," \
"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
ImaqDxCapsInfo imaq_dx_caps_infos[] = { ImaqDxCapsInfo imaq_dx_caps_infos[] = {
{"Mono 8", 0, GST_VIDEO_CAPS_GRAY8, 8, 8, 4} {"Mono 8", 0, GST_VIDEO_CAPS_MAKE ("GRAY8"), 8, 8, 4}
, ,
//TODO: for packed formats, should we unpack? //TODO: for packed formats, should we unpack?
//{"Mono 12 Packed", GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"), 16, 16}, //{"Mono 12 Packed", GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"), 16, 16},
{"Mono 16", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN"), 16, 16, {"Mono 16", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 16, 16,
4} 4}
, ,
{"Mono 16", G_BIG_ENDIAN, GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"), 16, 16, 4} {"Mono 16", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 16, 16, 4}
, ,
{"YUV 422 Packed", 0, GST_VIDEO_CAPS_YUV ("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, GST_VIDEO_CAPS_BAYER ("bggr"), 8, 8, 1}
, ,
@ -273,30 +263,10 @@ gst_niimaqdxsrc_new_caps_from_pixel_format (const char *pixel_format,
static void _____BEGIN_FUNCTIONS_____ (); static void _____BEGIN_FUNCTIONS_____ ();
/**
* gst_niimaqdxsrc_probe_get_properties:
* @probe: #GstPropertyProbe
*
* Gets list of properties that can be probed
*
* Returns: #GList of properties that can be probed
*/
static const GList *
gst_niimaqdxsrc_probe_get_properties (GstPropertyProbe * probe)
{
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
static GList *list = NULL;
if (!list) {
list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
}
return list;
}
static gboolean _imaqdx_init = FALSE; static gboolean _imaqdx_init = FALSE;
static GList *_imaqdx_devices = NULL; static GList *_imaqdx_devices = NULL;
#if 0
/** /**
* gst_niimaqdxsrc_class_probe_devices: * gst_niimaqdxsrc_class_probe_devices:
* @klass: #GstNiImaqDxClass * @klass: #GstNiImaqDxClass
@ -361,175 +331,7 @@ gst_niimaqdxsrc_class_probe_devices (GstNiImaqDxSrcClass * klass,
return _imaqdx_init; return _imaqdx_init;
} }
#endif
/**
* gst_niimaqdxsrc_probe_probe_property:
* @probe: #GstPropertyProbe
* @prop_id: Property id
* @pspec: #GParamSpec
*
* GstPropertyProbe _probe_proprty vmethod implementation that probes a
* property for possible values
*/
static void
gst_niimaqdxsrc_probe_probe_property (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
{
GstNiImaqDxSrcClass *klass = GST_NIIMAQDXSRC_GET_CLASS (probe);
switch (prop_id) {
case PROP_DEVICE:
gst_niimaqdxsrc_class_probe_devices (klass, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
}
/**
* gst_niimaqdxsrc_probe_needs_probe:
* @probe: #GstPropertyProbe
* @prop_id: Property id
* @pspec: #GParamSpec
*
* GstPropertyProbe _needs_probe vmethod implementation that indicates if
* a property needs to be updated
*
* Returns: TRUE if a property needs to be updated
*/
static gboolean
gst_niimaqdxsrc_probe_needs_probe (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
{
GstNiImaqDxSrcClass *klass = GST_NIIMAQDXSRC_GET_CLASS (probe);
gboolean ret = FALSE;
switch (prop_id) {
case PROP_DEVICE:
ret = !gst_niimaqdxsrc_class_probe_devices (klass, TRUE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
return ret;
}
/**
* gst_niimaqdxsrc_class_list_interfaces:
* @klass: #GstNiImaqDxClass
*
* Returns: #GValueArray of interface names
*/
static GValueArray *
gst_niimaqdxsrc_class_list_devices (GstNiImaqDxSrcClass * klass)
{
GValueArray *array;
GValue value = { 0 };
GList *item;
if (!klass->devices)
return NULL;
array = g_value_array_new (g_list_length (klass->devices));
item = klass->devices;
g_value_init (&value, G_TYPE_STRING);
while (item) {
gchar *iface = item->data;
g_value_set_string (&value, iface);
g_value_array_append (array, &value);
item = item->next;
}
g_value_unset (&value);
return array;
}
/**
* gst_niimaqdxsrc_probe_get_values:
* @probe: #GstPropertyProbe
* @prop_id: Property id
* @pspec: #GParamSpec
*
* GstPropertyProbe _get_values vmethod implementation that gets possible
* values for a property
*
* Returns: #GValueArray containing possible values for requested property
*/
static GValueArray *
gst_niimaqdxsrc_probe_get_values (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec)
{
GstNiImaqDxSrcClass *klass = GST_NIIMAQDXSRC_GET_CLASS (probe);
GValueArray *array = NULL;
switch (prop_id) {
case PROP_DEVICE:
array = gst_niimaqdxsrc_class_list_devices (klass);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
return array;
}
/**
* gst_v4l_property_probe_interface_init:
* @iface: #GstPropertyProbeInterface
*
* Install property probe interfaces functions
*/
static void
gst_niimaqdxsrc_property_probe_interface_init (GstPropertyProbeInterface *
iface)
{
iface->get_properties = gst_niimaqdxsrc_probe_get_properties;
iface->probe_property = gst_niimaqdxsrc_probe_probe_property;
iface->needs_probe = gst_niimaqdxsrc_probe_needs_probe;
iface->get_values = gst_niimaqdxsrc_probe_get_values;
}
/**
* gst_niimaqdxsrc_init_interfaces:
* @type: #GType
*
* Initialize all GStreamer interfaces
*/
static void
gst_niimaqdxsrc_init_interfaces (GType type)
{
static const GInterfaceInfo niimaqdx_propertyprobe_info = {
(GInterfaceInitFunc) gst_niimaqdxsrc_property_probe_interface_init,
NULL,
NULL,
};
g_type_add_interface_static (type,
GST_TYPE_PROPERTY_PROBE, &niimaqdx_propertyprobe_info);
}
/**
* gst_niimaqdxsrc_base_init:
* g_class:
*
* Base GObject initialization
*/
static void
gst_niimaqdxsrc_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &niimaqdxsrc_details);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
}
/** /**
* gst_niimaqdxsrc_class_init: * gst_niimaqdxsrc_class_init:
@ -542,9 +344,10 @@ static void
gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass) gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass)
{ {
/* get pointers to base classes */ /* get pointers to base classes */
GObjectClass *gobject_class = (GObjectClass *) klass; GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass; GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GstPushSrcClass *gstpushsrc_class = (GstPushSrcClass *) klass; GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
/* install GObject vmethod implementations */ /* install GObject vmethod implementations */
gobject_class->dispose = gst_niimaqdxsrc_dispose; gobject_class->dispose = gst_niimaqdxsrc_dispose;
@ -567,15 +370,21 @@ 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));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_set_static_metadata (gstelement_class,
"NI-IMAQdx Video Source", "Source/Video",
"National Instruments IMAQdx source, supports FireWire, USB, and GigE Vision cameras",
"Joshua M. Doe <oss@nvl.army.mil>");
/* install GstBaseSrc vmethod implementations */ /* install GstBaseSrc vmethod implementations */
gstbasesrc_class->get_caps = gst_niimaqdxsrc_get_caps; gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_start);
gstbasesrc_class->set_caps = gst_niimaqdxsrc_set_caps; gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_stop);
gstbasesrc_class->start = gst_niimaqdxsrc_start; gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_query);
gstbasesrc_class->stop = gst_niimaqdxsrc_stop;
gstbasesrc_class->query = gst_niimaqdxsrc_query;
/* install GstPushSrc vmethod implementations */ /* install GstPushSrc vmethod implementations */
gstpushsrc_class->create = gst_niimaqdxsrc_create; gstpushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_niimaqdxsrc_fill);
} }
/** /**
@ -586,8 +395,7 @@ gst_niimaqdxsrc_class_init (GstNiImaqDxSrcClass * klass)
* Initialize this instance of #GstNiImaqDx * Initialize this instance of #GstNiImaqDx
*/ */
static void static void
gst_niimaqdxsrc_init (GstNiImaqDxSrc * niimaqdxsrc, gst_niimaqdxsrc_init (GstNiImaqDxSrc * niimaqdxsrc)
GstNiImaqDxSrcClass * g_class)
{ {
GstPad *srcpad = GST_BASE_SRC_PAD (niimaqdxsrc); GstPad *srcpad = GST_BASE_SRC_PAD (niimaqdxsrc);
@ -597,7 +405,7 @@ gst_niimaqdxsrc_init (GstNiImaqDxSrc * niimaqdxsrc,
/* override default of BYTES to operate in time mode */ /* override default of BYTES to operate in time mode */
gst_base_src_set_format (GST_BASE_SRC (niimaqdxsrc), GST_FORMAT_TIME); gst_base_src_set_format (GST_BASE_SRC (niimaqdxsrc), GST_FORMAT_TIME);
niimaqdxsrc->mutex = g_mutex_new (); g_mutex_init (&niimaqdxsrc->mutex);
/* initialize properties */ /* initialize properties */
niimaqdxsrc->ringbuffer_count = DEFAULT_PROP_RING_BUFFER_COUNT; niimaqdxsrc->ringbuffer_count = DEFAULT_PROP_RING_BUFFER_COUNT;
@ -634,7 +442,7 @@ gst_niimaqdxsrc_dispose (GObject * object)
} }
/* chain dispose fuction of parent class */ /* chain dispose fuction of parent class */
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (gst_niimaqdxsrc_parent_class)->dispose (object);
} }
static void static void
@ -684,32 +492,16 @@ gst_niimaqdxsrc_get_property (GObject * object, guint prop_id, GValue * value,
} }
} }
static GstCaps * gboolean
gst_niimaqdxsrc_get_caps (GstBaseSrc * bsrc) gst_niimaqdxsrc_set_caps (GstNiImaqDxSrc * niimaqdxsrc)
{ {
GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (bsrc);
GST_LOG_OBJECT (bsrc, "Entering function get_caps");
/* return template caps if the session hasn't started yet */
if (!niimaqdxsrc->session) {
return
gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
(niimaqdxsrc)));
}
//TODO: should also call this when first opening the camera, in case format isn't supported
return gst_niimaqdxsrc_get_cam_caps (niimaqdxsrc);
}
static gboolean
gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
{
GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (bsrc);
gboolean res = TRUE; gboolean res = TRUE;
GstStructure *structure; GstStructure *structure;
const char *pixel_format; const char *pixel_format;
int endianness; int endianness;
GstCaps *caps;
caps = gst_niimaqdxsrc_get_cam_caps (niimaqdxsrc);
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
@ -726,18 +518,20 @@ gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, endianness, gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, endianness,
niimaqdxsrc->width); niimaqdxsrc->width);
niimaqdxsrc->framesize = niimaqdxsrc->dx_framesize = niimaqdxsrc->dx_row_stride * niimaqdxsrc->height;
GST_ROUND_UP_4 (niimaqdxsrc->dx_row_stride) * niimaqdxsrc->height;
if (niimaqdxsrc->temp_buffer) if (niimaqdxsrc->temp_buffer)
g_free (niimaqdxsrc->temp_buffer); g_free (niimaqdxsrc->temp_buffer);
niimaqdxsrc->temp_buffer = g_malloc (niimaqdxsrc->framesize); niimaqdxsrc->temp_buffer = g_malloc (niimaqdxsrc->dx_framesize);
GST_DEBUG ("Size %dx%d", niimaqdxsrc->width, niimaqdxsrc->height); GST_DEBUG ("Size %dx%d", niimaqdxsrc->width, niimaqdxsrc->height);
GST_LOG_OBJECT (niimaqdxsrc, "Caps set, framesize=%d", GST_LOG_OBJECT (niimaqdxsrc, "Caps set, framesize=%d",
niimaqdxsrc->framesize); 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; return res;
} }
@ -816,9 +610,9 @@ gst_niimaqdxsrc_get_timestamp_from_buffer_number (GstNiImaqDxSrc * niimaqdxsrc,
#define ROUND_UP_N(num, n) (((num)+((n)-1))&~((n)-1)) #define ROUND_UP_N(num, n) (((num)+((n)-1))&~((n)-1))
static GstFlowReturn static GstFlowReturn
gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer) gst_niimaqdxsrc_fill (GstPushSrc * src, GstBuffer * buf)
{ {
GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (psrc); GstNiImaqDxSrc *niimaqdxsrc = GST_NIIMAQDXSRC (src);
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
GstClockTime timestamp = GST_CLOCK_TIME_NONE; GstClockTime timestamp = GST_CLOCK_TIME_NONE;
GstClockTime duration; GstClockTime duration;
@ -826,6 +620,7 @@ gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
IMAQdxError rval; IMAQdxError rval;
uInt32 dropped; uInt32 dropped;
gboolean do_align_stride; gboolean do_align_stride;
GstMapInfo minfo;
/* start the IMAQ acquisition session if we haven't done so yet */ /* start the IMAQ acquisition session if we haven't done so yet */
if (!niimaqdxsrc->session_started) { if (!niimaqdxsrc->session_started) {
@ -836,38 +631,33 @@ gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
} }
} }
GST_LOG_OBJECT (niimaqdxsrc, "Copying IMAQ buffer #%d", GST_LOG_OBJECT (niimaqdxsrc, "Copying IMAQ buffer #%d, buffersize %d",
niimaqdxsrc->cumbufnum); niimaqdxsrc->cumbufnum, gst_buffer_get_size (buf));
ret =
gst_pad_alloc_buffer (GST_BASE_SRC_PAD (niimaqdxsrc), 0, g_assert (niimaqdxsrc->caps_info != NULL);
niimaqdxsrc->framesize, GST_PAD_CAPS (GST_BASE_SRC_PAD (niimaqdxsrc)),
buffer);
if (ret != GST_FLOW_OK) {
GST_ELEMENT_ERROR (niimaqdxsrc, RESOURCE, FAILED,
("Failed to get downstream pad to allocate buffer"), (NULL));
goto error;
}
do_align_stride = do_align_stride =
(niimaqdxsrc->dx_row_stride % niimaqdxsrc->caps_info->row_multiple) != 0; (niimaqdxsrc->dx_row_stride % niimaqdxsrc->caps_info->row_multiple) != 0;
g_mutex_lock (niimaqdxsrc->mutex); g_mutex_lock (&niimaqdxsrc->mutex);
if (!do_align_stride) { if (!do_align_stride) {
gst_buffer_map (buf, &minfo, GST_MAP_WRITE);
// we have properly aligned strides, copy directly to buffer // we have properly aligned strides, copy directly to buffer
rval = IMAQdxGetImageData (niimaqdxsrc->session, GST_BUFFER_DATA (*buffer), rval = IMAQdxGetImageData (niimaqdxsrc->session, minfo.data,
GST_BUFFER_SIZE (*buffer), IMAQdxBufferNumberModeBufferNumber, minfo.size, IMAQdxBufferNumberModeBufferNumber,
niimaqdxsrc->cumbufnum, &copied_number); niimaqdxsrc->cumbufnum, &copied_number);
gst_buffer_unmap (buf, &minfo);
} else { } else {
// we don't have aligned strides, copy to temp buffer // we don't have aligned strides, copy to temp buffer
rval = IMAQdxGetImageData (niimaqdxsrc->session, niimaqdxsrc->temp_buffer, rval = IMAQdxGetImageData (niimaqdxsrc->session, niimaqdxsrc->temp_buffer,
GST_BUFFER_SIZE (*buffer), IMAQdxBufferNumberModeBufferNumber, niimaqdxsrc->dx_framesize, IMAQdxBufferNumberModeBufferNumber,
niimaqdxsrc->cumbufnum, &copied_number); niimaqdxsrc->cumbufnum, &copied_number);
} }
//FIXME: handle timestamps //FIXME: handle timestamps
//timestamp = niimaqdxsrc->times[copied_index]; //timestamp = niimaqdxsrc->times[copied_index];
//niimaqdxsrc->times[copied_index] = GST_CLOCK_TIME_NONE; //niimaqdxsrc->times[copied_index] = GST_CLOCK_TIME_NONE;
g_mutex_unlock (niimaqdxsrc->mutex); g_mutex_unlock (&niimaqdxsrc->mutex);
// adjust for row stride if needed (must be multiple of 4) // adjust for row stride if needed (must be multiple of 4)
if (do_align_stride) { if (do_align_stride) {
@ -876,13 +666,16 @@ gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
int gst_row_stride = int gst_row_stride =
ROUND_UP_N (dx_row_stride, niimaqdxsrc->caps_info->row_multiple); ROUND_UP_N (dx_row_stride, niimaqdxsrc->caps_info->row_multiple);
guint8 *src = niimaqdxsrc->temp_buffer; guint8 *src = niimaqdxsrc->temp_buffer;
guint8 *dst = GST_BUFFER_DATA (*buffer); guint8 *dst;
gst_buffer_map (buf, &minfo, GST_MAP_WRITE);
dst = minfo.data;
GST_LOG_OBJECT (niimaqdxsrc, GST_LOG_OBJECT (niimaqdxsrc,
"Row stride not aligned, copying %d -> %d", "Row stride not aligned, copying %d -> %d",
dx_row_stride, gst_row_stride); dx_row_stride, gst_row_stride);
for (i = 0; i < niimaqdxsrc->height; i++) for (i = 0; i < niimaqdxsrc->height; i++)
memcpy (dst + i * gst_row_stride, src + i * dx_row_stride, dx_row_stride); memcpy (dst + i * gst_row_stride, src + i * dx_row_stride, dx_row_stride);
gst_buffer_unmap (buf, &minfo);
} }
if (rval) { if (rval) {
@ -899,15 +692,12 @@ gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
duration = 33 * GST_MSECOND; duration = 33 * GST_MSECOND;
} }
GST_BUFFER_OFFSET (*buffer) = copied_number; GST_BUFFER_OFFSET (buf) = copied_number;
GST_BUFFER_OFFSET_END (*buffer) = copied_number + 1; GST_BUFFER_OFFSET_END (buf) = copied_number + 1;
//TODO: handle timestamps //TODO: handle timestamps
//GST_BUFFER_TIMESTAMP (*buffer) = //GST_BUFFER_TIMESTAMP (*buffer) =
// timestamp - gst_element_get_base_time (GST_ELEMENT (niimaqdxsrc)); // timestamp - gst_element_get_base_time (GST_ELEMENT (niimaqdxsrc));
GST_BUFFER_DURATION (*buffer) = duration; GST_BUFFER_DURATION (buf) = duration;
/* the negotiate() method already set caps on the source pad */
gst_buffer_set_caps (*buffer, GST_PAD_CAPS (GST_BASE_SRC_PAD (niimaqdxsrc)));
dropped = copied_number - niimaqdxsrc->cumbufnum; dropped = copied_number - niimaqdxsrc->cumbufnum;
if (dropped > 0) { if (dropped > 0) {
@ -924,8 +714,7 @@ gst_niimaqdxsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
if (G_UNLIKELY (niimaqdxsrc->start_time && !niimaqdxsrc->start_time_sent)) { if (G_UNLIKELY (niimaqdxsrc->start_time && !niimaqdxsrc->start_time_sent)) {
GstTagList *tl = GstTagList *tl =
gst_tag_list_new_full (GST_TAG_DATE_TIME, niimaqdxsrc->start_time, gst_tag_list_new (GST_TAG_DATE_TIME, niimaqdxsrc->start_time, NULL);
NULL);
GstEvent *e = gst_event_new_tag (tl); GstEvent *e = gst_event_new_tag (tl);
GST_DEBUG_OBJECT (niimaqdxsrc, "Sending start time event: %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (niimaqdxsrc, "Sending start time event: %" GST_PTR_FORMAT,
e); e);
@ -945,7 +734,7 @@ gst_niimaqdxsrc_list_attributes (GstNiImaqDxSrc * niimaqdxsrc)
{ {
IMAQdxAttributeInformation *attributeInfoArray = NULL; IMAQdxAttributeInformation *attributeInfoArray = NULL;
uInt32 attributeCount; uInt32 attributeCount;
int i; guint i;
IMAQdxError rval; IMAQdxError rval;
IMAQdxSession session = niimaqdxsrc->session; IMAQdxSession session = niimaqdxsrc->session;
char *attributeTypeStrings[] = { "U32", "I64", char *attributeTypeStrings[] = { "U32", "I64",
@ -1089,8 +878,9 @@ gst_niimaqdxsrc_set_dx_attributes (GstNiImaqDxSrc * niimaqdxsrc)
GST_DEBUG_OBJECT (niimaqdxsrc, "Setting attribute, '%s'='%s'", pair[0], GST_DEBUG_OBJECT (niimaqdxsrc, "Setting attribute, '%s'='%s'", pair[0],
pair[1]); pair[1]);
IMAQdxSetAttribute (niimaqdxsrc->session, pair[0], IMAQdxValueTypeString, rval =
(const char *) pair[1]); IMAQdxSetAttribute (niimaqdxsrc->session, pair[0],
IMAQdxValueTypeString, (const char *) pair[1]);
if (rval != IMAQdxErrorSuccess) { if (rval != IMAQdxErrorSuccess) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
} }
@ -1113,6 +903,7 @@ 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);
@ -1164,7 +955,9 @@ gst_niimaqdxsrc_start (GstBaseSrc * src)
gst_niimaqdxsrc_set_dx_attributes (niimaqdxsrc); gst_niimaqdxsrc_set_dx_attributes (niimaqdxsrc);
return TRUE; ret = gst_niimaqdxsrc_set_caps (niimaqdxsrc);
return ret;
error: error:
gst_niimaqdxsrc_close_interface (niimaqdxsrc); gst_niimaqdxsrc_close_interface (niimaqdxsrc);
@ -1290,6 +1083,6 @@ plugin_init (GstPlugin * plugin)
} }
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "niimaqdx", GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, niimaqdx,
"NI-IMAQdx source element", plugin_init, VERSION, GST_LICENSE, PACKAGE_NAME, "NI-IMAQdx source element", plugin_init, VERSION, GST_LICENSE, PACKAGE_NAME,
GST_PACKAGE_ORIGIN) GST_PACKAGE_ORIGIN)

View File

@ -68,7 +68,7 @@ struct _GstNiImaqDxSrc {
int width; int width;
int height; int height;
int dx_row_stride; int dx_row_stride;
gint framesize; gint dx_framesize;
guint8 *temp_buffer; guint8 *temp_buffer;
const ImaqDxCapsInfo *caps_info; const ImaqDxCapsInfo *caps_info;
@ -85,7 +85,7 @@ struct _GstNiImaqDxSrc {
GstDateTime *start_time; GstDateTime *start_time;
gboolean start_time_sent; gboolean start_time_sent;
GMutex *mutex; GMutex mutex;
}; };
struct _GstNiImaqDxSrcClass { struct _GstNiImaqDxSrcClass {

View File

@ -53,23 +53,23 @@
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="niimaqdx.props" /> <Import Project="niimaqdx.props" />
<Import Project="..\..\..\..\gstreamer-sdk\0.10\x86\share\vs\2010\libs\gstreamer-interfaces-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86)\share\vs\2010\libs\gstreamer-video-1.0.props" />
<Import Project="..\..\..\..\gstreamer-sdk\0.10\x86\share\vs\2010\libs\gstreamer-video-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86)\share\vs\2010\msvc\x86.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="niimaqdx.props" /> <Import Project="niimaqdx.props" />
<Import Project="$(GSTREAMER_SDK_ROOT_X86_64)\share\vs\2010\libs\gstreamer-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86_64)\share\vs\2010\libs\gstreamer-1.0.props" />
<Import Project="$(GSTREAMER_SDK_ROOT_X86_64)\share\vs\2010\msvc\x86_64.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86_64)\share\vs\2010\msvc\x86_64.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="niimaqdx.props" /> <Import Project="niimaqdx.props" />
<Import Project="..\..\..\..\gstreamer-sdk\0.10\x86\share\vs\2010\libs\gstreamer-interfaces-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86)\share\vs\2010\libs\gstreamer-video-1.0.props" />
<Import Project="..\..\..\..\gstreamer-sdk\0.10\x86\share\vs\2010\libs\gstreamer-video-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86)\share\vs\2010\msvc\x86.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="niimaqdx.props" /> <Import Project="niimaqdx.props" />
<Import Project="$(GSTREAMER_SDK_ROOT_X86_64)\share\vs\2010\libs\gstreamer-0.10.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86_64)\share\vs\2010\libs\gstreamer-1.0.props" />
<Import Project="$(GSTREAMER_SDK_ROOT_X86_64)\share\vs\2010\msvc\x86_64.props" /> <Import Project="$(GSTREAMER_1_0_SDK_ROOT_X86_64)\share\vs\2010\msvc\x86_64.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'"> <PropertyGroup Condition="'$(Configuration)'=='Debug'">