diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2005-03-04 10:16:10 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2005-03-04 10:16:10 +0000 |
commit | c3d4f38a24c3a17c4b883a61a87e6a2d9a3c6a0d (patch) | |
tree | bfb16e6a10cddec4c13274cf72a85fb3aff2aaf7 | |
parent | 5e601af29d7462dede8dee14185467590c3adefe (diff) |
More work on subclassing the sinks from the basesink.BRANCH-THREADED
Original commit message from CVS:
More work on subclassing the sinks from the basesink.
First attempt at generic audiosink base objects.
Make oss DMA audiosink.
-rw-r--r-- | ChangeLog | 61 | ||||
-rw-r--r-- | examples/seeking/seek.c | 2 | ||||
-rw-r--r-- | sys/oss/Makefile.am | 10 | ||||
-rw-r--r-- | sys/oss/gstossdmabuffer.c | 316 | ||||
-rw-r--r-- | sys/oss/gstossdmabuffer.h | 77 | ||||
-rw-r--r-- | sys/oss/gstosselement.c | 58 | ||||
-rw-r--r-- | sys/oss/gstosselement.h | 5 | ||||
-rw-r--r-- | sys/oss/gstosssink.c | 321 | ||||
-rw-r--r-- | sys/oss/gstosssink.h | 29 |
9 files changed, 592 insertions, 287 deletions
@@ -1,3 +1,64 @@ +2005-03-04 Wim Taymans <wim@fluendo.com> + + * examples/seeking/seek.c: + * ext/theora/theoraenc.c: (theora_enc_sink_event), + (theora_enc_chain): + * ext/vorbis/vorbisenc.c: (gst_vorbisenc_sink_event), + (gst_vorbisenc_chain): + * gst-libs/gst/audio/Makefile.am: + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_baseaudiosink_base_init), (gst_baseaudiosink_class_init), + (gst_baseaudiosink_init), (gst_baseaudiosink_set_property), + (gst_baseaudiosink_get_property), (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_class_init), (gst_ringbuffer_init), + (gst_ringbuffer_dispose), (gst_ringbuffer_finalize), + (gst_ringbuffer_set_callback), (gst_ringbuffer_acquire), + (gst_ringbuffer_release), (gst_ringbuffer_play), + (gst_ringbuffer_stop), (gst_ringbuffer_callback), + (gst_ringbuffer_write): + * gst-libs/gst/audio/gstringbuffer.h: + * gst-libs/gst/video/Makefile.am: + * gst-libs/gst/video/gstvideosink.c: (gst_videosink_init), + (gst_videosink_class_init), (gst_videosink_get_type): + * gst-libs/gst/video/videosink.h: + * sys/oss/Makefile.am: + * sys/oss/gstossdmabuffer.c: (gst_ossdmabuffer_get_type), + (gst_ossdmabuffer_class_init), (gst_ossdmabuffer_init), + (gst_ossdmabuffer_dispose), (gst_ossdmabuffer_finalize), + (gst_ossdmabuffer_func), (gst_ossdmabuffer_acquire), + (gst_ossdmabuffer_release), (gst_ossdmabuffer_play), + (gst_ossdmabuffer_stop): + * sys/oss/gstossdmabuffer.h: + * sys/oss/gstosselement.c: (gst_osselement_class_init), + (gst_osselement_parse_caps), (gst_osselement_sync_parms), + (gst_osselement_open_audio): + * sys/oss/gstosselement.h: + * sys/oss/gstosssink.c: (gst_osssink_get_type), + (gst_osssink_gettemplate), (gst_osssink_class_init), + (gst_osssink_init), (gst_osssink_getcaps), (gst_osssink_get_delay), + (gst_osssink_get_time), (gst_osssink_create_ringbuffer), + (gst_osssink_render), (gst_osssink_convert), + (gst_osssink_sink_query), (gst_osssink_query), + (gst_osssink_set_property), (gst_osssink_get_property), + (gst_osssink_change_state): + * sys/oss/gstosssink.h: + * sys/xvimage/xvimagesink.c: (gst_xvimagesink_getcaps), + (gst_xvimagesink_setcaps), (gst_xvimagesink_change_state), + (gst_xvimagesink_get_times), (gst_xvimagesink_show_frame), + (gst_xvimagesink_chain), (gst_xvimagesink_buffer_alloc), + (gst_xvimagesink_init), (gst_xvimagesink_get_template), + (gst_xvimagesink_class_init): + * sys/xvimage/xvimagesink.h: + More work on subclassing the sinks from the basesink. + First attempt at generic audiosink base objects. + Make oss DMA audiosink. + 2005-02-20 Ronald S. Bultje <rbultje@ronald.bitfreak.net> * gst/avi/gstavidemux.c: (gst_avi_demux_index_next), diff --git a/examples/seeking/seek.c b/examples/seeking/seek.c index 81ba7d8f4..ef73db6b8 100644 --- a/examples/seeking/seek.c +++ b/examples/seeking/seek.c @@ -27,7 +27,7 @@ static gulong changed_id; /* number of milliseconds to play for after a seek */ #define SCRUB_TIME 250 -#undef SCRUB +#define SCRUB #define THREAD #define PAD_SEEK diff --git a/sys/oss/Makefile.am b/sys/oss/Makefile.am index 0f1d17ed7..5b7e829b2 100644 --- a/sys/oss/Makefile.am +++ b/sys/oss/Makefile.am @@ -4,15 +4,17 @@ libgstossaudio_la_SOURCES = gstossaudio.c \ gstosselement.c \ gstossmixer.c \ gstosssink.c \ + gstossdmabuffer.c \ gstosssrc.c libgstossaudio_la_CFLAGS = $(GST_CFLAGS) libgstossaudio_la_LIBADD = $(top_builddir)/gst-libs/gst/libgstinterfaces-@GST_MAJORMINOR@.la -libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstossaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) ../../../gstreamer2/gst/base/libgstbase.la -noinst_HEADERS = gstosssink.h \ - gstosssrc.h \ - gstosselement.h\ +noinst_HEADERS = gstosssink.h \ + gstosssrc.h \ + gstosselement.h \ + gstossdmabuffer.h \ gstossmixer.h noinst_PROGRAMS = oss_probe diff --git a/sys/oss/gstossdmabuffer.c b/sys/oss/gstossdmabuffer.c new file mode 100644 index 000000000..47e06d125 --- /dev/null +++ b/sys/oss/gstossdmabuffer.c @@ -0,0 +1,316 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2005 Wim Taymans <wim@fluendo.com> + * + * gstossdmabuffer.c: + * + * 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/soundcard.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <pthread.h> + +#include "gstossdmabuffer.h" + +static void gst_ossdmabuffer_class_init (GstOssDMABufferClass * klass); +static void gst_ossdmabuffer_init (GstOssDMABuffer * ossdmabuffer); +static void gst_ossdmabuffer_dispose (GObject * object); +static void gst_ossdmabuffer_finalize (GObject * object); + +static gboolean gst_ossdmabuffer_acquire (GstRingBuffer * buf, + GstRingBufferSpec * spec); +static gboolean gst_ossdmabuffer_release (GstRingBuffer * buf); +static gboolean gst_ossdmabuffer_play (GstRingBuffer * buf); +static gboolean gst_ossdmabuffer_stop (GstRingBuffer * buf); + +static GstRingBufferClass *parent_class = NULL; + +GType +gst_ossdmabuffer_get_type (void) +{ + static GType ossdmabuffer_type = 0; + + if (!ossdmabuffer_type) { + static const GTypeInfo ossdmabuffer_info = { + sizeof (GstOssDMABufferClass), + NULL, + NULL, + (GClassInitFunc) gst_ossdmabuffer_class_init, + NULL, + NULL, + sizeof (GstOssDMABuffer), + 0, + (GInstanceInitFunc) gst_ossdmabuffer_init, + NULL + }; + + ossdmabuffer_type = + g_type_register_static (GST_TYPE_RINGBUFFER, "GstOssDMABuffer", + &ossdmabuffer_info, 0); + } + return ossdmabuffer_type; +} + +static void +gst_ossdmabuffer_class_init (GstOssDMABufferClass * klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstRingBufferClass *gstringbuffer_class; + + gobject_class = (GObjectClass *) klass; + gstobject_class = (GstObjectClass *) klass; + gstringbuffer_class = (GstRingBufferClass *) klass; + + parent_class = g_type_class_ref (GST_TYPE_RINGBUFFER); + + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ossdmabuffer_dispose); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ossdmabuffer_finalize); + + gstringbuffer_class->acquire = gst_ossdmabuffer_acquire; + gstringbuffer_class->release = gst_ossdmabuffer_release; + gstringbuffer_class->play = gst_ossdmabuffer_play; + gstringbuffer_class->stop = gst_ossdmabuffer_stop; +} + +static void +gst_ossdmabuffer_init (GstOssDMABuffer * ossdmabuffer) +{ + ossdmabuffer->cond = g_cond_new (); + ossdmabuffer->element = g_object_new (GST_TYPE_OSSELEMENT, NULL); +} + +static void +gst_ossdmabuffer_dispose (GObject * object) +{ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_ossdmabuffer_finalize (GObject * object) +{ + GstOssDMABuffer *obuf = (GstOssDMABuffer *) object; + + g_cond_free (obuf->cond); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_ossdmabuffer_func (GstRingBuffer * buf) +{ + fd_set writeset; + struct count_info count; + GstOssDMABuffer *obuf = (GstOssDMABuffer *) buf; + + GST_LOCK (buf); + while (obuf->running) { + if (buf->state == GST_RINGBUFFER_STATE_PLAYING) { + int segsize; + + GST_UNLOCK (buf); + + segsize = buf->spec.segsize; + + FD_ZERO (&writeset); + FD_SET (obuf->fd, &writeset); + + select (obuf->fd + 1, NULL, &writeset, NULL, NULL); + + if (ioctl (obuf->fd, SNDCTL_DSP_GETOPTR, &count) == -1) { + perror ("GETOPTR"); + continue; + } + + if (count.blocks > buf->spec.segtotal) + count.blocks = buf->spec.segtotal; + + gst_ringbuffer_callback (buf, count.blocks); + + GST_LOCK (buf); + } else { + GST_OSSDMABUFFER_SIGNAL (obuf); + GST_OSSDMABUFFER_WAIT (obuf); + } + } + GST_UNLOCK (buf); +} + +static gboolean +gst_ossdmabuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec) +{ + int tmp; + struct audio_buf_info info; + GstOssDMABuffer *obuf = (GstOssDMABuffer *) buf;; + caddr_t mmap_buf; + int mode; + gint size; + gboolean parsed; + + parsed = gst_osselement_parse_caps (obuf->element, spec->caps); + if (!parsed) + return FALSE; + + mode = O_RDWR; + mode |= O_NONBLOCK; + + obuf->fd = open ("/dev/dsp", mode, 0); + if (obuf->fd == -1) { + perror ("OPEN"); + return FALSE; + } + //obuf->frag = 0x00040008; + obuf->frag = 0xffff000a; + + tmp = obuf->element->format; + if (ioctl (obuf->fd, SNDCTL_DSP_SETFMT, &tmp) == -1) { + perror ("SETFMT"); + return FALSE; + } + + tmp = obuf->element->channels; + if (ioctl (obuf->fd, SNDCTL_DSP_STEREO, &tmp) == -1) { + perror ("STEREO"); + return FALSE; + } + + tmp = obuf->element->channels; + if (ioctl (obuf->fd, SNDCTL_DSP_CHANNELS, &tmp) == -1) { + perror ("CHANNELS"); + return FALSE; + } + + tmp = obuf->element->rate; + if (ioctl (obuf->fd, SNDCTL_DSP_SPEED, &tmp) == -1) { + perror ("SPEED"); + return FALSE; + } + + if (ioctl (obuf->fd, SNDCTL_DSP_GETCAPS, &obuf->caps) == -1) { + perror ("/dev/dsp"); + fprintf (stderr, "Sorry but your sound driver is too old\n"); + return FALSE; + } + + if (!(obuf->caps & DSP_CAP_TRIGGER) || !(obuf->caps & DSP_CAP_MMAP)) { + fprintf (stderr, "Sorry but your soundcard can't do this\n"); + return FALSE; + } + + if (ioctl (obuf->fd, SNDCTL_DSP_SETFRAGMENT, &obuf->frag) == -1) { + perror ("SETFRAGMENT"); + return FALSE; + } + + if (ioctl (obuf->fd, SNDCTL_DSP_GETOSPACE, &info) == -1) { + perror ("GETOSPACE"); + return FALSE; + } + + buf->spec.segsize = info.fragsize; + buf->spec.segtotal = info.fragstotal; + size = info.fragsize * info.fragstotal; + g_print ("segsize %d, segtotal %d\n", info.fragsize, info.fragstotal); + + mmap_buf = (caddr_t) mmap (NULL, size, PROT_WRITE, + MAP_FILE | MAP_SHARED, obuf->fd, 0); + + if ((caddr_t) mmap_buf == (caddr_t) - 1) { + perror ("mmap (write)"); + return FALSE; + } + + buf->data = gst_buffer_new (); + GST_BUFFER_DATA (buf->data) = mmap_buf; + GST_BUFFER_SIZE (buf->data) = size; + GST_BUFFER_FLAG_SET (buf->data, GST_BUFFER_DONTFREE); + + tmp = 0; + if (ioctl (obuf->fd, SNDCTL_DSP_SETTRIGGER, &tmp) == -1) { + perror ("SETTRIGGER"); + return FALSE; + } + + GST_LOCK (obuf); + obuf->running = TRUE; + obuf->thread = g_thread_create ((GThreadFunc) gst_ossdmabuffer_func, + buf, TRUE, NULL); + GST_OSSDMABUFFER_WAIT (obuf); + GST_UNLOCK (obuf); + + return TRUE; +} + +static gboolean +gst_ossdmabuffer_release (GstRingBuffer * buf) +{ + GstOssDMABuffer *obuf = (GstOssDMABuffer *) buf;; + + gst_buffer_unref (buf->data); + + GST_LOCK (obuf); + obuf->running = FALSE; + GST_OSSDMABUFFER_SIGNAL (obuf); + GST_UNLOCK (obuf); + + g_thread_join (obuf->thread); + + return TRUE; +} + +static gboolean +gst_ossdmabuffer_play (GstRingBuffer * buf) +{ + int tmp; + GstOssDMABuffer *obuf; + + obuf = (GstOssDMABuffer *) buf; + + tmp = PCM_ENABLE_OUTPUT; + if (ioctl (obuf->fd, SNDCTL_DSP_SETTRIGGER, &tmp) == -1) { + perror ("SETTRIGGER"); + } + GST_OSSDMABUFFER_SIGNAL (obuf); + + return TRUE; +} + +static gboolean +gst_ossdmabuffer_stop (GstRingBuffer * buf) +{ + int tmp; + GstOssDMABuffer *obuf; + + obuf = (GstOssDMABuffer *) buf; + + tmp = 0; + if (ioctl (obuf->fd, SNDCTL_DSP_SETTRIGGER, &tmp) == -1) { + perror ("SETTRIGGER"); + } + GST_OSSDMABUFFER_WAIT (obuf); + buf->playseg = 0; + + return TRUE; +} diff --git a/sys/oss/gstossdmabuffer.h b/sys/oss/gstossdmabuffer.h new file mode 100644 index 000000000..3a2c6ea7e --- /dev/null +++ b/sys/oss/gstossdmabuffer.h @@ -0,0 +1,77 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2005 Wim Taymans <wim@fluendo.com> + * + * gstossdmabuffer.h: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_OSSDMABUFFER_H__ +#define __GST_OSSDMABUFFER_H__ + +#include <gst/gst.h> + +#include "gstosselement.h" +#include <gst/audio/gstringbuffer.h> + +G_BEGIN_DECLS + +#define GST_TYPE_OSSDMABUFFER (gst_ossdmabuffer_get_type()) +#define GST_OSSDMABUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSDMABUFFER,GstOssDMABuffer)) +#define GST_OSSDMABUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSDMABUFFER,GstOssDMABufferClass)) +#define GST_IS_OSSDMABUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSDMABUFFER)) +#define GST_IS_OSSDMABUFFER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSDMABUFFER)) + +#define GST_OSSELEMENT_GET(obj) GST_OSSELEMENT (obj->element) + +typedef enum { + GST_OSSDMABUFFER_OPEN = (1 << 0), +} GstOssDMABufferFlags; + +typedef struct _GstOssDMABuffer GstOssDMABuffer; +typedef struct _GstOssDMABufferClass GstOssDMABufferClass; + +#define GST_OSSDMABUFFER_THREAD(buf) (GST_OSSDMABUFFER(buf)->thread) +#define GST_OSSDMABUFFER_LOCK GST_LOCK +#define GST_OSSDMABUFFER_UNLOCK GST_UNLOCK +#define GST_OSSDMABUFFER_COND(buf) (GST_OSSDMABUFFER(buf)->cond) +#define GST_OSSDMABUFFER_SIGNAL(buf) (g_cond_signal (GST_OSSDMABUFFER_COND (buf))) +#define GST_OSSDMABUFFER_WAIT(buf) (g_cond_wait (GST_OSSDMABUFFER_COND (buf), GST_GET_LOCK (buf))) + +struct _GstOssDMABuffer { + GstRingBuffer buffer; + + GstOssElement *element; + + int fd; + int caps; + int frag; + + GThread *thread; + GCond *cond; + gboolean running; +}; + +struct _GstOssDMABufferClass { + GstRingBufferClass parent_class; +}; + +GType gst_ossdmabuffer_get_type(void); + +G_END_DECLS + +#endif /* __GST_OSSDMABUFFER_H__ */ diff --git a/sys/oss/gstosselement.c b/sys/oss/gstosselement.c index 649d28427..730e29767 100644 --- a/sys/oss/gstosselement.c +++ b/sys/oss/gstosselement.c @@ -78,7 +78,6 @@ static void gst_osselement_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_osselement_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstElementStateReturn gst_osselement_change_state (GstElement * element); static GstElementClass *parent_class = NULL; @@ -166,8 +165,6 @@ gst_osselement_class_init (GstOssElementClass * klass) NULL, G_PARAM_READABLE)); gobject_class->finalize = gst_osselement_finalize; - - gstelement_class->change_state = gst_osselement_change_state; } static const GList * @@ -606,8 +603,10 @@ gst_osselement_sync_parms (GstOssElement * oss) /* gint fragscale, frag_ln; */ - if (oss->fd == -1) + if (oss->fd == -1) { + GST_INFO ("osselement: no fd"); return FALSE; + } if ((oss->fragment & 0xFFFF) == 0) { frag = 0; @@ -681,31 +680,16 @@ gst_osselement_sync_parms (GstOssElement * oss) return TRUE; } -static gboolean -gst_osselement_open_audio (GstOssElement * oss) +gboolean +gst_osselement_open_audio (GstOssElement * oss, GstOssOpenMode mode) { gint caps; - GstOssOpenMode mode = GST_OSSELEMENT_READ; - const GList *padlist; g_return_val_if_fail (oss->fd == -1, FALSE); GST_INFO ("osselement: attempting to open sound device"); - /* Ok, so how do we open the device? We assume that we have (max.) one - * pad, and if this is a sinkpad, we're osssink (w). else, we're osssrc (r) */ - GST_LOCK (oss); - padlist = GST_ELEMENT (oss)->pads; - if (padlist != NULL) { - GstPad *firstpad = padlist->data; - - if (GST_PAD_IS_SINK (firstpad)) { - mode = GST_OSSELEMENT_WRITE; - } - GST_UNLOCK (oss); - } else { - GST_UNLOCK (oss); + if (mode == GST_OSSELEMENT_MIXER) goto do_mixer; - } /* first try to open the sound card */ if (mode == GST_OSSELEMENT_WRITE) { @@ -831,7 +815,7 @@ do_mixer: return TRUE; } -static void +void gst_osselement_close_audio (GstOssElement * oss) { gst_ossmixer_free_list (oss); @@ -974,34 +958,6 @@ gst_osselement_get_property (GObject * object, } } -static GstElementStateReturn -gst_osselement_change_state (GstElement * element) -{ - GstOssElement *oss = GST_OSSELEMENT (element); - - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - if (!gst_osselement_open_audio (oss)) { - return GST_STATE_FAILURE; - } - GST_INFO ("osselement: opened sound device"); - break; - case GST_STATE_READY_TO_NULL: - gst_osselement_close_audio (oss); - gst_osselement_reset (oss); - GST_INFO ("osselement: closed sound device"); - break; - default: - break; - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return GST_STATE_SUCCESS; -} - - /* rate probing code */ diff --git a/sys/oss/gstosselement.h b/sys/oss/gstosselement.h index fb161ad63..20d5e485d 100644 --- a/sys/oss/gstosselement.h +++ b/sys/oss/gstosselement.h @@ -51,6 +51,7 @@ typedef struct _GstOssElementClass GstOssElementClass; typedef enum { GST_OSSELEMENT_READ, GST_OSSELEMENT_WRITE, + GST_OSSELEMENT_MIXER, } GstOssOpenMode; typedef struct _GstOssDeviceCombination { @@ -115,8 +116,12 @@ gboolean gst_osselement_parse_caps (GstOssElement *oss, gboolean gst_osselement_merge_fixed_caps (GstOssElement *oss, GstCaps *caps); +gboolean gst_osselement_open_audio (GstOssElement *oss, GstOssOpenMode mode); gboolean gst_osselement_sync_parms (GstOssElement *oss); void gst_osselement_reset (GstOssElement *oss); +void gst_osselement_close_audio (GstOssElement *oss); + + gboolean gst_osselement_convert (GstOssElement *oss, GstFormat src_format, diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c index ff5bddb54..e327f7c8f 100644 --- a/sys/oss/gstosssink.c +++ b/sys/oss/gstosssink.c @@ -43,6 +43,7 @@ #endif /* HAVE_OSS_INCLUDE_IN_SYS */ #include "gstosssink.h" +#include "gstossdmabuffer.h" /* elementfactory information */ static GstElementDetails gst_osssink_details = @@ -58,9 +59,9 @@ static void gst_osssink_init (GstOssSink * osssink); static void gst_osssink_dispose (GObject * object); static GstElementStateReturn gst_osssink_change_state (GstElement * element); -static void gst_osssink_set_clock (GstElement * element, GstClock * clock); static GstClock *gst_osssink_get_clock (GstElement * element); static GstClockTime gst_osssink_get_time (GstClock * clock, gpointer data); +static GstRingBuffer *gst_osssink_create_ringbuffer (GstBaseAudioSink * bsink); static const GstFormat *gst_osssink_get_formats (GstPad * pad); static gboolean gst_osssink_convert (GstPad * pad, GstFormat src_format, @@ -71,24 +72,27 @@ static gboolean gst_osssink_query (GstElement * element, GstQueryType type, static gboolean gst_osssink_sink_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value); -static GstCaps *gst_osssink_getcaps (GstPad * pad); -static gboolean gst_osssink_setcaps (GstPad * pad, GstCaps * caps); +static GstCaps *gst_osssink_getcaps (GstBaseSink * bsink); + +//static gboolean gst_osssink_setcaps (GstBaseSink *bsink, GstCaps *caps); static void gst_osssink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_osssink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstFlowReturn gst_osssink_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_osssink_handle_event (GstPad * pad, GstEvent * event); - /* OssSink signals and args */ enum { - SIGNAL_HANDOFF, LAST_SIGNAL }; +#define DEFAULT_MUTE FALSE +#define DEFAULT_FRAGMENT 6 +#define DEFAULT_BUFFER_SIZE 4096 +#define DEFAULT_SYNC TRUE +#define DEFAULT_CHUNK_SIZE 4096 + enum { ARG_0, @@ -118,7 +122,8 @@ static GstStaticPadTemplate osssink_sink_factory = ); static GstElementClass *parent_class = NULL; -static guint gst_osssink_signals[LAST_SIGNAL] = { 0 }; + +/* static guint gst_osssink_signals[LAST_SIGNAL] = { 0 }; */ GType gst_osssink_get_type (void) @@ -139,7 +144,7 @@ gst_osssink_get_type (void) }; osssink_type = - g_type_register_static (GST_TYPE_OSSELEMENT, "GstOssSink", + g_type_register_static (GST_TYPE_BASEAUDIOSINK, "GstOssSink", &osssink_info, 0); } @@ -159,6 +164,12 @@ gst_osssink_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } +static GstStaticPadTemplate * +gst_osssink_gettemplate (GstBaseSink * bsink) +{ + return &osssink_sink_factory; +} + static void gst_osssink_base_init (gpointer g_class) { @@ -173,114 +184,119 @@ gst_osssink_class_init (GstOssSinkClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; + GstBaseAudioSinkClass *gstbaseaudiosink_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + gstbasesink_class = (GstBaseSinkClass *) klass; + gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass; - parent_class = g_type_class_ref (GST_TYPE_OSSELEMENT); + parent_class = g_type_class_ref (GST_TYPE_BASEAUDIOSINK); gobject_class->set_property = gst_osssink_set_property; gobject_class->get_property = gst_osssink_get_property; g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MUTE, g_param_spec_boolean ("mute", "Mute", "Mute the audio", - FALSE, G_PARAM_READWRITE)); + DEFAULT_MUTE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC, g_param_spec_boolean ("sync", "Sync", - "If syncing on timestamps should be enabled", TRUE, + "If syncing on timestamps should be enabled", DEFAULT_SYNC, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FRAGMENT, g_param_spec_int ("fragment", "Fragment", "The fragment as 0xMMMMSSSS (MMMM = total fragments, 2^SSSS = fragment size)", - 0, G_MAXINT, 6, G_PARAM_READWRITE)); + 0, G_MAXINT, DEFAULT_FRAGMENT, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFER_SIZE, g_param_spec_uint ("buffer_size", "Buffer size", - "Size of buffers in osssink's bufferpool (bytes)", 0, G_MAXINT, 4096, - G_PARAM_READWRITE)); + "Size of buffers in osssink's bufferpool (bytes)", 0, G_MAXINT, + DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHUNK_SIZE, g_param_spec_uint ("chunk_size", "Chunk size", - "Write data in chunk sized buffers", 0, G_MAXUINT, 4096, + "Write data in chunk sized buffers", 0, G_MAXUINT, DEFAULT_CHUNK_SIZE, G_PARAM_READWRITE)); - gst_osssink_signals[SIGNAL_HANDOFF] = - g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstOssSinkClass, handoff), NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - gobject_class->dispose = gst_osssink_dispose; gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_osssink_change_state); gstelement_class->query = GST_DEBUG_FUNCPTR (gst_osssink_query); - gstelement_class->set_clock = gst_osssink_set_clock; gstelement_class->get_clock = gst_osssink_get_clock; + gstbasesink_class->get_template = GST_DEBUG_FUNCPTR (gst_osssink_gettemplate); + gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_osssink_getcaps); + //gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_osssink_setcaps); + + gstbaseaudiosink_class->create_ringbuffer = + GST_DEBUG_FUNCPTR (gst_osssink_create_ringbuffer); } static void gst_osssink_init (GstOssSink * osssink) { - osssink->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get - (&osssink_sink_factory), "sink"); - gst_element_add_pad (GST_ELEMENT (osssink), osssink->sinkpad); - gst_pad_set_getcaps_function (osssink->sinkpad, gst_osssink_getcaps); - gst_pad_set_setcaps_function (osssink->sinkpad, gst_osssink_setcaps); - //gst_pad_set_fixate_function (osssink->sinkpad, gst_osssink_sink_fixate); - gst_pad_set_convert_function (osssink->sinkpad, gst_osssink_convert); - gst_pad_set_query_function (osssink->sinkpad, gst_osssink_sink_query); - gst_pad_set_query_type_function (osssink->sinkpad, - gst_osssink_get_query_types); - gst_pad_set_formats_function (osssink->sinkpad, gst_osssink_get_formats); - - gst_pad_set_event_function (osssink->sinkpad, gst_osssink_handle_event); - gst_pad_set_chain_function (osssink->sinkpad, gst_osssink_chain); + GstPad *sinkpad; + + sinkpad = GST_BASESINK_PAD (osssink); + + osssink->element = g_object_new (GST_TYPE_OSSELEMENT, NULL); + + gst_pad_set_convert_function (sinkpad, gst_osssink_convert); + gst_pad_set_query_function (sinkpad, gst_osssink_sink_query); + gst_pad_set_query_type_function (sinkpad, gst_osssink_get_query_types); + gst_pad_set_formats_function (sinkpad, gst_osssink_get_formats); GST_DEBUG ("initializing osssink"); - osssink->bufsize = 4096; - osssink->chunk_size = 4096; - osssink->mute = FALSE; - osssink->sync = TRUE; + + osssink->bufsize = DEFAULT_BUFFER_SIZE; + osssink->chunk_size = DEFAULT_CHUNK_SIZE; + osssink->mute = DEFAULT_MUTE; + osssink->sync = DEFAULT_SYNC; + osssink->provided_clock = gst_audio_clock_new ("ossclock", gst_osssink_get_time, osssink); gst_audio_clock_set_active (GST_AUDIO_CLOCK (osssink->provided_clock), TRUE); gst_object_set_parent (GST_OBJECT (osssink->provided_clock), GST_OBJECT (osssink)); + osssink->handled = 0; } +/* static gboolean -gst_osssink_setcaps (GstPad * pad, GstCaps * caps) +gst_osssink_setcaps (GstBaseSink *bsink, GstCaps *caps) { - GstOssSink *osssink = GST_OSSSINK (GST_PAD_PARENT (pad)); + GstOssSink *osssink = GST_OSSSINK (bsink); - if (!gst_osselement_parse_caps (GST_OSSELEMENT (osssink), caps)) { + if (!gst_osselement_parse_caps (GST_OSSELEMENT_GET (osssink), caps)) { GST_ELEMENT_ERROR (osssink, CORE, NEGOTIATION, (NULL), - ("received unkown format")); + ("received unkown format")); gst_element_abort_preroll (GST_ELEMENT (osssink)); return FALSE; } - if (!gst_osselement_sync_parms (GST_OSSELEMENT (osssink))) { + if (!gst_osselement_sync_parms (GST_OSSELEMENT_GET (osssink))) { GST_ELEMENT_ERROR (osssink, CORE, NEGOTIATION, (NULL), - ("received unkown format")); + ("received unkown format")); gst_element_abort_preroll (GST_ELEMENT (osssink)); return FALSE; } - return TRUE; } +*/ static GstCaps * -gst_osssink_getcaps (GstPad * pad) +gst_osssink_getcaps (GstBaseSink * bsink) { - GstOssSink *osssink = GST_OSSSINK (GST_PAD_PARENT (pad)); + GstOssSink *osssink = GST_OSSSINK (bsink); GstCaps *caps; - gst_osselement_probe_caps (GST_OSSELEMENT (osssink)); + gst_osselement_probe_caps (GST_OSSELEMENT_GET (osssink)); - if (GST_OSSELEMENT (osssink)->probed_caps == NULL) { - caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + if (GST_OSSELEMENT_GET (osssink)->probed_caps == NULL) { + caps = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASESINK_PAD + (bsink))); } else { - caps = gst_caps_copy (GST_OSSELEMENT (osssink)->probed_caps); + caps = gst_caps_ref (GST_OSSELEMENT_GET (osssink)->probed_caps); } return caps; @@ -292,18 +308,19 @@ gst_osssink_get_delay (GstOssSink * osssink) gint delay = 0; gint ret; - if (GST_OSSELEMENT (osssink)->fd == -1) + if (GST_OSSELEMENT_GET (osssink)->fd == -1) return 0; #ifdef SNDCTL_DSP_GETODELAY - ret = ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_GETODELAY, &delay); + ret = ioctl (GST_OSSELEMENT_GET (osssink)->fd, SNDCTL_DSP_GETODELAY, &delay); #else ret = -1; #endif if (ret < 0) { audio_buf_info info; - if (ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + if (ioctl (GST_OSSELEMENT_GET (osssink)->fd, SNDCTL_DSP_GETOSPACE, + &info) < 0) { delay = 0; } else { delay = (info.fragstotal * info.fragsize) - info.bytes; @@ -320,25 +337,14 @@ gst_osssink_get_time (GstClock * clock, gpointer data) gint delay; GstClockTime res; - if (!GST_OSSELEMENT (osssink)->bps) + if (!GST_OSSELEMENT_GET (osssink)->bps) return 0; delay = gst_osssink_get_delay (osssink); - /* sometimes delay is bigger than the number of bytes sent to the device, - * which screws up this calculation, we assume that everything is still - * in the device then - * thomas: with proper handling of the return value, this doesn't seem to - * happen anymore, so remove the second code path after april 2004 */ - if (delay > (gint64) osssink->handled) { - /*g_warning ("Delay %d > osssink->handled %" G_GUINT64_FORMAT - ", setting to osssink->handled", - delay, osssink->handled); */ - delay = osssink->handled; - } res = ((gint64) osssink->handled - - delay) * GST_SECOND / GST_OSSELEMENT (osssink)->bps; + delay) * GST_SECOND / GST_OSSELEMENT_GET (osssink)->bps; if (res < 0) res = 0; @@ -355,138 +361,34 @@ gst_osssink_get_clock (GstElement * element) return GST_CLOCK (osssink->provided_clock); } -static void -gst_osssink_set_clock (GstElement * element, GstClock * clock) -{ - GstOssSink *osssink; - - osssink = GST_OSSSINK (element); - - osssink->clock = clock; -} - -static GstFlowReturn -gst_osssink_finish_preroll (GstOssSink * osssink, GstPad * pad) -{ - GstFlowReturn result = GST_FLOW_OK; - - /* grab state change lock */ - GST_STATE_LOCK (osssink); - /* if we are going to PAUSED, we can commit the state change */ - if (GST_STATE_PENDING (osssink) == GST_STATE_PAUSED) { - gst_element_commit_state (GST_ELEMENT (osssink)); - } - /* if we are paused we need to wait for playing to continue */ - if (GST_STATE (osssink) == GST_STATE_PAUSED) { - GST_DEBUG_OBJECT (osssink, - "element %s wants to finish preroll", GST_ELEMENT_NAME (osssink)); - - /* here we wait for the next state change */ - while (GST_STATE (osssink) == GST_STATE_PAUSED) { - if (GST_RPAD_IS_FLUSHING (pad)) { - GST_DEBUG_OBJECT (osssink, "pad is flushing"); - result = GST_FLOW_UNEXPECTED; - goto done; - } - - GST_DEBUG_OBJECT (osssink, "waiting for next state change"); - GST_STATE_WAIT (osssink); - GST_DEBUG_OBJECT (osssink, "got unlocked, maybe a state change"); - - if (GST_RPAD_IS_FLUSHING (pad)) { - GST_DEBUG_OBJECT (osssink, "pad is flushing"); - result = GST_FLOW_UNEXPECTED; - goto done; - } - } - - /* check if we got playing */ - if (GST_STATE (osssink) != GST_STATE_PLAYING) { - /* not playing, we can't accept the buffer */ - result = GST_FLOW_WRONG_STATE; - } - - GST_DEBUG_OBJECT (osssink, "done preroll"); - } -done: - GST_STATE_UNLOCK (osssink); - - return result; -} - -static gboolean -gst_osssink_handle_event (GstPad * pad, GstEvent * event) +static GstRingBuffer * +gst_osssink_create_ringbuffer (GstBaseAudioSink * bsink) { - GstOssSink *osssink; - gboolean result = TRUE; - - osssink = GST_OSSSINK (GST_PAD_PARENT (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - - GST_STREAM_LOCK (pad); - ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_SYNC, 0); - gst_osssink_finish_preroll (osssink, pad); - gst_element_post_message (GST_ELEMENT (osssink), - gst_message_new_eos (GST_OBJECT (osssink))); - GST_STATE_LOCK (osssink); - osssink->in_eos = TRUE; - GST_STATE_UNLOCK (osssink); - GST_STREAM_UNLOCK (pad); - break; - case GST_EVENT_FLUSH: - /* make sure we are not blocked on anything */ - ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_RESET, 0); - - /* unlock from a possible state change/preroll */ - GST_STATE_LOCK (osssink); - osssink->in_eos = FALSE; - g_cond_broadcast (GST_STATE_GET_COND (osssink)); - GST_STATE_UNLOCK (osssink); - /* now we are completely unblocked and the _chain method - * will return */ - result = TRUE; - break; - default: - break; - } - - return result; + return GST_RINGBUFFER (g_object_new (GST_TYPE_OSSDMABUFFER, NULL)); } +#if 0 static GstFlowReturn -gst_osssink_chain (GstPad * pad, GstBuffer * buf) +gst_osssink_render (GstBaseSink * bsink, GstBuffer * buf) { GstOssSink *osssink; - - //GstClockTimeDiff buftime, soundtime, elementtime; guchar *data; guint to_write; - //gint delay; - GstFlowReturn result = GST_FLOW_OK; - /* this has to be an audio buffer */ - osssink = GST_OSSSINK (GST_PAD_PARENT (pad)); + osssink = GST_OSSSINK (bsink); - if (!GST_OSSELEMENT (osssink)->bps) { + if (!GST_OSSELEMENT_GET (osssink)->bps) { gst_buffer_unref (buf); GST_ELEMENT_ERROR (osssink, CORE, NEGOTIATION, (NULL), ("format wasn't negotiated before chain function")); return GST_FLOW_NOT_NEGOTIATED; } - GST_STREAM_LOCK (pad); - result = gst_osssink_finish_preroll (osssink, pad); - if (result != GST_FLOW_OK) { - goto done; - } - data = GST_BUFFER_DATA (buf); to_write = GST_BUFFER_SIZE (buf); - if (GST_OSSELEMENT (osssink)->fd >= 0 && to_write > 0) { + if (GST_OSSELEMENT_GET (osssink)->fd >= 0 && to_write > 0) { if (!osssink->mute) { while (to_write > 0) { @@ -496,7 +398,7 @@ gst_osssink_chain (GstPad * pad, GstBuffer * buf) writing = MIN (to_write, osssink->chunk_size); GST_DEBUG_OBJECT (osssink, "writing %d bytes", writing); - done = write (GST_OSSELEMENT (osssink)->fd, data, writing); + done = write (GST_OSSELEMENT_GET (osssink)->fd, data, writing); GST_DEBUG_OBJECT (osssink, "done writing %d bytes", done); if (done == -1) { @@ -512,13 +414,9 @@ gst_osssink_chain (GstPad * pad, GstBuffer * buf) g_warning ("muting osssinks unimplemented wrt clocks!"); } } - -done: - GST_STREAM_UNLOCK (pad); - gst_buffer_unref (buf); - - return result; + return GST_FLOW_OK; } +#endif static const GstFormat * gst_osssink_get_formats (GstPad * pad) @@ -541,7 +439,7 @@ gst_osssink_convert (GstPad * pad, GstFormat src_format, gint64 src_value, osssink = GST_OSSSINK (GST_PAD_PARENT (pad)); - return gst_osselement_convert (GST_OSSELEMENT (osssink), + return gst_osselement_convert (GST_OSSELEMENT_GET (osssink), src_format, src_value, dest_format, dest_value); } @@ -576,16 +474,24 @@ gst_osssink_sink_query (GstPad * pad, GstQueryType type, GstFormat * format, break; case GST_QUERY_POSITION: if (!gst_osssink_convert (pad, - GST_FORMAT_TIME, gst_element_get_time (GST_ELEMENT (osssink)), + GST_FORMAT_TIME, gst_osssink_get_time (NULL, osssink), format, value)) { res = FALSE; } break; default: - res = - gst_pad_query (gst_pad_get_peer (osssink->sinkpad), type, format, - value); + { + GstPad *peer; + + peer = gst_pad_get_peer (pad); + if (peer) { + res = gst_pad_query (peer, type, format, value); + gst_object_unref (GST_OBJECT (peer)); + } else { + res = FALSE; + } break; + } } return res; @@ -595,9 +501,8 @@ static gboolean gst_osssink_query (GstElement * element, GstQueryType type, GstFormat * format, gint64 * value) { - GstOssSink *osssink = GST_OSSSINK (element); - - return gst_osssink_sink_query (osssink->sinkpad, type, format, value); + return gst_osssink_sink_query (GST_BASESINK_PAD (element), type, format, + value); } static void @@ -614,8 +519,8 @@ gst_osssink_set_property (GObject * object, guint prop_id, const GValue * value, g_object_notify (G_OBJECT (osssink), "mute"); break; case ARG_FRAGMENT: - GST_OSSELEMENT (osssink)->fragment = g_value_get_int (value); - gst_osselement_sync_parms (GST_OSSELEMENT (osssink)); + GST_OSSELEMENT_GET (osssink)->fragment = g_value_get_int (value); + gst_osselement_sync_parms (GST_OSSELEMENT_GET (osssink)); break; case ARG_BUFFER_SIZE: osssink->bufsize = g_value_get_uint (value); @@ -647,7 +552,7 @@ gst_osssink_get_property (GObject * object, guint prop_id, GValue * value, g_value_set_boolean (value, osssink->mute); break; case ARG_FRAGMENT: - g_value_set_int (value, GST_OSSELEMENT (osssink)->fragment); + g_value_set_int (value, GST_OSSELEMENT_GET (osssink)->fragment); break; case ARG_BUFFER_SIZE: g_value_set_uint (value, osssink->bufsize); @@ -668,28 +573,21 @@ static GstElementStateReturn gst_osssink_change_state (GstElement * element) { GstOssSink *osssink; - GstElementStateReturn result = GST_STATE_SUCCESS; + GstOssElement *oss; osssink = GST_OSSSINK (element); + oss = GST_OSSELEMENT_GET (osssink); switch (GST_STATE_TRANSITION (element)) { case GST_STATE_NULL_TO_READY: break; case GST_STATE_READY_TO_PAUSED: - if (!osssink->in_eos) - result = GST_STATE_ASYNC; break; case GST_STATE_PAUSED_TO_PLAYING: break; case GST_STATE_PLAYING_TO_PAUSED: - //ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_RESET, 0); - if (!osssink->in_eos) - result = GST_STATE_ASYNC; break; case GST_STATE_PAUSED_TO_READY: - ioctl (GST_OSSELEMENT (osssink)->fd, SNDCTL_DSP_RESET, 0); - gst_osselement_reset (GST_OSSELEMENT (osssink)); - osssink->handled = 0; break; case GST_STATE_READY_TO_NULL: break; @@ -697,8 +595,5 @@ gst_osssink_change_state (GstElement * element) break; } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return result; + return GST_ELEMENT_CLASS (parent_class)->change_state (element); } diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h index 41ae182a8..e0b9d134a 100644 --- a/sys/oss/gstosssink.h +++ b/sys/oss/gstosssink.h @@ -29,19 +29,17 @@ #include "gstosselement.h" #include <gst/audio/audioclock.h> +#include <gst/audio/gstbaseaudiosink.h> G_BEGIN_DECLS -#define GST_TYPE_OSSSINK \ - (gst_osssink_get_type()) -#define GST_OSSSINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSSINK,GstOssSink)) -#define GST_OSSSINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSSINK,GstOssSinkClass)) -#define GST_IS_OSSSINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSSINK)) -#define GST_IS_OSSSINK_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSSINK)) +#define GST_TYPE_OSSSINK (gst_osssink_get_type()) +#define GST_OSSSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OSSSINK,GstOssSink)) +#define GST_OSSSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OSSSINK,GstOssSinkClass)) +#define GST_IS_OSSSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSSSINK)) +#define GST_IS_OSSSINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OSSSINK)) + +#define GST_OSSELEMENT_GET(obj) GST_OSSELEMENT (obj->element) typedef enum { GST_OSSSINK_OPEN = GST_ELEMENT_FLAG_LAST, @@ -53,15 +51,13 @@ typedef struct _GstOssSink GstOssSink; typedef struct _GstOssSinkClass GstOssSinkClass; struct _GstOssSink { - GstOssElement element; + GstBaseAudioSink sink; - GstPad *sinkpad; + GstOssElement *element; GstClock *provided_clock; - GstClock *clock; gboolean sync; guint64 handled; - gboolean in_eos; gboolean mute; guint bufsize; @@ -69,10 +65,7 @@ struct _GstOssSink { }; struct _GstOssSinkClass { - GstOssElementClass parent_class; - - /* signals */ - void (*handoff) (GstElement *element,GstPad *pad); + GstBaseAudioSinkClass parent_class; }; GType gst_osssink_get_type(void); |