framelinksrc: callback used now and use unpack function

Making the callback __stdcall fixed the problem. No clear way how to do a
grab without using a callback, so remove that code. Also use unpack
function provided by the library rather than rolling our own.
This commit is contained in:
Joshua M. Doe 2014-01-16 08:49:35 -05:00
parent 9e585ffd46
commit 17a360b8d2
2 changed files with 54 additions and 64 deletions

View File

@ -319,6 +319,9 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
/* use shortcut since we use this struct a lot */ /* use shortcut since we use this struct a lot */
ci = &camConfig.pixelInfo.cameraData; ci = &camConfig.pixelInfo.cameraData;
/* copy pixel info struct to be used when unpacking data */
memcpy (&src->pixInfo, &camConfig.pixelInfo, sizeof (VCECLB_RawPixelInfoEx));
if (ci->Packed == 1) { 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));
@ -389,10 +392,6 @@ gst_framelinksrc_start (GstBaseSrc * bsrc)
return FALSE; return FALSE;
} }
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); src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0);
@ -478,31 +477,51 @@ gst_framelinksrc_create_buffer_from_frameinfo (GstFramelinkSrc * src,
{ {
GstMapInfo minfo; GstMapInfo minfo;
GstBuffer *buf; GstBuffer *buf;
INT_PTR strideSize;
unsigned long outputBitDepth;
VCECLB_Error err;
/* TODO: use allocator or use from pool */ /* TODO: use allocator or use from pool */
buf = gst_buffer_new_and_alloc (src->height * src->gst_stride); buf = gst_buffer_new_and_alloc (src->height * src->gst_stride);
/* Copy image to buffer from surface TODO: use orc_memcpy */ /* Copy image to buffer from surface */
gst_buffer_map (buf, &minfo, GST_MAP_WRITE); gst_buffer_map (buf, &minfo, GST_MAP_WRITE);
GST_LOG_OBJECT (src, GST_LOG_OBJECT (src,
"GstBuffer size=%d, gst_stride=%d, phx_stride=%d, number=%d, timestamp=%d", "GstBuffer size=%d, gst_stride=%d, number=%d, timestamp=%d",
minfo.size, src->gst_stride, src->flex_stride, pFrameInfo->number, minfo.size, src->gst_stride, pFrameInfo->number, pFrameInfo->timestamp);
pFrameInfo->timestamp);
if (src->gst_stride == src->flex_stride) { #if GST_FRAMELINKSRC_COPY_EXPLICITLY
guint flex_stride =
(ci->WidthPreValid + ci->Width + ci->WidthPostValid) * Bpp;
gint widthBytesPreValid = ci->WidthPreValid * Bpp;
gint widthBytes = ci->Width * Bpp;
gint heightPreValid = ci->HeightPreValid;
/* TODO: use orc_memcpy */
if (src->gst_stride == flex_stride) {
memcpy (minfo.data, memcpy (minfo.data,
((guint8 *) pFrameInfo->lpRawBuffer) + ((guint8 *) pFrameInfo->lpRawBuffer) +
src->flex_stride * src->heightPreValid, minfo.size); flex_stride * heightPreValid, minfo.size);
} else { } else {
int i; int i;
GST_LOG_OBJECT (src, "Image strides not identical, copy will be slower."); GST_LOG_OBJECT (src, "Image strides not identical, 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) + ((guint8 *) pFrameInfo->lpRawBuffer) +
(src->heightPreValid + i) * src->flex_stride + (heightPreValid + i) * flex_stride + widthBytesPreValid, widthBytes);
src->widthBytesPreValid, src->widthBytes);
} }
} }
#else
strideSize = src->gst_stride;
err =
VCECLB_UnpackRawPixelsEx (&src->pixInfo, pFrameInfo->lpRawBuffer,
minfo.data, &strideSize, VCECLB_EX_FMT_16BIT | VCECLB_EX_FMT_TopDown,
&outputBitDepth);
if (err != VCECLB_Err_Success) {
GST_ELEMENT_ERROR (src, STREAM, DECODE,
("Failed to unpack raw pixels (code %d)", err), (NULL));
goto Error;
}
#endif
gst_buffer_unmap (buf, &minfo); gst_buffer_unmap (buf, &minfo);
GST_BUFFER_OFFSET (buf) = pFrameInfo->number; GST_BUFFER_OFFSET (buf) = pFrameInfo->number;
@ -510,17 +529,22 @@ gst_framelinksrc_create_buffer_from_frameinfo (GstFramelinkSrc * src,
/* GST_BUFFER_OFFSET (src->timestamp) = pFrameInfo->timestamp * G_GINT64_CONSTANT (1000); */ /* GST_BUFFER_OFFSET (src->timestamp) = pFrameInfo->timestamp * G_GINT64_CONSTANT (1000); */
return buf; return buf;
Error:
if (minfo.memory != NULL)
gst_buffer_unmap (buf, &minfo);
if (buf)
gst_buffer_unref (buf);
return NULL;
} }
static void static void __stdcall
gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo) gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
{ {
GstFramelinkSrc *src; GstFramelinkSrc *src = GST_FRAMELINK_SRC (lpUserData);
return; guint dropped_frames;
printf ("callback, status=%d, buffersize=%d, number=%d, timestamp=%d \n",
pFrameInfo->dma_status, pFrameInfo->bufferSize, pFrameInfo->number,
pFrameInfo->timestamp);
src = GST_FRAMELINK_SRC (lpUserData);
g_assert (src != NULL); g_assert (src != NULL);
if (pFrameInfo->dma_status == VCECLB_DMA_STATUS_FRAME_DROP) { if (pFrameInfo->dma_status == VCECLB_DMA_STATUS_FRAME_DROP) {
@ -541,8 +565,6 @@ gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
return; return;
} }
GST_LOG_OBJECT (src, "callback received for new buffer");
g_mutex_lock (&src->mutex); g_mutex_lock (&src->mutex);
if (src->buffer) { if (src->buffer) {
@ -555,6 +577,14 @@ gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
src->buffer = gst_framelinksrc_create_buffer_from_frameinfo (src, pFrameInfo); src->buffer = gst_framelinksrc_create_buffer_from_frameinfo (src, pFrameInfo);
dropped_frames = pFrameInfo->number - src->last_buffer_number - 1;
if (dropped_frames > 0) {
src->dropped_frame_count += dropped_frames;
GST_WARNING_OBJECT (src, "Dropped %d frames (%d total)", dropped_frames,
src->dropped_frame_count);
}
src->last_buffer_number = pFrameInfo->number;
g_cond_signal (&src->cond); g_cond_signal (&src->cond);
g_mutex_unlock (&src->mutex); g_mutex_unlock (&src->mutex);
} }
@ -564,20 +594,12 @@ gst_framelinksrc_create (GstPushSrc * psrc, GstBuffer ** buf)
{ {
GstFramelinkSrc *src = GST_FRAMELINK_SRC (psrc); GstFramelinkSrc *src = GST_FRAMELINK_SRC (psrc);
VCECLB_Error err; VCECLB_Error err;
VCECLB_FrameInfoEx pFrameInfo;
gboolean got_new_buffer = FALSE;
/* Start acquisition if not already started */ /* Start acquisition if not already started */
if (!src->acq_started) { if (!src->acq_started) {
#if GST_FRAMELINKSRC_USE_CALLBACK
err = err =
VCECLB_StartGrabEx (src->grabber, src->channel, 0, VCECLB_StartGrabEx (src->grabber, src->channel, 0,
(VCECLB_GrabFrame_CallbackEx) gst_framelinksrc_callback, src); gst_framelinksrc_callback, src);
#else
err =
VCECLB_StartGrabEx (src->grabber, src->channel, 0,
(VCECLB_GrabFrame_CallbackEx) NULL, src);
#endif
if (err != VCECLB_Err_Success) { if (err != VCECLB_Err_Success) {
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to start grabbing (code %d)", err), (NULL)); ("Failed to start grabbing (code %d)", err), (NULL));
@ -585,7 +607,7 @@ gst_framelinksrc_create (GstPushSrc * psrc, GstBuffer ** buf)
} }
src->acq_started = TRUE; src->acq_started = TRUE;
} }
#if GST_FRAMELINKSRC_USE_CALLBACK
/* wait for a buffer to be ready */ /* wait for a buffer to be ready */
g_mutex_lock (&src->mutex); g_mutex_lock (&src->mutex);
while (!src->buffer) { while (!src->buffer) {
@ -598,35 +620,6 @@ gst_framelinksrc_create (GstPushSrc * psrc, GstBuffer ** buf)
src->buffer = NULL; src->buffer = NULL;
} }
g_mutex_unlock (&src->mutex); g_mutex_unlock (&src->mutex);
#else
while (!got_new_buffer) {
guint dropped_frames;
err = VCECLB_GetLastBufferData (src->grabber, src->channel, &pFrameInfo);
if (err != VCECLB_Err_Success) {
GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to get last buffer (code %d)", err), (NULL));
return GST_FLOW_ERROR;
}
if (pFrameInfo.lpRawBuffer == NULL
|| pFrameInfo.number == src->last_buffer_number)
continue;
got_new_buffer = TRUE;
dropped_frames = pFrameInfo.number - src->last_buffer_number - 1;
if (dropped_frames > 0) {
src->dropped_frame_count += dropped_frames;
GST_WARNING_OBJECT (src, "Dropped %d frames (%d total)", dropped_frames,
src->dropped_frame_count);
}
src->last_buffer_number = pFrameInfo.number;
}
/* TODO: check for missed frames by comparing pFrameInfo.number */
*buf = gst_framelinksrc_create_buffer_from_frameinfo (src, &pFrameInfo);
#endif
return GST_FLOW_OK; return GST_FLOW_OK;
} }

View File

@ -57,11 +57,8 @@ struct _GstFramelinkSrc
GstCaps *caps; GstCaps *caps;
gint height; gint height;
gint widthBytesPreValid;
gint widthBytes;
gint heightPreValid;
gint gst_stride; gint gst_stride;
guint flex_stride; VCECLB_RawPixelInfoEx pixInfo;
GMutex mutex; GMutex mutex;
GCond cond; GCond cond;