framelinksrc: properly copy buffer if there is pre- or post-valid data

This commit is contained in:
Joshua M. Doe 2014-01-15 15:52:43 -05:00
parent aa46f16701
commit 61b7040c2d
2 changed files with 27 additions and 20 deletions

View File

@ -276,7 +276,8 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
VCECLB_ConfigurationA camConfig; VCECLB_ConfigurationA camConfig;
VCECLB_Error err; VCECLB_Error err;
GstVideoInfo vinfo; GstVideoInfo vinfo;
int bpp; int bpp, Bpp;
VCECLB_CameraDataEx *ci;
GST_DEBUG_OBJECT (src, "start"); GST_DEBUG_OBJECT (src, "start");
@ -315,7 +316,10 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
g_free (camConfig.lpszManufacturer); g_free (camConfig.lpszManufacturer);
g_free (camConfig.lpszModel); g_free (camConfig.lpszModel);
if (camConfig.pixelInfo.cameraData.Packed == 1) { /* use shortcut since we use this struct a lot */
ci = &camConfig.pixelInfo.cameraData;
if (ci->Packed == 1) {
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS,
("Packed pixel data not supported yet."), (NULL)); ("Packed pixel data not supported yet."), (NULL));
return FALSE; return FALSE;
@ -337,9 +341,7 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
return FALSE; return FALSE;
} }
err = err = VCECLB_PrepareEx (src->grabber, src->channel, ci);
VCECLB_PrepareEx (src->grabber, src->channel,
&camConfig.pixelInfo.cameraData);
if (err != VCECLB_Err_Success) { if (err != VCECLB_Err_Success) {
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS,
("Failed to configure grabber (code %d)", err), (NULL)); ("Failed to configure grabber (code %d)", err), (NULL));
@ -353,15 +355,15 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
} }
gst_video_info_init (&vinfo); gst_video_info_init (&vinfo);
vinfo.width = camConfig.pixelInfo.cameraData.Width; vinfo.width = ci->Width;
vinfo.height = camConfig.pixelInfo.cameraData.Height; vinfo.height = ci->Height;
bpp = camConfig.pixelInfo.cameraData.BitDepth; bpp = ci->BitDepth;
if (bpp <= 8) { if (bpp <= 8) {
vinfo.finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY8); vinfo.finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_GRAY8);
src->caps = gst_video_info_to_caps (&vinfo); src->caps = gst_video_info_to_caps (&vinfo);
src->flex_stride = vinfo.width; Bpp = 1;
} else if (bpp > 8 && bpp <= 16) { } else if (bpp > 8 && bpp <= 16) {
GValue val = G_VALUE_INIT; GValue val = G_VALUE_INIT;
GstStructure *s; GstStructure *s;
@ -379,7 +381,7 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
gst_structure_set_value (s, "bpp", &val); gst_structure_set_value (s, "bpp", &val);
g_value_unset (&val); g_value_unset (&val);
src->flex_stride = vinfo.width * 2; Bpp = 2;
} else { } else {
/* TODO: support 24-bit RGB */ /* TODO: support 24-bit RGB */
GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE, GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE,
@ -387,8 +389,12 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
return FALSE; return FALSE;
} }
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); src->flex_stride = (ci->WidthPreValid + ci->Width + ci->WidthPostValid) * Bpp;
src->widthBytesPreValid = ci->WidthPreValid * Bpp;
src->widthBytes = ci->Width * Bpp;
src->heightPreValid = ci->HeightPreValid;
src->height = vinfo.height; src->height = vinfo.height;
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0);
return TRUE; return TRUE;
} }
@ -455,7 +461,6 @@ gst_framelinksrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) { if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) {
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0);
src->height = vinfo.height;
} else { } else {
goto unsupported_caps; goto unsupported_caps;
} }
@ -485,15 +490,17 @@ gst_framelinksrc_create_buffer_from_frameinfo (GstFramelinkSrc * src,
pFrameInfo->timestamp); pFrameInfo->timestamp);
if (src->gst_stride == src->flex_stride) { if (src->gst_stride == src->flex_stride) {
memcpy (minfo.data, pFrameInfo->lpRawBuffer, minfo.size); memcpy (minfo.data,
((guint8 *) pFrameInfo->lpRawBuffer) +
src->flex_stride * src->heightPreValid, minfo.size);
} else { } else {
int i; int i;
GST_WARNING_OBJECT (src, GST_LOG_OBJECT (src, "Image strides not identical, copy will be slower.");
"Image stride not a multiple of 4, copy will be slower.");
for (i = 0; i < src->height; i++) { for (i = 0; i < src->height; i++) {
memcpy (minfo.data + i * src->gst_stride, memcpy (minfo.data + i * src->gst_stride,
((guint8 *) pFrameInfo->lpRawBuffer) + i * src->flex_stride, ((guint8 *) pFrameInfo->lpRawBuffer) +
src->flex_stride); (src->heightPreValid + i) * src->flex_stride +
src->widthBytesPreValid, src->widthBytes);
} }
} }
gst_buffer_unmap (buf, &minfo); gst_buffer_unmap (buf, &minfo);

View File

@ -54,11 +54,11 @@ struct _GstFramelinkSrc
GstBuffer *buffer; GstBuffer *buffer;
gboolean buffer_ready;
guint buffer_processed_count;
GstCaps *caps; GstCaps *caps;
gint height; gint height;
gint widthBytesPreValid;
gint widthBytes;
gint heightPreValid;
gint gst_stride; gint gst_stride;
guint flex_stride; guint flex_stride;