niimaq: handle byte alignment during copying

Previously if the row stride wasn't a multiple of 4, display would not work
correctly. Rely on NI-IMAQ to fix the byte alignment for us. This hasn't
been thoroughly tested yet however.
This commit is contained in:
Joshua M. Doe 2012-06-29 04:42:44 -04:00
parent 865b416cd0
commit 9002eb1f70
2 changed files with 43 additions and 5 deletions

View File

@ -504,6 +504,10 @@ gst_niimaqsrc_init (GstNiImaqSrc * niimaqsrc, GstNiImaqSrcClass * g_class)
niimaqsrc->camera_name = g_strdup (DEFAULT_PROP_INTERFACE); niimaqsrc->camera_name = g_strdup (DEFAULT_PROP_INTERFACE);
niimaqsrc->interface_name = g_strdup (DEFAULT_PROP_INTERFACE); niimaqsrc->interface_name = g_strdup (DEFAULT_PROP_INTERFACE);
niimaqsrc->session_started = FALSE; niimaqsrc->session_started = FALSE;
niimaqsrc->format = GST_VIDEO_FORMAT_UNKNOWN;
niimaqsrc->width = 0;
niimaqsrc->height = 0;
niimaqsrc->rowpixels = 0;
niimaqsrc->timelist = NULL; niimaqsrc->timelist = NULL;
niimaqsrc->frametime_mutex = g_mutex_new (); niimaqsrc->frametime_mutex = g_mutex_new ();
@ -616,10 +620,31 @@ gst_niimaqsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
{ {
GstNiImaqSrc *niimaqsrc = GST_NIIMAQSRC (bsrc); GstNiImaqSrc *niimaqsrc = GST_NIIMAQSRC (bsrc);
gboolean res = TRUE; gboolean res = TRUE;
int depth;
res = gst_video_get_size_from_caps (caps, &niimaqsrc->framesize); gst_video_format_parse_caps (caps, &niimaqsrc->format, &niimaqsrc->width,
&niimaqsrc->height);
GST_DEBUG_OBJECT (niimaqsrc, "Caps set, framesize=%d", niimaqsrc->framesize); /* this will handle byte alignment (i.e. row multiple of 4 bytes) */
niimaqsrc->framesize =
gst_video_format_get_size (niimaqsrc->format, niimaqsrc->width,
niimaqsrc->height);
/* TODO: use gst_video_format_get_component once 0.10.37 is out */
if (niimaqsrc->format == GST_VIDEO_FORMAT_GRAY8)
depth = 8;
else if (niimaqsrc->format == GST_VIDEO_FORMAT_GRAY16_LE)
depth = 16;
else
g_assert_not_reached (); /* negotiation failed? */
/* use this so NI can give us proper byte alignment */
niimaqsrc->rowpixels =
gst_video_format_get_row_stride (niimaqsrc->format, 0,
niimaqsrc->width) / (depth / 8);
GST_DEBUG_OBJECT (niimaqsrc, "Caps set, framesize=%d, rowpixels=%d",
niimaqsrc->framesize, niimaqsrc->rowpixels);
return res; return res;
} }
@ -707,9 +732,16 @@ gst_niimaqsrc_create (GstPushSrc * psrc, GstBuffer ** buffer)
data = GST_BUFFER_DATA (*buffer); data = GST_BUFFER_DATA (*buffer);
/* TODO: optionally use ExamineBuffer and byteswap in transfer (to offer BIG_ENDIAN) */ /* TODO: optionally use ExamineBuffer and byteswap in transfer (to offer BIG_ENDIAN) */
if (niimaqsrc->width == niimaqsrc->rowpixels)
rval = rval =
imgSessionCopyBufferByNumber (niimaqsrc->sid, niimaqsrc->cumbufnum, data, imgSessionCopyBufferByNumber (niimaqsrc->sid, niimaqsrc->cumbufnum,
data, IMG_OVERWRITE_GET_OLDEST, &copied_number, &copied_index);
else
rval =
imgSessionCopyAreaByNumber (niimaqsrc->sid, niimaqsrc->cumbufnum, 0, 0,
niimaqsrc->height, niimaqsrc->width, data, niimaqsrc->rowpixels,
IMG_OVERWRITE_GET_OLDEST, &copied_number, &copied_index); IMG_OVERWRITE_GET_OLDEST, &copied_number, &copied_index);
if (rval) { if (rval) {
gst_niimaqsrc_report_imaq_error (rval); gst_niimaqsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (niimaqsrc, RESOURCE, FAILED, GST_ELEMENT_ERROR (niimaqsrc, RESOURCE, FAILED,

View File

@ -24,6 +24,8 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/base/gstpushsrc.h> #include <gst/base/gstpushsrc.h>
#include <gst/video/video.h>
#include <niimaq.h> #include <niimaq.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -47,7 +49,11 @@ typedef struct _GstNiImaqSrcClass GstNiImaqSrcClass;
struct _GstNiImaqSrc { struct _GstNiImaqSrc {
GstPushSrc element; GstPushSrc element;
GstVideoFormat format;
int width;
int height;
gint framesize; gint framesize;
int rowpixels;
/* private */ /* private */
gint64 timestamp_offset; /* base offset */ gint64 timestamp_offset; /* base offset */