From 3dc2c2472c0b70a05b09c2248e9c332fdb08b98d Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 9 Sep 2009 17:51:19 -0700 Subject: dv1394src: Add a clock based on isochronous cycle counter Partial fix for #169383. --- ext/raw1394/Makefile.am | 8 ++- ext/raw1394/gst1394clock.c | 150 +++++++++++++++++++++++++++++++++++++++++++++ ext/raw1394/gst1394clock.h | 81 ++++++++++++++++++++++++ ext/raw1394/gstdv1394src.c | 25 ++++++++ ext/raw1394/gstdv1394src.h | 3 + 5 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 ext/raw1394/gst1394clock.c create mode 100644 ext/raw1394/gst1394clock.h (limited to 'ext') diff --git a/ext/raw1394/Makefile.am b/ext/raw1394/Makefile.am index ff152fab..45ec58f5 100644 --- a/ext/raw1394/Makefile.am +++ b/ext/raw1394/Makefile.am @@ -1,6 +1,8 @@ plugin_LTLIBRARIES = libgst1394.la -libgst1394_la_SOURCES = gst1394.c gst1394probe.c gstdv1394src.c gsthdv1394src.c +libgst1394_la_SOURCES = \ + gst1394.c gst1394probe.c gstdv1394src.c gsthdv1394src.c \ + gst1394clock.c libgst1394_la_CFLAGS = \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ @@ -14,4 +16,6 @@ libgst1394_la_LIBADD = \ libgst1394_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgst1394_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstdv1394src.h gst1394probe.h gsthdv1394src.h +noinst_HEADERS = gstdv1394src.h gst1394probe.h gsthdv1394src.h \ + gst1394clock.h + diff --git a/ext/raw1394/gst1394clock.c b/ext/raw1394/gst1394clock.c new file mode 100644 index 00000000..bb6de102 --- /dev/null +++ b/ext/raw1394/gst1394clock.c @@ -0,0 +1,150 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * Copyright (C) 2009 David Schleef + * + * gst1394clock.c: Clock for use by IEEE 1394 plugins + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gst1394clock.h" + +GST_DEBUG_CATEGORY_STATIC (gst_1394_clock_debug); +#define GST_CAT_DEFAULT gst_1394_clock_debug + +static void gst_1394_clock_class_init (Gst1394ClockClass * klass); +static void gst_1394_clock_init (Gst1394Clock * clock); + +static GstClockTime gst_1394_clock_get_internal_time (GstClock * clock); + +static GstSystemClockClass *parent_class = NULL; + +/* static guint gst_1394_clock_signals[LAST_SIGNAL] = { 0 }; */ + +GType +gst_1394_clock_get_type (void) +{ + static GType clock_type = 0; + + if (!clock_type) { + static const GTypeInfo clock_info = { + sizeof (Gst1394ClockClass), + NULL, + NULL, + (GClassInitFunc) gst_1394_clock_class_init, + NULL, + NULL, + sizeof (Gst1394Clock), + 4, + (GInstanceInitFunc) gst_1394_clock_init, + NULL + }; + + clock_type = g_type_register_static (GST_TYPE_SYSTEM_CLOCK, "Gst1394Clock", + &clock_info, 0); + } + return clock_type; +} + + +static void +gst_1394_clock_class_init (Gst1394ClockClass * klass) +{ + GstClockClass *gstclock_class; + + gstclock_class = (GstClockClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gstclock_class->get_internal_time = gst_1394_clock_get_internal_time; + + GST_DEBUG_CATEGORY_INIT (gst_1394_clock_debug, "1394clock", 0, "1394clock"); +} + +static void +gst_1394_clock_init (Gst1394Clock * clock) +{ + clock->last_time = 0; + GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER); +} + +/** + * gst_1394_clock_new: + * @name: the name of the clock + * + * Create a new #Gst1394Clock instance. + * + * Returns: a new #Gst1394Clock + */ +Gst1394Clock * +gst_1394_clock_new (const gchar * name) +{ + Gst1394Clock *_1394clock = + GST_1394_CLOCK (g_object_new (GST_TYPE_1394_CLOCK, "name", name, NULL)); + + return _1394clock; +} + +static GstClockTime +gst_1394_clock_get_internal_time (GstClock * clock) +{ + Gst1394Clock *_1394clock; + GstClockTime result; + guint32 cycle_timer; + guint64 local_time; + + _1394clock = GST_1394_CLOCK_CAST (clock); + + if (_1394clock->handle != NULL) { + raw1394_read_cycle_timer (_1394clock->handle, &cycle_timer, &local_time); + + if (cycle_timer < _1394clock->cycle_timer_lo) { + GST_LOG_OBJECT (clock, "overflow %u to %u", + _1394clock->cycle_timer_lo, cycle_timer); + + _1394clock->cycle_timer_hi++; + } + _1394clock->cycle_timer_lo = cycle_timer; + + result = (((guint64) _1394clock->cycle_timer_hi) << 32) | cycle_timer; + result *= 40; + + GST_LOG_OBJECT (clock, "result %lld", result); + } else { + result = GST_CLOCK_TIME_NONE; + } + + return result; +} + +void +gst_1394_clock_set_handle (Gst1394Clock * clock, raw1394handle_t handle) +{ + clock->handle = handle; + clock->cycle_timer_lo = 0; + clock->cycle_timer_hi = 0; +} + +void +gst_1394_clock_unset_handle (Gst1394Clock * clock) +{ + clock->handle = NULL; +} diff --git a/ext/raw1394/gst1394clock.h b/ext/raw1394/gst1394clock.h new file mode 100644 index 00000000..3d693003 --- /dev/null +++ b/ext/raw1394/gst1394clock.h @@ -0,0 +1,81 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2005 Wim Taymans + * Copyright (C) 2009 David Schleef + * + * gst1394clock.h: Clock for use by the IEEE 1394 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_1394_CLOCK_H__ +#define __GST_1394_CLOCK_H__ + +#include +#include + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_1394_CLOCK \ + (gst_1394_clock_get_type()) +#define GST_1394_CLOCK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_1394_CLOCK,Gst1394Clock)) +#define GST_1394_CLOCK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_1394_CLOCK,Gst1394ClockClass)) +#define GST_IS_1394_CLOCK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_1394_CLOCK)) +#define GST_IS_1394_CLOCK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_1394_CLOCK)) +#define GST_1394_CLOCK_CAST(obj) \ + ((Gst1394Clock*)(obj)) + +typedef struct _Gst1394Clock Gst1394Clock; +typedef struct _Gst1394ClockClass Gst1394ClockClass; + +/** + * Gst1394Clock: + * @clock: parent #GstSystemClock + * + * Opaque #Gst1394Clock. + */ +struct _Gst1394Clock { + GstSystemClock clock; + + raw1394handle_t handle; + + GstClockTime last_time; + guint32 cycle_timer_lo; + guint32 cycle_timer_hi; +}; + +struct _Gst1394ClockClass { + GstSystemClockClass parent_class; + + /*< private >*/ + gpointer _gst_reserved[GST_PADDING]; +}; + +GType gst_1394_clock_get_type (void); +Gst1394Clock* gst_1394_clock_new (const gchar *name); +void gst_1394_clock_set_handle (Gst1394Clock *clock, + raw1394handle_t handle); +void gst_1394_clock_unset_handle (Gst1394Clock *clock); + +G_END_DECLS + +#endif /* __GST_1394_CLOCK_H__ */ diff --git a/ext/raw1394/gstdv1394src.c b/ext/raw1394/gstdv1394src.c index 5bcaa7d7..6e3b4c10 100644 --- a/ext/raw1394/gstdv1394src.c +++ b/ext/raw1394/gstdv1394src.c @@ -56,6 +56,7 @@ #include "gstdv1394src.h" #include "gst1394probe.h" +#include "gst1394clock.h" #define CONTROL_STOP 'S' /* stop the select call */ @@ -136,6 +137,8 @@ static void gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_dv1394src_dispose (GObject * object); +static GstClock *gst_dv1394src_provide_clock (GstElement * element); + static gboolean gst_dv1394src_start (GstBaseSrc * bsrc); static gboolean gst_dv1394src_stop (GstBaseSrc * bsrc); static gboolean gst_dv1394src_unlock (GstBaseSrc * bsrc); @@ -183,10 +186,12 @@ static void gst_dv1394src_class_init (GstDV1394SrcClass * klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; GstBaseSrcClass *gstbasesrc_class; GstPushSrcClass *gstpushsrc_class; gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; gstbasesrc_class = (GstBaseSrcClass *) klass; gstpushsrc_class = (GstPushSrcClass *) klass; @@ -194,6 +199,8 @@ gst_dv1394src_class_init (GstDV1394SrcClass * klass) gobject_class->get_property = gst_dv1394src_get_property; gobject_class->dispose = gst_dv1394src_dispose; + gstelement_class->provide_clock = gst_dv1394src_provide_clock; + gst_dv1394src_signals[SIGNAL_FRAME_DROPPED] = g_signal_new ("frame-dropped", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDV1394SrcClass, frame_dropped), @@ -274,6 +281,8 @@ gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass) dv1394src->buf = NULL; dv1394src->frame = NULL; dv1394src->frame_sequence = 0; + + dv1394src->provided_clock = gst_1394_clock_new ("dv1394clock"); } static void @@ -281,6 +290,10 @@ gst_dv1394src_dispose (GObject * object) { GstDV1394Src *src = GST_DV1394SRC (object); + if (src->provided_clock) { + g_object_unref (src->provided_clock); + } + g_free (src->uri); src->uri = NULL; @@ -363,6 +376,14 @@ gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value, } } +static GstClock * +gst_dv1394src_provide_clock (GstElement * element) +{ + GstDV1394Src *dv1394src = GST_DV1394SRC (element); + + return GST_CLOCK_CAST (gst_object_ref (dv1394src->provided_clock)); +} + #ifdef HAVE_LIBIEC61883 static GstDV1394Src * gst_dv1394src_from_raw1394handle (raw1394handle_t handle) @@ -833,6 +854,8 @@ gst_dv1394src_start (GstBaseSrc * bsrc) } } + gst_1394_clock_set_handle (src->provided_clock, src->handle); + return TRUE; socket_pair: @@ -927,6 +950,8 @@ gst_dv1394src_stop (GstBaseSrc * bsrc) } } + gst_1394_clock_unset_handle (src->provided_clock); + raw1394_destroy_handle (src->handle); return TRUE; diff --git a/ext/raw1394/gstdv1394src.h b/ext/raw1394/gstdv1394src.h index 0e750dc8..bf9a3e07 100644 --- a/ext/raw1394/gstdv1394src.h +++ b/ext/raw1394/gstdv1394src.h @@ -24,6 +24,7 @@ #include #include +#include "gst1394clock.h" #include #ifdef HAVE_LIBIEC61883 @@ -82,6 +83,8 @@ struct _GstDV1394Src { #ifdef HAVE_LIBIEC61883 iec61883_dv_fb_t iec61883dv; #endif + + Gst1394Clock *provided_clock; }; struct _GstDV1394SrcClass { -- cgit