From ad240b0ae37877966a8272ec4ade67a7797feaae Mon Sep 17 00:00:00 2001 From: "Joshua M. Doe" Date: Fri, 29 Jun 2012 07:35:26 -0400 Subject: [PATCH] niimaq: try to improve accuracy of timestamping By reducing instructions in callback, and adjusting for base time. This last part needs testing however. --- sys/niimaq/gstniimaq.c | 79 ++++++++++++++++++++++-------------------- sys/niimaq/gstniimaq.h | 12 ++++--- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/sys/niimaq/gstniimaq.c b/sys/niimaq/gstniimaq.c index 8160d4e..fda2018 100644 --- a/sys/niimaq/gstniimaq.c +++ b/sys/niimaq/gstniimaq.c @@ -123,30 +123,39 @@ gst_niimaqsrc_frame_start_callback (SESSION_ID sid, IMG_ERR err, { GstNiImaqSrc *niimaqsrc = GST_NIIMAQSRC (userdata); GstClock *clock; - GstNiImaqSrcFrameTime *frametime = g_new (GstNiImaqSrcFrameTime, 1); - uInt32 val; + GstNiImaqSrcFrameTime *frametime; + guint32 bufnum; + GstClockTime abstime; + + if (!niimaqsrc->session_started) + return 1; if (G_UNLIKELY (niimaqsrc->start_time == NULL)) niimaqsrc->start_time = gst_date_time_new_now_utc (); - /* get clock time and set to frametime struct */ + /* get clock time */ clock = gst_element_get_clock (GST_ELEMENT (niimaqsrc)); - if (G_LIKELY (clock)) { - frametime->time = gst_clock_get_time (clock); - gst_object_unref (clock); - } else { - frametime->time = GST_CLOCK_TIME_NONE; - } + g_assert (clock != NULL); + abstime = gst_clock_get_time (clock); /* get current frame number */ - imgGetAttribute (sid, IMG_ATTR_FRAME_COUNT, &val); - frametime->number = val; + imgGetAttribute (sid, IMG_ATTR_FRAME_COUNT, &bufnum); + + /* first frame, use as element base time */ + if (niimaqsrc->base_time == GST_CLOCK_TIME_NONE) + niimaqsrc->base_time = abstime; + + frametime = g_new (GstNiImaqSrcFrameTime, 1); + frametime->number = bufnum; + frametime->time = abstime; /* append frame number and clock time to list */ g_mutex_lock (niimaqsrc->frametime_mutex); niimaqsrc->timelist = g_slist_append (niimaqsrc->timelist, frametime); g_mutex_unlock (niimaqsrc->frametime_mutex); + gst_object_unref (clock); + /* return 1 to rearm the callback */ return 1; } @@ -654,6 +663,7 @@ gst_niimaqsrc_reset (GstNiImaqSrc * niimaqsrc) niimaqsrc->timelist = NULL; niimaqsrc->start_time = NULL; niimaqsrc->start_time_sent = FALSE; + niimaqsrc->base_time = GST_CLOCK_TIME_NONE; } static gboolean @@ -692,36 +702,36 @@ static GstClockTime gst_niimaqsrc_get_timestamp_from_buffer_number (GstNiImaqSrc * niimaqsrc, guint32 buffer_number) { - GstClockTime timestamp = GST_CLOCK_TIME_NONE; + GstClockTime abstime = GST_CLOCK_TIME_NONE; GstNiImaqSrcFrameTime *frametime; /* search linked list for frame time */ g_mutex_lock (niimaqsrc->frametime_mutex); - if (G_LIKELY (niimaqsrc->timelist) - && g_slist_length (niimaqsrc->timelist) > 0) { - /* remove all old frametimes from the list */ + + g_assert (niimaqsrc->timelist != NULL); + + /* remove all old frametimes from the list */ + frametime = (GstNiImaqSrcFrameTime *) niimaqsrc->timelist->data; + while (frametime->number < buffer_number) { + niimaqsrc->timelist = + g_slist_delete_link (niimaqsrc->timelist, niimaqsrc->timelist); frametime = (GstNiImaqSrcFrameTime *) niimaqsrc->timelist->data; - while (frametime->number < buffer_number) { - niimaqsrc->timelist = - g_slist_delete_link (niimaqsrc->timelist, niimaqsrc->timelist); - frametime = (GstNiImaqSrcFrameTime *) niimaqsrc->timelist->data; - } + } - if (frametime->number == buffer_number) { - timestamp = frametime->time; + if (frametime->number == buffer_number) { + abstime = frametime->time; - /* remove frame time as we no longer need it */ - niimaqsrc->timelist = - g_slist_delete_link (niimaqsrc->timelist, niimaqsrc->timelist); - } else { - GST_WARNING_OBJECT (niimaqsrc, - "Did NOT find buffer date-timestamp in list generated by callback"); - } + /* remove frame time as we no longer need it */ + niimaqsrc->timelist = + g_slist_delete_link (niimaqsrc->timelist, niimaqsrc->timelist); + } else { + GST_WARNING_OBJECT (niimaqsrc, + "Did NOT find buffer date-timestamp in list generated by callback"); } g_mutex_unlock (niimaqsrc->frametime_mutex); - return timestamp; + return GST_CLOCK_DIFF (niimaqsrc->base_time, abstime); } static GstFlowReturn @@ -780,14 +790,7 @@ gst_niimaqsrc_create (GstPushSrc * psrc, GstBuffer ** buffer) /* set timestamp */ timestamp = gst_niimaqsrc_get_timestamp_from_buffer_number (niimaqsrc, copied_number); - if (timestamp == GST_CLOCK_TIME_NONE) { - GST_WARNING_OBJECT (niimaqsrc, "No timestamp found; callback failed?"); - /* FIXME: the clock isn't valid before the first FVAL callback? */ - } else { - timestamp = - GST_CLOCK_DIFF (gst_element_get_base_time (GST_ELEMENT (niimaqsrc)), - timestamp); - } + g_assert (timestamp != GST_CLOCK_TIME_NONE); /* make guess of duration from timestamp and cumulative buffer number */ if (GST_CLOCK_TIME_IS_VALID (timestamp)) { diff --git a/sys/niimaq/gstniimaq.h b/sys/niimaq/gstniimaq.h index f20f603..742dbd9 100644 --- a/sys/niimaq/gstniimaq.h +++ b/sys/niimaq/gstniimaq.h @@ -49,26 +49,28 @@ typedef struct _GstNiImaqSrcClass GstNiImaqSrcClass; struct _GstNiImaqSrc { GstPushSrc element; + /* properties */ + gchar *interface_name; + gint bufsize; + + /* image info */ GstVideoFormat format; int width; int height; gint framesize; int rowpixels; - /* private */ - GstClockTime running_time; /* total running time */ gint64 n_frames; /* total frames sent */ uInt32 cumbufnum; gint64 n_dropped_frames; - gboolean segment; - gint bufsize; + guint32** buflist; - gchar *interface_name; INTERFACE_ID iid; SESSION_ID sid; gboolean session_started; + GstClockTime base_time; GSList *timelist; GMutex *frametime_mutex;