From: <wt...@fr...> - 2005-04-28 16:16:01
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Fri Apr 29 2005 02:15:54 EST Log message: Make ringbuffer faster and more simple by removing the locks in the playback thread. Add sample accurate playback based on buffer sample offsets. Make the baseaudiosink provide a clock. Parse caps in the base class. Correctly handle seeking, flushing and state changes. Modified files: . : ChangeLog gst-libs/gst/audio: Makefile.am audio.h gstaudiosink.c gstbaseaudiosink.c gstbaseaudiosink.h gstringbuffer.c gstringbuffer.h Added files: gst-libs/gst/audio: gstaudioclock.c gstaudioclock.h Removed files: gst-libs/gst/audio: audioclock.c audioclock.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1662&r2=1.1663 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/Makefile.am.diff?r1=1.20&r2=1.21 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/audio.h.diff?r1=1.16&r2=1.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/audioclock.c http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/audioclock.h http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h.diff?r1=1.1&r2=1.2 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1662 retrieving revision 1.1663 diff -u -d -r1.1662 -r1.1663 --- ChangeLog 25 Apr 2005 13:29:40 -0000 1.1662 +++ ChangeLog 28 Apr 2005 16:15:41 -0000 1.1663 @@ -1,3 +1,47 @@ +2005-04-28 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/Makefile.am: + * gst-libs/gst/audio/audio.h: + * gst-libs/gst/audio/audioclock.c: + * gst-libs/gst/audio/audioclock.h: + * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_get_type), + (gst_audio_clock_class_init), (gst_audio_clock_init), + (gst_audio_clock_new), (gst_audio_clock_get_internal_time): + * gst-libs/gst/audio/gstaudioclock.h: + * gst-libs/gst/audio/gstaudiosink.c: + (gst_audioringbuffer_get_type), (gst_audioringbuffer_class_init), + (audioringbuffer_thread_func), (gst_audioringbuffer_init), + (gst_audioringbuffer_acquire), (gst_audioringbuffer_release), + (gst_audioringbuffer_play), (gst_audioringbuffer_stop), + (gst_audioringbuffer_delay), (gst_audiosink_class_init), + (gst_audiosink_create_ringbuffer): + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_baseaudiosink_class_init), (gst_baseaudiosink_init), + (gst_baseaudiosink_get_clock), (gst_baseaudiosink_get_time), + (gst_baseaudiosink_set_property), (gst_baseaudiosink_get_property), + (build_linear_format), (debug_spec_caps), (debug_spec_buffer), + (gst_baseaudiosink_setcaps), (gst_baseaudiosink_get_times), + (gst_baseaudiosink_event), (gst_baseaudiosink_preroll), + (gst_baseaudiosink_render), (gst_baseaudiosink_create_ringbuffer), + (gst_baseaudiosink_callback), (gst_baseaudiosink_change_state): + * gst-libs/gst/audio/gstbaseaudiosink.h: + * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_get_type), + (gst_ringbuffer_init), (gst_ringbuffer_finalize), + (gst_ringbuffer_set_callback), (gst_ringbuffer_acquire), + (gst_ringbuffer_release), (gst_ringbuffer_play), + (gst_ringbuffer_pause), (gst_ringbuffer_stop), + (gst_ringbuffer_delay), (gst_ringbuffer_played_samples), + (gst_ringbuffer_set_sample), (wait_segment), + (gst_ringbuffer_commit), (gst_ringbuffer_prepare_read), + (gst_ringbuffer_advance), (gst_ringbuffer_clear): + * gst-libs/gst/audio/gstringbuffer.h: + Make ringbuffer faster and more simple by removing the locks + in the playback thread. + Add sample accurate playback based on buffer sample offsets. + Make the baseaudiosink provide a clock. + Parse caps in the base class. + Correctly handle seeking, flushing and state changes. 2005-04-25 Thomas Vander Stichele <thomas at apestaart dot org> * configure.ac: Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/Makefile.am,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- Makefile.am 25 Apr 2005 07:06:07 -0000 1.20 +++ Makefile.am 28 Apr 2005 16:15:42 -0000 1.21 @@ -14,7 +14,7 @@ CLEANFILES = gstaudiofilterexample.c \ $(BUILT_SOURCES) -libgstaudio_@GST_MAJORMINOR@_la_SOURCES = audio.c audioclock.c \ +libgstaudio_@GST_MAJORMINOR@_la_SOURCES = audio.c gstaudioclock.c \ multichannel.c \ gstaudiosink.c \ gstbaseaudiosink.c \ @@ -24,7 +24,7 @@ libgstaudio_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/audio libgstaudio_@GST_MAJORMINOR@include_HEADERS = \ audio.h \ - audioclock.h \ + gstaudioclock.h \ gstaudiofilter.h \ gstaudiosink.h \ gstbaseaudiosink.h \ Index: audio.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/audio.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- audio.h 9 Nov 2004 06:08:22 -0000 1.16 +++ audio.h 28 Apr 2005 16:15:42 -0000 1.17 @@ -20,8 +20,6 @@ #include <gst/gst.h> -#include <gst/audio/audioclock.h> - #ifndef __GST_AUDIO_AUDIO_H__ #define __GST_AUDIO_AUDIO_H__ --- audioclock.c DELETED --- --- audioclock.h DELETED --- --- NEW FILE: gstaudioclock.c --- /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen <om...@cs...> * 2000 Wim Taymans <wt...@ch...> * * audioclock.c: Clock for use by audio 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 "gstaudioclock.h" static void gst_audio_clock_class_init (GstAudioClockClass * klass); static void gst_audio_clock_init (GstAudioClock * clock); static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock); static GstSystemClockClass *parent_class = NULL; /* static guint gst_audio_clock_signals[LAST_SIGNAL] = { 0 }; */ GType gst_audio_clock_get_type (void) { static GType clock_type = 0; if (!clock_type) { static const GTypeInfo clock_info = { sizeof (GstAudioClockClass), NULL, (GClassInitFunc) gst_audio_clock_class_init, sizeof (GstAudioClock), 4, (GInstanceInitFunc) gst_audio_clock_init, NULL }; clock_type = g_type_register_static (GST_TYPE_SYSTEM_CLOCK, "GstAudioClock", &clock_info, 0); } return clock_type; } static void gst_audio_clock_class_init (GstAudioClockClass * klass) GObjectClass *gobject_class; GstObjectClass *gstobject_class; GstClockClass *gstclock_class; gobject_class = (GObjectClass *) klass; gstobject_class = (GstObjectClass *) klass; gstclock_class = (GstClockClass *) klass; parent_class = g_type_class_ref (GST_TYPE_SYSTEM_CLOCK); gstclock_class->get_internal_time = gst_audio_clock_get_internal_time; gst_audio_clock_init (GstAudioClock * clock) gst_object_set_name (GST_OBJECT (clock), "GstAudioClock"); GstClock * gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func, gpointer user_data) GstAudioClock *aclock = GST_AUDIO_CLOCK (g_object_new (GST_TYPE_AUDIO_CLOCK, NULL)); aclock->func = func; aclock->user_data = user_data; return (GstClock *) aclock; static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock) GstAudioClock *aclock = GST_AUDIO_CLOCK (clock); return aclock->func (clock, aclock->user_data); --- NEW FILE: gstaudioclock.h --- * 2005 Wim Taymans <wi...@fl...> * gstaudioclock.h: Clock for use by audio plugins #ifndef __GST_AUDIO_CLOCK_H__ #define __GST_AUDIO_CLOCK_H__ #include <gst/gstsystemclock.h> G_BEGIN_DECLS #define GST_TYPE_AUDIO_CLOCK \ (gst_audio_clock_get_type()) #define GST_AUDIO_CLOCK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_CLOCK,GstAudioClock)) #define GST_AUDIO_CLOCK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_CLOCK,GstAudioClockClass)) #define GST_IS_AUDIO_CLOCK(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_CLOCK)) #define GST_IS_AUDIO_CLOCK_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_CLOCK)) typedef struct _GstAudioClock GstAudioClock; typedef struct _GstAudioClockClass GstAudioClockClass; typedef GstClockTime (*GstAudioClockGetTimeFunc) (GstClock *clock, gpointer user_data); struct _GstAudioClock { GstSystemClock clock; /* --- protected --- */ GstAudioClockGetTimeFunc func; gpointer user_data; gpointer _gst_reserved[GST_PADDING]; }; struct _GstAudioClockClass { GstSystemClockClass parent_class; GType gst_audio_clock_get_type (void); GstClock* gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func, gpointer user_data); G_END_DECLS #endif /* __GST_AUDIO_CLOCK_H__ */ Index: gstaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- gstaudiosink.c 20 Apr 2005 10:19:54 -0000 1.1 +++ gstaudiosink.c 28 Apr 2005 16:15:42 -0000 1.2 @@ -125,6 +125,7 @@ gstringbuffer_class->release = GST_DEBUG_FUNCPTR (gst_audioringbuffer_release); gstringbuffer_class->play = GST_DEBUG_FUNCPTR (gst_audioringbuffer_play); + gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_play); gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop); gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_audioringbuffer_delay); @@ -144,7 +145,6 @@ GstAudioSinkClass *csink; GstAudioRingBuffer *abuf = GST_AUDIORINGBUFFER (buf); WriteFunc writefunc; - gint segsize, segtotal; sink = GST_AUDIOSINK (GST_OBJECT_PARENT (buf)); csink = GST_AUDIOSINK_GET_CLASS (sink); @@ -155,53 +155,48 @@ if (writefunc == NULL) goto no_function; - segsize = buf->spec.segsize; - segtotal = buf->spec.segtotal; while (TRUE) { - if (g_atomic_int_get (&buf->state) == GST_RINGBUFFER_STATE_PLAYING) { - gint to_write, written; - guint8 *readptr; - gint readseg; + gint left, len; + guint8 *readptr; + gint readseg; - /* we write one segment */ - to_write = segsize; - written = 0; - /* need to read and write the next segment */ - readseg = (buf->playseg + 1) % segtotal; - /* get a pointer in the buffer to this segment */ - readptr = gst_ringbuffer_prepare_read (buf, readseg); + if (gst_ringbuffer_prepare_read (buf, &readseg, &readptr, &len)) { + gint written = 0; + left = len; do { - written = writefunc (sink, readptr + written, to_write); - if (written < 0 || written > to_write) { - perror ("error writing data\n"); + GST_DEBUG ("transfer %d bytes from segment %d", left, readseg); + written = writefunc (sink, readptr + written, left); + GST_DEBUG ("transfered %d bytes", written); + if (written < 0 || written > left) { + GST_WARNING ("error writing data (reason: %s), skipping segment\n", + strerror (errno)); break; } - to_write -= written; - } while (to_write > 0); + left -= written; + } while (left > 0); /* clear written samples */ gst_ringbuffer_clear (buf, readseg); /* we wrote one segment */ - gst_ringbuffer_callback (buf, 1); + gst_ringbuffer_advance (buf, 1); } else { GST_LOCK (abuf); GST_DEBUG ("signal wait"); GST_AUDIORINGBUFFER_SIGNAL (buf); - GST_DEBUG ("wait for play"); + GST_DEBUG ("wait for action"); GST_AUDIORINGBUFFER_WAIT (buf); GST_DEBUG ("got signal"); if (!abuf->running) { GST_UNLOCK (abuf); GST_DEBUG ("stop running"); - goto done; + break; } + GST_DEBUG ("continue running"); GST_UNLOCK (abuf); } } -done: GST_DEBUG ("exit thread"); return; @@ -305,7 +300,7 @@ - GST_DEBUG ("play"); + GST_DEBUG ("play, sending signal"); GST_AUDIORINGBUFFER_SIGNAL (buf); return TRUE; @@ -321,11 +316,15 @@ /* unblock any pending writes to the audio device */ - if (csink->reset) + if (csink->reset) { + GST_DEBUG ("reset..."); csink->reset (sink); + GST_DEBUG ("reset done"); + } - GST_DEBUG ("stop"); + GST_DEBUG ("stop, waiting..."); GST_AUDIORINGBUFFER_WAIT (buf); + GST_DEBUG ("stoped"); } @@ -398,7 +397,9 @@ { GstRingBuffer *buffer; + GST_DEBUG ("creating ringbuffer"); buffer = g_object_new (GST_TYPE_AUDIORINGBUFFER, NULL); + GST_DEBUG ("created ringbuffer @%p", buffer); return buffer; Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v --- gstbaseaudiosink.c 20 Apr 2005 10:19:54 -0000 1.1 +++ gstbaseaudiosink.c 28 Apr 2005 16:15:42 -0000 1.2 @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include <string.h> #include "gstbaseaudiosink.h" GST_DEBUG_CATEGORY_STATIC (gst_baseaudiosink_debug); @@ -32,13 +34,13 @@ LAST_SIGNAL }; -#define DEFAULT_BUFFER -1 -#define DEFAULT_LATENCY -1 +#define DEFAULT_BUFFER_TIME 500 * GST_USECOND +#define DEFAULT_LATENCY_TIME 10 * GST_USECOND enum PROP_0, - PROP_BUFFER, - PROP_LATENCY, + PROP_BUFFER_TIME, + PROP_LATENCY_TIME, #define _do_init(bla) \ @@ -55,6 +57,10 @@ static GstElementStateReturn gst_baseaudiosink_change_state (GstElement * element); +static GstClock *gst_baseaudiosink_get_clock (GstElement * elem); +static GstClockTime gst_baseaudiosink_get_time (GstClock * clock, + GstBaseAudioSink * sink); static GstFlowReturn gst_baseaudiosink_preroll (GstBaseSink * bsink, GstBuffer * buffer); static GstFlowReturn gst_baseaudiosink_render (GstBaseSink * bsink, @@ -87,17 +93,18 @@ gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_baseaudiosink_get_property); - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER, - g_param_spec_uint64 ("buffer", "Buffer", - "Size of audio buffer in nanoseconds (-1 = default)", - 0, G_MAXUINT64, DEFAULT_BUFFER, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LATENCY, - g_param_spec_uint64 ("latency", "Latency", - "Audio latency in nanoseconds (-1 = default)", - 0, G_MAXUINT64, DEFAULT_LATENCY, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER_TIME, + g_param_spec_int64 ("buffer-time", "Buffer Time", + "Size of audio buffer in milliseconds (-1 = default)", + -1, G_MAXINT64, DEFAULT_BUFFER_TIME, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LATENCY_TIME, + g_param_spec_int64 ("latency-time", "Latency Time", + "Audio latency in milliseconds (-1 = default)", + -1, G_MAXINT64, DEFAULT_LATENCY_TIME, G_PARAM_READWRITE)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_baseaudiosink_change_state); + gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_baseaudiosink_get_clock); gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_baseaudiosink_event); gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_baseaudiosink_preroll); @@ -110,8 +117,38 @@ static void gst_baseaudiosink_init (GstBaseAudioSink * baseaudiosink) - baseaudiosink->buffer = DEFAULT_BUFFER; - baseaudiosink->latency = DEFAULT_LATENCY; + baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME; + baseaudiosink->latency_time = DEFAULT_LATENCY_TIME; + baseaudiosink->clock = gst_audio_clock_new ("clock", + (GstAudioClockGetTimeFunc) gst_baseaudiosink_get_time, baseaudiosink); +} +static GstClock * +gst_baseaudiosink_get_clock (GstElement * elem) +{ + GstBaseAudioSink *sink; + sink = GST_BASEAUDIOSINK (elem); + return GST_CLOCK (gst_object_ref (GST_OBJECT (sink->clock))); +static GstClockTime +gst_baseaudiosink_get_time (GstClock * clock, GstBaseAudioSink * sink) + guint64 samples; + GstClockTime result; + if (sink->ringbuffer == NULL || sink->ringbuffer->spec.rate == 0) + return 0; + samples = gst_ringbuffer_played_samples (sink->ringbuffer); + result = samples * GST_SECOND / sink->ringbuffer->spec.rate; + result += GST_ELEMENT (sink)->base_time; + return result; @@ -123,9 +160,11 @@ sink = GST_BASEAUDIOSINK (object); switch (prop_id) { - case PROP_BUFFER: + case PROP_BUFFER_TIME: + sink->buffer_time = g_value_get_int64 (value); break; - case PROP_LATENCY: + case PROP_LATENCY_TIME: + sink->latency_time = g_value_get_int64 (value); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -142,9 +181,11 @@ + g_value_set_int64 (value, sink->buffer_time); + g_value_set_int64 (value, sink->latency_time); @@ -152,25 +193,228 @@ +static int linear_formats[4 * 2 * 2] = { + GST_S8, + GST_U8, + GST_S16_LE, + GST_S16_BE, + GST_U16_LE, + GST_U16_BE, + GST_S24_LE, + GST_S24_BE, + GST_U24_LE, + GST_U24_BE, + GST_S32_LE, + GST_S32_BE, + GST_U32_LE, + GST_U32_BE +}; +static int linear24_formats[3 * 2 * 2] = { + GST_S24_3LE, + GST_S24_3BE, + GST_U24_3LE, + GST_U24_3BE, + GST_S20_3LE, + GST_S20_3BE, + GST_U20_3LE, + GST_U20_3BE, + GST_S18_3LE, + GST_S18_3BE, + GST_U18_3LE, + GST_U18_3BE, +static GstBufferFormat +build_linear_format (int depth, int width, int unsignd, int big_endian) + if (width == 24) { + switch (depth) { + case 24: + depth = 0; + case 20: + depth = 1; + case 18: + depth = 2; + default: + return GST_UNKNOWN; + } + return ((int (*)[2][2]) linear24_formats)[depth][!!unsignd][!!big_endian]; + } else { + case 8: + case 16: + case 32: + depth = 3; + return ((int (*)[2][2]) linear_formats)[depth][!!unsignd][!!big_endian]; +static void +debug_spec_caps (GstBaseAudioSink * sink, GstRingBufferSpec * spec) + GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps); + GST_DEBUG ("parsed caps: type: %d", spec->type); + GST_DEBUG ("parsed caps: format: %d", spec->format); + GST_DEBUG ("parsed caps: width: %d", spec->width); + GST_DEBUG ("parsed caps: depth: %d", spec->depth); + GST_DEBUG ("parsed caps: sign: %d", spec->sign); + GST_DEBUG ("parsed caps: bigend: %d", spec->bigend); + GST_DEBUG ("parsed caps: rate: %d", spec->rate); + GST_DEBUG ("parsed caps: channels: %d", spec->channels); + GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample); +debug_spec_buffer (GstBaseAudioSink * sink, GstRingBufferSpec * spec) + GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec", + spec->buffer_time); + GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec", + spec->latency_time); + GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal); + GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples", + spec->segsize, spec->segsize / spec->bytes_per_sample); + GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples", + spec->segsize * spec->segtotal, + spec->segsize * spec->segtotal / spec->bytes_per_sample); static gboolean gst_baseaudiosink_setcaps (GstBaseSink * bsink, GstCaps * caps) GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink); GstRingBufferSpec *spec; + const gchar *mimetype; + GstStructure *structure; spec = &sink->ringbuffer->spec; + structure = gst_caps_get_structure (caps, 0); + /* we have to differentiate between int and float formats */ + mimetype = gst_structure_get_name (structure); + if (!strncmp (mimetype, "audio/x-raw-int", 15)) { + gint endianness; + spec->type = GST_BUFTYPE_LINEAR; + /* extract the needed information from the cap */ + if (!(gst_structure_get_int (structure, "width", &spec->width) && + gst_structure_get_int (structure, "depth", &spec->depth) && + gst_structure_get_boolean (structure, "signed", &spec->sign))) + goto parse_error; + /* extract endianness if needed */ + if (spec->width > 8) { + if (!gst_structure_get_int (structure, "endianness", &endianness)) + goto parse_error; + } else { + endianness = G_BYTE_ORDER; + spec->bigend = endianness == G_LITTLE_ENDIAN ? FALSE : TRUE; + spec->format = + build_linear_format (spec->depth, spec->width, spec->sign ? 0 : 1, + spec->bigend ? 1 : 0); + } else if (!strncmp (mimetype, "audio/x-raw-float", 17)) { + spec->type = GST_BUFTYPE_FLOAT; + /* get layout */ + if (!gst_structure_get_int (structure, "width", &spec->width)) + /* match layout to format wrt to endianness */ + switch (spec->width) { + spec->format = + G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT32_LE : GST_FLOAT32_BE; + case 64: + G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT64_LE : GST_FLOAT64_BE; + } else if (!strncmp (mimetype, "audio/x-alaw", 12)) { + spec->type = GST_BUFTYPE_A_LAW; + spec->format = GST_A_LAW; + } else if (!strncmp (mimetype, "audio/x-mulaw", 13)) { + spec->type = GST_BUFTYPE_MU_LAW; + spec->format = GST_MU_LAW; + goto parse_error; + /* get rate and channels */ + if (!(gst_structure_get_int (structure, "rate", &spec->rate) && + gst_structure_get_int (structure, "channels", &spec->channels))) + spec->bytes_per_sample = (spec->width >> 3) * spec->channels; gst_caps_replace (&spec->caps, caps); - spec->buffersize = sink->buffer; - spec->latency = sink->latency; - spec->segtotal = 0x7fff; - spec->segsize = 0x2048; + debug_spec_caps (sink, spec); + spec->buffer_time = sink->buffer_time; + spec->latency_time = sink->latency_time; + /* calculate suggested segsize and segtotal */ + spec->segsize = + spec->rate * spec->bytes_per_sample * spec->latency_time / GST_MSECOND; + spec->segtotal = spec->buffer_time / spec->latency_time; + GST_DEBUG ("release old ringbuffer"); gst_ringbuffer_release (sink->ringbuffer); - gst_ringbuffer_acquire (sink->ringbuffer, spec); + debug_spec_buffer (sink, spec); + if (!gst_ringbuffer_acquire (sink->ringbuffer, spec)) + goto acquire_error; + /* calculate actual latency and buffer times */ + spec->latency_time = + spec->segsize * GST_MSECOND / (spec->rate * spec->bytes_per_sample); + spec->buffer_time = + spec->segtotal * spec->segsize * GST_MSECOND / (spec->rate * + spec->bytes_per_sample); + /* ERRORS */ +parse_error: + { + return FALSE; +acquire_error: @@ -184,6 +428,36 @@ gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event) + GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + if (GST_EVENT_FLUSH_DONE (event)) { + } else { + gst_ringbuffer_pause (sink->ringbuffer); + } + break; + case GST_EVENT_DISCONTINUOUS: + { + guint64 time, sample; + if (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &sample, + NULL)) + goto have_value; + if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time, NULL)) { + sample = time * sink->ringbuffer->spec.rate / GST_SECOND; + g_warning ("discont without valid timestamp"); + sample = 0; + have_value: + gst_ringbuffer_set_sample (sink->ringbuffer, sample); + default: static GstFlowReturn @@ -195,9 +469,14 @@ gst_baseaudiosink_render (GstBaseSink * bsink, GstBuffer * buf) + guint64 offset; - gst_ringbuffer_commit (sink->ringbuffer, 0, + offset = GST_BUFFER_OFFSET (buf); + GST_DEBUG ("in offset %llu, time %lld", offset, GST_BUFFER_TIMESTAMP (buf)); + gst_ringbuffer_commit (sink->ringbuffer, offset, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); return GST_FLOW_OK; @@ -221,7 +500,8 @@ void -gst_baseaudiosink_callback (GstRingBuffer * rbuf, guint advance, gpointer data) +gst_baseaudiosink_callback (GstRingBuffer * rbuf, guint8 * data, guint len, + gpointer user_data) //GstBaseAudioSink *sink = GST_BASEAUDIOSINK (data); @@ -251,9 +531,14 @@ switch (transition) { case GST_STATE_PLAYING_TO_PAUSED: - gst_ringbuffer_stop (sink->ringbuffer); + gst_ringbuffer_pause (sink->ringbuffer); + /* + while (gst_ringbuffer_delay (sink->ringbuffer) > 0) + g_usleep (100); + */ case GST_STATE_PAUSED_TO_READY: + gst_ringbuffer_stop (sink->ringbuffer); gst_ringbuffer_release (sink->ringbuffer); gst_object_unref (GST_OBJECT (sink->ringbuffer)); Index: gstbaseaudiosink.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h,v --- gstbaseaudiosink.h 20 Apr 2005 10:19:54 -0000 1.1 +++ gstbaseaudiosink.h 28 Apr 2005 16:15:42 -0000 1.2 @@ -52,6 +52,7 @@ #include <gst/base/gstbasesink.h> #include "gstringbuffer.h" +#include "gstaudioclock.h" G_BEGIN_DECLS @@ -75,8 +76,11 @@ GstRingBuffer *ringbuffer; /* required buffer and latency */ - GstClockTime buffer; - GstClockTime latency; + GstClockTime buffer_time; + GstClockTime latency_time; + /* clock */ + GstClock *clock; struct _GstBaseAudioSinkClass { Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v --- gstringbuffer.c 20 Apr 2005 10:19:54 -0000 1.1 +++ gstringbuffer.c 28 Apr 2005 16:15:42 -0000 1.2 @@ -23,6 +23,9 @@ +GST_DEBUG_CATEGORY_STATIC (gst_ringbuffer_debug); +#define GST_CAT_DEFAULT gst_ringbuffer_debug static void gst_ringbuffer_class_init (GstRingBufferClass * klass); static void gst_ringbuffer_init (GstRingBuffer * ringbuffer); static void gst_ringbuffer_dispose (GObject * object); @@ -52,6 +55,9 @@ ringbuffer_type = g_type_register_static (GST_TYPE_OBJECT, "GstRingBuffer", &ringbuffer_info, G_TYPE_FLAG_ABSTRACT); + GST_DEBUG_CATEGORY_INIT (gst_ringbuffer_debug, "ringbuffer", 0, + "ringbuffer class"); return ringbuffer_type; @@ -76,12 +82,9 @@ ringbuffer->acquired = FALSE; ringbuffer->state = GST_RINGBUFFER_STATE_STOPPED; - ringbuffer->playseg = -1; - ringbuffer->writeseg = -1; - ringbuffer->segfilled = 0; - ringbuffer->freeseg = -1; - ringbuffer->segplayed = 0; ringbuffer->cond = g_cond_new (); + ringbuffer->waiting = 0; + ringbuffer->empty_seg = NULL; @@ -98,6 +101,7 @@ GstRingBuffer *ringbuffer = GST_RINGBUFFER (object); g_cond_free (ringbuffer->cond); + g_free (ringbuffer->empty_seg); G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (ringbuffer)); @@ -117,6 +121,8 @@ gst_ringbuffer_set_callback (GstRingBuffer * buf, GstRingBufferCallback cb, gpointer data) + g_return_if_fail (buf != NULL); GST_LOCK (buf); buf->callback = cb; buf->cb_data = data; @@ -142,6 +148,8 @@ gboolean res = FALSE; GstRingBufferClass *rclass; + g_return_val_if_fail (buf != NULL, FALSE); if (buf->acquired) { res = TRUE; @@ -156,12 +164,25 @@ if (!res) { buf->acquired = FALSE; } else { - buf->freeseg = spec->segtotal; if (buf->spec.bytes_per_sample != 0) { + gint i, j; buf->samples_per_seg = buf->spec.segsize / buf->spec.bytes_per_sample; + /* create an empty segment */ + g_free (buf->empty_seg); + buf->empty_seg = g_malloc (buf->spec.segsize); + for (i = 0, j = 0; i < buf->spec.segsize; i++) { + buf->empty_seg[i] = buf->spec.silence_sample[j]; + j = (j + 1) % buf->spec.bytes_per_sample; + /* set sample position to 0 */ + gst_ringbuffer_set_sample (buf, 0); - g_warning ("invalid bytes_per_sample from acquire ringbuffer"); - buf->samples_per_seg = buf->spec.segsize; + g_warning + ("invalid bytes_per_sample from acquire ringbuffer, fix the element"); + buf->acquired = FALSE; + res = FALSE; done: @@ -186,6 +207,8 @@ gst_ringbuffer_stop (buf); @@ -201,6 +224,9 @@ buf->acquired = TRUE; + g_free (buf->empty_seg); + buf->empty_seg = NULL; @@ -209,33 +235,6 @@ return res; -static gboolean -gst_ringbuffer_play_unlocked (GstRingBuffer * buf) -{ - gboolean res = FALSE; - GstRingBufferClass *rclass; - /* if paused, set to playing */ - res = g_atomic_int_compare_and_exchange (&buf->state, - GST_RINGBUFFER_STATE_STOPPED, GST_RINGBUFFER_STATE_PLAYING); - if (!res) { - /* was not stopped */ - res = TRUE; - goto done; - } - rclass = GST_RINGBUFFER_GET_CLASS (buf); - if (rclass->play) - res = rclass->play (buf); - buf->state = GST_RINGBUFFER_STATE_PAUSED; - return res; -} /** * gst_ringbuffer_play: * @buf: the #GstRingBuffer to play @@ -250,51 +249,41 @@ gst_ringbuffer_play (GstRingBuffer * buf) - GST_LOCK (buf); - res = gst_ringbuffer_play_unlocked (buf); - GST_UNLOCK (buf); -/** - * gst_ringbuffer_pause: - * @buf: the #GstRingBuffer to pause - * - * Pause playing samples from the ringbuffer. - * Returns: TRUE if the device could be paused, FALSE on error. - * MT safe. - */ -gboolean -gst_ringbuffer_pause (GstRingBuffer * buf) + gboolean resume = FALSE; - /* if playing, set to paused */ + /* if paused, set to playing */ res = g_atomic_int_compare_and_exchange (&buf->state, - GST_RINGBUFFER_STATE_PLAYING, GST_RINGBUFFER_STATE_PAUSED); + GST_RINGBUFFER_STATE_STOPPED, GST_RINGBUFFER_STATE_PLAYING); - /* was not playing */ + /* was not stopped, try from paused */ + res = g_atomic_int_compare_and_exchange (&buf->state, + GST_RINGBUFFER_STATE_PAUSED, GST_RINGBUFFER_STATE_PLAYING); + if (!res) { + /* was not paused either, must be playing then */ + res = TRUE; + goto done; + resume = TRUE; - /* signal any waiters */ - GST_RINGBUFFER_SIGNAL (buf); rclass = GST_RINGBUFFER_GET_CLASS (buf); - if (rclass->pause) - res = rclass->pause (buf); + if (resume) { + if (rclass->resume) + res = rclass->resume (buf); + if (rclass->play) + res = rclass->play (buf); - buf->state = GST_RINGBUFFER_STATE_PLAYING; + buf->state = GST_RINGBUFFER_STATE_PAUSED; GST_UNLOCK (buf); @@ -302,28 +291,30 @@ - * gst_ringbuffer_resume: - * @buf: the #GstRingBuffer to resume + * gst_ringbuffer_pause: + * @buf: the #GstRingBuffer to pause * - * Resume playing samples from the ringbuffer in the paused state. + * Pause playing samples from the ringbuffer. * Returns: TRUE if the device could be paused, FALSE on error. * MT safe. gboolean -gst_ringbuffer_resume (GstRingBuffer * buf) +gst_ringbuffer_pause (GstRingBuffer * buf) /* if playing, set to paused */ - GST_RINGBUFFER_STATE_PAUSED, GST_RINGBUFFER_STATE_PLAYING); + GST_RINGBUFFER_STATE_PLAYING, GST_RINGBUFFER_STATE_PAUSED); - /* was not paused */ + /* was not playing */ goto done; @@ -332,11 +323,11 @@ GST_RINGBUFFER_SIGNAL (buf); - if (rclass->resume) - res = rclass->resume (buf); + if (rclass->pause) + res = rclass->pause (buf); + buf->state = GST_RINGBUFFER_STATE_PLAYING; @@ -344,7 +335,6 @@ * gst_ringbuffer_stop: * @buf: the #GstRingBuffer to stop @@ -361,6 +351,8 @@ /* if playing, set to stopped */ @@ -382,11 +374,7 @@ buf->state = GST_RINGBUFFER_STATE_PLAYING; - buf->segfilled = 0; - buf->playseg = -1; - buf->writeseg = -1; - buf->freeseg = buf->spec.segtotal; - buf->segplayed = 0; + gst_ringbuffer_set_sample (buf, 0); @@ -395,55 +383,6 @@ - * gst_ringbuffer_callback: - * @buf: the #GstRingBuffer to callback - * @advance: the number of segments written - * Subclasses should call this function to notify the fact that - * @advance segments are now played by the device. -void -gst_ringbuffer_callback (GstRingBuffer * buf, guint advance) - gint prevfree; - gint segtotal; - if (advance == 0) - return; - /* update counter */ - g_atomic_int_add (&buf->segplayed, advance); - /* update free segments counter */ - prevfree = g_atomic_int_exchange_and_add (&buf->freeseg, advance); - if (prevfree + advance > segtotal) { - g_warning ("underrun!! read %d, write %d, advance %d, free %d, prevfree %d", - buf->playseg, buf->writeseg, advance, buf->freeseg, prevfree); - buf->freeseg = segtotal; - buf->writeseg = buf->playseg; - /* make sure to signal */ - prevfree = -1; - buf->playseg = (buf->playseg + advance) % segtotal; - if (prevfree == -1) { - /* we need to take the lock to make sure the other thread is - * blocking in the wait */ - GST_LOCK (buf); - GST_RINGBUFFER_SIGNAL (buf); - GST_UNLOCK (buf); - if (buf->callback) - buf->callback (buf, advance, buf->cb_data); * gst_ringbuffer_delay: * @buf: the #GstRingBuffer to query @@ -462,6 +401,8 @@ guint res = 0; + g_return_val_if_fail (buf != NULL, 0); if (rclass->delay) res = rclass->delay (buf); @@ -484,20 +425,101 @@ gst_ringbuffer_played_samples (GstRingBuffer * buf) gint segplayed; - guint64 samples; + guint64 raw, samples; guint delay; /* get the amount of segments we played */ segplayed = g_atomic_int_get (&buf->segplayed); /* and the number of samples not yet played */ delay = gst_ringbuffer_delay (buf); - samples = (segplayed * buf->samples_per_seg) - delay; + samples = (segplayed * buf->samples_per_seg); + raw = samples; + if (samples >= delay) + samples -= delay; + GST_DEBUG ("played samples: raw %llu, delay %u, real %llu", raw, delay, + samples); return samples; + * gst_ringbuffer_set_sample: + * @buf: the #GstRingBuffer to use + * @sample: the sample number to set + * + * Make sure that the next sample written to the device is + * accounted for as being the @sample sample written to the + * device. This value will be used in reporting the current + * sample position of the ringbuffer. + * This function will also clear the buffer with silence. + * MT safe. + */ +void +gst_ringbuffer_set_sample (GstRingBuffer * buf, guint64 sample) + gint i; + if (sample == -1) + sample = 0; + /* FIXME, we assume the ringbuffer can restart at a random + * position, round down to the beginning and keep track of + * offset when calculating the played samples. */ + buf->segplayed = sample / buf->samples_per_seg; + buf->next_sample = sample; + for (i = 0; i < buf->spec.segtotal; i++) { + gst_ringbuffer_clear (buf, i); + GST_DEBUG ("setting sample to %llu, segplayed %d", sample, buf->segplayed); +static gboolean +wait_segment (GstRingBuffer * buf) + /* buffer must be playing now or we deadlock since nobody is reading */ + if (g_atomic_int_get (&buf->state) != GST_RINGBUFFER_STATE_PLAYING) { + GST_DEBUG ("play!"); + gst_ringbuffer_play (buf); + /* take lock first, then update our waiting flag */ + GST_LOCK (buf); + if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) { + GST_DEBUG ("waiting.."); + if (g_atomic_int_get (&buf->state) != GST_RINGBUFFER_STATE_PLAYING) + goto not_playing; + GST_RINGBUFFER_WAIT (buf); + GST_UNLOCK (buf); + return TRUE; + /* ERROR */ +not_playing: + GST_UNLOCK (buf); + GST_DEBUG ("stopped playing"); +/** * gst_ringbuffer_commit: * @buf: the #GstRingBuffer to commit * @sample: the sample position of the data @@ -511,106 +533,106 @@ * @len should not be a multiple of the segment size of the ringbuffer * although it is recommended. - * Returns: The number of samples written to the ringbuffer. + * Returns: The number of samples written to the ringbuffer or -1 on + * error. -/* FIXME, write the samples into the right position in the ringbuffer based - * on the sample position argument guint gst_ringbuffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data, guint len) - guint towrite = len; + gint segplayed; + gint segsize, segtotal, bps, sps; guint8 *dest; - if (buf->data == NULL) - goto no_buffer; + g_return_val_if_fail (buf != NULL, -1); + g_return_val_if_fail (buf->data != NULL, -1); + g_return_val_if_fail (data != NULL, -1); + if (sample == -1) { + /* play aligned with last sample */ + sample = buf->next_sample; + if (sample != buf->next_sample) { + GST_WARNING ("discontinuity found got %" G_GUINT64_FORMAT + ", expected %" G_GUINT64_FORMAT, sample, buf->next_sample); dest = GST_BUFFER_DATA (buf->data); segsize = buf->spec.segsize; segtotal = buf->spec.segtotal; + bps = buf->spec.bytes_per_sample; + sps = buf->samples_per_seg; - /* we write the complete buffer in chunks of segsize so that we can check for - * a filled buffer after each segment. */ - while (towrite > 0) { - gint segavail; - gint segwrite; - gint writeseg; - gint segfilled; + /* we assume the complete buffer will be consumed and the next sample + * should be written after this */ + buf->next_sample = sample + len / bps; - segfilled = buf->segfilled; + /* write out all bytes */ + while (len > 0) { + gint writelen; + gint writeseg, writeoff; - /* check for partial buffer */ - if (G_LIKELY (segfilled == 0)) { - gint prevfree; - gint newseg; + /* figure out the segment and the offset inside the segment where + * the sample should be written. */ + writeseg = sample / sps; + writeoff = (sample % sps) * bps; - /* no partial buffer to fill up, allocate a new one */ - prevfree = g_atomic_int_exchange_and_add (&buf->freeseg, -1); - if (prevfree == 0) { - /* nothing was free */ - GST_DEBUG ("filled %d %d", buf->writeseg, buf->playseg); + while (TRUE) { + gint diff; - GST_LOCK (buf); - /* buffer must be playing now or we deadlock since nobody is reading */ - if (g_atomic_int_get (&buf->state) != GST_RINGBUFFER_STATE_PLAYING) - gst_ringbuffer_play_unlocked (buf); + /* get the currently playing segment */ + segplayed = g_atomic_int_get (&buf->segplayed); - GST_RINGBUFFER_WAIT (buf); - goto not_playing; - GST_UNLOCK (buf); + /* see how far away it is from the write segment */ + diff = writeseg - segplayed; + GST_DEBUG + ("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d", + segplayed, sample, writeseg, writeoff, len, diff, segtotal, segsize); + /* play segment too far ahead, we need to drop */ + if (diff < 0) { + /* we need to drop one segment at a time, pretend we wrote a + * segment. */ + writelen = MIN (segsize, len); + goto next; - /* need to do this atomic as the reader updates the write pointer on - * overruns */ - do { - writeseg = g_atomic_int_get (&buf->writeseg); - newseg = (writeseg + 1) % segtotal; - } while (!g_atomic_int_compare_and_exchange (&buf->writeseg, writeseg, - newseg)); - writeseg = newseg; - } else { - /* this is the segment we should write to */ - writeseg = g_atomic_int_get (&buf->writeseg); - } - if (writeseg < 0 || writeseg > segtotal) { - g_warning ("invalid segment %d", writeseg); - writeseg = 0; + /* write segment is within writable range, we can break the loop and + * start writing the data. */ + if (diff < segtotal) - /* this is the available size now in the current segment */ - segavail = segsize - segfilled; + /* else we need to wait for the segment to become writable. */ + if (!wait_segment (buf)) + goto not_playing; - /* we write up to the available space */ - segwrite = MIN (segavail, towrite); + /* we can write now */ + writeseg = writeseg % segtotal; + writelen = MIN (segsize - writeoff, len); - memcpy (dest + writeseg * segsize + segfilled, data, segwrite); + GST_DEBUG ("write @%p seg %d, off %d, len %d", + dest + writeseg * segsize, writeseg, writeoff, writelen); - towrite -= segwrite; - data += segwrite; + memcpy (dest + writeseg * segsize + writeoff, data, writelen); - if (segfilled + segwrite == segsize) { - buf->segfilled = 0; - buf->segfilled = segfilled + segwrite; + next: + len -= writelen; + data += writelen; + sample += writelen / bps; - return len - towrite; -no_buffer: - { - GST_DEBUG ("no buffer"); - return -1; + return len; not_playing: { GST_DEBUG ("stopped playing"); - return len - towrite; + return -1; @@ -618,20 +640,78 @@ * gst_ringbuffer_prepare_read: * @buf: the #GstRingBuffer to read from * @segment: the segment to read + * @readptr: the pointer to the memory where samples can be read + * @len: the number of bytes to read * Returns a pointer to memory where the data from segment @segment - * can be found. + * can be found. This function is used by subclasses. + * Returns: FALSE if the buffer is not playing. -guint8 * -gst_ringbuffer_prepare_read (GstRingBuffer * buf, gint segment) +gboolean +gst_ringbuffer_prepare_read (GstRingBuffer * buf, gint * segment, + guint8 ** readptr, gint * len) guint8 *data; + /* buffer must be playing */ + if (g_atomic_int_get (&buf->state) != GST_RINGBUFFER_STATE_PLAYING) + g_return_val_if_fail (buf->data != NULL, FALSE); + g_return_val_if_fail (readptr != NULL, FALSE); + g_return_val_if_fail (len != NULL, FALSE); data = GST_BUFFER_DATA (buf->data); - return data + (segment % buf->spec.segtotal) * buf->spec.segsize; + /* get the position of the play pointer */ + segplayed = g_atomic_int_get (&buf->segplayed); + *segment = segplayed % buf->spec.segtotal; + *len = buf->spec.segsize; + *readptr = data + *segment * *len; + /* callback to fill the memory with data */ + if (buf->callback) + buf->callback (buf, *readptr, *len, buf->cb_data); + GST_DEBUG ("prepare read from segment %d (real %d) @%p", + *segment, segplayed, *readptr); + * gst_ringbuffer_advance: + * @buf: the #GstRingBuffer to advance + * @advance: the number of segments written + * Subclasses should call this function to notify the fact that + * @advance segments are now played by the device. +gst_ringbuffer_advance (GstRingBuffer * buf, guint advance) + /* update counter */ + g_atomic_int_add (&buf->segplayed, advance); + /* the lock is already taken when the waiting flag is set, + * we grab the lock as well to make sure the waiter is actually + * waiting for the signal */ + if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) { + GST_LOCK (buf); + GST_DEBUG ("signal waiter"); + GST_RINGBUFFER_SIGNAL (buf); @@ -649,8 +729,13 @@ + g_return_if_fail (buf->data != NULL); + g_return_if_fail (buf->empty_seg != NULL); + data += (segment % buf->spec.segtotal) * buf->spec.segsize, + GST_DEBUG ("clear segment %d @%p", segment, data); - memset (data + (segment % buf->spec.segtotal) * buf->spec.segsize, 0, - buf->spec.segsize); + memcpy (data, buf->empty_seg, buf->spec.segsize); Index: gstringbuffer.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h,v --- gstringbuffer.h 20 Apr 2005 10:19:54 -0000 1.1 +++ gstringbuffer.h 28 Apr 2005 16:15:42 -0000 1.2 @@ -38,7 +38,8 @@ typedef struct _GstRingBufferClass GstRingBufferClass; typedef struct _GstRingBufferSpec GstRingBufferSpec; -typedef void (*GstRingBufferCallback) (GstRingBuffer *rbuf, guint advance, gpointer data); +/* called to fill data with len bytes of samples */ +typedef void (*GstRingBufferCallback) (GstRingBuffer *rbuf, guint8* data, guint len, gpointer user_data); typedef enum { GST_RINGBUFFER_STATE_STOPPED, @@ -55,21 +56,64 @@ typedef enum - GST_U8, + GST_BUFTYPE_LINEAR, + GST_BUFTYPE_FLOAT, + GST_BUFTYPE_MU_LAW, + GST_BUFTYPE_A_LAW, + GST_BUFTYPE_IMA_ADPCM, + GST_BUFTYPE_MPEG, + GST_BUFTYPE_GSM, +} GstBufferFormatType; +typedef enum + GST_UNKNOWN, GST_S8, - GST_U16_LE, GST_S16_LE, - GST_U16_BE, GST_S16_BE, - GST_U24_LE, GST_S24_LE, - GST_U24_BE, GST_S24_BE, + GST_U32_BE, + GST_FLOAT32_LE, + GST_FLOAT32_BE, + GST_FLOAT64_LE, + GST_FLOAT64_BE, + GST_MU_LAW, + GST_A_LAW, + GST_IMA_ADPCM, + GST_MPEG, + GST_GSM, + /* fill me */ - GST_FLOAT_LE, - GST_FLOAT_BE, } GstBufferFormat; struct _GstRingBufferSpec @@ -78,12 +122,17 @@ GstCaps *caps; /* the caps of the buffer */ /* in/out */ + GstBufferFormatType type; GstBufferFormat format; + gboolean sign; + gboolean bigend; + gint width; + gint depth; gint rate; gint channels; - GstClockTime latency; /* the required/actual latency */ - GstClockTime buffersize; /* the required/actual size of the buffer */ + GstClockTime latency_time; /* the required/actual latency time */ + GstClockTime buffer_time; /* the required/actual time of the buffer */ gint segsize; /* size of one buffer segement */ gint segtotal; /* total number of segments */ @@ -107,18 +156,15 @@ GstRingBufferSpec spec; GstRingBufferSegState *segstate; gint samples_per_seg; /* number of samples per segment */ + guint8 *empty_seg; /*< public >*/ /* ATOMIC */ gint state; /* state of the buffer */ - gint freeseg; /* number of free segments */ gint segplayed; /* number of segments played since last start */ - /*< protected >*/ - gint playseg; /* segment currently playing */ - gint writeseg; /* segment currently written */ - gint segfilled; /* bytes used in current write segment */ + gint waiting; /* when waiting for a segment to be freed */ /*< private >*/ + guint64 next_sample; /* the next sample we need to write */ GstRingBufferCallback callback; gpointer cb_data; @@ -146,8 +192,7 @@ /* callback stuff */ void gst_ringbuffer_set_callback (GstRingBuffer *buf, GstRingBufferCallback cb, - gpointer data); -void gst_ringbuffer_callback (GstRingBuffer *buf, guint advance); + gpointer user_data); /* allocate resources */ gboolean gst_ringbuffer_acquire (GstRingBuffer *buf, GstRingBufferSpec *spec); @@ -156,20 +201,22 @@ /* playback/pause */ gboolean gst_ringbuffer_play (GstRingBuffer *buf); gboolean gst_ringbuffer_pause (GstRingBuffer *buf); -gboolean gst_ringbuffer_resume (GstRingBuffer *buf); gboolean gst_ringbuffer_stop (GstRingBuffer *buf); /* get status */ guint gst_ringbuffer_delay (GstRingBuffer *buf); guint64 gst_ringbuffer_played_samples (GstRingBuffer *buf); +void gst_ringbuffer_set_sample (GstRingBuffer *buf, guint64 sample); /* commit samples */ guint gst_ringbuffer_commit (GstRingBuffer *buf, guint64 sample, guchar *data, guint len); /* mostly protected */ -guint8* gst_ringbuffer_prepare_read (GstRingBuffer *buf, gint segment); +gboolean gst_ringbuffer_prepare_read (GstRingBuffer *buf, gint *segment, guint8 **readptr, gint *len); void gst_ringbuffer_clear (GstRingBuffer *buf, gint segment); +void gst_ringbuffer_advance (GstRingBuffer *buf, guint advance); G_END_DECLS |
From: <wt...@fr...> - 2005-05-06 16:18:38
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Sat May 07 2005 02:18:37 EST Log message: Make the base audiosink return an error when there is no audiobuffer negotiated. Modified files: . : ChangeLog gst-libs/gst/audio: gstaudiosink.c gstbaseaudiosink.c gstbaseaudiosink.h gstringbuffer.c gstringbuffer.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1678&r2=1.1679 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h.diff?r1=1.2&r2=1.3 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1678 retrieving revision 1.1679 diff -u -d -r1.1678 -r1.1679 --- ChangeLog 6 May 2005 10:09:43 -0000 1.1678 +++ ChangeLog 6 May 2005 16:18:24 -0000 1.1679 @@ -1,3 +1,35 @@ +2005-05-06 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstaudiosink.c: + (gst_audioringbuffer_get_type), (gst_audioringbuffer_class_init), + (audioringbuffer_thread_func), (gst_audioringbuffer_init), + (gst_audioringbuffer_acquire), (gst_audioringbuffer_release), + (gst_audioringbuffer_play), (gst_audioringbuffer_stop), + (gst_audioringbuffer_delay), (gst_audiosink_class_init), + (gst_audiosink_create_ringbuffer): + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_baseaudiosink_class_init), (gst_baseaudiosink_init), + (gst_baseaudiosink_get_clock), (gst_baseaudiosink_get_time), + (gst_baseaudiosink_set_property), (build_linear_format), + (debug_spec_caps), (debug_spec_buffer), + (gst_baseaudiosink_setcaps), (gst_baseaudiosink_get_times), + (gst_baseaudiosink_event), (gst_baseaudiosink_preroll), + (gst_baseaudiosink_render), (gst_baseaudiosink_create_ringbuffer), + (gst_baseaudiosink_callback), (gst_baseaudiosink_change_state): + * gst-libs/gst/audio/gstbaseaudiosink.h: + * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_get_type), + (gst_ringbuffer_set_callback), (gst_ringbuffer_acquire), + (gst_ringbuffer_release), (gst_ringbuffer_is_acquired), + (gst_ringbuffer_play), (gst_ringbuffer_pause), + (gst_ringbuffer_stop), (gst_ringbuffer_delay), + (gst_ringbuffer_played_samples), (gst_ringbuffer_set_sample), + (wait_segment), (gst_ringbuffer_commit), + (gst_ringbuffer_prepare_read), (gst_ringbuffer_advance), + (gst_ringbuffer_clear): + * gst-libs/gst/audio/gstringbuffer.h: + Make the base audiosink return an error when there is no + audiobuffer negotiated. 2005-05-06 Zaheer Abbas Merali <zaheerabbas at merali dot org> * ext/Makefile.am: Index: gstaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gstaudiosink.c 5 May 2005 09:37:46 -0000 1.3 +++ gstaudiosink.c 6 May 2005 16:18:24 -0000 1.4 @@ -292,6 +292,9 @@ GST_LOCK (buf); + /* free the buffer */ + gst_buffer_unref (buf->data); if (csink->close) result = csink->close (sink); Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gstbaseaudiosink.c 5 May 2005 10:42:41 -0000 1.4 +++ gstbaseaudiosink.c 6 May 2005 16:18:24 -0000 1.5 @@ -484,11 +484,19 @@ offset = GST_BUFFER_OFFSET (buf); GST_DEBUG ("in offset %llu, time %lld", offset, GST_BUFFER_TIMESTAMP (buf)); + if (!gst_ringbuffer_is_acquired (sink->ringbuffer)) + goto wrong_state; gst_ringbuffer_commit (sink->ringbuffer, offset, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); return GST_FLOW_OK; +wrong_state: + { + GST_DEBUG ("ringbuffer in wrong state"); + return GST_FLOW_ERROR; + } } GstRingBuffer * Index: gstbaseaudiosink.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h,v retrieving revision 1.2 diff -u -d -r1.2 -r1.3 --- gstbaseaudiosink.h 28 Apr 2005 16:15:42 -0000 1.2 +++ gstbaseaudiosink.h 6 May 2005 16:18:24 -0000 1.3 @@ -72,6 +72,7 @@ struct _GstBaseAudioSink { GstBaseSink element; + /*< protected >*/ /* with LOCK */ /* our ringbuffer */ GstRingBuffer *ringbuffer; Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v --- gstringbuffer.c 5 May 2005 09:37:46 -0000 1.3 +++ gstringbuffer.c 6 May 2005 16:18:24 -0000 1.4 @@ -239,6 +239,31 @@ /** + * gst_ringbuffer_is_acquired: + * @buf: the #GstRingBuffer to check + * + * Check if the ringbuffer is acquired and ready to use. + * Returns: TRUE if the ringbuffer is acquired, FALSE on error. + * MT safe. + */ +gboolean +gst_ringbuffer_is_acquired (GstRingBuffer * buf) +{ + gboolean res; + g_return_val_if_fail (buf != NULL, FALSE); + GST_LOCK (buf); + res = buf->acquired; + GST_UNLOCK (buf); + return res; +} +/** * gst_ringbuffer_play: * @buf: the #GstRingBuffer to play * Index: gstringbuffer.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h,v --- gstringbuffer.h 28 Apr 2005 16:15:42 -0000 1.2 +++ gstringbuffer.h 6 May 2005 16:18:24 -0000 1.3 @@ -198,6 +198,8 @@ gboolean gst_ringbuffer_acquire (GstRingBuffer *buf, GstRingBufferSpec *spec); gboolean gst_ringbuffer_release (GstRingBuffer *buf); +gboolean gst_ringbuffer_is_acquired (GstRingBuffer *buf); /* playback/pause */ gboolean gst_ringbuffer_play (GstRingBuffer *buf); gboolean gst_ringbuffer_pause (GstRingBuffer *buf); |
From: <wt...@fr...> - 2005-05-31 11:38:33
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue May 31 2005 04:38:22 PDT Log message: * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_delay): Don't try to call the delay method when the device is not opened. Modified files: . : ChangeLog gst-libs/gst/audio: gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1720&r2=1.1721 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.6&r2=1.7 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1720 retrieving revision 1.1721 diff -u -d -r1.1720 -r1.1721 --- ChangeLog 31 May 2005 11:22:32 -0000 1.1720 +++ ChangeLog 31 May 2005 11:38:10 -0000 1.1721 @@ -1,5 +1,11 @@ 2005-05-31 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_delay): + Don't try to call the delay method when the device is not + opened. + +2005-05-31 Wim Taymans <wi...@fl...> * ext/alsa/gstalsasink.c: (set_hwparams), (gst_alsasink_open): Get actual segment size and buffer size after opening the device. Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- gstringbuffer.c 25 May 2005 19:52:14 -0000 1.6 +++ gstringbuffer.c 31 May 2005 11:38:10 -0000 1.7 @@ -431,6 +431,9 @@ g_return_val_if_fail (buf != NULL, 0); + if (!gst_ringbuffer_is_acquired (buf)) + return 0; rclass = GST_RINGBUFFER_GET_CLASS (buf); if (rclass->delay) res = rclass->delay (buf); |
From: <wt...@fr...> - 2005-06-29 11:17:47
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Jun 29 2005 04:17:45 PDT Log message: * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_init): * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_baseaudiosink_class_init), (gst_baseaudiosink_dispose), (gst_baseaudiosink_change_state): * gst-libs/gst/audio/gstbaseaudiosink.h: * gst-libs/gst/audio/gstringbuffer.c: (gst_ringbuffer_set_callback): Fix compilation error. Ringbuffer starts out as not running. Free our clock in dispose. When releasing the ringbuffer we need to renegotiate so clear the pad caps. Modified files: . : ChangeLog gst-libs/gst/audio: gstaudiosink.c gstbaseaudiosink.c gstbaseaudiosink.h gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1743&r2=1.1744 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.8&r2=1.9 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1743 retrieving revision 1.1744 diff -u -d -r1.1743 -r1.1744 --- ChangeLog 29 Jun 2005 10:56:25 -0000 1.1743 +++ ChangeLog 29 Jun 2005 11:17:33 -0000 1.1744 @@ -1,3 +1,18 @@ +2005-06-29 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_init): + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_baseaudiosink_class_init), (gst_baseaudiosink_dispose), + (gst_baseaudiosink_change_state): + * gst-libs/gst/audio/gstbaseaudiosink.h: + * gst-libs/gst/audio/gstringbuffer.c: + (gst_ringbuffer_set_callback): + Fix compilation error. + Ringbuffer starts out as not running. + Free our clock in dispose. + When releasing the ringbuffer we need to renegotiate so + clear the pad caps. 2005-06-29 Thomas Vander Stichele <thomas at apestaart dot org> * autogen.sh: Index: gstaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gstaudiosink.c 24 Jun 2005 16:15:25 -0000 1.7 +++ gstaudiosink.c 29 Jun 2005 11:17:33 -0000 1.8 @@ -217,7 +217,7 @@ static void gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer) { - ringbuffer->running = TRUE; + ringbuffer->running = FALSE; ringbuffer->queuedseg = 0; ringbuffer->cond = g_cond_new (); Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v --- gstbaseaudiosink.c 28 Jun 2005 10:16:13 -0000 1.7 +++ gstbaseaudiosink.c 29 Jun 2005 11:17:33 -0000 1.8 @@ -49,6 +49,8 @@ GST_BOILERPLATE_FULL (GstBaseAudioSink, gst_baseaudiosink, GstBaseSink, GST_TYPE_BASESINK, _do_init); +static void gst_baseaudiosink_dispose (GObject * object); static void gst_baseaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_baseaudiosink_get_property (GObject * object, guint prop_id, @@ -92,6 +94,7 @@ GST_DEBUG_FUNCPTR (gst_baseaudiosink_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_baseaudiosink_get_property); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_baseaudiosink_dispose); g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER_TIME, g_param_spec_int64 ("buffer-time", "Buffer Time", @@ -124,6 +127,20 @@ (GstAudioClockGetTimeFunc) gst_baseaudiosink_get_time, baseaudiosink); } +static void +gst_baseaudiosink_dispose (GObject * object) +{ + GstBaseAudioSink *sink; + sink = GST_BASEAUDIOSINK (object); + if (sink->clock) + gst_object_unref (sink->clock); + sink->clock = NULL; + G_OBJECT_CLASS (parent_class)->dispose (object); +} static GstClock * gst_baseaudiosink_get_clock (GstElement * elem) @@ -557,6 +574,7 @@ gst_ringbuffer_release (sink->ringbuffer); gst_object_unref (sink->ringbuffer); sink->ringbuffer = NULL; + gst_pad_set_caps (GST_BASESINK_PAD (sink), NULL); break; case GST_STATE_READY_TO_NULL: Index: gstbaseaudiosink.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gstbaseaudiosink.h 6 May 2005 16:18:24 -0000 1.3 +++ gstbaseaudiosink.h 29 Jun 2005 11:17:33 -0000 1.4 @@ -64,7 +64,7 @@ #define GST_IS_BASEAUDIOSINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASEAUDIOSINK)) #define GST_BASEAUDIOSINK_CLOCK(obj) (GST_BASEAUDIOSINK (obj)->clock) -#define GST_BASEAUDIOSINK_PAD(obj) (GST_BASEAUDIOSINK (obj)->sinkpad) +#define GST_BASEAUDIOSINK_PAD(obj) (GST_BASESINK (obj)->sinkpad) typedef struct _GstBaseAudioSink GstBaseAudioSink; typedef struct _GstBaseAudioSinkClass GstBaseAudioSinkClass; Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- gstringbuffer.c 29 Jun 2005 10:56:25 -0000 1.8 +++ gstringbuffer.c 29 Jun 2005 11:17:33 -0000 1.9 @@ -125,7 +125,7 @@ GST_LOCK (buf); buf->callback = cb; - buf->cb_data = data; + buf->cb_data = user_data; GST_UNLOCK (buf); |
From: <wt...@fr...> - 2005-07-16 17:13:53
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Sat Jul 16 2005 10:13:47 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): Align samples even if we have roundoff errors in the timestamp conversion. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1787&r2=1.1788 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.11&r2=1.12 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1787 retrieving revision 1.1788 diff -u -d -r1.1787 -r1.1788 --- ChangeLog 16 Jul 2005 14:47:25 -0000 1.1787 +++ ChangeLog 16 Jul 2005 17:13:35 -0000 1.1788 @@ -1,5 +1,12 @@ 2005-07-16 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): + Align samples even if we have roundoff errors in the + timestamp conversion. + +2005-07-16 Wim Taymans <wi...@fl...> * docs/libs/tmpl/gstringbuffer.sgml: * examples/seeking/seek.c: (make_vorbis_theora_pipeline), (query_rates), (query_positions_elems), (query_positions_pads), Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- gstbaseaudiosink.c 16 Jul 2005 14:47:26 -0000 1.11 +++ gstbaseaudiosink.c 16 Jul 2005 17:13:35 -0000 1.12 @@ -322,6 +322,7 @@ guint64 render_offset, in_offset; GstClockTime time, render_time; GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); + gint64 diff; /* can't do anything when we don't have the device */ if (!gst_ring_buffer_is_acquired (sink->ringbuffer)) @@ -336,7 +337,7 @@ /* samples should be rendered based on their timestamp. All samples * arriving before the discont_start are to be trown away */ /* FIXME, for now we drop the sample completely, we should - * in fact clip the sample */ + * in fact clip the sample. Same for the segment_stop, actually. */ if (time < bsink->discont_start) return GST_FLOW_OK; @@ -347,8 +348,19 @@ /* and bring the time to the offset in the buffer */ render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND; - GST_DEBUG ("render time %" GST_TIME_FORMAT ", render offset %llu", - GST_TIME_ARGS (render_time), render_offset); + /* roundoff errors in timestamp conversion */ + diff = ABS ((gint64) render_offset - (gint64) sink->ringbuffer->next_sample); + GST_DEBUG ("render time %" GST_TIME_FORMAT ", render offset %llu, diff %lld", + GST_TIME_ARGS (render_time), render_offset, diff); + /* FIXME, depends on samplerate... Also the purpose of the OFFSET fields + * are to detect gaps and dropouts, we might better use them if they are + * valid. */ + if (diff < 10) { + /* just align with previous sample then */ + render_offset = -1; + } gst_ring_buffer_commit (sink->ringbuffer, render_offset, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); |
From: <wt...@fr...> - 2005-07-20 09:08:23
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Jul 20 2005 02:08:17 PDT Log message: * gst-libs/gst/audio/TODO: * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init), (gst_audio_clock_get_internal_time): * gst-libs/gst/audio/gstaudioclock.h: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_init), (gst_base_audio_sink_dispose), (gst_base_audio_sink_get_time), (gst_base_audio_sink_event), (gst_base_audio_sink_render), (gst_base_audio_sink_create_ringbuffer), (gst_base_audio_sink_change_state): Make sure the audio clock always returns an increasing value. Modified files: . : ChangeLog gst-libs/gst/audio: TODO gstaudioclock.c gstaudioclock.h gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1794&r2=1.1795 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/TODO.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.h.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.12&r2=1.13 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1794 retrieving revision 1.1795 diff -u -d -r1.1794 -r1.1795 --- ChangeLog 19 Jul 2005 12:01:48 -0000 1.1794 +++ ChangeLog 20 Jul 2005 09:08:05 -0000 1.1795 @@ -1,3 +1,17 @@ +2005-07-20 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/TODO: + * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init), + (gst_audio_clock_get_internal_time): + * gst-libs/gst/audio/gstaudioclock.h: + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_init), (gst_base_audio_sink_dispose), + (gst_base_audio_sink_get_time), (gst_base_audio_sink_event), + (gst_base_audio_sink_render), + (gst_base_audio_sink_create_ringbuffer), + (gst_base_audio_sink_change_state): + Make sure the audio clock always returns an increasing value. 2005-07-19 Andy Wingo <wi...@po...> * gst/videotestsrc/: Cleanups. Index: TODO RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/TODO,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- TODO 5 May 2005 09:37:46 -0000 1.2 +++ TODO 20 Jul 2005 09:08:05 -0000 1.3 @@ -7,4 +7,4 @@ is parsed correctly. - implement seek/query/convert - implement getrange scheduling - + - on EOS, only post EOS when the complete ringbuffer has been played. Index: gstaudioclock.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.c,v retrieving revision 1.1 diff -u -d -r1.1 -r1.2 --- gstaudioclock.c 28 Apr 2005 16:15:42 -0000 1.1 +++ gstaudioclock.c 20 Jul 2005 09:08:05 -0000 1.2 @@ -81,6 +81,8 @@ gst_audio_clock_init (GstAudioClock * clock) { gst_object_set_name (GST_OBJECT (clock), "GstAudioClock"); + clock->last_time = 0; } GstClock * @@ -100,6 +102,13 @@ gst_audio_clock_get_internal_time (GstClock * clock) GstAudioClock *aclock = GST_AUDIO_CLOCK (clock); + GstClockTime result; - return aclock->func (clock, aclock->user_data); + result = aclock->func (clock, aclock->user_data); + if (result == GST_CLOCK_TIME_NONE) + result = aclock->last_time; + else + aclock->last_time = result; + return result; Index: gstaudioclock.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudioclock.h,v --- gstaudioclock.h 10 Jul 2005 12:03:58 -0000 1.2 +++ gstaudioclock.h 20 Jul 2005 09:08:05 -0000 1.3 @@ -51,6 +51,8 @@ GstAudioClockGetTimeFunc func; gpointer user_data; + GstClockTime last_time; gpointer _gst_reserved[GST_PADDING]; }; Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- gstbaseaudiosink.c 16 Jul 2005 17:13:35 -0000 1.12 +++ gstbaseaudiosink.c 20 Jul 2005 09:08:05 -0000 1.13 @@ -62,6 +62,8 @@ static GstClock *gst_base_audio_sink_get_clock (GstElement * elem); static GstClockTime gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink); +static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, + guint len, gpointer user_data); static GstFlowReturn gst_base_audio_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer); @@ -126,8 +128,10 @@ baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME; baseaudiosink->latency_time = DEFAULT_LATENCY_TIME; baseaudiosink->clock = gst_audio_clock_new ("clock", (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink); static void @@ -141,6 +145,10 @@ gst_object_unref (sink->clock); sink->clock = NULL; + if (sink->ringbuffer) + gst_object_unref (sink->ringbuffer); + sink->ringbuffer = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); @@ -161,7 +169,7 @@ GstClockTime result; if (sink->ringbuffer == NULL || sink->ringbuffer->spec.rate == 0) - return 0; + return GST_CLOCK_TIME_NONE; /* our processed samples are always increasing */ samples = gst_ring_buffer_samples_done (sink->ringbuffer); @@ -288,6 +296,8 @@ gst_ring_buffer_pause (sink->ringbuffer); } break; + case GST_EVENT_EOS: + break; default: } @@ -335,7 +345,7 @@ GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->discont_start)); /* samples should be rendered based on their timestamp. All samples - * arriving before the discont_start are to be trown away */ + * arriving before the discont_start are to be thrown away */ /* FIXME, for now we drop the sample completely, we should * in fact clip the sample. Same for the segment_stop, actually. */ if (time < bsink->discont_start) @@ -369,10 +379,10 @@ wrong_state: { - GST_DEBUG ("ringbuffer in wrong state"); + GST_DEBUG ("ringbuffer not negotiated"); GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, - ("sink not negotiated."), (NULL)); - return GST_FLOW_ERROR; + ("sink not negotiated."), ("sink not negotiated.")); + return GST_FLOW_NOT_NEGOTIATED; @@ -386,14 +396,13 @@ if (bclass->create_ringbuffer) buffer = bclass->create_ringbuffer (sink); - if (buffer) { + if (buffer) gst_object_set_parent (GST_OBJECT (buffer), GST_OBJECT (sink)); - } return buffer; -void +static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len, gpointer user_data) @@ -411,9 +420,11 @@ case GST_STATE_NULL_TO_READY: case GST_STATE_READY_TO_PAUSED: - sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink); - gst_ring_buffer_set_callback (sink->ringbuffer, - gst_base_audio_sink_callback, sink); + if (sink->ringbuffer == NULL) { + sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink); + gst_ring_buffer_set_callback (sink->ringbuffer, + gst_base_audio_sink_callback, sink); + } case GST_STATE_PAUSED_TO_PLAYING: @@ -430,8 +441,6 @@ case GST_STATE_PAUSED_TO_READY: gst_ring_buffer_stop (sink->ringbuffer); gst_ring_buffer_release (sink->ringbuffer); - gst_object_unref (sink->ringbuffer); - sink->ringbuffer = NULL; gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL); case GST_STATE_READY_TO_NULL: |
From: <wt...@fr...> - 2005-07-27 19:10:39
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Jul 27 2005 12:10:32 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render), (gst_base_audio_sink_create_ringbuffer), (gst_base_audio_sink_change_state): Fix compilation. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1807&r2=1.1808 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.14&r2=1.15 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1807 retrieving revision 1.1808 diff -u -d -r1.1807 -r1.1808 --- ChangeLog 27 Jul 2005 18:34:27 -0000 1.1807 +++ ChangeLog 27 Jul 2005 19:10:20 -0000 1.1808 @@ -1,5 +1,13 @@ 2005-07-27 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_event), (gst_base_audio_sink_render), + (gst_base_audio_sink_create_ringbuffer), + (gst_base_audio_sink_change_state): + Fix compilation. + +2005-07-27 Wim Taymans <wi...@fl...> * examples/seeking/seek.c: (setup_dynamic_link), (make_dv_pipeline), (make_vorbis_theora_pipeline), (query_rates), (query_positions_elems), (query_positions_pads), (do_seek): Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- gstbaseaudiosink.c 21 Jul 2005 17:25:40 -0000 1.14 +++ gstbaseaudiosink.c 27 Jul 2005 19:10:20 -0000 1.15 @@ -290,11 +290,10 @@ GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - if (GST_EVENT_FLUSH_DONE (event)) { - } else { - gst_ring_buffer_pause (sink->ringbuffer); - } + case GST_EVENT_FLUSH_START: + gst_ring_buffer_pause (sink->ringbuffer); + break; + case GST_EVENT_FLUSH_STOP: break; case GST_EVENT_EOS: |
From: <wt...@fr...> - 2005-07-27 19:13:40
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Jul 27 2005 12:13:39 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_event): More compilation fixen. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1808&r2=1.1809 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.4&r2=1.5 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1808 retrieving revision 1.1809 diff -u -d -r1.1808 -r1.1809 --- ChangeLog 27 Jul 2005 19:10:20 -0000 1.1808 +++ ChangeLog 27 Jul 2005 19:13:26 -0000 1.1809 @@ -1,5 +1,10 @@ 2005-07-27 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_event): + More compilation fixen. + +2005-07-27 Wim Taymans <wi...@fl...> * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render), (gst_base_audio_sink_create_ringbuffer), Index: gstbaseaudiosrc.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gstbaseaudiosrc.c 16 Jul 2005 14:47:26 -0000 1.4 +++ gstbaseaudiosrc.c 27 Jul 2005 19:13:27 -0000 1.5 @@ -285,11 +285,10 @@ GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - if (GST_EVENT_FLUSH_DONE (event)) { - } else { - gst_ring_buffer_pause (src->ringbuffer); - } + case GST_EVENT_FLUSH_START: + gst_ring_buffer_pause (src->ringbuffer); + break; + case GST_EVENT_FLUSH_STOP: break; default: |
From: <wt...@fr...> - 2005-08-16 15:55:45
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Aug 16 2005 08:54:11 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_change_state): Open and close device in READY<->NULL state change. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1836&r2=1.1837 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.5&r2=1.6 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1836 retrieving revision 1.1837 diff -u -d -r1.1836 -r1.1837 --- ChangeLog 16 Aug 2005 14:35:51 -0000 1.1836 +++ ChangeLog 16 Aug 2005 15:53:58 -0000 1.1837 @@ -1,3 +1,9 @@ +2005-08-16 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_change_state): + Open and close device in READY<->NULL state change. 2005-08-16 Andy Wingo <wi...@po...> * examples/seeking/Makefile.am: Don't compile non-compiling Index: gstbaseaudiosrc.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- gstbaseaudiosrc.c 27 Jul 2005 19:13:27 -0000 1.5 +++ gstbaseaudiosrc.c 16 Aug 2005 15:53:59 -0000 1.6 @@ -369,11 +369,15 @@ switch (transition) { case GST_STATE_NULL_TO_READY: + if (src->ringbuffer == NULL) { + src->ringbuffer = gst_base_audio_src_create_ringbuffer (src); + gst_ring_buffer_set_callback (src->ringbuffer, + gst_base_audio_src_callback, src); + } + if (!gst_ring_buffer_open_device (src->ringbuffer)) + return GST_STATE_FAILURE; break; case GST_STATE_READY_TO_PAUSED: - src->ringbuffer = gst_base_audio_src_create_ringbuffer (src); - gst_ring_buffer_set_callback (src->ringbuffer, - gst_base_audio_src_callback, src); case GST_STATE_PAUSED_TO_PLAYING: @@ -390,10 +394,11 @@ case GST_STATE_PAUSED_TO_READY: gst_ring_buffer_stop (src->ringbuffer); gst_ring_buffer_release (src->ringbuffer); - gst_object_unref (GST_OBJECT (src->ringbuffer)); - src->ringbuffer = NULL; case GST_STATE_READY_TO_NULL: + gst_ring_buffer_close_device (src->ringbuffer); + gst_object_unref (GST_OBJECT (src->ringbuffer)); + src->ringbuffer = NULL; default: |
From: <wt...@fr...> - 2005-08-24 11:29:26
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Aug 24 2005 04:29:22 PDT Log message: * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_set_sample), (gst_ring_buffer_clear_all): * gst-libs/gst/audio/gstringbuffer.h: Added function to clear the ringbuffer. Modified files: . : ChangeLog gst-libs/gst/audio: gstringbuffer.c gstringbuffer.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1848&r2=1.1849 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.13&r2=1.14 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h.diff?r1=1.8&r2=1.9 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1848 retrieving revision 1.1849 diff -u -d -r1.1848 -r1.1849 --- ChangeLog 24 Aug 2005 11:07:51 -0000 1.1848 +++ ChangeLog 24 Aug 2005 11:29:10 -0000 1.1849 @@ -1,3 +1,10 @@ +2005-08-24 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_set_sample), + (gst_ring_buffer_clear_all): + * gst-libs/gst/audio/gstringbuffer.h: + Added function to clear the ringbuffer. 2005-08-24 Andy Wingo <wi...@po...> * sys/v4l/gstv4lelement.c (gst_v4lelement_start) Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- gstringbuffer.c 8 Aug 2005 16:42:10 -0000 1.13 +++ gstringbuffer.c 24 Aug 2005 11:29:10 -0000 1.14 @@ -822,8 +822,6 @@ void gst_ring_buffer_set_sample (GstRingBuffer * buf, guint64 sample) { - gint i; - g_return_if_fail (buf != NULL); if (sample == -1) @@ -838,13 +836,33 @@ buf->segbase = buf->segdone - sample / buf->samples_per_seg; buf->next_sample = sample; + gst_ring_buffer_clear_all (buf); + GST_DEBUG ("set sample to %llu, segbase %d", sample, buf->segbase); +} +/** + * gst_ring_buffer_clear_all: + * @buf: the #GstRingBuffer to clear + * + * Fill the ringbuffer with silence. + * MT safe. + */ +void +gst_ring_buffer_clear_all (GstRingBuffer * buf) +{ + gint i; + g_return_if_fail (buf != NULL); + g_return_if_fail (buf->spec.segtotal > 0); for (i = 0; i < buf->spec.segtotal; i++) { gst_ring_buffer_clear (buf, i); } - GST_DEBUG ("set sample to %llu, segbase %d", sample, buf->segbase); } static gboolean wait_segment (GstRingBuffer * buf) Index: gstringbuffer.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- gstringbuffer.h 9 Aug 2005 17:29:40 -0000 1.8 +++ gstringbuffer.h 24 Aug 2005 11:29:10 -0000 1.9 @@ -236,6 +236,9 @@ void gst_ring_buffer_set_sample (GstRingBuffer *buf, guint64 sample); +/* clear all segments */ +void gst_ring_buffer_clear_all (GstRingBuffer *buf); /* commit samples */ guint gst_ring_buffer_commit (GstRingBuffer *buf, guint64 sample, guchar *data, guint len); |
From: <wt...@fr...> - 2005-08-31 10:57:49
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Aug 31 2005 03:57:47 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): Resync if the buffer timestamps drift more than a 10th of a second. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1884&r2=1.1885 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.18&r2=1.19 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1884 retrieving revision 1.1885 diff -u -d -r1.1884 -r1.1885 --- ChangeLog 31 Aug 2005 08:58:02 -0000 1.1884 +++ ChangeLog 31 Aug 2005 10:57:34 -0000 1.1885 @@ -1,3 +1,10 @@ +2005-08-31 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): + Resync if the buffer timestamps drift more than a 10th + of a second. 2005-08-31 Tim-Philipp Müller <tim at centricular dot net> * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_set_property), Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- gstbaseaudiosink.c 28 Aug 2005 17:52:45 -0000 1.18 +++ gstbaseaudiosink.c 31 Aug 2005 10:57:35 -0000 1.19 @@ -335,6 +335,8 @@ GstClockTimeDiff render_diff; GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); gint64 diff; + guint8 *data; + guint size; /* can't do anything when we don't have the device */ if (!gst_ring_buffer_is_acquired (sink->ringbuffer)) @@ -342,6 +344,8 @@ in_offset = GST_BUFFER_OFFSET (buf); time = GST_BUFFER_TIMESTAMP (buf); + data = GST_BUFFER_DATA (buf); + size = GST_BUFFER_SIZE (buf); GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT, GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); @@ -367,16 +371,16 @@ GST_DEBUG ("render time %" GST_TIME_FORMAT ", render offset %llu, diff %lld", GST_TIME_ARGS (render_time), render_offset, diff); - /* FIXME, depends on samplerate... Also the purpose of the OFFSET fields - * are to detect gaps and dropouts, we might better use them if they are - * valid. */ - if (diff < 10) { + /* we tollerate a 10th of a second diff before we start resyncing. This + * should be enough to compensate for various rounding errors in the timestamp + * and sample offset position. */ + if (diff < sink->ringbuffer->spec.rate / 10) { /* just align with previous sample then */ render_offset = -1; + /* FIXME, can we use the OFFSET field to detect a gap? */ } - gst_ring_buffer_commit (sink->ringbuffer, render_offset, - GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + gst_ring_buffer_commit (sink->ringbuffer, render_offset, data, size); return GST_FLOW_OK; |
From: <wt...@fr...> - 2005-09-28 13:41:49
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Sep 28 2005 06:41:41 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_class_init), (gst_base_audio_sink_provide_clock), (gst_base_audio_sink_render): * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_class_init), (gst_base_audio_src_provide_clock): get_clock -> provide_clock Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c gstbaseaudiosrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1946&r2=1.1947 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.22&r2=1.23 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.9&r2=1.10 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1946 retrieving revision 1.1947 diff -u -d -r1.1946 -r1.1947 --- ChangeLog 28 Sep 2005 13:36:44 -0000 1.1946 +++ ChangeLog 28 Sep 2005 13:41:29 -0000 1.1947 @@ -1,3 +1,13 @@ +2005-09-28 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_class_init), + (gst_base_audio_sink_provide_clock), (gst_base_audio_sink_render): + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_class_init), + (gst_base_audio_src_provide_clock): + get_clock -> provide_clock 2005-09-28 Andy Wingo <wi...@po...> * gst/videotestsrc/gstvideotestsrc.c: Implement live source mode Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- gstbaseaudiosink.c 24 Sep 2005 13:06:03 -0000 1.22 +++ gstbaseaudiosink.c 28 Sep 2005 13:41:29 -0000 1.23 @@ -64,7 +64,7 @@ static GstStateChangeReturn gst_base_audio_sink_change_state (GstElement * element, GstStateChange transition); -static GstClock *gst_base_audio_sink_get_clock (GstElement * elem); +static GstClock *gst_base_audio_sink_provide_clock (GstElement * elem); static GstClockTime gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink); static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, @@ -116,8 +116,8 @@ gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state); - gstelement_class->get_clock = - GST_DEBUG_FUNCPTR (gst_base_audio_sink_get_clock); + gstelement_class->provide_clock = + GST_DEBUG_FUNCPTR (gst_base_audio_sink_provide_clock); gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_base_audio_sink_event); gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_base_audio_sink_preroll); @@ -159,7 +159,7 @@ } static GstClock * -gst_base_audio_sink_get_clock (GstElement * elem) +gst_base_audio_sink_provide_clock (GstElement * elem) { GstBaseAudioSink *sink; Index: gstbaseaudiosrc.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gstbaseaudiosrc.c 2 Sep 2005 15:43:17 -0000 1.9 +++ gstbaseaudiosrc.c 28 Sep 2005 13:41:29 -0000 1.10 @@ -59,7 +59,7 @@ static GstStateChangeReturn gst_base_audio_src_change_state (GstElement * -static GstClock *gst_base_audio_src_get_clock (GstElement * elem); +static GstClock *gst_base_audio_src_provide_clock (GstElement * elem); static GstClockTime gst_base_audio_src_get_time (GstClock * clock, GstBaseAudioSrc * src); @@ -107,8 +107,8 @@ GST_DEBUG_FUNCPTR (gst_base_audio_src_change_state); - GST_DEBUG_FUNCPTR (gst_base_audio_src_get_clock); + GST_DEBUG_FUNCPTR (gst_base_audio_src_provide_clock); gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_base_audio_src_setcaps); gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_base_audio_src_event); @@ -133,7 +133,7 @@ -gst_base_audio_src_get_clock (GstElement * elem) +gst_base_audio_src_provide_clock (GstElement * elem) GstBaseAudioSrc *src; |
From: <wt...@fr...> - 2005-10-06 15:15:19
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Oct 06 2005 08:15:16 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_event), (gst_base_audio_src_create), (gst_base_audio_src_change_state): * gst-libs/gst/audio/gstbaseaudiosrc.h: * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_read): patch from Edgard Lima <edg...@in...> Fixed gstbaseaudiosrc adding ring buffer sync to it. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosrc.c gstbaseaudiosrc.h gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1958&r2=1.1959 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.10&r2=1.11 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.h.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.18&r2=1.19 ====Begin Diffs==== Index: gstbaseaudiosrc.c =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- gstbaseaudiosrc.c 28 Sep 2005 13:41:29 -0000 1.10 +++ gstbaseaudiosrc.c 6 Oct 2005 15:15:04 -0000 1.11 @@ -289,8 +289,12 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: gst_ring_buffer_pause (src->ringbuffer); + gst_ring_buffer_clear_all (src->ringbuffer); break; case GST_EVENT_FLUSH_STOP: + /* always resync on sample after a flush */ + src->next_sample = -1; default: @@ -306,6 +310,7 @@ guchar *data; guint len; guint res; + guint64 sample; if (!gst_ring_buffer_is_acquired (src->ringbuffer)) goto wrong_state; @@ -315,10 +320,18 @@ data = GST_BUFFER_DATA (buf); len = GST_BUFFER_SIZE (buf); - res = gst_ring_buffer_read (src->ringbuffer, -1, data, len); + if (src->next_sample != -1) { + sample = src->next_sample; + } else { + sample = 0; + } + + res = gst_ring_buffer_read (src->ringbuffer, sample, data, len); if (res == -1) goto stopped; + src->next_sample = sample + len / src->ringbuffer->spec.bytes_per_sample; gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc))); *outbuf = buf; @@ -378,6 +391,7 @@ } if (!gst_ring_buffer_open_device (src->ringbuffer)) return GST_STATE_CHANGE_FAILURE; + src->next_sample = 0; case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -394,8 +408,8 @@ case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_ring_buffer_stop (src->ringbuffer); gst_ring_buffer_release (src->ringbuffer); case GST_STATE_CHANGE_READY_TO_NULL: gst_ring_buffer_close_device (src->ringbuffer); Index: gstbaseaudiosrc.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gstbaseaudiosrc.h 9 Aug 2005 17:29:40 -0000 1.3 +++ gstbaseaudiosrc.h 6 Oct 2005 15:15:04 -0000 1.4 @@ -57,6 +57,9 @@ GstClockTime buffer_time; GstClockTime latency_time; + /* the next sample to write */ + guint64 next_sample; /* clock */ GstClock *clock; Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- gstringbuffer.c 6 Oct 2005 13:11:54 -0000 1.18 +++ gstringbuffer.c 6 Oct 2005 15:15:04 -0000 1.19 @@ -1065,9 +1065,10 @@ /* segment too far ahead, we need to drop */ if (diff < 0) { - /* we need to drop one segment at a time, pretend we wrote a - * segment. */ + /* we need to drop one segment at a time, pretend we read an + * empty segment. */ readlen = MIN (segsize, len); + memcpy (data, buf->empty_seg, readlen); goto next; Index: ChangeLog RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1958 retrieving revision 1.1959 diff -u -d -r1.1958 -r1.1959 --- ChangeLog 6 Oct 2005 13:11:55 -0000 1.1958 +++ ChangeLog 6 Oct 2005 15:15:04 -0000 1.1959 @@ -1,5 +1,14 @@ 2005-10-06 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_event), + (gst_base_audio_src_create), (gst_base_audio_src_change_state): + * gst-libs/gst/audio/gstbaseaudiosrc.h: + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_read): + patch from Edgard Lima <edg...@in...> + Fixed gstbaseaudiosrc adding ring buffer sync to it. +2005-10-06 Wim Taymans <wi...@fl...> * ext/ogg/gstoggdemux.c: (gst_ogg_demux_loop): Report the FLOW_RETURN as string in the error message. |
From: <wt...@fr...> - 2005-10-08 11:48:08
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Sat Oct 08 2005 04:48:04 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render): If we receive EOS we can start playback of what we had. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1960&r2=1.1961 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.23&r2=1.24 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1960 retrieving revision 1.1961 diff -u -d -r1.1960 -r1.1961 --- ChangeLog 8 Oct 2005 08:50:37 -0000 1.1960 +++ ChangeLog 8 Oct 2005 11:47:51 -0000 1.1961 @@ -1,5 +1,11 @@ 2005-10-08 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_event), (gst_base_audio_sink_render): + If we receive EOS we can start playback of what we had. + +2005-10-08 Wim Taymans <wi...@fl...> * gst/tcp/gstmultifdsink.c: (gst_multifdsink_class_init), (gst_multifdsink_finalize), (multifdsink_hash_remove), (gst_multifdsink_stop): Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstbaseaudiosink.c 28 Sep 2005 13:41:29 -0000 1.23 +++ gstbaseaudiosink.c 8 Oct 2005 11:47:52 -0000 1.24 @@ -306,6 +306,7 @@ gst_ring_buffer_clear_all (sink->ringbuffer); break; case GST_EVENT_EOS: + gst_ring_buffer_start (sink->ringbuffer); default: |
From: <wt...@fr...> - 2005-10-08 12:02:30
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Sat Oct 08 2005 05:02:20 PDT Log message: * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_stop): Only actually wait for the thread to be stopped if it's running. Modified files: . : ChangeLog gst-libs/gst/audio: gstaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1961&r2=1.1962 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c.diff?r1=1.14&r2=1.15 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1961 retrieving revision 1.1962 diff -u -d -r1.1961 -r1.1962 --- ChangeLog 8 Oct 2005 11:47:51 -0000 1.1961 +++ ChangeLog 8 Oct 2005 12:02:08 -0000 1.1962 @@ -1,5 +1,11 @@ 2005-10-08 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_stop): + Only actually wait for the thread to be stopped if it's + running. + +2005-10-08 Wim Taymans <wi...@fl...> * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render): If we receive EOS we can start playback of what we had. Index: gstaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstaudiosink.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- gstaudiosink.c 2 Oct 2005 15:58:57 -0000 1.14 +++ gstaudiosink.c 8 Oct 2005 12:02:08 -0000 1.15 @@ -381,9 +381,11 @@ { GstAudioSink *sink; GstAudioSinkClass *csink; + GstAudioRingBuffer *abuf; sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf)); csink = GST_AUDIO_SINK_GET_CLASS (sink); + abuf = GST_AUDIORING_BUFFER (buf); /* unblock any pending writes to the audio device */ if (csink->reset) { @@ -392,9 +394,11 @@ GST_DEBUG ("reset done"); } - GST_DEBUG ("stop, waiting..."); - GST_AUDIORING_BUFFER_WAIT (buf); - GST_DEBUG ("stopped"); + if (abuf->running) { + GST_DEBUG ("stop, waiting..."); + GST_AUDIORING_BUFFER_WAIT (buf); + GST_DEBUG ("stopped"); + } return TRUE; } |
From: <wt...@fr...> - 2005-10-11 17:31:47
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Oct 11 2005 10:32:00 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): Respect segment rate and accum when scheduling samples. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1976&r2=1.1977 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.24&r2=1.25 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1976 retrieving revision 1.1977 diff -u -d -r1.1976 -r1.1977 --- ChangeLog 11 Oct 2005 17:19:36 -0000 1.1976 +++ ChangeLog 11 Oct 2005 17:31:48 -0000 1.1977 @@ -1,3 +1,9 @@ +2005-10-11 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): + Respect segment rate and accum when scheduling samples. 2005-10-11 Julien MOUTTE <ju...@mo...> * ext/ogg/gstoggmux.c: (gst_ogg_mux_queue_pads), Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- gstbaseaudiosink.c 8 Oct 2005 11:47:52 -0000 1.24 +++ gstbaseaudiosink.c 11 Oct 2005 17:31:48 -0000 1.25 @@ -369,6 +369,10 @@ /* bring buffer timestamp to stream time */ render_time = render_diff; + /* adjust for rate */ + render_time /= ABS (bsink->segment_rate); + /* adjust for accumulated segments */ + render_time += bsink->segment_accum; /* add base time to get absolute clock time */ render_time += gst_element_get_base_time (GST_ELEMENT (bsink)); /* and bring the time to the offset in the buffer */ |
From: <wt...@fr...> - 2005-10-11 18:32:30
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Oct 11 2005 11:32:15 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_create): * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit), (gst_ring_buffer_read): Cleanups. Commit and read from ringbuffer in samples rather than bytes. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c gstbaseaudiosrc.c gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.1977&r2=1.1978 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.25&r2=1.26 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.12&r2=1.13 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.19&r2=1.20 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.1977 retrieving revision 1.1978 diff -u -d -r1.1977 -r1.1978 --- ChangeLog 11 Oct 2005 17:31:48 -0000 1.1977 +++ ChangeLog 11 Oct 2005 18:31:56 -0000 1.1978 @@ -2,6 +2,17 @@ * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_create): + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit), + (gst_ring_buffer_read): + Cleanups. + Commit and read from ringbuffer in samples rather than bytes. + +2005-10-11 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): Respect segment rate and accum when scheduling samples. 2005-10-11 Julien MOUTTE <ju...@mo...> Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- gstbaseaudiosink.c 11 Oct 2005 17:31:48 -0000 1.25 +++ gstbaseaudiosink.c 11 Oct 2005 18:32:01 -0000 1.26 @@ -340,21 +340,36 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) { guint64 render_offset, in_offset; - GstClockTime time, render_time; + GstClockTime time, render_time, duration; GstClockTimeDiff render_diff; - GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink); + GstBaseAudioSink *sink; + GstRingBuffer *ringbuf; gint64 diff; guint8 *data; guint size; + guint samples; + gint bps; + sink = GST_BASE_AUDIO_SINK (bsink); + ringbuf = sink->ringbuffer; /* can't do anything when we don't have the device */ - if (!gst_ring_buffer_is_acquired (sink->ringbuffer)) + if (!gst_ring_buffer_is_acquired (ringbuf)) goto wrong_state; + bps = ringbuf->spec.bytes_per_sample; + size = GST_BUFFER_SIZE (buf); + if (size % bps != 0) + goto wrong_size; + samples = size / bps; in_offset = GST_BUFFER_OFFSET (buf); time = GST_BUFFER_TIMESTAMP (buf); + duration = GST_BUFFER_DURATION (buf); data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT, GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); @@ -376,34 +391,42 @@ /* add base time to get absolute clock time */ render_time += gst_element_get_base_time (GST_ELEMENT (bsink)); /* and bring the time to the offset in the buffer */ - render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND; + render_offset = render_time * ringbuf->spec.rate / GST_SECOND; /* roundoff errors in timestamp conversion */ if (sink->next_sample != -1) diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); else - diff = sink->ringbuffer->spec.rate; + diff = ringbuf->spec.rate; GST_DEBUG ("render time %" GST_TIME_FORMAT - ", render offset %llu, diff %lld, size %lu", GST_TIME_ARGS (render_time), - render_offset, diff, size); + ", render offset %llu, diff %lld, samples %lu", + GST_TIME_ARGS (render_time), render_offset, diff, samples); /* we tollerate a 10th of a second diff before we start resyncing. This * should be enough to compensate for various rounding errors in the timestamp * and sample offset position. */ - if (diff < sink->ringbuffer->spec.rate / DIFF_TOLERANCE) { + if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) { GST_DEBUG ("align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, - sink->ringbuffer->spec.rate / DIFF_TOLERANCE); + ringbuf->spec.rate / DIFF_TOLERANCE); /* just align with previous sample then */ render_offset = sink->next_sample; } else { GST_DEBUG ("resync"); } - gst_ring_buffer_commit (sink->ringbuffer, render_offset, data, size); + /* clip length based on rate */ + samples /= ABS (bsink->segment_rate); /* the next sample should be current sample and its length */ - sink->next_sample = - render_offset + size / sink->ringbuffer->spec.bytes_per_sample; + sink->next_sample = render_offset + samples; + gst_ring_buffer_commit (ringbuf, render_offset, data, samples); + if (time + duration >= bsink->segment_stop) { + GST_DEBUG ("start playback because we are at the end of segment"); + gst_ring_buffer_start (ringbuf); + } return GST_FLOW_OK; @@ -414,6 +437,14 @@ ("sink not negotiated."), ("sink not negotiated.")); return GST_FLOW_NOT_NEGOTIATED; +wrong_size: + { + GST_DEBUG ("wrong size"); + GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND, + ("sink received buffer of wrong size."), + ("sink received buffer of wrong size.")); + return GST_FLOW_ERROR; } GstRingBuffer * Index: gstbaseaudiosrc.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- gstbaseaudiosrc.c 10 Oct 2005 17:04:24 -0000 1.12 +++ gstbaseaudiosrc.c 11 Oct 2005 18:32:01 -0000 1.13 @@ -308,7 +308,7 @@ GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (psrc); GstBuffer *buf; guchar *data; - guint len; + guint len, samples; guint res; guint64 sample; @@ -326,11 +326,13 @@ sample = 0; - res = gst_ring_buffer_read (src->ringbuffer, sample, data, len); + samples = len / src->ringbuffer->spec.bytes_per_sample; + res = gst_ring_buffer_read (src->ringbuffer, sample, data, samples); if (res == -1) goto stopped; - src->next_sample = sample + len / src->ringbuffer->spec.bytes_per_sample; + src->next_sample = sample + samples; gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc))); Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- gstringbuffer.c 6 Oct 2005 15:15:04 -0000 1.19 +++ gstringbuffer.c 11 Oct 2005 18:32:01 -0000 1.20 @@ -904,7 +904,7 @@ * @buf: the #GstRingBuffer to commit * @sample: the sample position of the data * @data: the data to commit - * @len: the length of the data to commit + * @len: the number of samples in the data to commit * * Commit @len samples pointed to by @data to the ringbuffer * @buf. The first sample should be written at position @sample in @@ -936,15 +936,15 @@ bps = buf->spec.bytes_per_sample; sps = buf->samples_per_seg; - /* write out all bytes */ + /* write out all samples */ while (len > 0) { - gint writelen; - gint writeseg, writeoff; + gint sampleslen; + gint writeseg, sampleoff; /* figure out the segment and the offset inside the segment where * the sample should be written. */ writeseg = sample / sps; - writeoff = (sample % sps) * bps; + sampleoff = (sample % sps); while (TRUE) { gint diff; @@ -957,13 +957,13 @@ GST_DEBUG ("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d", - segdone, sample, writeseg, writeoff, len, diff, segtotal, segsize); + segdone, sample, writeseg, sampleoff, len, diff, segtotal, sps); /* segment too far ahead, we need to drop */ if (diff < 0) { /* we need to drop one segment at a time, pretend we wrote a * segment. */ - writelen = MIN (segsize, len); + sampleslen = MIN (sps, len); goto next; } @@ -979,17 +979,18 @@ /* we can write now */ writeseg = writeseg % segtotal; - writelen = MIN (segsize - writeoff, len); + sampleslen = MIN (sps - sampleoff, len); GST_DEBUG ("write @%p seg %d, off %d, len %d", - dest + writeseg * segsize, writeseg, writeoff, writelen); + dest + writeseg * segsize, writeseg, sampleoff, sampleslen); - memcpy (dest + writeseg * segsize + writeoff, data, writelen); + memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data, + (sampleslen * bps)); next: - len -= writelen; - data += writelen; - sample += writelen / bps; + len -= sampleslen; + sample += sampleslen; + data += sampleslen * bps; return len; @@ -1007,9 +1008,9 @@ * @buf: the #GstRingBuffer to read from * @data: where the data should be read - * @len: the length of the data to read + * @len: the number of samples in data to read - * Read @length samples from the ringbuffer into the memory pointed + * Read @len samples from the ringbuffer into the memory pointed * to by @data. * The first sample should be read from position @sample in * the ringbuffer. @@ -1040,15 +1041,15 @@ - /* read enough bytes */ + /* read enough samples */ - gint readlen; - gint readseg, readoff; + gint readseg, sampleoff; readseg = sample / sps; - readoff = (sample % sps) * bps; @@ -1061,14 +1062,14 @@ ("pointer at %d, sample %llu, read from %d-%d, len %d, diff %d, segtotal %d, segsize %d", - segdone, sample, readseg, readoff, len, diff, segtotal, segsize); + segdone, sample, readseg, sampleoff, len, diff, segtotal, segsize); /* we need to drop one segment at a time, pretend we read an * empty segment. */ - readlen = MIN (segsize, len); - memcpy (data, buf->empty_seg, readlen); + memcpy (data, buf->empty_seg, sampleslen * bps); @@ -1084,17 +1085,18 @@ /* we can read now */ readseg = readseg % segtotal; - readlen = MIN (segsize - readoff, len); GST_DEBUG ("read @%p seg %d, off %d, len %d", - dest + readseg * segsize, readseg, readoff, readlen); + dest + readseg * segsize, readseg, sampleoff, sampleslen); - memcpy (data, dest + readseg * segsize + readoff, readlen); + memcpy (data, dest + (readseg * segsize) + (sampleoff * bps), - len -= readlen; - data += readlen; - sample += readlen / bps; |
From: <wt...@fr...> - 2005-10-24 14:52:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon Oct 24 2005 07:52:34 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): Buffers with no timestamps get aligned with previous buffers or on underrun, played ASAP. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2017&r2=1.2018 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.27&r2=1.28 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2017 retrieving revision 1.2018 diff -u -d -r1.2017 -r1.2018 --- ChangeLog 24 Oct 2005 13:36:39 -0000 1.2017 +++ ChangeLog 24 Oct 2005 14:52:22 -0000 1.2018 @@ -1,3 +1,10 @@ +2005-10-24 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): + Buffers with no timestamps get aligned with previous buffers or + on underrun, played ASAP. 2005-10-24 Julien MOUTTE <ju...@mo...> * gst-libs/gst/video/video.h: Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- gstbaseaudiosink.c 21 Oct 2005 15:14:36 -0000 1.27 +++ gstbaseaudiosink.c 24 Oct 2005 14:52:22 -0000 1.28 @@ -336,6 +336,38 @@ } } +static guint64 +gst_base_audio_sink_get_offset (GstBaseAudioSink * sink) +{ + guint64 sample; + gint writeseg, segdone, sps; + gint diff; + /* assume we can append to the previous sample */ + sample = sink->next_sample; + sps = sink->ringbuffer->samples_per_seg; + /* figure out the segment and the offset inside the segment where + * the sample should be written. */ + writeseg = sample / sps; + /* get the currently processed segment */ + segdone = g_atomic_int_get (&sink->ringbuffer->segdone) + - sink->ringbuffer->segbase; + /* see how far away it is from the write segment */ + diff = writeseg - segdone; + if (diff < 0) { + /* sample would be dropped, position to next playable position */ + sample = (segdone + 1) * sps; + } + g_print ("diff: %d\n", diff); + return sample; +} static GstFlowReturn gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) { @@ -375,7 +407,7 @@ GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); if (!GST_CLOCK_TIME_IS_VALID (time)) { - render_offset = sink->next_sample; + render_offset = gst_base_audio_sink_get_offset (sink); goto no_sync; @@ -423,7 +455,7 @@ no_sync: /* clip length based on rate */ - samples /= ABS (bsink->segment_rate); + samples = MIN (samples, samples / ABS (bsink->segment_rate)); /* the next sample should be current sample and its length */ sink->next_sample = render_offset + samples; |
From: <wt...@fr...> - 2005-10-24 15:00:13
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon Oct 24 2005 08:00:07 PDT Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): Remove g_print Use sync property from baseclass to disable sync. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2018&r2=1.2019 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.28&r2=1.29 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2018 retrieving revision 1.2019 diff -u -d -r1.2018 -r1.2019 --- ChangeLog 24 Oct 2005 14:52:22 -0000 1.2018 +++ ChangeLog 24 Oct 2005 14:59:55 -0000 1.2019 @@ -2,6 +2,13 @@ * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): + Remove g_print + Use sync property from baseclass to disable sync. + +2005-10-24 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): Buffers with no timestamps get aligned with previous buffers or on underrun, played ASAP. Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- gstbaseaudiosink.c 24 Oct 2005 14:52:22 -0000 1.28 +++ gstbaseaudiosink.c 24 Oct 2005 14:59:55 -0000 1.29 @@ -363,8 +363,6 @@ sample = (segdone + 1) * sps; } - g_print ("diff: %d\n", diff); - return sample; } @@ -406,7 +404,9 @@ GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT, GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start)); - if (!GST_CLOCK_TIME_IS_VALID (time)) { + /* if not valid timestamp or we don't need to sync, try to play + * sample ASAP */ + if (!GST_CLOCK_TIME_IS_VALID (time) || !bsink->sync) { render_offset = gst_base_audio_sink_get_offset (sink); goto no_sync; |
From: <wt...@fr...> - 2005-10-31 10:30:55
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Mon Oct 31 2005 02:30:53 PST Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_get_offset), (gst_base_audio_sink_render): * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_open_device), (gst_ring_buffer_close_device), (gst_ring_buffer_set_flushing), (gst_ring_buffer_start), (gst_ring_buffer_pause_unlocked), (gst_ring_buffer_pause), (gst_ring_buffer_stop), (wait_segment), (gst_ring_buffer_commit), (gst_ring_buffer_read): * gst-libs/gst/audio/gstringbuffer.h: Add flushing mode to the ringbuffer so that it in all cases does not try to handle more audio. This makes sure it does not try to block anymore when flushing and fixes a livelock. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c gstringbuffer.c gstringbuffer.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2034&r2=1.2035 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.29&r2=1.30 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.22&r2=1.23 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h.diff?r1=1.10&r2=1.11 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2034 retrieving revision 1.2035 diff -u -d -r1.2034 -r1.2035 --- ChangeLog 29 Oct 2005 13:39:20 -0000 1.2034 +++ ChangeLog 31 Oct 2005 10:30:41 -0000 1.2035 @@ -1,3 +1,19 @@ +2005-10-31 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_event), (gst_base_audio_sink_get_offset), + (gst_base_audio_sink_render): + * gst-libs/gst/audio/gstringbuffer.c: + (gst_ring_buffer_open_device), (gst_ring_buffer_close_device), + (gst_ring_buffer_set_flushing), (gst_ring_buffer_start), + (gst_ring_buffer_pause_unlocked), (gst_ring_buffer_pause), + (gst_ring_buffer_stop), (wait_segment), (gst_ring_buffer_commit), + (gst_ring_buffer_read): + * gst-libs/gst/audio/gstringbuffer.h: + Add flushing mode to the ringbuffer so that it in all cases does + not try to handle more audio. This makes sure it does not try to + block anymore when flushing and fixes a livelock. 2005-10-29 Tim-Philipp Müller <tim at centricular dot net> * ext/ogg/gstoggdemux.c: (gst_ogg_pad_query_convert), Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- gstbaseaudiosink.c 24 Oct 2005 14:59:55 -0000 1.29 +++ gstbaseaudiosink.c 31 Oct 2005 10:30:41 -0000 1.30 @@ -297,13 +297,12 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: - gst_ring_buffer_pause (sink->ringbuffer); - gst_ring_buffer_clear_all (sink->ringbuffer); + gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE); break; case GST_EVENT_FLUSH_STOP: /* always resync on sample after a flush */ sink->next_sample = -1; + gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE); case GST_EVENT_EOS: gst_ring_buffer_start (sink->ringbuffer); Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- gstringbuffer.c 18 Oct 2005 11:07:25 -0000 1.22 +++ gstringbuffer.c 31 Oct 2005 10:30:41 -0000 1.23 @@ -31,6 +31,8 @@ static void gst_ring_buffer_dispose (GObject * object); static void gst_ring_buffer_finalize (GObject * object); +static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf); static GstObjectClass *parent_class = NULL; /* ringbuffer abstract base class */ @@ -608,6 +610,28 @@ return res; } +/** + * gst_ring_buffer_set_flushing: + * @buf: the #GstRingBuffer to flush + * + * Set the ringbuffer to flushing mode or normal mode. + * MT safe. + */ +void +gst_ring_buffer_set_flushing (GstRingBuffer * buf, gboolean flushing) +{ + GST_LOCK (buf); + buf->flushing = flushing; + gst_ring_buffer_clear_all (buf); + if (flushing) { + gst_ring_buffer_pause_unlocked (buf); + } + GST_UNLOCK (buf); +} /** * gst_ring_buffer_start: @@ -631,6 +655,9 @@ GST_DEBUG_OBJECT (buf, "starting ringbuffer"); GST_LOCK (buf); + if (buf->flushing) + goto flushing; /* if stopped, set to started */ res = g_atomic_int_compare_and_exchange (&buf->state, GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED); @@ -669,29 +696,22 @@ GST_UNLOCK (buf); +flushing: + { + GST_UNLOCK (buf); + return FALSE; -/** - * gst_ring_buffer_pause: - * @buf: the #GstRingBuffer to pause - * - * Pause processing samples from the ringbuffer. - * Returns: TRUE if the device could be paused, FALSE on error. - * MT safe. - */ -gboolean -gst_ring_buffer_pause (GstRingBuffer * buf) +static gboolean +gst_ring_buffer_pause_unlocked (GstRingBuffer * buf) { gboolean res = FALSE; GstRingBufferClass *rclass; - g_return_val_if_fail (buf != NULL, FALSE); - GST_DEBUG_OBJECT (buf, "pausing ringbuffer"); - GST_LOCK (buf); /* if started, set to paused */ GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_PAUSED); @@ -718,9 +738,41 @@ } done: + return res; + * gst_ring_buffer_pause: + * @buf: the #GstRingBuffer to pause + * Pause processing samples from the ringbuffer. + * Returns: TRUE if the device could be paused, FALSE on error. +gboolean +gst_ring_buffer_pause (GstRingBuffer * buf) + gboolean res = FALSE; + g_return_val_if_fail (buf != NULL, FALSE); + res = gst_ring_buffer_pause_unlocked (buf); @@ -744,6 +796,9 @@ GST_DEBUG_OBJECT (buf, "stopping"); /* if started, set to stopped */ GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED); @@ -772,6 +827,12 @@ @@ -916,12 +977,17 @@ /* take lock first, then update our waiting flag */ if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) { GST_DEBUG ("waiting.."); if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED) goto not_started; GST_RING_BUFFER_WAIT (buf); + if (buf->flushing) + goto flushing; @@ -937,6 +1003,12 @@ GST_DEBUG ("stopped processing"); return FALSE; + GST_DEBUG ("flushing"); Index: gstringbuffer.h RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- gstringbuffer.h 24 Sep 2005 13:06:03 -0000 1.10 +++ gstringbuffer.h 31 Oct 2005 10:30:41 -0000 1.11 @@ -172,6 +172,8 @@ GstRingBufferCallback callback; gpointer cb_data; + gboolean flushing; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; }; @@ -224,6 +226,9 @@ gboolean gst_ring_buffer_is_acquired (GstRingBuffer *buf); +/* flushing */ +void gst_ring_buffer_set_flushing (GstRingBuffer *buf, gboolean flushing); /* playback/pause */ gboolean gst_ring_buffer_start (GstRingBuffer *buf); gboolean gst_ring_buffer_pause (GstRingBuffer *buf); |
From: <wt...@fr...> - 2005-11-08 11:42:16
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Nov 08 2005 03:42:04 PST Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_render): No need to do a typecheck. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2046&r2=1.2047 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.30&r2=1.31 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2046 retrieving revision 1.2047 diff -u -d -r1.2046 -r1.2047 --- ChangeLog 7 Nov 2005 19:42:38 -0000 1.2046 +++ ChangeLog 8 Nov 2005 11:41:52 -0000 1.2047 @@ -1,3 +1,9 @@ +2005-11-08 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_render): + No need to do a typecheck. 2005-11-07 Tim-Philipp Müller <tim at centricular dot net> * ext/alsa/gstalsa.h: Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- gstbaseaudiosink.c 31 Oct 2005 10:30:41 -0000 1.30 +++ gstbaseaudiosink.c 8 Nov 2005 11:41:52 -0000 1.31 @@ -426,7 +426,7 @@ /* adjust for accumulated segments */ render_time += bsink->segment_accum; /* add base time to get absolute clock time */ - render_time += gst_element_get_base_time (GST_ELEMENT (bsink)); + render_time += gst_element_get_base_time (GST_ELEMENT_CAST (bsink)); /* and bring the time to the offset in the buffer */ render_offset = render_time * ringbuf->spec.rate / GST_SECOND; |
From: <wt...@fr...> - 2005-11-16 12:17:20
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Nov 16 2005 04:17:18 PST Log message: * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_stop): Set ringbuffer to flushing when stopping so that we don't block on wait_segment anymore and livelock. Modified files: . : ChangeLog gst-libs/gst/audio: gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2081&r2=1.2082 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.23&r2=1.24 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2081 retrieving revision 1.2082 diff -u -d -r1.2081 -r1.2082 --- ChangeLog 16 Nov 2005 10:54:45 -0000 1.2081 +++ ChangeLog 16 Nov 2005 12:17:06 -0000 1.2082 @@ -1,5 +1,11 @@ 2005-11-16 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_stop): + Set ringbuffer to flushing when stopping so that we don't + block on wait_segment anymore and livelock. + +2005-11-16 Wim Taymans <wi...@fl...> * examples/seeking/seek.c: (send_event), (do_seek), (loop_toggle_cb), (segment_done), (main): Added looping checkbox. Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstringbuffer.c 31 Oct 2005 10:30:41 -0000 1.23 +++ gstringbuffer.c 16 Nov 2005 12:17:06 -0000 1.24 @@ -796,8 +796,7 @@ GST_DEBUG_OBJECT (buf, "stopping"); GST_LOCK (buf); - if (buf->flushing) - goto flushing; + buf->flushing = TRUE; /* if started, set to stopped */ res = g_atomic_int_compare_and_exchange (&buf->state, @@ -827,12 +826,6 @@ GST_UNLOCK (buf); return res; - -flushing: - { - GST_UNLOCK (buf); - return FALSE; - } } /** |
From: <wt...@fr...> - 2005-11-16 16:48:48
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Wed Nov 16 2005 08:48:47 PST Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_provide_clock), (gst_base_audio_sink_change_state): Set ringbuffer to non-flushing when going to PAUSED, set to flushing again when going to READY. * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_init), (gst_ring_buffer_stop): Start in flushing mode by default. Don't set flushing in the _stop method, let the app call this explicitly. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c gstringbuffer.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2084&r2=1.2085 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.31&r2=1.32 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c.diff?r1=1.24&r2=1.25 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2084 retrieving revision 1.2085 diff -u -d -r1.2084 -r1.2085 --- ChangeLog 16 Nov 2005 15:59:21 -0000 1.2084 +++ ChangeLog 16 Nov 2005 16:48:35 -0000 1.2085 @@ -1,3 +1,17 @@ +2005-11-16 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_provide_clock), + (gst_base_audio_sink_change_state): + Set ringbuffer to non-flushing when going to PAUSED, set to + flushing again when going to READY. + * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_init), + (gst_ring_buffer_stop): + Start in flushing mode by default. + Don't set flushing in the _stop method, let the app call + this explicitly. 2005-11-16 Julien MOUTTE <ju...@mo...> * gst-libs/gst/video/gstvideosink.c: (gst_video_sink_center_rect): Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- gstbaseaudiosink.c 8 Nov 2005 11:41:52 -0000 1.31 +++ gstbaseaudiosink.c 16 Nov 2005 16:48:35 -0000 1.32 @@ -162,10 +162,17 @@ gst_base_audio_sink_provide_clock (GstElement * elem) { GstBaseAudioSink *sink; + GstClock *clock; sink = GST_BASE_AUDIO_SINK (elem); - return GST_CLOCK (gst_object_ref (sink->clock)); +#if 1 + clock = GST_CLOCK_CAST (gst_object_ref (sink->clock)); +#else + clock = gst_system_clock_obtain (); +#endif + return clock; } static GstClockTime @@ -534,6 +541,7 @@ sink->next_sample = 0; break; case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE); case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -548,9 +556,10 @@ gst_ring_buffer_pause (sink->ringbuffer); case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE); gst_ring_buffer_stop (sink->ringbuffer); - gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL); gst_ring_buffer_release (sink->ringbuffer); + gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL); case GST_STATE_CHANGE_READY_TO_NULL: gst_ring_buffer_close_device (sink->ringbuffer); Index: gstringbuffer.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstringbuffer.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- gstringbuffer.c 16 Nov 2005 12:17:06 -0000 1.24 +++ gstringbuffer.c 16 Nov 2005 16:48:35 -0000 1.25 @@ -88,6 +88,7 @@ ringbuffer->cond = g_cond_new (); ringbuffer->waiting = 0; ringbuffer->empty_seg = NULL; + ringbuffer->flushing = TRUE; static void @@ -796,7 +797,6 @@ GST_DEBUG_OBJECT (buf, "stopping"); GST_LOCK (buf); - buf->flushing = TRUE; /* if started, set to stopped */ res = g_atomic_int_compare_and_exchange (&buf->state, |
From: <wt...@fr...> - 2005-11-17 14:40:27
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Thu Nov 17 2005 06:40:24 PST Log message: * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_change_state): Fix the audiosrc base class again, we did not unflush. Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2093&r2=1.2094 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c.diff?r1=1.13&r2=1.14 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2093 retrieving revision 1.2094 diff -u -d -r1.2093 -r1.2094 --- ChangeLog 17 Nov 2005 12:36:36 -0000 1.2093 +++ ChangeLog 17 Nov 2005 14:40:11 -0000 1.2094 @@ -1,3 +1,9 @@ +2005-11-17 Wim Taymans <wi...@fl...> + + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_change_state): + Fix the audiosrc base class again, we did not unflush. 2005-11-17 Julien MOUTTE <ju...@mo...> * examples/seeking/seek.c: (make_dv_pipeline), Index: gstbaseaudiosrc.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosrc.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- gstbaseaudiosrc.c 11 Oct 2005 18:32:01 -0000 1.13 +++ gstbaseaudiosrc.c 17 Nov 2005 14:40:12 -0000 1.14 @@ -396,6 +396,7 @@ src->next_sample = 0; break; case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_ring_buffer_set_flushing (src->ringbuffer, FALSE); case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -410,6 +411,7 @@ gst_ring_buffer_pause (src->ringbuffer); case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_ring_buffer_set_flushing (src->ringbuffer, TRUE); gst_ring_buffer_release (src->ringbuffer); |
From: <wt...@fr...> - 2005-11-22 18:55:11
|
CVS Root: /cvs/gstreamer Module: gst-plugins-base Changes by: wtay Date: Tue Nov 22 2005 10:55:08 PST Log message: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_class_init), (gst_base_audio_sink_set_clock), (gst_base_audio_sink_render), (gst_base_audio_sink_change_state): And we provide a clock by default, of course... Modified files: . : ChangeLog gst-libs/gst/audio: gstbaseaudiosink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.2132&r2=1.2133 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c.diff?r1=1.34&r2=1.35 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v retrieving revision 1.2132 retrieving revision 1.2133 diff -u -d -r1.2132 -r1.2133 --- ChangeLog 22 Nov 2005 18:32:08 -0000 1.2132 +++ ChangeLog 22 Nov 2005 18:54:55 -0000 1.2133 @@ -1,5 +1,12 @@ 2005-11-22 Wim Taymans <wi...@fl...> + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_class_init), (gst_base_audio_sink_set_clock), + (gst_base_audio_sink_render), (gst_base_audio_sink_change_state): + And we provide a clock by default, of course... + +2005-11-22 Wim Taymans <wi...@fl...> * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init): This clock can be slaved to a master clock now. Index: gstbaseaudiosink.c RCS file: /cvs/gstreamer/gst-plugins-base/gst-libs/gst/audio/gstbaseaudiosink.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- gstbaseaudiosink.c 22 Nov 2005 18:32:09 -0000 1.34 +++ gstbaseaudiosink.c 22 Nov 2005 18:54:56 -0000 1.35 @@ -41,8 +41,7 @@ #define DEFAULT_BUFFER_TIME 500 * GST_USECOND #define DEFAULT_LATENCY_TIME 10 * GST_USECOND -//#define DEFAULT_PROVIDE_CLOCK TRUE -#define DEFAULT_PROVIDE_CLOCK FALSE +#define DEFAULT_PROVIDE_CLOCK TRUE enum { |