mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-24 01:24:20 +00:00
ext/alsa/: Port to 0.9.
Original commit message from CVS: 2005-08-19 Andy Wingo <wingo@pobox.com> * ext/alsa/gstalsamixertrack.h: * ext/alsa/gstalsamixertrack.c: * ext/alsa/gstalsamixeroptions.h: * ext/alsa/gstalsamixeroptions.c: * ext/alsa/gstalsamixer.h: * ext/alsa/gstalsamixer.c: Port to 0.9. * ext/alsa/Makefile.am: Build mixer, mixeroptions, mixertracks. Remove gstalsa.c and alsaclock. No more cruft here.
This commit is contained in:
parent
256c7c115e
commit
b05796c9d9
11 changed files with 143 additions and 2738 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2005-08-19 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* ext/alsa/gstalsamixertrack.h:
|
||||||
|
* ext/alsa/gstalsamixertrack.c:
|
||||||
|
* ext/alsa/gstalsamixeroptions.h:
|
||||||
|
* ext/alsa/gstalsamixeroptions.c:
|
||||||
|
* ext/alsa/gstalsamixer.h:
|
||||||
|
* ext/alsa/gstalsamixer.c: Port to 0.9.
|
||||||
|
|
||||||
|
* ext/alsa/Makefile.am: Build mixer, mixeroptions, mixertracks.
|
||||||
|
Remove gstalsa.c and alsaclock. No more cruft here.
|
||||||
|
|
||||||
2005-08-18 Wim Taymans <wim@fluendo.com>
|
2005-08-18 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst-libs/gst/rtp/gstbasertpdepayload.c:
|
* gst-libs/gst/rtp/gstbasertpdepayload.c:
|
||||||
|
|
|
@ -2,16 +2,11 @@ plugin_LTLIBRARIES = libgstalsa.la
|
||||||
|
|
||||||
libgstalsa_la_SOURCES = \
|
libgstalsa_la_SOURCES = \
|
||||||
gstalsaplugin.c \
|
gstalsaplugin.c \
|
||||||
gstalsasink.c \
|
gstalsamixer.c \
|
||||||
gstalsasrc.c
|
|
||||||
|
|
||||||
# port alsa stuff then add the _SOURCES above
|
|
||||||
EXTRA_DIST = \
|
|
||||||
gstalsamixer.c \
|
|
||||||
gstalsamixertrack.c \
|
gstalsamixertrack.c \
|
||||||
gstalsamixeroptions.c \
|
gstalsamixeroptions.c \
|
||||||
gstalsa.c \
|
gstalsasink.c \
|
||||||
gstalsaclock.c
|
gstalsasrc.c
|
||||||
|
|
||||||
libgstalsa_la_CFLAGS = $(GST_CFLAGS) $(ALSA_CFLAGS)
|
libgstalsa_la_CFLAGS = $(GST_CFLAGS) $(ALSA_CFLAGS)
|
||||||
libgstalsa_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstalsa_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
@ -22,7 +17,6 @@ libgstalsa_la_LIBADD = \
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
gstalsa.h \
|
gstalsa.h \
|
||||||
gstalsaclock.h \
|
|
||||||
gstalsasink.h \
|
gstalsasink.h \
|
||||||
gstalsasrc.h \
|
gstalsasrc.h \
|
||||||
gstalsamixer.h \
|
gstalsamixer.h \
|
||||||
|
|
2125
ext/alsa/gstalsa.c
2125
ext/alsa/gstalsa.c
File diff suppressed because it is too large
Load diff
|
@ -19,9 +19,11 @@
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_ALSA_H__
|
#ifndef __GST_ALSA_H__
|
||||||
#define __GST_ALSA_H__
|
#define __GST_ALSA_H__
|
||||||
|
|
||||||
|
|
||||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||||
#define ALSA_PCM_NEW_SW_PARAMS_API
|
#define ALSA_PCM_NEW_SW_PARAMS_API
|
||||||
|
|
||||||
|
@ -31,210 +33,4 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (alsa_debug);
|
|
||||||
#define GST_CAT_DEFAULT alsa_debug
|
|
||||||
|
|
||||||
|
|
||||||
/* error checking for standard alsa functions */
|
|
||||||
/* NOTE: these functions require a GObject *this and can only be used in
|
|
||||||
functions that return TRUE on success and FALSE on error */
|
|
||||||
#define SIMPLE_ERROR_CHECK(value) G_STMT_START{ \
|
|
||||||
int err = (value); \
|
|
||||||
if (err < 0) { \
|
|
||||||
GST_WARNING_OBJECT (this, "\"" #value "\": %s", snd_strerror (err)); \
|
|
||||||
return FALSE; \
|
|
||||||
} \
|
|
||||||
}G_STMT_END
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef G_HAVE_ISO_VARARGS
|
|
||||||
#define ERROR_CHECK(value, ...) G_STMT_START{ \
|
|
||||||
int err = (value); \
|
|
||||||
if (err < 0) { \
|
|
||||||
GST_WARNING_OBJECT (this, __VA_ARGS__, snd_strerror (err)); \
|
|
||||||
return FALSE; \
|
|
||||||
} \
|
|
||||||
}G_STMT_END
|
|
||||||
|
|
||||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
|
||||||
#define ERROR_CHECK(value, args...) G_STMT_START{ \
|
|
||||||
int err = (value); \
|
|
||||||
if (err < 0) { \
|
|
||||||
GST_WARNING_OBJECT (this, ## args, snd_strerror (err)); \
|
|
||||||
return FALSE; \
|
|
||||||
} \
|
|
||||||
}G_STMT_END
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define ERROR_CHECK(value, args...) G_STMT_START{ \
|
|
||||||
int err = (value); \
|
|
||||||
if (err < 0) { \
|
|
||||||
GST_WARNING_OBJECT (this, snd_strerror (err)); \
|
|
||||||
return FALSE; \
|
|
||||||
} \
|
|
||||||
}G_STMT_END
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define GST_ALSA_MIN_RATE 8000
|
|
||||||
#define GST_ALSA_MAX_RATE 192000
|
|
||||||
#define GST_ALSA_MIN_PERIOD_CNT 2
|
|
||||||
#define GST_ALSA_MAX_PERIOD_CNT 64
|
|
||||||
#define GST_ALSA_MIN_PERIOD_SZ 2
|
|
||||||
#define GST_ALSA_MAX_PERIOD_SZ 8192
|
|
||||||
#define GST_ALSA_MIN_BUFFER_SZ GST_ALSA_MIN_PERIOD_CNT*GST_ALSA_MIN_PERIOD_SZ
|
|
||||||
#define GST_ALSA_MAX_BUFFER_SZ 65536
|
|
||||||
#define GST_ALSA_MAX_TRACKS 64 /* we don't support more than 64 tracks */
|
|
||||||
#define GST_ALSA_MAX_CHANNELS 32 /* tracks can have up to 32 channels */
|
|
||||||
|
|
||||||
/* a few alsa functions return an int value and a 'direction', -1, 0 or +1
|
|
||||||
0 = exact value
|
|
||||||
-1 = real value is up to 1 before given value
|
|
||||||
+1 = real value is up to 1 after given value
|
|
||||||
*/
|
|
||||||
#define GST_ALSA_DIR_MIN(i) ((i == 1) ? 1 : 0)
|
|
||||||
#define GST_ALSA_DIR_MAX(i) ((i ==-1) ?-1 : 0)
|
|
||||||
|
|
||||||
/* Mono is 1 channel ; the 5.1 standard is 6 channels. The value for
|
|
||||||
GST_ALSA_MAX_CHANNELS comes from alsa/mixer.h. */
|
|
||||||
|
|
||||||
/* Max allowed discontinuity in time units between timestamp and playback
|
|
||||||
pointer before killing/inserting samples. This should be big enough to allow
|
|
||||||
smoothing errors on different video formats. */
|
|
||||||
#define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10)
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GST_ALSA(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa))
|
|
||||||
#define GST_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA, GstAlsaClass))
|
|
||||||
#define GST_ALSA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ALSA, GstAlsaClass))
|
|
||||||
#define GST_IS_ALSA(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GST_TYPE_ALSA))
|
|
||||||
#define GST_IS_ALSA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE(klass, GST_TYPE_ALSA))
|
|
||||||
#define GST_TYPE_ALSA (gst_alsa_get_type())
|
|
||||||
|
|
||||||
enum {
|
|
||||||
GST_ALSA_OPEN = GST_ELEMENT_FLAG_LAST,
|
|
||||||
GST_ALSA_RUNNING,
|
|
||||||
GST_ALSA_CAPS_NEGO,
|
|
||||||
GST_ALSA_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 3
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GST_ALSA_CAPS_PAUSE = 0,
|
|
||||||
GST_ALSA_CAPS_RESUME,
|
|
||||||
GST_ALSA_CAPS_SYNC_START
|
|
||||||
/* add more */
|
|
||||||
} GstAlsaPcmCaps;
|
|
||||||
|
|
||||||
#define GST_ALSA_CAPS_IS_SET(obj, flag) (GST_ALSA (obj)->pcm_caps & (1<<(flag)))
|
|
||||||
#define GST_ALSA_CAPS_SET(obj, flag, set) G_STMT_START{ \
|
|
||||||
if (set) { (GST_ALSA (obj)->pcm_caps |= (1<<(flag))); } \
|
|
||||||
else { (GST_ALSA (obj)->pcm_caps &= ~(1<<(flag))); } \
|
|
||||||
}G_STMT_END
|
|
||||||
|
|
||||||
typedef struct _GstAlsaClock GstAlsaClock;
|
|
||||||
typedef struct _GstAlsaClockClass GstAlsaClockClass;
|
|
||||||
|
|
||||||
typedef struct _GstAlsa GstAlsa;
|
|
||||||
typedef struct _GstAlsaClass GstAlsaClass;
|
|
||||||
|
|
||||||
typedef int (*GstAlsaTransmitFunction) (GstAlsa *this, snd_pcm_sframes_t *avail);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
snd_pcm_format_t format;
|
|
||||||
guint rate;
|
|
||||||
gint channels;
|
|
||||||
} GstAlsaFormat;
|
|
||||||
|
|
||||||
struct _GstAlsa {
|
|
||||||
GstElement parent;
|
|
||||||
|
|
||||||
/* array of GstAlsaPads */
|
|
||||||
GstPad * pad[GST_ALSA_MAX_TRACKS];
|
|
||||||
|
|
||||||
gchar * device;
|
|
||||||
gchar * cardname;
|
|
||||||
snd_pcm_t * handle;
|
|
||||||
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
|
|
||||||
snd_output_t * out;
|
|
||||||
|
|
||||||
GstAlsaFormat * format; /* NULL if undefined */
|
|
||||||
gboolean mmap; /* use mmap transmit (fast) or read/write (sloooow) */
|
|
||||||
GstAlsaTransmitFunction transmit;
|
|
||||||
GstCaps * cached_caps; /* we cache caps to speed up get_caps */
|
|
||||||
|
|
||||||
/* latency / performance parameters */
|
|
||||||
snd_pcm_uframes_t period_size;
|
|
||||||
unsigned int period_count;
|
|
||||||
|
|
||||||
gboolean autorecover;
|
|
||||||
|
|
||||||
/* clocking */
|
|
||||||
GstAlsaClock * clock; /* our provided clock */
|
|
||||||
GstClock * ext_clock; /* externally set clock. */
|
|
||||||
snd_pcm_uframes_t played; /* samples transmitted since last sync
|
|
||||||
This thing actually is our master clock.
|
|
||||||
We will event insert silent samples or
|
|
||||||
drop some to sync to incoming timestamps.
|
|
||||||
*/
|
|
||||||
snd_pcm_uframes_t captured;
|
|
||||||
GstClockTime max_discont; /* max difference between current
|
|
||||||
playback timestamp and buffers timestamps
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstAlsaClass {
|
|
||||||
GstElementClass parent_class;
|
|
||||||
|
|
||||||
snd_pcm_stream_t stream;
|
|
||||||
|
|
||||||
/* different transmit functions */
|
|
||||||
GstAlsaTransmitFunction transmit_mmap;
|
|
||||||
GstAlsaTransmitFunction transmit_rw;
|
|
||||||
|
|
||||||
/* autodetected devices available */
|
|
||||||
GList *devices;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType gst_alsa_get_type (void);
|
|
||||||
|
|
||||||
void gst_alsa_set_eos (GstAlsa * this);
|
|
||||||
GstPadLinkReturn gst_alsa_link (GstPad * pad,
|
|
||||||
const GstCaps * caps);
|
|
||||||
GstCaps * gst_alsa_get_caps (GstPad * pad);
|
|
||||||
GstCaps * gst_alsa_fixate (GstPad * pad,
|
|
||||||
const GstCaps * caps);
|
|
||||||
GstCaps * gst_alsa_caps (snd_pcm_format_t format,
|
|
||||||
gint rate,
|
|
||||||
gint channels);
|
|
||||||
|
|
||||||
/* audio processing functions */
|
|
||||||
inline snd_pcm_sframes_t gst_alsa_update_avail (GstAlsa * this);
|
|
||||||
inline gboolean gst_alsa_pcm_wait (GstAlsa * this);
|
|
||||||
inline gboolean gst_alsa_start (GstAlsa * this);
|
|
||||||
gboolean gst_alsa_xrun_recovery (GstAlsa * this);
|
|
||||||
|
|
||||||
/* format conversions */
|
|
||||||
inline snd_pcm_uframes_t gst_alsa_timestamp_to_samples (GstAlsa * this,
|
|
||||||
GstClockTime time);
|
|
||||||
inline GstClockTime gst_alsa_samples_to_timestamp (GstAlsa * this,
|
|
||||||
snd_pcm_uframes_t samples);
|
|
||||||
inline snd_pcm_uframes_t gst_alsa_bytes_to_samples (GstAlsa * this,
|
|
||||||
guint bytes);
|
|
||||||
inline guint gst_alsa_samples_to_bytes (GstAlsa * this,
|
|
||||||
snd_pcm_uframes_t samples);
|
|
||||||
inline GstClockTime gst_alsa_bytes_to_timestamp (GstAlsa * this,
|
|
||||||
guint bytes);
|
|
||||||
inline guint gst_alsa_timestamp_to_bytes (GstAlsa * this,
|
|
||||||
GstClockTime time);
|
|
||||||
|
|
||||||
/* debugging functions (useful in gdb) - require running with --gst-debug=alsa:4 or better */
|
|
||||||
void gst_alsa_sw_params_dump (GstAlsa * this,
|
|
||||||
snd_pcm_sw_params_t * sw_params);
|
|
||||||
void gst_alsa_hw_params_dump (GstAlsa * this,
|
|
||||||
snd_pcm_hw_params_t * hw_params);
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GST_ALSA_H__ */
|
#endif /* __GST_ALSA_H__ */
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001 CodeFactory AB
|
|
||||||
* Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se>
|
|
||||||
* Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu>
|
|
||||||
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
|
||||||
*
|
|
||||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gstalsaclock.h"
|
|
||||||
|
|
||||||
/* clock functions */
|
|
||||||
static void gst_alsa_clock_class_init (gpointer g_class, gpointer class_data);
|
|
||||||
static void gst_alsa_clock_init (GstAlsaClock * clock);
|
|
||||||
|
|
||||||
static GstClockTime gst_alsa_clock_get_internal_time (GstClock * clock);
|
|
||||||
static guint64 gst_alsa_clock_get_resolution (GstClock * clock);
|
|
||||||
static GstClockEntryStatus gst_alsa_clock_wait (GstClock * clock,
|
|
||||||
GstClockEntry * entry);
|
|
||||||
static void gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry);
|
|
||||||
|
|
||||||
static GstClockClass *clock_parent_class = NULL;
|
|
||||||
|
|
||||||
/* static guint gst_alsa_clock_signals[LAST_SIGNAL] = { 0 }; */
|
|
||||||
|
|
||||||
GType
|
|
||||||
gst_alsa_clock_get_type (void)
|
|
||||||
{
|
|
||||||
static GType clock_type = 0;
|
|
||||||
|
|
||||||
if (!clock_type) {
|
|
||||||
static const GTypeInfo clock_info = {
|
|
||||||
sizeof (GstAlsaClockClass),
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
gst_alsa_clock_class_init,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
sizeof (GstAlsaClock),
|
|
||||||
4,
|
|
||||||
(GInstanceInitFunc) gst_alsa_clock_init,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
clock_type = g_type_register_static (GST_TYPE_CLOCK, "GstAlsaClock",
|
|
||||||
&clock_info, 0);
|
|
||||||
}
|
|
||||||
return clock_type;
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
gst_alsa_clock_class_init (gpointer g_class, gpointer class_data)
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class;
|
|
||||||
GstObjectClass *gstobject_class;
|
|
||||||
GstClockClass *gstclock_class;
|
|
||||||
GstAlsaClockClass *klass;
|
|
||||||
|
|
||||||
klass = (GstAlsaClockClass *) g_class;
|
|
||||||
gobject_class = (GObjectClass *) klass;
|
|
||||||
gstobject_class = (GstObjectClass *) klass;
|
|
||||||
gstclock_class = (GstClockClass *) klass;
|
|
||||||
|
|
||||||
clock_parent_class = g_type_class_ref (GST_TYPE_CLOCK);
|
|
||||||
|
|
||||||
gstclock_class->get_internal_time = gst_alsa_clock_get_internal_time;
|
|
||||||
gstclock_class->get_resolution = gst_alsa_clock_get_resolution;
|
|
||||||
gstclock_class->wait = gst_alsa_clock_wait;
|
|
||||||
gstclock_class->unlock = gst_alsa_clock_unlock;
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
gst_alsa_clock_init (GstAlsaClock * clock)
|
|
||||||
{
|
|
||||||
gst_object_set_name (GST_OBJECT (clock), "GstAlsaClock");
|
|
||||||
|
|
||||||
clock->start_time = GST_CLOCK_TIME_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GstAlsaClock *
|
|
||||||
gst_alsa_clock_new (gchar * name, GstAlsaClockGetTimeFunc get_time,
|
|
||||||
GstAlsa * owner)
|
|
||||||
{
|
|
||||||
GstAlsaClock *alsa_clock =
|
|
||||||
GST_ALSA_CLOCK (g_object_new (GST_TYPE_ALSA_CLOCK, NULL));
|
|
||||||
|
|
||||||
g_assert (alsa_clock);
|
|
||||||
|
|
||||||
alsa_clock->get_time = get_time;
|
|
||||||
alsa_clock->owner = owner;
|
|
||||||
alsa_clock->adjust = 0;
|
|
||||||
|
|
||||||
gst_object_set_name (GST_OBJECT (alsa_clock), name);
|
|
||||||
gst_object_set_parent (GST_OBJECT (alsa_clock), GST_OBJECT (owner));
|
|
||||||
|
|
||||||
return alsa_clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gst_alsa_clock_start (GstAlsaClock * clock)
|
|
||||||
{
|
|
||||||
g_assert (!GST_CLOCK_TIME_IS_VALID (clock->start_time));
|
|
||||||
|
|
||||||
if (clock->owner->format) {
|
|
||||||
clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock))
|
|
||||||
- clock->get_time (clock->owner);
|
|
||||||
} else {
|
|
||||||
clock->start_time = gst_clock_get_event_time (GST_CLOCK (clock));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void
|
|
||||||
gst_alsa_clock_stop (GstAlsaClock * clock)
|
|
||||||
{
|
|
||||||
GTimeVal timeval;
|
|
||||||
|
|
||||||
g_get_current_time (&timeval);
|
|
||||||
|
|
||||||
g_assert (GST_CLOCK_TIME_IS_VALID (clock->start_time));
|
|
||||||
|
|
||||||
clock->adjust +=
|
|
||||||
GST_TIMEVAL_TO_TIME (timeval) -
|
|
||||||
gst_clock_get_event_time (GST_CLOCK (clock));
|
|
||||||
clock->start_time = GST_CLOCK_TIME_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstClockTime
|
|
||||||
gst_alsa_clock_get_internal_time (GstClock * clock)
|
|
||||||
{
|
|
||||||
GstAlsaClock *alsa_clock = GST_ALSA_CLOCK (clock);
|
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (alsa_clock->start_time)) {
|
|
||||||
return alsa_clock->get_time (alsa_clock->owner) + alsa_clock->start_time;
|
|
||||||
} else {
|
|
||||||
GTimeVal timeval;
|
|
||||||
|
|
||||||
g_get_current_time (&timeval);
|
|
||||||
return GST_TIMEVAL_TO_TIME (timeval) + alsa_clock->adjust;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static guint64
|
|
||||||
gst_alsa_clock_get_resolution (GstClock * clock)
|
|
||||||
{
|
|
||||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
|
||||||
|
|
||||||
if (this->owner->format) {
|
|
||||||
return GST_SECOND / this->owner->format->rate;
|
|
||||||
} else {
|
|
||||||
/* FIXME: is there an "unknown" value? We just return the sysclock's time by default */
|
|
||||||
return 1 * GST_USECOND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static GstClockEntryStatus
|
|
||||||
gst_alsa_clock_wait (GstClock * clock, GstClockEntry * entry)
|
|
||||||
{
|
|
||||||
GstClockTime target, entry_time, glib_start, glib_cur;
|
|
||||||
GstClockTimeDiff diff;
|
|
||||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
|
||||||
GTimeVal t;
|
|
||||||
|
|
||||||
entry_time = gst_alsa_clock_get_internal_time (clock);
|
|
||||||
diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock);
|
|
||||||
|
|
||||||
if (diff < 0)
|
|
||||||
return GST_CLOCK_ENTRY_EARLY;
|
|
||||||
|
|
||||||
if (diff > clock->max_diff) {
|
|
||||||
GST_INFO_OBJECT (this,
|
|
||||||
"GstAlsaClock: abnormal clock request diff: %" GST_TIME_FORMAT ") >"
|
|
||||||
" %" GST_TIME_FORMAT, GST_TIME_ARGS (diff),
|
|
||||||
GST_TIME_ARGS (clock->max_diff));
|
|
||||||
return GST_CLOCK_ENTRY_EARLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = entry_time + diff;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (this, "real_target %" GST_TIME_FORMAT
|
|
||||||
" target %" GST_TIME_FORMAT
|
|
||||||
" now %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (target), GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)),
|
|
||||||
GST_TIME_ARGS (entry_time));
|
|
||||||
|
|
||||||
g_get_current_time (&t);
|
|
||||||
glib_cur = glib_start = GST_TIMEVAL_TO_TIME (t);
|
|
||||||
while (gst_alsa_clock_get_internal_time (clock) < target &&
|
|
||||||
this->last_unlock < entry_time && glib_start + diff * 1.5 > glib_cur) {
|
|
||||||
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC /
|
|
||||||
GST_SECOND);
|
|
||||||
g_get_current_time (&t);
|
|
||||||
glib_cur = GST_TIMEVAL_TO_TIME (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry->status;
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
gst_alsa_clock_unlock (GstClock * clock, GstClockEntry * entry)
|
|
||||||
{
|
|
||||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
|
||||||
|
|
||||||
this->last_unlock = this->get_time (this->owner);
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001 CodeFactory AB
|
|
||||||
* Copyright (C) 2001 Thomas Nyberg <thomas@codefactory.se>
|
|
||||||
* Copyright (C) 2001-2002 Andy Wingo <apwingo@eos.ncsu.edu>
|
|
||||||
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
|
||||||
*
|
|
||||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GST_ALSA_CLOCK_H__
|
|
||||||
#define __GST_ALSA_CLOCK_H__
|
|
||||||
|
|
||||||
#include "gstalsa.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GST_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_CLOCK,GstAlsaClock))
|
|
||||||
#define GST_ALSA_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_CLOCK,GstAlsaClockClass))
|
|
||||||
#define GST_IS_ALSA_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_CLOCK))
|
|
||||||
#define GST_IS_ALSA_CLOCK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_CLOCK))
|
|
||||||
#define GST_TYPE_ALSA_CLOCK (gst_alsa_clock_get_type())
|
|
||||||
|
|
||||||
typedef GstClockTime (*GstAlsaClockGetTimeFunc) (GstAlsa *);
|
|
||||||
|
|
||||||
struct _GstAlsaClock {
|
|
||||||
GstSystemClock parent;
|
|
||||||
|
|
||||||
GstAlsaClockGetTimeFunc get_time;
|
|
||||||
GstAlsa * owner;
|
|
||||||
|
|
||||||
GstClockTimeDiff adjust; /* adjustment to real clock (recalculated when stopping) */
|
|
||||||
GstClockTime start_time; /* time when the stream started (NONE when stopped) */
|
|
||||||
GstClockTime last_unlock; /* time of last unlock request */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstAlsaClockClass {
|
|
||||||
GstSystemClockClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType gst_alsa_clock_get_type (void);
|
|
||||||
GstAlsaClock * gst_alsa_clock_new (gchar * name,
|
|
||||||
GstAlsaClockGetTimeFunc func,
|
|
||||||
GstAlsa * owner);
|
|
||||||
|
|
||||||
void gst_alsa_clock_start (GstAlsaClock * clock);
|
|
||||||
void gst_alsa_clock_stop (GstAlsaClock * clock);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GST_ALSA_CLOCK_H__ */
|
|
|
@ -17,113 +17,91 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstalsamixer.h"
|
#include "gstalsamixer.h"
|
||||||
|
|
||||||
/* elementfactory information */
|
|
||||||
static GstElementDetails gst_alsa_mixer_details =
|
static GstElementDetails gst_alsa_mixer_details =
|
||||||
GST_ELEMENT_DETAILS ("Alsa Mixer",
|
GST_ELEMENT_DETAILS ("Alsa Mixer",
|
||||||
"Generic/Audio",
|
"Generic/Audio",
|
||||||
"Control sound input and output levels with ALSA",
|
"Control sound input and output levels with ALSA",
|
||||||
"Leif Johnson <leif@ambient.2y.net>");
|
"Leif Johnson <leif@ambient.2y.net>");
|
||||||
|
|
||||||
static void gst_alsa_interface_init (GstImplementsInterfaceClass * klass);
|
|
||||||
|
|
||||||
static void gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data);
|
#define GST_BOILERPLATE_WITH_INTERFACE(type, type_as_function, parent_type, \
|
||||||
static void gst_alsa_mixer_init (GstAlsaMixer * mixer);
|
parent_type_as_macro, interface_type, interface_type_as_macro, \
|
||||||
static void gst_alsa_mixer_interface_init (GstMixerClass * klass);
|
interface_as_function) \
|
||||||
static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface,
|
\
|
||||||
GType iface_type);
|
static void interface_as_function ## _interface_init (interface_type ## Class *klass); \
|
||||||
|
static gboolean interface_as_function ## _supported (type *object, GType iface_type); \
|
||||||
|
\
|
||||||
|
static void \
|
||||||
|
type_as_function ## _implements_interface_init (GstImplementsInterfaceClass *klass) \
|
||||||
|
{ \
|
||||||
|
klass->supported = (gpointer)interface_as_function ## _supported; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static void \
|
||||||
|
type_as_function ## _init_interfaces (GType type) \
|
||||||
|
{ \
|
||||||
|
static const GInterfaceInfo implements_iface_info = { \
|
||||||
|
(GInterfaceInitFunc) type_as_function ## _implements_interface_init, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
}; \
|
||||||
|
static const GInterfaceInfo iface_info = { \
|
||||||
|
(GInterfaceInitFunc) interface_as_function ## _interface_init, \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, \
|
||||||
|
&implements_iface_info); \
|
||||||
|
g_type_add_interface_static (type, interface_type_as_macro, &iface_info); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
GST_BOILERPLATE_FULL (type, type_as_function, parent_type, \
|
||||||
|
parent_type_as_macro, type_as_function ## _init_interfaces)
|
||||||
|
|
||||||
|
GST_BOILERPLATE_WITH_INTERFACE (GstAlsaMixer, gst_alsa_mixer, GstElement,
|
||||||
|
GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, gst_alsa_mixer);
|
||||||
|
|
||||||
/* GStreamer stuff */
|
|
||||||
static GstElementStateReturn gst_alsa_mixer_change_state (GstElement * element);
|
static GstElementStateReturn gst_alsa_mixer_change_state (GstElement * element);
|
||||||
|
|
||||||
static void gst_alsa_mixer_build_list (GstAlsaMixer * mixer);
|
/* GstMixer */
|
||||||
static void gst_alsa_mixer_free_list (GstAlsaMixer * mixer);
|
|
||||||
|
|
||||||
/* interface implementation */
|
|
||||||
static const GList *gst_alsa_mixer_list_tracks (GstMixer * mixer);
|
static const GList *gst_alsa_mixer_list_tracks (GstMixer * mixer);
|
||||||
|
|
||||||
static void gst_alsa_mixer_set_volume (GstMixer * mixer,
|
static void gst_alsa_mixer_set_volume (GstMixer * mixer,
|
||||||
GstMixerTrack * track, gint * volumes);
|
GstMixerTrack * track, gint * volumes);
|
||||||
static void gst_alsa_mixer_get_volume (GstMixer * mixer,
|
static void gst_alsa_mixer_get_volume (GstMixer * mixer,
|
||||||
GstMixerTrack * track, gint * volumes);
|
GstMixerTrack * track, gint * volumes);
|
||||||
|
|
||||||
static void gst_alsa_mixer_set_record (GstMixer * mixer,
|
static void gst_alsa_mixer_set_record (GstMixer * mixer,
|
||||||
GstMixerTrack * track, gboolean record);
|
GstMixerTrack * track, gboolean record);
|
||||||
static void gst_alsa_mixer_set_mute (GstMixer * mixer,
|
static void gst_alsa_mixer_set_mute (GstMixer * mixer,
|
||||||
GstMixerTrack * track, gboolean mute);
|
GstMixerTrack * track, gboolean mute);
|
||||||
|
|
||||||
static void gst_alsa_mixer_set_option (GstMixer * mixer,
|
static void gst_alsa_mixer_set_option (GstMixer * mixer,
|
||||||
GstMixerOptions * opts, gchar * value);
|
GstMixerOptions * opts, gchar * value);
|
||||||
static const gchar *gst_alsa_mixer_get_option (GstMixer * mixer,
|
static const gchar *gst_alsa_mixer_get_option (GstMixer * mixer,
|
||||||
GstMixerOptions * opts);
|
GstMixerOptions * opts);
|
||||||
|
|
||||||
/*** GOBJECT STUFF ************************************************************/
|
static void
|
||||||
|
gst_alsa_mixer_base_init (gpointer klass)
|
||||||
static GstAlsa *parent_class = NULL;
|
|
||||||
|
|
||||||
GType
|
|
||||||
gst_alsa_mixer_get_type (void)
|
|
||||||
{
|
{
|
||||||
static GType alsa_mixer_type = 0;
|
gst_element_class_set_details (GST_ELEMENT_CLASS (klass),
|
||||||
|
&gst_alsa_mixer_details);
|
||||||
if (!alsa_mixer_type) {
|
|
||||||
static const GTypeInfo alsa_mixer_info = {
|
|
||||||
sizeof (GstAlsaMixerClass),
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
gst_alsa_mixer_class_init,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
sizeof (GstAlsaMixer),
|
|
||||||
0,
|
|
||||||
(GInstanceInitFunc) gst_alsa_mixer_init,
|
|
||||||
};
|
|
||||||
static const GInterfaceInfo alsa_iface_info = {
|
|
||||||
(GInterfaceInitFunc) gst_alsa_interface_init,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
static const GInterfaceInfo alsa_mixer_iface_info = {
|
|
||||||
(GInterfaceInitFunc) gst_alsa_mixer_interface_init,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
alsa_mixer_type =
|
|
||||||
g_type_register_static (GST_TYPE_ALSA, "GstAlsaMixer", &alsa_mixer_info,
|
|
||||||
0);
|
|
||||||
|
|
||||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_IMPLEMENTS_INTERFACE,
|
|
||||||
&alsa_iface_info);
|
|
||||||
g_type_add_interface_static (alsa_mixer_type, GST_TYPE_MIXER,
|
|
||||||
&alsa_mixer_iface_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
return alsa_mixer_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data)
|
gst_alsa_mixer_class_init (GstAlsaMixerClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class;
|
|
||||||
GstElementClass *element_class;
|
GstElementClass *element_class;
|
||||||
GstAlsaClass *klass;
|
|
||||||
|
|
||||||
klass = (GstAlsaClass *) g_class;
|
element_class = (GstElementClass *) klass;
|
||||||
object_class = (GObjectClass *) g_class;
|
|
||||||
element_class = (GstElementClass *) g_class;
|
|
||||||
|
|
||||||
if (parent_class == NULL)
|
|
||||||
parent_class = g_type_class_ref (GST_TYPE_ALSA);
|
|
||||||
|
|
||||||
element_class->change_state = gst_alsa_mixer_change_state;
|
element_class->change_state = gst_alsa_mixer_change_state;
|
||||||
|
|
||||||
gst_element_class_set_details (element_class, &gst_alsa_mixer_details);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -136,10 +114,9 @@ static gboolean
|
||||||
gst_alsa_mixer_open (GstAlsaMixer * mixer)
|
gst_alsa_mixer_open (GstAlsaMixer * mixer)
|
||||||
{
|
{
|
||||||
gint err, device;
|
gint err, device;
|
||||||
GstAlsa *alsa = GST_ALSA (mixer);
|
|
||||||
gchar *nocomma = NULL;
|
gchar *nocomma = NULL;
|
||||||
|
|
||||||
mixer->mixer_handle = NULL;
|
g_return_val_if_fail (mixer->mixer_handle == NULL, FALSE);
|
||||||
|
|
||||||
/* open and initialize the mixer device */
|
/* open and initialize the mixer device */
|
||||||
err = snd_mixer_open (&mixer->mixer_handle, 0);
|
err = snd_mixer_open (&mixer->mixer_handle, 0);
|
||||||
|
@ -148,6 +125,8 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
|
||||||
mixer->mixer_handle = NULL;
|
mixer->mixer_handle = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
GstAlsa *alsa = GST_ALSA (mixer);
|
||||||
|
|
||||||
if (!strncmp (alsa->device, "hw:", 3))
|
if (!strncmp (alsa->device, "hw:", 3))
|
||||||
nocomma = g_strdup (alsa->device);
|
nocomma = g_strdup (alsa->device);
|
||||||
|
@ -155,6 +134,9 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
|
||||||
nocomma = g_strdup (alsa->device + 4);
|
nocomma = g_strdup (alsa->device + 4);
|
||||||
else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
|
#else
|
||||||
|
nocomma = g_strdup ("hw:0");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (strchr (nocomma, ','))
|
if (strchr (nocomma, ','))
|
||||||
strchr (nocomma, ',')[0] = '\0';
|
strchr (nocomma, ',')[0] = '\0';
|
||||||
|
@ -181,7 +163,7 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
if (!snd_card_get_name (device, &name))
|
if (!snd_card_get_name (device, &name))
|
||||||
alsa->cardname = name;
|
mixer->cardname = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (nocomma);
|
g_free (nocomma);
|
||||||
|
@ -198,48 +180,18 @@ error:
|
||||||
static void
|
static void
|
||||||
gst_alsa_mixer_close (GstAlsaMixer * mixer)
|
gst_alsa_mixer_close (GstAlsaMixer * mixer)
|
||||||
{
|
{
|
||||||
GstAlsa *alsa = GST_ALSA (mixer);
|
|
||||||
|
|
||||||
if (mixer->mixer_handle == NULL)
|
if (mixer->mixer_handle == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (alsa->cardname) {
|
if (mixer->cardname) {
|
||||||
g_free (alsa->cardname);
|
free (mixer->cardname);
|
||||||
alsa->cardname = NULL;
|
mixer->cardname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_mixer_close (mixer->mixer_handle);
|
snd_mixer_close (mixer->mixer_handle);
|
||||||
mixer->mixer_handle = NULL;
|
mixer->mixer_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_alsa_interface_init (GstImplementsInterfaceClass * klass)
|
|
||||||
{
|
|
||||||
klass->supported = gst_alsa_mixer_supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_alsa_mixer_interface_init (GstMixerClass * klass)
|
|
||||||
{
|
|
||||||
GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
|
|
||||||
|
|
||||||
/* set up the interface hooks */
|
|
||||||
klass->list_tracks = gst_alsa_mixer_list_tracks;
|
|
||||||
klass->set_volume = gst_alsa_mixer_set_volume;
|
|
||||||
klass->get_volume = gst_alsa_mixer_get_volume;
|
|
||||||
klass->set_mute = gst_alsa_mixer_set_mute;
|
|
||||||
klass->set_record = gst_alsa_mixer_set_record;
|
|
||||||
klass->set_option = gst_alsa_mixer_set_option;
|
|
||||||
klass->get_option = gst_alsa_mixer_get_option;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gst_alsa_mixer_supported (GstImplementsInterface * iface, GType iface_type)
|
|
||||||
{
|
|
||||||
g_assert (iface_type == GST_TYPE_MIXER);
|
|
||||||
|
|
||||||
return (GST_ALSA_MIXER (iface)->mixer_handle != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
|
gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
|
||||||
{
|
{
|
||||||
|
@ -349,8 +301,6 @@ gst_alsa_mixer_free_list (GstAlsaMixer * mixer)
|
||||||
mixer->tracklist = NULL;
|
mixer->tracklist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** GSTREAMER FUNCTIONS ******************************************************/
|
|
||||||
|
|
||||||
static GstElementStateReturn
|
static GstElementStateReturn
|
||||||
gst_alsa_mixer_change_state (GstElement * element)
|
gst_alsa_mixer_change_state (GstElement * element)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +332,29 @@ gst_alsa_mixer_change_state (GstElement * element)
|
||||||
|
|
||||||
/*** INTERFACE IMPLEMENTATION *************************************************/
|
/*** INTERFACE IMPLEMENTATION *************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_alsa_mixer_interface_init (GstMixerClass * klass)
|
||||||
|
{
|
||||||
|
GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE;
|
||||||
|
|
||||||
|
/* set up the interface hooks */
|
||||||
|
klass->list_tracks = gst_alsa_mixer_list_tracks;
|
||||||
|
klass->set_volume = gst_alsa_mixer_set_volume;
|
||||||
|
klass->get_volume = gst_alsa_mixer_get_volume;
|
||||||
|
klass->set_mute = gst_alsa_mixer_set_mute;
|
||||||
|
klass->set_record = gst_alsa_mixer_set_record;
|
||||||
|
klass->set_option = gst_alsa_mixer_set_option;
|
||||||
|
klass->get_option = gst_alsa_mixer_get_option;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_alsa_mixer_supported (GstAlsaMixer * object, GType iface_type)
|
||||||
|
{
|
||||||
|
g_assert (iface_type == GST_TYPE_MIXER);
|
||||||
|
|
||||||
|
return (object->mixer_handle != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const GList *
|
static const GList *
|
||||||
gst_alsa_mixer_list_tracks (GstMixer * mixer)
|
gst_alsa_mixer_list_tracks (GstMixer * mixer)
|
||||||
{
|
{
|
||||||
|
@ -559,13 +532,16 @@ static const gchar *
|
||||||
gst_alsa_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
|
gst_alsa_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
|
||||||
{
|
{
|
||||||
GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
|
GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
|
||||||
gint idx = -1;
|
gint ret;
|
||||||
|
guint idx;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_ALSA_MIXER (mixer)->mixer_handle != NULL, NULL);
|
g_return_val_if_fail (GST_ALSA_MIXER (mixer)->mixer_handle != NULL, NULL);
|
||||||
|
|
||||||
gst_alsa_mixer_update (GST_ALSA_MIXER (mixer), NULL);
|
gst_alsa_mixer_update (GST_ALSA_MIXER (mixer), NULL);
|
||||||
|
|
||||||
snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
|
ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
|
||||||
|
if (ret == 0)
|
||||||
return g_list_nth_data (opts->values, idx);
|
return g_list_nth_data (opts->values, idx);
|
||||||
|
else
|
||||||
|
return snd_strerror (ret); /* feeble attempt at error handling */
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,37 +16,51 @@
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_ALSA_MIXER_H__
|
#ifndef __GST_ALSA_MIXER_H__
|
||||||
#define __GST_ALSA_MIXER_H__
|
#define __GST_ALSA_MIXER_H__
|
||||||
|
|
||||||
|
|
||||||
#include "gstalsa.h"
|
#include "gstalsa.h"
|
||||||
#include "gstalsamixeroptions.h"
|
|
||||||
#include "gstalsamixertrack.h"
|
|
||||||
#include <gst/interfaces/mixer.h>
|
#include <gst/interfaces/mixer.h>
|
||||||
|
|
||||||
|
#include "gstalsamixeroptions.h"
|
||||||
|
#include "gstalsamixertrack.h"
|
||||||
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
#define GST_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer))
|
#define GST_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER,GstAlsaMixer))
|
||||||
#define GST_ALSA_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER,GstAlsaMixerClass))
|
#define GST_ALSA_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER,GstAlsaMixerClass))
|
||||||
#define GST_IS_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER))
|
#define GST_IS_ALSA_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER))
|
||||||
#define GST_IS_ALSA_MIXER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER))
|
#define GST_IS_ALSA_MIXER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER))
|
||||||
#define GST_TYPE_ALSA_MIXER (gst_alsa_mixer_get_type())
|
#define GST_TYPE_ALSA_MIXER (gst_alsa_mixer_get_type())
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GstAlsaMixer GstAlsaMixer;
|
typedef struct _GstAlsaMixer GstAlsaMixer;
|
||||||
typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
|
typedef struct _GstAlsaMixerClass GstAlsaMixerClass;
|
||||||
|
|
||||||
|
|
||||||
struct _GstAlsaMixer {
|
struct _GstAlsaMixer {
|
||||||
GstAlsa parent;
|
GstElement parent;
|
||||||
GList * tracklist; /* list of available tracks */
|
|
||||||
snd_mixer_t * mixer_handle;
|
GList * tracklist; /* list of available tracks */
|
||||||
|
|
||||||
|
snd_mixer_t * mixer_handle;
|
||||||
|
|
||||||
|
gchar * cardname;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstAlsaMixerClass {
|
struct _GstAlsaMixerClass {
|
||||||
GstAlsaClass parent;
|
GstElementClass parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType gst_alsa_mixer_get_type (void);
|
GType gst_alsa_mixer_get_type (void);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_ALSA_MIXER_H__ */
|
#endif /* __GST_ALSA_MIXER_H__ */
|
||||||
|
|
|
@ -16,14 +16,18 @@
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_ALSA_MIXER_OPTIONS_H__
|
#ifndef __GST_ALSA_MIXER_OPTIONS_H__
|
||||||
#define __GST_ALSA_MIXER_OPTIONS_H__
|
#define __GST_ALSA_MIXER_OPTIONS_H__
|
||||||
|
|
||||||
|
|
||||||
#include "gstalsa.h"
|
#include "gstalsa.h"
|
||||||
#include <gst/interfaces/mixeroptions.h>
|
#include <gst/interfaces/mixeroptions.h>
|
||||||
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
#define GST_ALSA_MIXER_OPTIONS_TYPE (gst_alsa_mixer_options_get_type ())
|
#define GST_ALSA_MIXER_OPTIONS_TYPE (gst_alsa_mixer_options_get_type ())
|
||||||
#define GST_ALSA_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptions))
|
#define GST_ALSA_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptions))
|
||||||
#define GST_ALSA_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptionsClass))
|
#define GST_ALSA_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptionsClass))
|
||||||
|
@ -31,9 +35,11 @@ G_BEGIN_DECLS
|
||||||
#define GST_IS_ALSA_MIXER_OPTIONS_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_OPTIONS))
|
#define GST_IS_ALSA_MIXER_OPTIONS_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_OPTIONS))
|
||||||
#define GST_TYPE_ALSA_MIXER_OPTIONS (gst_alsa_mixer_options_get_type())
|
#define GST_TYPE_ALSA_MIXER_OPTIONS (gst_alsa_mixer_options_get_type())
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GstAlsaMixerOptions GstAlsaMixerOptions;
|
typedef struct _GstAlsaMixerOptions GstAlsaMixerOptions;
|
||||||
typedef struct _GstAlsaMixerOptionsClass GstAlsaMixerOptionsClass;
|
typedef struct _GstAlsaMixerOptionsClass GstAlsaMixerOptionsClass;
|
||||||
|
|
||||||
|
|
||||||
struct _GstAlsaMixerOptions {
|
struct _GstAlsaMixerOptions {
|
||||||
GstMixerOptions parent;
|
GstMixerOptions parent;
|
||||||
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
|
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
|
||||||
|
@ -44,10 +50,13 @@ struct _GstAlsaMixerOptionsClass {
|
||||||
GstMixerOptionsClass parent;
|
GstMixerOptionsClass parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType gst_alsa_mixer_options_get_type (void);
|
GType gst_alsa_mixer_options_get_type (void);
|
||||||
GstMixerOptions *gst_alsa_mixer_options_new (snd_mixer_elem_t * element,
|
GstMixerOptions *gst_alsa_mixer_options_new (snd_mixer_elem_t * element,
|
||||||
gint track_num);
|
gint track_num);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_ALSA_MIXER_OPTIONS_H__ */
|
#endif /* __GST_ALSA_MIXER_OPTIONS_H__ */
|
||||||
|
|
|
@ -16,14 +16,18 @@
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_ALSA_MIXER_TRACK_H__
|
#ifndef __GST_ALSA_MIXER_TRACK_H__
|
||||||
#define __GST_ALSA_MIXER_TRACK_H__
|
#define __GST_ALSA_MIXER_TRACK_H__
|
||||||
|
|
||||||
|
|
||||||
#include "gstalsa.h"
|
#include "gstalsa.h"
|
||||||
#include <gst/interfaces/mixertrack.h>
|
#include <gst/interfaces/mixertrack.h>
|
||||||
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
#define GST_ALSA_MIXER_TRACK_TYPE (gst_alsa_mixer_track_get_type ())
|
#define GST_ALSA_MIXER_TRACK_TYPE (gst_alsa_mixer_track_get_type ())
|
||||||
#define GST_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrack))
|
#define GST_ALSA_MIXER_TRACK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrack))
|
||||||
#define GST_ALSA_MIXER_TRACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrackClass))
|
#define GST_ALSA_MIXER_TRACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_TRACK,GstAlsaMixerTrackClass))
|
||||||
|
@ -37,6 +41,7 @@ typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
|
||||||
#define GST_ALSA_MIXER_TRACK_CAPTURE (1<<0)
|
#define GST_ALSA_MIXER_TRACK_CAPTURE (1<<0)
|
||||||
#define GST_ALSA_MIXER_TRACK_PLAYBACK (1<<1)
|
#define GST_ALSA_MIXER_TRACK_PLAYBACK (1<<1)
|
||||||
|
|
||||||
|
#define GST_ALSA_MAX_CHANNELS 32 /* tracks can have up to 32 channels */
|
||||||
struct _GstAlsaMixerTrack {
|
struct _GstAlsaMixerTrack {
|
||||||
GstMixerTrack parent;
|
GstMixerTrack parent;
|
||||||
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
|
snd_mixer_elem_t *element; /* the ALSA mixer element for this track */
|
||||||
|
@ -57,6 +62,8 @@ GstMixerTrack * gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
|
||||||
gint flags,
|
gint flags,
|
||||||
gint alsa_flags);
|
gint alsa_flags);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_ALSA_MIXER_TRACK_H__ */
|
#endif /* __GST_ALSA_MIXER_TRACK_H__ */
|
||||||
|
|
|
@ -56,11 +56,9 @@ plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/*
|
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
|
||||||
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
|
GST_TYPE_ALSA_MIXER))
|
||||||
GST_TYPE_ALSA_MIXER))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
*/
|
|
||||||
if (!gst_element_register (plugin, "alsasrc", GST_RANK_PRIMARY,
|
if (!gst_element_register (plugin, "alsasrc", GST_RANK_PRIMARY,
|
||||||
GST_TYPE_ALSA_SRC))
|
GST_TYPE_ALSA_SRC))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue