niimaq: try to improve accuracy of timestamping
By reducing instructions in callback, and adjusting for base time. This last part needs testing however.
This commit is contained in:
parent
4fa97a4290
commit
ad240b0ae3
@ -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)) {
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user