imperxflexsrc: recover from disrupted signals and better accounting of dropped frames
This commit is contained in:
parent
e876660438
commit
425994d8fb
@ -156,8 +156,6 @@ gst_framelinksrc_reset (GstFramelinkSrc * src)
|
|||||||
{
|
{
|
||||||
g_assert_null (src->grabber);
|
g_assert_null (src->grabber);
|
||||||
|
|
||||||
src->dropped_frame_count = 0;
|
|
||||||
src->last_buffer_number = 0;
|
|
||||||
src->acq_started = FALSE;
|
src->acq_started = FALSE;
|
||||||
|
|
||||||
if (src->caps) {
|
if (src->caps) {
|
||||||
@ -636,9 +634,14 @@ static void __stdcall
|
|||||||
gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
|
gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
|
||||||
{
|
{
|
||||||
GstFramelinkSrc *src = GST_FRAMELINK_SRC (lpUserData);
|
GstFramelinkSrc *src = GST_FRAMELINK_SRC (lpUserData);
|
||||||
guint dropped_frames;
|
gint dropped_frames;
|
||||||
|
static guint64 last_frame_number = 0;
|
||||||
|
static guint64 buffers_processed = 0;
|
||||||
|
static guint64 total_dropped_frames = 0;
|
||||||
|
|
||||||
g_assert (src != NULL);
|
g_assert (src != NULL);
|
||||||
|
|
||||||
|
/* check for DMA errors */
|
||||||
if (pFrameInfo->dma_status == VCECLB_DMA_STATUS_FRAME_DROP) {
|
if (pFrameInfo->dma_status == VCECLB_DMA_STATUS_FRAME_DROP) {
|
||||||
/* TODO: save this in dropped frame total? */
|
/* TODO: save this in dropped frame total? */
|
||||||
GST_WARNING_OBJECT (src, "Frame dropped from DMA system.");
|
GST_WARNING_OBJECT (src, "Frame dropped from DMA system.");
|
||||||
@ -657,6 +660,23 @@ gst_framelinksrc_callback (void *lpUserData, VCECLB_FrameInfoEx * pFrameInfo)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for dropped frames and disrupted signal */
|
||||||
|
dropped_frames = (pFrameInfo->number - last_frame_number) - 1;
|
||||||
|
if (dropped_frames > 0) {
|
||||||
|
total_dropped_frames += dropped_frames;
|
||||||
|
GST_WARNING_OBJECT (src, "Dropped %d frames (%d total)", dropped_frames,
|
||||||
|
total_dropped_frames);
|
||||||
|
} else if (dropped_frames < 0) {
|
||||||
|
GST_WARNING_OBJECT (src,
|
||||||
|
"Signal disrupted, frames likely dropped and timestamps inaccurate");
|
||||||
|
|
||||||
|
/* frame timestamps reset, so adjust start time, accuracy reduced */
|
||||||
|
src->acq_start_time =
|
||||||
|
gst_clock_get_time (gst_element_get_clock (GST_ELEMENT (src))) -
|
||||||
|
pFrameInfo->timestamp * GST_USECOND;
|
||||||
|
}
|
||||||
|
last_frame_number = pFrameInfo->number;
|
||||||
|
|
||||||
g_mutex_lock (&src->mutex);
|
g_mutex_lock (&src->mutex);
|
||||||
|
|
||||||
if (src->buffer) {
|
if (src->buffer) {
|
||||||
@ -669,21 +689,11 @@ 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);
|
||||||
|
|
||||||
/* number always starts at one for IMPERX, zero for GStreamer */
|
|
||||||
GST_BUFFER_OFFSET (src->buffer) = pFrameInfo->number - 1;
|
|
||||||
|
|
||||||
/* TODO: this isn't quite right, I think */
|
|
||||||
GST_BUFFER_TIMESTAMP (src->buffer) =
|
GST_BUFFER_TIMESTAMP (src->buffer) =
|
||||||
GST_ELEMENT_CAST (src)->base_time +
|
GST_CLOCK_DIFF (gst_element_get_base_time (GST_ELEMENT (src)),
|
||||||
(pFrameInfo->timestamp * G_GINT64_CONSTANT (1000));
|
src->acq_start_time + pFrameInfo->timestamp * GST_USECOND);
|
||||||
|
GST_BUFFER_OFFSET (src->buffer) = buffers_processed;
|
||||||
dropped_frames = pFrameInfo->number - src->last_buffer_number - 1;
|
++buffers_processed;
|
||||||
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);
|
||||||
@ -701,9 +711,12 @@ gst_framelinksrc_create (GstPushSrc * psrc, GstBuffer ** buf)
|
|||||||
/* Start acquisition if not already started */
|
/* Start acquisition if not already started */
|
||||||
if (G_UNLIKELY (!src->acq_started)) {
|
if (G_UNLIKELY (!src->acq_started)) {
|
||||||
GST_LOG_OBJECT (src, "starting acquisition");
|
GST_LOG_OBJECT (src, "starting acquisition");
|
||||||
|
src->acq_start_time =
|
||||||
|
gst_clock_get_time (gst_element_get_clock (GST_ELEMENT (src)));
|
||||||
err =
|
err =
|
||||||
VCECLB_StartGrabEx (src->grabber, src->channel, 0,
|
VCECLB_StartGrabEx (src->grabber, src->channel, 0,
|
||||||
gst_framelinksrc_callback, src);
|
gst_framelinksrc_callback, src);
|
||||||
|
|
||||||
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));
|
||||||
|
|||||||
@ -43,8 +43,6 @@ struct _GstFramelinkSrc
|
|||||||
{
|
{
|
||||||
GstPushSrc base_framelinksrc;
|
GstPushSrc base_framelinksrc;
|
||||||
|
|
||||||
guint last_buffer_number;
|
|
||||||
gint dropped_frame_count;
|
|
||||||
gboolean acq_started;
|
gboolean acq_started;
|
||||||
|
|
||||||
/* camera handle */
|
/* camera handle */
|
||||||
@ -58,6 +56,7 @@ struct _GstFramelinkSrc
|
|||||||
gint timeout;
|
gint timeout;
|
||||||
|
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
GstClockTime acq_start_time;
|
||||||
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
gint height;
|
gint height;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user