niimaqdx: allow Mono16 to be big or little endian depending on interface

It appears FireWire and GigE Vision use different endianness. So now we need
to keep track of two things, PixelFormat and endianness.
This commit is contained in:
Joshua M. Doe 2013-01-30 12:07:19 -05:00
parent b7e1085885
commit 881a75b1f8
2 changed files with 59 additions and 40 deletions

View File

@ -160,95 +160,100 @@ gst_niimaqdxsrc_frame_done_callback (IMAQdxSession session, uInt32 bufferNumber,
"framerate = " GST_VIDEO_FPS_RANGE "framerate = " GST_VIDEO_FPS_RANGE
ImaqDxCapsInfo imaq_dx_caps_infos[] = { ImaqDxCapsInfo imaq_dx_caps_infos[] = {
{"Mono 8", GST_VIDEO_CAPS_GRAY8, 8, 8, 4} {"Mono 8", 0, GST_VIDEO_CAPS_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", GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"), 16, 16, 4} {"Mono 16", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN"), 16, 16,
4}
, ,
{"YUV 422 Packed", GST_VIDEO_CAPS_YUV ("UYVY"), 16, 16, 4} {"Mono 16", G_BIG_ENDIAN, GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN"), 16, 16, 4}
, ,
{"Bayer BG 8", GST_VIDEO_CAPS_BAYER ("bggr"), 8, 8, 1} {"YUV 422 Packed", 0, GST_VIDEO_CAPS_YUV ("UYVY"), 16, 16, 4}
,
{"Bayer BG 8", 0, GST_VIDEO_CAPS_BAYER ("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", GST_VIDEO_CAPS_BAYER ("bggr16"), 16, 16, 1} {"Bayer BG 16", 0, GST_VIDEO_CAPS_BAYER ("bggr16"), 16, 16, 1}
}; };
static ImaqDxCapsInfo * static ImaqDxCapsInfo *
gst_niimaqdxsrc_get_caps_info (const char *pixel_format) gst_niimaqdxsrc_get_caps_info (const char *pixel_format, int endianness)
{ {
int i; int i;
for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) { for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) {
if (g_strcmp0 (pixel_format, imaq_dx_caps_infos[i].pixel_format) == 0) ImaqDxCapsInfo *info = &imaq_dx_caps_infos[i];
return &imaq_dx_caps_infos[i]; if (g_strcmp0 (pixel_format, info->pixel_format) == 0 &&
(info->endianness == endianness || info->endianness == 0))
return info;
} }
GST_WARNING ("PixelFormat '%s' is not supported", pixel_format);
return NULL; return NULL;
} }
static const char * static const char *
gst_niimaqdxsrc_pixel_format_to_caps_string (const char *pixel_format) gst_niimaqdxsrc_pixel_format_to_caps_string (const char *pixel_format,
int endianness)
{ {
int i; ImaqDxCapsInfo *info =
gst_niimaqdxsrc_get_caps_info (pixel_format, endianness);
for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) { if (!info)
if (g_strcmp0 (pixel_format, imaq_dx_caps_infos[i].pixel_format) == 0)
break;
}
if (i == G_N_ELEMENTS (imaq_dx_caps_infos)) {
GST_WARNING ("PixelFormat '%s' is not supported",
imaq_dx_caps_infos[i].pixel_format);
return NULL; return NULL;
}
return imaq_dx_caps_infos[i].gst_caps_string; return info->gst_caps_string;
} }
static const char * static const char *
gst_niimaqdxsrc_pixel_format_from_caps (const GstCaps * caps) gst_niimaqdxsrc_pixel_format_from_caps (const GstCaps * caps, int *endianness)
{ {
int i; int i;
for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) { for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) {
GstCaps *super_caps; GstCaps *super_caps;
super_caps = gst_caps_from_string (imaq_dx_caps_infos[i].gst_caps_string); super_caps = gst_caps_from_string (imaq_dx_caps_infos[i].gst_caps_string);
if (gst_caps_is_subset (caps, super_caps)) if (gst_caps_is_subset (caps, super_caps)) {
*endianness = imaq_dx_caps_infos[i].endianness;
return imaq_dx_caps_infos[i].pixel_format; return imaq_dx_caps_infos[i].pixel_format;
}
} }
return NULL; return NULL;
} }
static int static int
gst_niimaqdxsrc_pixel_format_get_bpp (const char *pixel_format) gst_niimaqdxsrc_pixel_format_get_bpp (const char *pixel_format, int endianness)
{ {
int i; ImaqDxCapsInfo *info =
gst_niimaqdxsrc_get_caps_info (pixel_format, endianness);
for (i = 0; i < G_N_ELEMENTS (imaq_dx_caps_infos); i++) { if (!info)
if (g_strcmp0 (pixel_format, imaq_dx_caps_infos[i].pixel_format) == 0) { return 0;
return imaq_dx_caps_infos[i].bpp;
} return info->bpp;
}
return 0;
} }
static int static int
gst_niimaqdxsrc_pixel_format_get_stride (const char *pixel_format, int width) gst_niimaqdxsrc_pixel_format_get_stride (const char *pixel_format,
int endianness, int width)
{ {
return width * gst_niimaqdxsrc_pixel_format_get_bpp (pixel_format) / 8; return width * gst_niimaqdxsrc_pixel_format_get_bpp (pixel_format,
endianness) / 8;
} }
static GstCaps * static GstCaps *
gst_niimaqdxsrc_new_caps_from_pixel_format (const char *pixel_format, gst_niimaqdxsrc_new_caps_from_pixel_format (const char *pixel_format,
int width, int height, int endianness, int width, int height, int framerate_n, int framerate_d,
int framerate_n, int framerate_d, int par_n, int par_d) int par_n, int par_d)
{ {
const char *caps_string; const char *caps_string;
GstCaps *caps; GstCaps *caps;
GstStructure *structure; GstStructure *structure;
caps_string = gst_niimaqdxsrc_pixel_format_to_caps_string (pixel_format); caps_string =
gst_niimaqdxsrc_pixel_format_to_caps_string (pixel_format, endianness);
if (caps_string == NULL) if (caps_string == NULL)
return NULL; return NULL;
@ -704,19 +709,21 @@ gst_niimaqdxsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
gboolean res = TRUE; gboolean res = TRUE;
GstStructure *structure; GstStructure *structure;
const char *pixel_format; const char *pixel_format;
int endianness;
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "width", &niimaqdxsrc->width); gst_structure_get_int (structure, "width", &niimaqdxsrc->width);
gst_structure_get_int (structure, "height", &niimaqdxsrc->height); gst_structure_get_int (structure, "height", &niimaqdxsrc->height);
pixel_format = gst_niimaqdxsrc_pixel_format_from_caps (caps); pixel_format = gst_niimaqdxsrc_pixel_format_from_caps (caps, &endianness);
g_assert (pixel_format); g_assert (pixel_format);
niimaqdxsrc->caps_info = gst_niimaqdxsrc_get_caps_info (pixel_format); niimaqdxsrc->caps_info =
gst_niimaqdxsrc_get_caps_info (pixel_format, endianness);
niimaqdxsrc->dx_row_stride = niimaqdxsrc->dx_row_stride =
gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, gst_niimaqdxsrc_pixel_format_get_stride (pixel_format, endianness,
niimaqdxsrc->width); niimaqdxsrc->width);
niimaqdxsrc->framesize = niimaqdxsrc->framesize =
@ -1000,6 +1007,8 @@ gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * niimaqdxsrc)
IMAQdxError rval; IMAQdxError rval;
uInt32 val; uInt32 val;
char pixel_format[IMAQDX_MAX_API_STRING_LENGTH]; char pixel_format[IMAQDX_MAX_API_STRING_LENGTH];
int endianness;
char bus_type[IMAQDX_MAX_API_STRING_LENGTH];
gint width, height; gint width, height;
if (!niimaqdxsrc->session) { if (!niimaqdxsrc->session) {
@ -1015,6 +1024,9 @@ gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * niimaqdxsrc)
rval = IMAQdxGetAttribute (niimaqdxsrc->session, IMAQdxAttributePixelFormat, rval = IMAQdxGetAttribute (niimaqdxsrc->session, IMAQdxAttributePixelFormat,
IMAQdxValueTypeString, &pixel_format); IMAQdxValueTypeString, &pixel_format);
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
rval &= IMAQdxGetAttribute (niimaqdxsrc->session, IMAQdxAttributeBusType,
IMAQdxValueTypeString, &bus_type);
gst_niimaqdxsrc_report_imaq_error (rval);
rval &= IMAQdxGetAttribute (niimaqdxsrc->session, IMAQdxAttributeWidth, rval &= IMAQdxGetAttribute (niimaqdxsrc->session, IMAQdxAttributeWidth,
IMAQdxValueTypeU32, &val); IMAQdxValueTypeU32, &val);
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
@ -1030,10 +1042,16 @@ gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * niimaqdxsrc)
("attempt to read attributes failed")); ("attempt to read attributes failed"));
goto error; goto error;
} }
if (g_strcmp0 (bus_type, "Ethernet") == 0)
endianness = G_LITTLE_ENDIAN;
else
endianness = G_BIG_ENDIAN;
//TODO: add all available caps by enumerating PixelFormat's available, and query for framerate //TODO: add all available caps by enumerating PixelFormat's available, and query for framerate
caps = caps =
gst_niimaqdxsrc_new_caps_from_pixel_format (pixel_format, width, height, gst_niimaqdxsrc_new_caps_from_pixel_format (pixel_format, endianness,
30, 1, 1, 1); width, height, 30, 1, 1, 1);
if (!caps) { if (!caps) {
GST_ERROR_OBJECT (niimaqdxsrc, "PixelFormat '%s' not supported yet", GST_ERROR_OBJECT (niimaqdxsrc, "PixelFormat '%s' not supported yet",
pixel_format); pixel_format);

View File

@ -49,6 +49,7 @@ typedef struct _GstNiImaqDxSrcClass GstNiImaqDxSrcClass;
typedef struct typedef struct
{ {
const char *pixel_format; const char *pixel_format;
int endianness;
const char *gst_caps_string; const char *gst_caps_string;
int bpp; int bpp;
int depth; int depth;