mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
Update everything for the removal of the interface library and mixer/tuner interfaces
This commit is contained in:
parent
71fc25849e
commit
d99eb6d2cb
28 changed files with 1209 additions and 1297 deletions
|
@ -79,7 +79,6 @@ EXTRA_HFILES = \
|
|||
$(top_srcdir)/ext/taglib/gstid3v2mux.h \
|
||||
$(top_srcdir)/ext/pulse/pulsesink.h \
|
||||
$(top_srcdir)/ext/pulse/pulsesrc.h \
|
||||
$(top_srcdir)/ext/pulse/pulsemixer.h \
|
||||
$(top_srcdir)/ext/speex/gstspeexenc.h \
|
||||
$(top_srcdir)/ext/speex/gstspeexdec.h \
|
||||
$(top_srcdir)/ext/wavpack/gstwavpackdec.h \
|
||||
|
|
|
@ -2,9 +2,6 @@ plugin_LTLIBRARIES = libgstpulse.la
|
|||
|
||||
libgstpulse_la_SOURCES = \
|
||||
plugin.c \
|
||||
pulsemixer.c \
|
||||
pulsemixerctrl.c \
|
||||
pulsemixertrack.c \
|
||||
pulseprobe.c \
|
||||
pulsesink.c \
|
||||
pulsesrc.c \
|
||||
|
@ -12,15 +9,12 @@ libgstpulse_la_SOURCES = \
|
|||
|
||||
libgstpulse_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(PULSE_CFLAGS)
|
||||
libgstpulse_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
|
||||
-lgstinterfaces-$(GST_API_VERSION) -lgstpbutils-$(GST_API_VERSION) \
|
||||
-lgstpbutils-$(GST_API_VERSION) \
|
||||
$(GST_BASE_LIBS) $(GST_LIBS) $(PULSE_LIBS)
|
||||
libgstpulse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
libgstpulse_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
noinst_HEADERS = \
|
||||
pulsemixerctrl.h \
|
||||
pulsemixer.h \
|
||||
pulsemixertrack.h \
|
||||
pulseprobe.h \
|
||||
pulsesink.h \
|
||||
pulsesrc.h \
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "pulsesink.h"
|
||||
#include "pulsesrc.h"
|
||||
#include "pulsemixer.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (pulse_debug);
|
||||
|
||||
|
@ -49,10 +48,6 @@ plugin_init (GstPlugin * plugin)
|
|||
GST_TYPE_PULSESRC))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_element_register (plugin, "pulsemixer", GST_RANK_NONE,
|
||||
GST_TYPE_PULSEMIXER))
|
||||
return FALSE;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (pulse_debug, "pulse", 0, "PulseAudio elements");
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-pulsemixer
|
||||
* @see_also: pulsesrc, pulsesink
|
||||
*
|
||||
* This element lets you adjust sound input and output levels for the
|
||||
* PulseAudio sound server. It supports the GstMixer interface, which can be
|
||||
* used to obtain a list of available mixer tracks. Set the mixer element to
|
||||
* READY state before using the GstMixer interface on it.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Example pipelines</title>
|
||||
* <para>
|
||||
* pulsemixer can't be used in a sensible way in gst-launch.
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pulsemixer.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_SERVER = 1,
|
||||
PROP_DEVICE,
|
||||
PROP_DEVICE_NAME
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
|
||||
#define GST_CAT_DEFAULT pulse_debug
|
||||
|
||||
static void gst_pulsemixer_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_pulsemixer_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_pulsemixer_finalize (GObject * object);
|
||||
|
||||
static GstStateChangeReturn gst_pulsemixer_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseMixer, gst_pulsemixer);
|
||||
|
||||
|
||||
#define gst_pulsemixer_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstPulseMixer, gst_pulsemixer, GST_TYPE_ELEMENT,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_MIXER,
|
||||
gst_pulsemixer_mixer_interface_init));
|
||||
|
||||
static void
|
||||
gst_pulsemixer_class_init (GstPulseMixerClass * g_class)
|
||||
{
|
||||
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_pulsemixer_change_state);
|
||||
|
||||
gobject_class->finalize = gst_pulsemixer_finalize;
|
||||
gobject_class->get_property = gst_pulsemixer_get_property;
|
||||
gobject_class->set_property = gst_pulsemixer_set_property;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SERVER,
|
||||
g_param_spec_string ("server", "Server",
|
||||
"The PulseAudio server to connect to", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DEVICE,
|
||||
g_param_spec_string ("device", "Device",
|
||||
"The PulseAudio sink or source to control", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DEVICE_NAME,
|
||||
g_param_spec_string ("device-name", "Device name",
|
||||
"Human-readable name of the sound device", NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (g_class),
|
||||
"PulseAudio Mixer",
|
||||
"Generic/Audio",
|
||||
"Control sound input and output levels for PulseAudio",
|
||||
"Lennart Poettering");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_init (GstPulseMixer * this)
|
||||
{
|
||||
this->mixer = NULL;
|
||||
this->server = NULL;
|
||||
this->device = NULL;
|
||||
|
||||
this->probe =
|
||||
gst_pulseprobe_new (G_OBJECT (this), G_OBJECT_GET_CLASS (this),
|
||||
PROP_DEVICE, this->device, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_finalize (GObject * object)
|
||||
{
|
||||
GstPulseMixer *this = GST_PULSEMIXER (object);
|
||||
|
||||
g_free (this->server);
|
||||
g_free (this->device);
|
||||
|
||||
if (this->mixer) {
|
||||
gst_pulsemixer_ctrl_free (this->mixer);
|
||||
this->mixer = NULL;
|
||||
}
|
||||
|
||||
if (this->probe) {
|
||||
gst_pulseprobe_free (this->probe);
|
||||
this->probe = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPulseMixer *this = GST_PULSEMIXER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_SERVER:
|
||||
g_free (this->server);
|
||||
this->server = g_value_dup_string (value);
|
||||
|
||||
if (this->probe)
|
||||
gst_pulseprobe_set_server (this->probe, this->server);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_DEVICE:
|
||||
g_free (this->device);
|
||||
this->device = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPulseMixer *this = GST_PULSEMIXER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_SERVER:
|
||||
g_value_set_string (value, this->server);
|
||||
break;
|
||||
case PROP_DEVICE:
|
||||
g_value_set_string (value, this->device);
|
||||
break;
|
||||
case PROP_DEVICE_NAME:
|
||||
if (this->mixer) {
|
||||
char *t = g_strdup_printf ("%s: %s",
|
||||
this->mixer->type == GST_PULSEMIXER_SINK ? "Playback" : "Capture",
|
||||
this->mixer->description);
|
||||
g_value_take_string (value, t);
|
||||
} else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstPulseMixer *this = GST_PULSEMIXER (element);
|
||||
GstStateChangeReturn res;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!this->mixer)
|
||||
this->mixer =
|
||||
gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
|
||||
this->device, GST_PULSEMIXER_UNKNOWN);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
if (this->mixer) {
|
||||
gst_pulsemixer_ctrl_free (this->mixer);
|
||||
this->mixer = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_PULSEMIXER_H__
|
||||
#define __GST_PULSEMIXER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/thread-mainloop.h>
|
||||
|
||||
#include "pulsemixerctrl.h"
|
||||
#include "pulseprobe.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_PULSEMIXER \
|
||||
(gst_pulsemixer_get_type())
|
||||
#define GST_PULSEMIXER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PULSEMIXER,GstPulseMixer))
|
||||
#define GST_PULSEMIXER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PULSEMIXER,GstPulseMixerClass))
|
||||
#define GST_IS_PULSEMIXER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PULSEMIXER))
|
||||
#define GST_IS_PULSEMIXER_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PULSEMIXER))
|
||||
|
||||
typedef struct _GstPulseMixer GstPulseMixer;
|
||||
typedef struct _GstPulseMixerClass GstPulseMixerClass;
|
||||
|
||||
struct _GstPulseMixer
|
||||
{
|
||||
GstElement parent;
|
||||
|
||||
gchar *server, *device;
|
||||
|
||||
GstPulseMixerCtrl *mixer;
|
||||
GstPulseProbe *probe;
|
||||
};
|
||||
|
||||
struct _GstPulseMixerClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_pulsemixer_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PULSEMIXER_H__ */
|
|
@ -1,640 +0,0 @@
|
|||
/*-*- Mode: C; c-basic-offset: 2 -*-*/
|
||||
|
||||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; 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 <gst/gst.h>
|
||||
|
||||
#include "pulsemixerctrl.h"
|
||||
#include "pulsemixertrack.h"
|
||||
#include "pulseutil.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
|
||||
#define GST_CAT_DEFAULT pulse_debug
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_context_state_cb (pa_context * context, void *userdata)
|
||||
{
|
||||
GstPulseMixerCtrl *c = GST_PULSEMIXER_CTRL (userdata);
|
||||
|
||||
/* Called from the background thread! */
|
||||
|
||||
switch (pa_context_get_state (context)) {
|
||||
case PA_CONTEXT_READY:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
case PA_CONTEXT_FAILED:
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
break;
|
||||
|
||||
case PA_CONTEXT_UNCONNECTED:
|
||||
case PA_CONTEXT_CONNECTING:
|
||||
case PA_CONTEXT_AUTHORIZING:
|
||||
case PA_CONTEXT_SETTING_NAME:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_sink_info_cb (pa_context * context, const pa_sink_info * i,
|
||||
int eol, void *userdata)
|
||||
{
|
||||
GstPulseMixerCtrl *c = userdata;
|
||||
gboolean vol_chg = FALSE;
|
||||
gboolean old_mute;
|
||||
|
||||
/* Called from the background thread! */
|
||||
|
||||
if (c->outstandig_queries > 0)
|
||||
c->outstandig_queries--;
|
||||
|
||||
if (c->ignore_queries > 0 || c->time_event) {
|
||||
|
||||
if (c->ignore_queries > 0)
|
||||
c->ignore_queries--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!i && eol < 0) {
|
||||
c->operation_success = FALSE;
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (eol)
|
||||
return;
|
||||
|
||||
g_free (c->name);
|
||||
g_free (c->description);
|
||||
c->name = g_strdup (i->name);
|
||||
c->description = g_strdup (i->description);
|
||||
c->index = i->index;
|
||||
c->channel_map = i->channel_map;
|
||||
vol_chg = !pa_cvolume_equal (&c->volume, &i->volume);
|
||||
c->volume = i->volume;
|
||||
old_mute = c->muted;
|
||||
c->muted = !!i->mute;
|
||||
c->type = GST_PULSEMIXER_SINK;
|
||||
|
||||
if (c->track) {
|
||||
GstMixerTrackFlags flags = c->track->flags;
|
||||
|
||||
flags =
|
||||
(flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0);
|
||||
c->track->flags = flags;
|
||||
}
|
||||
|
||||
c->operation_success = TRUE;
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
|
||||
if (vol_chg && c->track) {
|
||||
gint volumes[PA_CHANNELS_MAX];
|
||||
gint i;
|
||||
for (i = 0; i < c->volume.channels; i++)
|
||||
volumes[i] = (gint) (c->volume.values[i]);
|
||||
GST_LOG_OBJECT (c->object, "Sending volume change notification");
|
||||
gst_mixer_volume_changed (GST_MIXER (c->object), c->track, volumes);
|
||||
}
|
||||
if ((c->muted != old_mute) && c->track) {
|
||||
GST_LOG_OBJECT (c->object, "Sending mute toggled notification");
|
||||
gst_mixer_mute_toggled (GST_MIXER (c->object), c->track, c->muted);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_source_info_cb (pa_context * context,
|
||||
const pa_source_info * i, int eol, void *userdata)
|
||||
{
|
||||
GstPulseMixerCtrl *c = userdata;
|
||||
gboolean vol_chg = FALSE;
|
||||
gboolean old_mute;
|
||||
|
||||
/* Called from the background thread! */
|
||||
|
||||
if (c->outstandig_queries > 0)
|
||||
c->outstandig_queries--;
|
||||
|
||||
if (c->ignore_queries > 0 || c->time_event) {
|
||||
|
||||
if (c->ignore_queries > 0)
|
||||
c->ignore_queries--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!i && eol < 0) {
|
||||
c->operation_success = FALSE;
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (eol)
|
||||
return;
|
||||
|
||||
g_free (c->name);
|
||||
g_free (c->description);
|
||||
c->name = g_strdup (i->name);
|
||||
c->description = g_strdup (i->description);
|
||||
c->index = i->index;
|
||||
c->channel_map = i->channel_map;
|
||||
vol_chg = !pa_cvolume_equal (&c->volume, &i->volume);
|
||||
c->volume = i->volume;
|
||||
old_mute = c->muted;
|
||||
c->muted = !!i->mute;
|
||||
c->type = GST_PULSEMIXER_SOURCE;
|
||||
|
||||
if (c->track) {
|
||||
GstMixerTrackFlags flags = c->track->flags;
|
||||
|
||||
flags =
|
||||
(flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0);
|
||||
c->track->flags = flags;
|
||||
}
|
||||
|
||||
c->operation_success = TRUE;
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
|
||||
if (vol_chg && c->track) {
|
||||
gint volumes[PA_CHANNELS_MAX];
|
||||
gint i;
|
||||
for (i = 0; i < c->volume.channels; i++)
|
||||
volumes[i] = (gint) (c->volume.values[i]);
|
||||
GST_LOG_OBJECT (c->object, "Sending volume change notification");
|
||||
gst_mixer_volume_changed (GST_MIXER (c->object), c->track, volumes);
|
||||
}
|
||||
if ((c->muted != old_mute) && c->track) {
|
||||
GST_LOG_OBJECT (c->object, "Sending mute toggled notification");
|
||||
gst_mixer_mute_toggled (GST_MIXER (c->object), c->track, c->muted);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_subscribe_cb (pa_context * context,
|
||||
pa_subscription_event_type_t t, uint32_t idx, void *userdata)
|
||||
{
|
||||
GstPulseMixerCtrl *c = GST_PULSEMIXER_CTRL (userdata);
|
||||
pa_operation *o = NULL;
|
||||
|
||||
/* Called from the background thread! */
|
||||
|
||||
if (c->index != idx)
|
||||
return;
|
||||
|
||||
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
|
||||
return;
|
||||
|
||||
if (c->type == GST_PULSEMIXER_SINK)
|
||||
o = pa_context_get_sink_info_by_index (c->context, c->index,
|
||||
gst_pulsemixer_ctrl_sink_info_cb, c);
|
||||
else
|
||||
o = pa_context_get_source_info_by_index (c->context, c->index,
|
||||
gst_pulsemixer_ctrl_source_info_cb, c);
|
||||
|
||||
if (!o) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
return;
|
||||
}
|
||||
|
||||
pa_operation_unref (o);
|
||||
|
||||
c->outstandig_queries++;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_success_cb (pa_context * context, int success,
|
||||
void *userdata)
|
||||
{
|
||||
GstPulseMixerCtrl *c = (GstPulseMixerCtrl *) userdata;
|
||||
|
||||
c->operation_success = !!success;
|
||||
pa_threaded_mainloop_signal (c->mainloop, 0);
|
||||
}
|
||||
|
||||
#define CHECK_DEAD_GOTO(c, label) \
|
||||
G_STMT_START { \
|
||||
if (!(c)->context || \
|
||||
!PA_CONTEXT_IS_GOOD(pa_context_get_state((c)->context))) { \
|
||||
GST_WARNING_OBJECT ((c)->object, "Not connected: %s", \
|
||||
(c)->context ? pa_strerror(pa_context_errno((c)->context)) : "NULL"); \
|
||||
goto label; \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
static gboolean
|
||||
gst_pulsemixer_ctrl_open (GstPulseMixerCtrl * c)
|
||||
{
|
||||
int e;
|
||||
gchar *name;
|
||||
pa_operation *o = NULL;
|
||||
|
||||
g_assert (c);
|
||||
|
||||
GST_DEBUG_OBJECT (c->object, "ctrl open");
|
||||
|
||||
c->mainloop = pa_threaded_mainloop_new ();
|
||||
if (!c->mainloop)
|
||||
return FALSE;
|
||||
|
||||
e = pa_threaded_mainloop_start (c->mainloop);
|
||||
if (e < 0)
|
||||
return FALSE;
|
||||
|
||||
name = gst_pulse_client_name ();
|
||||
|
||||
pa_threaded_mainloop_lock (c->mainloop);
|
||||
|
||||
if (!(c->context =
|
||||
pa_context_new (pa_threaded_mainloop_get_api (c->mainloop), name))) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to create context");
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
pa_context_set_state_callback (c->context,
|
||||
gst_pulsemixer_ctrl_context_state_cb, c);
|
||||
pa_context_set_subscribe_callback (c->context,
|
||||
gst_pulsemixer_ctrl_subscribe_cb, c);
|
||||
|
||||
if (pa_context_connect (c->context, c->server, 0, NULL) < 0) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to connect context: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
/* Wait until the context is ready */
|
||||
while (pa_context_get_state (c->context) != PA_CONTEXT_READY) {
|
||||
CHECK_DEAD_GOTO (c, unlock_and_fail);
|
||||
pa_threaded_mainloop_wait (c->mainloop);
|
||||
}
|
||||
|
||||
/* Subscribe to events */
|
||||
if (!(o =
|
||||
pa_context_subscribe (c->context,
|
||||
PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE,
|
||||
gst_pulsemixer_ctrl_success_cb, c))) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to subscribe to events: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
c->operation_success = FALSE;
|
||||
while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
|
||||
CHECK_DEAD_GOTO (c, unlock_and_fail);
|
||||
pa_threaded_mainloop_wait (c->mainloop);
|
||||
}
|
||||
|
||||
if (!c->operation_success) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to subscribe to events: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
pa_operation_unref (o);
|
||||
o = NULL;
|
||||
|
||||
/* Get sink info */
|
||||
|
||||
if (c->type == GST_PULSEMIXER_UNKNOWN || c->type == GST_PULSEMIXER_SINK) {
|
||||
GST_WARNING_OBJECT (c->object, "Get info for '%s'", c->device);
|
||||
if (!(o =
|
||||
pa_context_get_sink_info_by_name (c->context, c->device,
|
||||
gst_pulsemixer_ctrl_sink_info_cb, c))) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
c->operation_success = FALSE;
|
||||
while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
|
||||
CHECK_DEAD_GOTO (c, unlock_and_fail);
|
||||
pa_threaded_mainloop_wait (c->mainloop);
|
||||
}
|
||||
|
||||
pa_operation_unref (o);
|
||||
o = NULL;
|
||||
|
||||
if (!c->operation_success && (c->type == GST_PULSEMIXER_SINK
|
||||
|| pa_context_errno (c->context) != PA_ERR_NOENTITY)) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to get sink info: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->type == GST_PULSEMIXER_UNKNOWN || c->type == GST_PULSEMIXER_SOURCE) {
|
||||
if (!(o =
|
||||
pa_context_get_source_info_by_name (c->context, c->device,
|
||||
gst_pulsemixer_ctrl_source_info_cb, c))) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to get source info: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
c->operation_success = FALSE;
|
||||
while (pa_operation_get_state (o) != PA_OPERATION_DONE) {
|
||||
CHECK_DEAD_GOTO (c, unlock_and_fail);
|
||||
pa_threaded_mainloop_wait (c->mainloop);
|
||||
}
|
||||
|
||||
pa_operation_unref (o);
|
||||
o = NULL;
|
||||
|
||||
if (!c->operation_success) {
|
||||
GST_WARNING_OBJECT (c->object, "Failed to get source info: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (c->type != GST_PULSEMIXER_UNKNOWN);
|
||||
|
||||
c->track = gst_pulsemixer_track_new (c);
|
||||
c->tracklist = g_list_append (c->tracklist, c->track);
|
||||
|
||||
pa_threaded_mainloop_unlock (c->mainloop);
|
||||
g_free (name);
|
||||
|
||||
return TRUE;
|
||||
|
||||
unlock_and_fail:
|
||||
|
||||
if (o)
|
||||
pa_operation_unref (o);
|
||||
|
||||
if (c->mainloop)
|
||||
pa_threaded_mainloop_unlock (c->mainloop);
|
||||
|
||||
g_free (name);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_close (GstPulseMixerCtrl * c)
|
||||
{
|
||||
g_assert (c);
|
||||
|
||||
GST_DEBUG_OBJECT (c->object, "ctrl close");
|
||||
|
||||
if (c->mainloop)
|
||||
pa_threaded_mainloop_stop (c->mainloop);
|
||||
|
||||
if (c->context) {
|
||||
pa_context_disconnect (c->context);
|
||||
pa_context_unref (c->context);
|
||||
c->context = NULL;
|
||||
}
|
||||
|
||||
if (c->mainloop) {
|
||||
pa_threaded_mainloop_free (c->mainloop);
|
||||
c->mainloop = NULL;
|
||||
c->time_event = NULL;
|
||||
}
|
||||
|
||||
if (c->tracklist) {
|
||||
g_list_free (c->tracklist);
|
||||
c->tracklist = NULL;
|
||||
}
|
||||
|
||||
if (c->track) {
|
||||
GST_PULSEMIXER_TRACK (c->track)->control = NULL;
|
||||
g_object_unref (c->track);
|
||||
c->track = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GstPulseMixerCtrl *
|
||||
gst_pulsemixer_ctrl_new (GObject * object, const gchar * server,
|
||||
const gchar * device, GstPulseMixerType type)
|
||||
{
|
||||
GstPulseMixerCtrl *c = NULL;
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE ((object),
|
||||
GST_TYPE_MIXER), c);
|
||||
|
||||
GST_DEBUG_OBJECT (object, "new mixer ctrl for %s", device);
|
||||
c = g_new (GstPulseMixerCtrl, 1);
|
||||
c->object = g_object_ref (object);
|
||||
c->tracklist = NULL;
|
||||
c->server = g_strdup (server);
|
||||
c->device = g_strdup (device);
|
||||
c->mainloop = NULL;
|
||||
c->context = NULL;
|
||||
c->track = NULL;
|
||||
c->ignore_queries = c->outstandig_queries = 0;
|
||||
|
||||
pa_cvolume_mute (&c->volume, PA_CHANNELS_MAX);
|
||||
pa_channel_map_init (&c->channel_map);
|
||||
c->muted = FALSE;
|
||||
c->index = PA_INVALID_INDEX;
|
||||
c->type = type;
|
||||
c->name = NULL;
|
||||
c->description = NULL;
|
||||
|
||||
c->time_event = NULL;
|
||||
c->update_volume = c->update_mute = FALSE;
|
||||
|
||||
if (!(gst_pulsemixer_ctrl_open (c))) {
|
||||
gst_pulsemixer_ctrl_free (c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
gst_pulsemixer_ctrl_free (GstPulseMixerCtrl * c)
|
||||
{
|
||||
g_assert (c);
|
||||
|
||||
gst_pulsemixer_ctrl_close (c);
|
||||
|
||||
g_free (c->server);
|
||||
g_free (c->device);
|
||||
g_free (c->name);
|
||||
g_free (c->description);
|
||||
g_object_unref (c->object);
|
||||
g_free (c);
|
||||
}
|
||||
|
||||
const GList *
|
||||
gst_pulsemixer_ctrl_list_tracks (GstPulseMixerCtrl * c)
|
||||
{
|
||||
g_assert (c);
|
||||
|
||||
return c->tracklist;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_ctrl_timeout_event (pa_mainloop_api * a, pa_time_event * e,
|
||||
const struct timeval *tv, void *userdata)
|
||||
{
|
||||
pa_operation *o;
|
||||
GstPulseMixerCtrl *c = GST_PULSEMIXER_CTRL (userdata);
|
||||
|
||||
if (c->update_volume) {
|
||||
if (c->type == GST_PULSEMIXER_SINK)
|
||||
o = pa_context_set_sink_volume_by_index (c->context, c->index, &c->volume,
|
||||
NULL, NULL);
|
||||
else
|
||||
o = pa_context_set_source_volume_by_index (c->context, c->index,
|
||||
&c->volume, NULL, NULL);
|
||||
|
||||
if (!o)
|
||||
GST_WARNING_OBJECT (c->object, "Failed to set device volume: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
else
|
||||
pa_operation_unref (o);
|
||||
|
||||
c->update_volume = FALSE;
|
||||
}
|
||||
|
||||
if (c->update_mute) {
|
||||
if (c->type == GST_PULSEMIXER_SINK)
|
||||
o = pa_context_set_sink_mute_by_index (c->context, c->index, c->muted,
|
||||
NULL, NULL);
|
||||
else
|
||||
o = pa_context_set_source_mute_by_index (c->context, c->index, c->muted,
|
||||
NULL, NULL);
|
||||
|
||||
if (!o)
|
||||
GST_WARNING_OBJECT (c->object, "Failed to set device mute: %s",
|
||||
pa_strerror (pa_context_errno (c->context)));
|
||||
else
|
||||
pa_operation_unref (o);
|
||||
|
||||
c->update_mute = FALSE;
|
||||
}
|
||||
|
||||
/* Make sure that all outstanding queries are being ignored */
|
||||
c->ignore_queries = c->outstandig_queries;
|
||||
|
||||
g_assert (e == c->time_event);
|
||||
a->time_free (e);
|
||||
c->time_event = NULL;
|
||||
}
|
||||
|
||||
#define UPDATE_DELAY 50000
|
||||
|
||||
static void
|
||||
restart_time_event (GstPulseMixerCtrl * c)
|
||||
{
|
||||
struct timeval tv;
|
||||
pa_mainloop_api *api;
|
||||
|
||||
g_assert (c);
|
||||
|
||||
if (c->time_event)
|
||||
return;
|
||||
|
||||
/* Updating the volume too often will cause a lot of traffic
|
||||
* when accessing a networked server. Therefore we make sure
|
||||
* to update the volume only once every 50ms */
|
||||
|
||||
api = pa_threaded_mainloop_get_api (c->mainloop);
|
||||
|
||||
c->time_event =
|
||||
api->time_new (api, pa_timeval_add (pa_gettimeofday (&tv), UPDATE_DELAY),
|
||||
gst_pulsemixer_ctrl_timeout_event, c);
|
||||
}
|
||||
|
||||
void
|
||||
gst_pulsemixer_ctrl_set_volume (GstPulseMixerCtrl * c, GstMixerTrack * track,
|
||||
gint * volumes)
|
||||
{
|
||||
pa_cvolume v;
|
||||
int i;
|
||||
|
||||
g_assert (c);
|
||||
g_assert (track == c->track);
|
||||
|
||||
pa_threaded_mainloop_lock (c->mainloop);
|
||||
|
||||
for (i = 0; i < c->channel_map.channels; i++)
|
||||
v.values[i] = (pa_volume_t) volumes[i];
|
||||
|
||||
v.channels = c->channel_map.channels;
|
||||
|
||||
c->volume = v;
|
||||
c->update_volume = TRUE;
|
||||
|
||||
restart_time_event (c);
|
||||
|
||||
pa_threaded_mainloop_unlock (c->mainloop);
|
||||
}
|
||||
|
||||
void
|
||||
gst_pulsemixer_ctrl_get_volume (GstPulseMixerCtrl * c, GstMixerTrack * track,
|
||||
gint * volumes)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_assert (c);
|
||||
g_assert (track == c->track);
|
||||
|
||||
pa_threaded_mainloop_lock (c->mainloop);
|
||||
|
||||
for (i = 0; i < c->channel_map.channels; i++)
|
||||
volumes[i] = c->volume.values[i];
|
||||
|
||||
pa_threaded_mainloop_unlock (c->mainloop);
|
||||
}
|
||||
|
||||
void
|
||||
gst_pulsemixer_ctrl_set_record (GstPulseMixerCtrl * c, GstMixerTrack * track,
|
||||
gboolean record)
|
||||
{
|
||||
g_assert (c);
|
||||
g_assert (track == c->track);
|
||||
}
|
||||
|
||||
void
|
||||
gst_pulsemixer_ctrl_set_mute (GstPulseMixerCtrl * c, GstMixerTrack * track,
|
||||
gboolean mute)
|
||||
{
|
||||
g_assert (c);
|
||||
g_assert (track == c->track);
|
||||
|
||||
pa_threaded_mainloop_lock (c->mainloop);
|
||||
|
||||
c->muted = mute;
|
||||
c->update_mute = TRUE;
|
||||
|
||||
if (c->track) {
|
||||
GstMixerTrackFlags flags = c->track->flags;
|
||||
|
||||
flags =
|
||||
(flags & ~GST_MIXER_TRACK_MUTE) | (c->muted ? GST_MIXER_TRACK_MUTE : 0);
|
||||
c->track->flags = flags;
|
||||
}
|
||||
|
||||
restart_time_event (c);
|
||||
|
||||
pa_threaded_mainloop_unlock (c->mainloop);
|
||||
}
|
||||
|
||||
GstMixerFlags
|
||||
gst_pulsemixer_ctrl_get_mixer_flags (GstPulseMixerCtrl * mixer)
|
||||
{
|
||||
return GST_MIXER_FLAG_AUTO_NOTIFICATIONS;
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/*-*- Mode: C; c-basic-offset: 2 -*-*/
|
||||
|
||||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_PULSEMIXERCTRL_H__
|
||||
#define __GST_PULSEMIXERCTRL_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/mixer.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/thread-mainloop.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_PULSEMIXER_CTRL(obj) ((GstPulseMixerCtrl*)(obj))
|
||||
typedef struct _GstPulseMixerCtrl GstPulseMixerCtrl;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_PULSEMIXER_UNKNOWN,
|
||||
GST_PULSEMIXER_SINK,
|
||||
GST_PULSEMIXER_SOURCE
|
||||
} GstPulseMixerType;
|
||||
|
||||
struct _GstPulseMixerCtrl
|
||||
{
|
||||
GObject *object;
|
||||
|
||||
GList *tracklist;
|
||||
|
||||
gchar *server, *device;
|
||||
|
||||
pa_threaded_mainloop *mainloop;
|
||||
pa_context *context;
|
||||
|
||||
gchar *name, *description;
|
||||
pa_channel_map channel_map;
|
||||
|
||||
pa_cvolume volume;
|
||||
gboolean muted:1;
|
||||
|
||||
gboolean update_volume:1;
|
||||
gboolean update_mute:1;
|
||||
|
||||
gboolean operation_success:1;
|
||||
|
||||
guint32 index;
|
||||
GstPulseMixerType type;
|
||||
|
||||
GstMixerTrack *track;
|
||||
|
||||
pa_time_event *time_event;
|
||||
|
||||
int outstandig_queries;
|
||||
int ignore_queries;
|
||||
|
||||
};
|
||||
|
||||
GstPulseMixerCtrl *gst_pulsemixer_ctrl_new (GObject *object, const gchar * server,
|
||||
const gchar * device, GstPulseMixerType type);
|
||||
void gst_pulsemixer_ctrl_free (GstPulseMixerCtrl * mixer);
|
||||
|
||||
const GList *gst_pulsemixer_ctrl_list_tracks (GstPulseMixerCtrl * mixer);
|
||||
|
||||
void gst_pulsemixer_ctrl_set_volume (GstPulseMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_pulsemixer_ctrl_get_volume (GstPulseMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gint * volumes);
|
||||
void gst_pulsemixer_ctrl_set_mute (GstPulseMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gboolean mute);
|
||||
void gst_pulsemixer_ctrl_set_record (GstPulseMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gboolean record);
|
||||
GstMixerFlags gst_pulsemixer_ctrl_get_mixer_flags (GstPulseMixerCtrl * mixer);
|
||||
|
||||
#define GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS(Type, interface_as_function) \
|
||||
static const GList* \
|
||||
interface_as_function ## _list_tracks (GstMixer * mixer) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_val_if_fail (this != NULL, NULL); \
|
||||
g_return_val_if_fail (this->mixer != NULL, NULL); \
|
||||
\
|
||||
return gst_pulsemixer_ctrl_list_tracks (this->mixer); \
|
||||
} \
|
||||
static void \
|
||||
interface_as_function ## _set_volume (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gint * volumes) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_pulsemixer_ctrl_set_volume (this->mixer, track, volumes); \
|
||||
} \
|
||||
static void \
|
||||
interface_as_function ## _get_volume (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gint * volumes) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_pulsemixer_ctrl_get_volume (this->mixer, track, volumes); \
|
||||
} \
|
||||
static void \
|
||||
interface_as_function ## _set_record (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gboolean record) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_pulsemixer_ctrl_set_record (this->mixer, track, record); \
|
||||
} \
|
||||
static void \
|
||||
interface_as_function ## _set_mute (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gboolean mute) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_pulsemixer_ctrl_set_mute (this->mixer, track, mute); \
|
||||
} \
|
||||
static GstMixerFlags \
|
||||
interface_as_function ## _get_mixer_flags (GstMixer * mixer) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_val_if_fail (this != NULL, GST_MIXER_FLAG_NONE); \
|
||||
g_return_val_if_fail (this->mixer != NULL, GST_MIXER_FLAG_NONE); \
|
||||
\
|
||||
return gst_pulsemixer_ctrl_get_mixer_flags (this->mixer); \
|
||||
} \
|
||||
static GstMixerType \
|
||||
interface_as_function ## _get_mixer_type (GstMixer * mixer) \
|
||||
{ \
|
||||
return GST_MIXER_HARDWARE; \
|
||||
} \
|
||||
static void \
|
||||
interface_as_function ## _mixer_interface_init (GstMixerInterface * iface) \
|
||||
{ \
|
||||
iface->list_tracks = interface_as_function ## _list_tracks; \
|
||||
iface->set_volume = interface_as_function ## _set_volume; \
|
||||
iface->get_volume = interface_as_function ## _get_volume; \
|
||||
iface->set_mute = interface_as_function ## _set_mute; \
|
||||
iface->set_record = interface_as_function ## _set_record; \
|
||||
iface->get_mixer_flags = interface_as_function ## _get_mixer_flags; \
|
||||
iface->get_mixer_type = interface_as_function ## _get_mixer_type; \
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; 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 <gst/gst.h>
|
||||
|
||||
#include "pulsemixertrack.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
|
||||
#define GST_CAT_DEFAULT pulse_debug
|
||||
|
||||
G_DEFINE_TYPE (GstPulseMixerTrack, gst_pulsemixer_track, GST_TYPE_MIXER_TRACK);
|
||||
|
||||
static void
|
||||
gst_pulsemixer_track_class_init (GstPulseMixerTrackClass * klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pulsemixer_track_init (GstPulseMixerTrack * track)
|
||||
{
|
||||
track->control = NULL;
|
||||
}
|
||||
|
||||
GstMixerTrack *
|
||||
gst_pulsemixer_track_new (GstPulseMixerCtrl * control)
|
||||
{
|
||||
GstPulseMixerTrack *pulsetrack;
|
||||
GstMixerTrack *track;
|
||||
|
||||
pulsetrack = g_object_new (GST_TYPE_PULSEMIXER_TRACK, NULL);
|
||||
pulsetrack->control = control;
|
||||
|
||||
track = GST_MIXER_TRACK (pulsetrack);
|
||||
track->label = g_strdup ("Master");
|
||||
track->num_channels = control->channel_map.channels;
|
||||
track->flags =
|
||||
(control->type ==
|
||||
GST_PULSEMIXER_SINK ? GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_MASTER :
|
||||
GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_RECORD) | (control->muted ?
|
||||
GST_MIXER_TRACK_MUTE : 0);
|
||||
track->min_volume = PA_VOLUME_MUTED;
|
||||
track->max_volume = PA_VOLUME_NORM;
|
||||
|
||||
return track;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* GStreamer pulseaudio plugin
|
||||
*
|
||||
* Copyright (c) 2004-2008 Lennart Poettering
|
||||
*
|
||||
* gst-pulse is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* gst-pulse 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with gst-pulse; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_PULSEMIXERTRACK_H__
|
||||
#define __GST_PULSEMIXERTRACK_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "pulsemixerctrl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_PULSEMIXER_TRACK \
|
||||
(gst_pulsemixer_track_get_type())
|
||||
#define GST_PULSEMIXER_TRACK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_PULSEMIXER_TRACK, GstPulseMixerTrack))
|
||||
#define GST_PULSEMIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_PULSEMIXER_TRACK, GstPulseMixerTrackClass))
|
||||
#define GST_IS_PULSEMIXER_TRACK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_PULSEMIXER_TRACK))
|
||||
#define GST_IS_PULSEMIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_PULSEMIXER_TRACK))
|
||||
|
||||
|
||||
typedef struct _GstPulseMixerTrack
|
||||
{
|
||||
GstMixerTrack parent;
|
||||
GstPulseMixerCtrl *control;
|
||||
} GstPulseMixerTrack;
|
||||
|
||||
typedef struct _GstPulseMixerTrackClass
|
||||
{
|
||||
GstMixerTrackClass parent;
|
||||
} GstPulseMixerTrackClass;
|
||||
|
||||
GType gst_pulsemixer_track_get_type (void);
|
||||
|
||||
GstMixerTrack *gst_pulsemixer_track_new (GstPulseMixerCtrl * control);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
/**
|
||||
* SECTION:element-pulsesink
|
||||
* @see_also: pulsesrc, pulsemixer
|
||||
* @see_also: pulsesrc
|
||||
*
|
||||
* This element outputs audio to a
|
||||
* <ulink href="http://www.pulseaudio.org">PulseAudio sound server</ulink>.
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
/**
|
||||
* SECTION:element-pulsesrc
|
||||
* @see_also: pulsesink, pulsemixer
|
||||
* @see_also: pulsesink
|
||||
*
|
||||
* This element captures audio from a
|
||||
* <ulink href="http://www.pulseaudio.org">PulseAudio sound server</ulink>.
|
||||
|
@ -47,7 +47,6 @@
|
|||
|
||||
#include "pulsesrc.h"
|
||||
#include "pulseutil.h"
|
||||
#include "pulsemixerctrl.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
|
||||
#define GST_CAT_DEFAULT pulse_debug
|
||||
|
@ -127,11 +126,8 @@ static GstStaticPadTemplate pad_template = GST_STATIC_PAD_TEMPLATE ("src",
|
|||
);
|
||||
|
||||
|
||||
GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseSrc, gst_pulsesrc);
|
||||
|
||||
#define gst_pulsesrc_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstPulseSrc, gst_pulsesrc, GST_TYPE_AUDIO_SRC,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_MIXER, gst_pulsesrc_mixer_interface_init);
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
|
||||
|
||||
static void
|
||||
|
@ -287,8 +283,6 @@ gst_pulsesrc_init (GstPulseSrc * pulsesrc)
|
|||
|
||||
pulsesrc->notify = 0;
|
||||
|
||||
pulsesrc->mixer = NULL;
|
||||
|
||||
pulsesrc->properties = NULL;
|
||||
pulsesrc->proplist = NULL;
|
||||
|
||||
|
@ -348,11 +342,6 @@ gst_pulsesrc_finalize (GObject * object)
|
|||
if (pulsesrc->proplist)
|
||||
pa_proplist_free (pulsesrc->proplist);
|
||||
|
||||
if (pulsesrc->mixer) {
|
||||
gst_pulsemixer_ctrl_free (pulsesrc->mixer);
|
||||
pulsesrc->mixer = NULL;
|
||||
}
|
||||
|
||||
if (pulsesrc->probe) {
|
||||
gst_pulseprobe_free (pulsesrc->probe);
|
||||
pulsesrc->probe = NULL;
|
||||
|
@ -1616,11 +1605,6 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition)
|
|||
this->mainloop = NULL;
|
||||
goto mainloop_start_failed;
|
||||
}
|
||||
|
||||
if (!this->mixer)
|
||||
this->mixer =
|
||||
gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
|
||||
this->device, GST_PULSEMIXER_SOURCE);
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
/* uncork and start recording */
|
||||
|
@ -1645,11 +1629,6 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_pulsesrc_pause (this);
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
if (this->mixer) {
|
||||
gst_pulsemixer_ctrl_free (this->mixer);
|
||||
this->mixer = NULL;
|
||||
}
|
||||
|
||||
if (this->mainloop)
|
||||
pa_threaded_mainloop_stop (this->mainloop);
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/thread-mainloop.h>
|
||||
|
||||
#include "pulsemixerctrl.h"
|
||||
#include "pulseprobe.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -69,7 +68,6 @@ struct _GstPulseSrc
|
|||
size_t read_buffer_length;
|
||||
|
||||
gchar *device_description;
|
||||
GstPulseMixerCtrl *mixer;
|
||||
GstPulseProbe *probe;
|
||||
|
||||
gdouble volume;
|
||||
|
|
|
@ -5,7 +5,6 @@ libgstrtsp_la_SOURCES = gstrtsp.c gstrtspsrc.c \
|
|||
|
||||
libgstrtsp_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstrtsp_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
|
||||
-lgstinterfaces-@GST_API_VERSION@ \
|
||||
-lgstrtp-@GST_API_VERSION@ -lgstrtsp-@GST_API_VERSION@ \
|
||||
-lgstsdp-@GST_API_VERSION@ $(GST_LIBS)
|
||||
libgstrtsp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
|
|
@ -8,17 +8,42 @@ xv_source =
|
|||
xv_libs =
|
||||
endif
|
||||
|
||||
|
||||
# variables used for enum/marshal generation
|
||||
glib_enum_headers = tuner.h tunernorm.h tunerchannel.h
|
||||
glib_enum_define = GST_INTERFACES
|
||||
glib_gen_prefix = gst_interfaces
|
||||
glib_gen_basename = tuner
|
||||
|
||||
built_sources = \
|
||||
tuner-marshal.c \
|
||||
tuner-enumtypes.c
|
||||
|
||||
built_headers = \
|
||||
tuner-marshal.h \
|
||||
tuner-enumtypes.h
|
||||
|
||||
EXTRA_DIST = tuner-marshal.list
|
||||
|
||||
CLEANFILES = $(built_sources) $(built_headers)
|
||||
|
||||
include $(top_srcdir)/common/gst-glib-gen.mak
|
||||
|
||||
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
||||
gstv4l2colorbalance.c \
|
||||
gstv4l2object.c \
|
||||
gstv4l2bufferpool.c \
|
||||
gstv4l2sink.c \
|
||||
gstv4l2src.c \
|
||||
gstv4l2radio.c \
|
||||
gstv4l2tuner.c \
|
||||
gstv4l2vidorient.c \
|
||||
v4l2_calls.c \
|
||||
tuner.c \
|
||||
tunerchannel.c \
|
||||
tunernorm.c \
|
||||
$(xv_source)
|
||||
libgstvideo4linux2_la_SOURCES += gstv4l2sink.c
|
||||
nodist_libgstvideo4linux2_la_SOURCES = $(built_sources) $(built_headers)
|
||||
|
||||
libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
|
||||
$(GST_BASE_CFLAGS) \
|
||||
|
@ -34,7 +59,6 @@ libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
|
|||
$(GST_BASE_LIBS) \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
-lgstvideo-$(GST_API_VERSION) \
|
||||
-lgstinterfaces-$(GST_API_VERSION) \
|
||||
$(GST_LIBS) \
|
||||
$(xv_libs) \
|
||||
$(LIBV4L2_LIBS) \
|
||||
|
@ -50,4 +74,8 @@ noinst_HEADERS = \
|
|||
gstv4l2tuner.h \
|
||||
gstv4l2vidorient.h \
|
||||
gstv4l2videooverlay.h \
|
||||
v4l2_calls.h
|
||||
v4l2_calls.h \
|
||||
tuner.h \
|
||||
tunerchannel.h \
|
||||
tunernorm.h
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#define __GST_V4L2_TUNER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/tuner.h>
|
||||
|
||||
#include "tuner.h"
|
||||
#include "gstv4l2object.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
/* for XkbKeycodeToKeysym */
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <gst/interfaces/navigation.h>
|
||||
#include <gst/video/navigation.h>
|
||||
|
||||
#include "gstv4l2videooverlay.h"
|
||||
#include "gstv4l2object.h"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <X11/X.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/navigation.h>
|
||||
#include <gst/video/navigation.h>
|
||||
#include <gst/video/gstvideosink.h> /* for GstVideoRectange */
|
||||
#include <gst/video/videooverlay.h>
|
||||
|
||||
|
|
2
sys/v4l2/tuner-marshal.list
Normal file
2
sys/v4l2/tuner-marshal.list
Normal file
|
@ -0,0 +1,2 @@
|
|||
VOID:OBJECT,ULONG
|
||||
VOID:OBJECT,INT
|
577
sys/v4l2/tuner.c
Normal file
577
sys/v4l2/tuner.c
Normal file
|
@ -0,0 +1,577 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tuner.c: tuner design virtual class function wrappers
|
||||
*
|
||||
* 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 "tuner.h"
|
||||
#include "tuner-marshal.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* SECTION:gsttuner
|
||||
* @short_description: Interface for elements providing tuner operations
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>
|
||||
* The GstTuner interface is provided by elements that have the ability to
|
||||
* tune into multiple input signals, for example TV or radio capture cards.
|
||||
* </para><para>
|
||||
* The interpretation of 'tuning into' an input stream depends on the element
|
||||
* implementing the interface. For v4lsrc, it might imply selection of an
|
||||
* input source and/or frequency to be configured on a TV card. Another
|
||||
* GstTuner implementation might be to allow selection of an active input pad
|
||||
* from multiple input pads.
|
||||
* </para><para>
|
||||
* That said, the GstTuner interface functions are biased toward the
|
||||
* TV capture scenario.
|
||||
* </para><para>
|
||||
* The general parameters provided are for configuration are:
|
||||
* <itemizedlist>
|
||||
* <listitem>Selection of a current #GstTunerChannel. The current channel
|
||||
* represents the input source (e.g. Composite, S-Video etc for TV capture).
|
||||
* </listitem>
|
||||
* <listitem>The #GstTunerNorm for the channel. The norm chooses the
|
||||
* interpretation of the incoming signal for the current channel. For example,
|
||||
* PAL or NTSC, or more specific variants there-of.
|
||||
* </listitem>
|
||||
* <listitem>Channel frequency. If the current channel has the ability to tune
|
||||
* between multiple frequencies (if it has the GST_TUNER_CHANNEL_FREQUENCY flag)
|
||||
* then the frequency can be changed/retrieved via the
|
||||
* gst_tuner_set_frequency() and gst_tuner_get_frequency() methods.
|
||||
* </listitem>
|
||||
* </itemizedlist>
|
||||
* </para>
|
||||
* <para>
|
||||
* Where applicable, the signal strength can be retrieved and/or monitored
|
||||
* via a signal.
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
/* FIXME 0.11: check if we need to add API for sometimes-supportedness
|
||||
* (aka making up for GstImplementsInterface removal) */
|
||||
|
||||
/* FIXME 0.11: replace signals with messages (+ make API thread-safe) */
|
||||
|
||||
enum
|
||||
{
|
||||
NORM_CHANGED,
|
||||
CHANNEL_CHANGED,
|
||||
FREQUENCY_CHANGED,
|
||||
SIGNAL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_class_init (GstTunerInterface * iface);
|
||||
|
||||
static guint gst_tuner_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
GType
|
||||
gst_tuner_get_type (void)
|
||||
{
|
||||
static GType gst_tuner_type = 0;
|
||||
|
||||
if (!gst_tuner_type) {
|
||||
static const GTypeInfo gst_tuner_info = {
|
||||
sizeof (GstTunerInterface),
|
||||
(GBaseInitFunc) gst_tuner_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
gst_tuner_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GstTuner", &gst_tuner_info, 0);
|
||||
}
|
||||
|
||||
return gst_tuner_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_class_init (GstTunerInterface * iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized) {
|
||||
/**
|
||||
* GstTuner::norm-changed:
|
||||
* @tuner: The element providing the GstTuner interface
|
||||
* @norm: The new configured norm.
|
||||
*
|
||||
* Reports that the current #GstTunerNorm has changed.
|
||||
*/
|
||||
gst_tuner_signals[NORM_CHANGED] =
|
||||
g_signal_new ("norm-changed",
|
||||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerInterface, norm_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_TUNER_NORM);
|
||||
/**
|
||||
* GstTuner::channel-changed:
|
||||
* @tuner: The element providing the GstTuner interface
|
||||
* @channel: The new configured channel.
|
||||
*
|
||||
* Reports that the current #GstTunerChannel has changed.
|
||||
*/
|
||||
gst_tuner_signals[CHANNEL_CHANGED] =
|
||||
g_signal_new ("channel-changed",
|
||||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerInterface, channel_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
|
||||
GST_TYPE_TUNER_CHANNEL);
|
||||
/**
|
||||
* GstTuner::frequency-changed:
|
||||
* @tuner: The element providing the GstTuner interface
|
||||
* @frequency: The new frequency (an unsigned long)
|
||||
*
|
||||
* Reports that the current frequency has changed.
|
||||
*/
|
||||
gst_tuner_signals[FREQUENCY_CHANGED] =
|
||||
g_signal_new ("frequency-changed",
|
||||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerInterface, frequency_changed),
|
||||
NULL, NULL,
|
||||
gst_interfaces_marshal_VOID__OBJECT_ULONG, G_TYPE_NONE, 2,
|
||||
GST_TYPE_TUNER_CHANNEL, G_TYPE_ULONG);
|
||||
/**
|
||||
* GstTuner::signal-changed:
|
||||
* @tuner: The element providing the GstTuner interface
|
||||
* @channel: The current #GstTunerChannel
|
||||
* @signal: The new signal strength (an integer)
|
||||
*
|
||||
* Reports that the signal strength has changed.
|
||||
*
|
||||
* See Also: gst_tuner_signal_strength()
|
||||
*/
|
||||
gst_tuner_signals[SIGNAL_CHANGED] =
|
||||
g_signal_new ("signal-changed",
|
||||
GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerInterface, signal_changed),
|
||||
NULL, NULL,
|
||||
gst_interfaces_marshal_VOID__OBJECT_INT, G_TYPE_NONE, 2,
|
||||
GST_TYPE_TUNER_CHANNEL, G_TYPE_INT);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
/* default virtual functions */
|
||||
iface->list_channels = NULL;
|
||||
iface->set_channel = NULL;
|
||||
iface->get_channel = NULL;
|
||||
|
||||
iface->list_norms = NULL;
|
||||
iface->set_norm = NULL;
|
||||
iface->get_norm = NULL;
|
||||
|
||||
iface->set_frequency = NULL;
|
||||
iface->get_frequency = NULL;
|
||||
iface->signal_strength = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_list_channels:
|
||||
* @tuner: the #GstTuner (a #GstElement) to get the channels from.
|
||||
*
|
||||
* Retrieve a #GList of #GstTunerChannels available
|
||||
* (e.g. 'composite', 's-video', ...) from the given tuner object.
|
||||
*
|
||||
* Returns: A list of channels available on this tuner. The list is
|
||||
* owned by the GstTuner and must not be freed.
|
||||
*/
|
||||
const GList *
|
||||
gst_tuner_list_channels (GstTuner * tuner)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->list_channels) {
|
||||
return iface->list_channels (tuner);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_set_channel:
|
||||
* @tuner: the #GstTuner (a #GstElement) that owns the channel.
|
||||
* @channel: the channel to tune to.
|
||||
*
|
||||
* Tunes the object to the given channel, which should be one of the
|
||||
* channels returned by gst_tuner_list_channels().
|
||||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_channel (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->set_channel) {
|
||||
iface->set_channel (tuner, channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_get_channel:
|
||||
* @tuner: the #GstTuner (a #GstElement) to get the current channel from.
|
||||
*
|
||||
* Retrieve the current channel from the tuner.
|
||||
*
|
||||
* Returns: the current channel of the tuner object.
|
||||
*/
|
||||
|
||||
GstTunerChannel *
|
||||
gst_tuner_get_channel (GstTuner * tuner)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->get_channel) {
|
||||
return iface->get_channel (tuner);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_list_norms:
|
||||
* @tuner: the #GstTuner (*a #GstElement) to get the list of norms from.
|
||||
*
|
||||
* Retrieve a GList of available #GstTunerNorm settings for the currently
|
||||
* tuned channel on the given tuner object.
|
||||
*
|
||||
* Returns: A list of norms available on the current channel for this
|
||||
* tuner object. The list is owned by the GstTuner and must not
|
||||
* be freed.
|
||||
*/
|
||||
|
||||
const GList *
|
||||
gst_tuner_list_norms (GstTuner * tuner)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->list_norms) {
|
||||
return iface->list_norms (tuner);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_set_norm:
|
||||
* @tuner: the #GstTuner (a #GstElement) to set the norm on.
|
||||
* @norm: the norm to use for the current channel.
|
||||
*
|
||||
* Changes the video norm on this tuner to the given norm, which should be
|
||||
* one of the norms returned by gst_tuner_list_norms().
|
||||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_norm (GstTuner * tuner, GstTunerNorm * norm)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->set_norm) {
|
||||
iface->set_norm (tuner, norm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_get_norm:
|
||||
* @tuner: the #GstTuner (a #GstElement) to get the current norm from.
|
||||
*
|
||||
* Get the current video norm from the given tuner object for the
|
||||
* currently selected channel.
|
||||
*
|
||||
* Returns: the current norm.
|
||||
*/
|
||||
|
||||
GstTunerNorm *
|
||||
gst_tuner_get_norm (GstTuner * tuner)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->get_norm) {
|
||||
return iface->get_norm (tuner);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_set_frequency:
|
||||
* @tuner: The #GstTuner (a #GstElement) that owns the given channel.
|
||||
* @channel: The #GstTunerChannel to set the frequency on.
|
||||
* @frequency: The frequency to tune in to.
|
||||
*
|
||||
* Sets a tuning frequency on the given tuner/channel. Note that this
|
||||
* requires the given channel to be a "tuning" channel, which can be
|
||||
* checked using GST_TUNER_CHANNEL_HAS_FLAG (), with the proper flag
|
||||
* being GST_TUNER_CHANNEL_FREQUENCY.
|
||||
*
|
||||
* The frequency is in Hz, with minimum steps indicated by the
|
||||
* frequency_multiplicator provided in the #GstTunerChannel. The
|
||||
* valid range is provided in the min_frequency and max_frequency properties
|
||||
* of the #GstTunerChannel.
|
||||
*/
|
||||
|
||||
void
|
||||
gst_tuner_set_frequency (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
|
||||
GST_TUNER_CHANNEL_FREQUENCY));
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->set_frequency) {
|
||||
iface->set_frequency (tuner, channel, frequency);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_get_frequency:
|
||||
* @tuner: The #GstTuner (a #GstElement) that owns the given channel.
|
||||
* @channel: The #GstTunerChannel to retrieve the frequency from.
|
||||
*
|
||||
* Retrieve the current frequency from the given channel. As for
|
||||
* gst_tuner_set_frequency(), the #GstTunerChannel must support frequency
|
||||
* operations, as indicated by the GST_TUNER_CHANNEL_FREQUENCY flag.
|
||||
*
|
||||
* Returns: The current frequency, or 0 on error.
|
||||
*/
|
||||
|
||||
gulong
|
||||
gst_tuner_get_frequency (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), 0);
|
||||
g_return_val_if_fail (GST_IS_TUNER_CHANNEL (channel), 0);
|
||||
g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
|
||||
GST_TUNER_CHANNEL_FREQUENCY), 0);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
|
||||
if (iface->get_frequency) {
|
||||
return iface->get_frequency (tuner, channel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_signal_strength:
|
||||
* @tuner: the #GstTuner (a #GstElement) that owns the given channel.
|
||||
* @channel: the #GstTunerChannel to get the signal strength from.
|
||||
*
|
||||
* Get the strength of the signal on this channel. Note that this
|
||||
* requires the current channel to be a "tuning" channel, i.e. a
|
||||
* channel on which frequency can be set. This can be checked using
|
||||
* GST_TUNER_CHANNEL_HAS_FLAG (), and the appropriate flag to check
|
||||
* for is GST_TUNER_CHANNEL_FREQUENCY.
|
||||
*
|
||||
* The valid range of the signal strength is indicated in the
|
||||
* min_signal and max_signal properties of the #GstTunerChannel.
|
||||
*
|
||||
* Returns: Signal strength, or 0 on error.
|
||||
*/
|
||||
gint
|
||||
gst_tuner_signal_strength (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
GstTunerInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), 0);
|
||||
g_return_val_if_fail (GST_IS_TUNER_CHANNEL (channel), 0);
|
||||
g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
|
||||
GST_TUNER_CHANNEL_FREQUENCY), 0);
|
||||
|
||||
iface = GST_TUNER_GET_INTERFACE (tuner);
|
||||
if (iface->signal_strength) {
|
||||
return iface->signal_strength (tuner, channel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_find_norm_by_name:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @norm: A string containing the name of a #GstTunerNorm
|
||||
*
|
||||
* Look up a #GstTunerNorm by name.
|
||||
*
|
||||
* Returns: A #GstTunerNorm, or NULL if no norm with the provided name
|
||||
* is available.
|
||||
*/
|
||||
GstTunerNorm *
|
||||
gst_tuner_find_norm_by_name (GstTuner * tuner, gchar * norm)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
g_return_val_if_fail (norm != NULL, NULL);
|
||||
|
||||
walk = (GList *) gst_tuner_list_norms (tuner);
|
||||
while (walk) {
|
||||
if (strcmp (GST_TUNER_NORM (walk->data)->label, norm) == 0)
|
||||
return GST_TUNER_NORM (walk->data);
|
||||
walk = g_list_next (walk);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_find_channel_by_name:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @channel: A string containing the name of a #GstTunerChannel
|
||||
*
|
||||
* Look up a #GstTunerChannel by name.
|
||||
*
|
||||
* Returns: A #GstTunerChannel, or NULL if no channel with the provided name
|
||||
* is available.
|
||||
*/
|
||||
GstTunerChannel *
|
||||
gst_tuner_find_channel_by_name (GstTuner * tuner, gchar * channel)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
g_return_val_if_fail (GST_IS_TUNER (tuner), NULL);
|
||||
g_return_val_if_fail (channel != NULL, NULL);
|
||||
|
||||
walk = (GList *) gst_tuner_list_channels (tuner);
|
||||
while (walk) {
|
||||
if (strcmp (GST_TUNER_CHANNEL (walk->data)->label, channel) == 0)
|
||||
return GST_TUNER_CHANNEL (walk->data);
|
||||
walk = g_list_next (walk);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_channel_changed:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @channel: A #GstTunerChannel instance
|
||||
*
|
||||
* Called by elements implementing the #GstTuner interface when the
|
||||
* current channel changes. Fires the #GstTuner::channel-changed signal.
|
||||
*/
|
||||
void
|
||||
gst_tuner_channel_changed (GstTuner * tuner, GstTunerChannel * channel)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[CHANNEL_CHANGED], 0, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_norm_changed:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @norm: A #GstTunerNorm instance
|
||||
*
|
||||
* Called by elements implementing the #GstTuner interface when the
|
||||
* current norm changes. Fires the #GstTuner::norm-changed signal.
|
||||
*
|
||||
*/
|
||||
void
|
||||
gst_tuner_norm_changed (GstTuner * tuner, GstTunerNorm * norm)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_NORM (norm));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner), gst_tuner_signals[NORM_CHANGED], 0, norm);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_frequency_changed:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @channel: The current #GstTunerChannel
|
||||
* @frequency: The new frequency setting
|
||||
*
|
||||
* Called by elements implementing the #GstTuner interface when the
|
||||
* configured frequency changes. Fires the #GstTuner::frequency-changed
|
||||
* signal on the tuner, and the #GstTunerChannel::frequency-changed signal
|
||||
* on the channel.
|
||||
*/
|
||||
void
|
||||
gst_tuner_frequency_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gulong frequency)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[FREQUENCY_CHANGED], 0, channel, frequency);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "frequency_changed", frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_tuner_signal_changed:
|
||||
* @tuner: A #GstTuner instance
|
||||
* @channel: The current #GstTunerChannel
|
||||
* @signal: The new signal strength
|
||||
*
|
||||
* Called by elements implementing the #GstTuner interface when the
|
||||
* incoming signal strength changes. Fires the #GstTuner::signal-changed
|
||||
* signal on the tuner and the #GstTunerChannel::signal-changed signal on
|
||||
* the channel.
|
||||
*/
|
||||
void
|
||||
gst_tuner_signal_changed (GstTuner * tuner,
|
||||
GstTunerChannel * channel, gint signal)
|
||||
{
|
||||
g_return_if_fail (GST_IS_TUNER (tuner));
|
||||
g_return_if_fail (GST_IS_TUNER_CHANNEL (channel));
|
||||
|
||||
g_signal_emit (G_OBJECT (tuner),
|
||||
gst_tuner_signals[SIGNAL_CHANGED], 0, channel, signal);
|
||||
|
||||
g_signal_emit_by_name (G_OBJECT (channel), "signal_changed", signal);
|
||||
}
|
142
sys/v4l2/tuner.h
Normal file
142
sys/v4l2/tuner.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tuner.h: tuner interface design
|
||||
*
|
||||
* 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_TUNER_H__
|
||||
#define __GST_TUNER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "tunernorm.h"
|
||||
#include "tunerchannel.h"
|
||||
#include "tuner-enumtypes.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER \
|
||||
(gst_tuner_get_type ())
|
||||
#define GST_TUNER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER, GstTuner))
|
||||
#define GST_IS_TUNER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER))
|
||||
#define GST_TUNER_GET_INTERFACE(inst) \
|
||||
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TUNER, GstTunerInterface))
|
||||
|
||||
typedef struct _GstTuner GstTuner;
|
||||
typedef struct _GstTunerInterface GstTunerInterface;
|
||||
|
||||
/**
|
||||
* GstTunerInterface:
|
||||
* @iface: the parent interface
|
||||
* @list_channels: list available channels
|
||||
* @set_channel: set to a channel
|
||||
* @get_channel: return the current channel
|
||||
* @list_norms: list available norms
|
||||
* @set_norm: set a norm
|
||||
* @get_norm: return the current norm
|
||||
* @set_frequency: set the frequency
|
||||
* @get_frequency: return the current frequency
|
||||
* @signal_strength: get the signal strength
|
||||
* @channel_changed: default handler for channel changed notification
|
||||
* @norm_changed: default handler for norm changed notification
|
||||
* @frequency_changed: default handler for frequency changed notification
|
||||
* @signal_changed: default handler for signal-strength changed notification
|
||||
*
|
||||
* Tuner interface.
|
||||
*/
|
||||
struct _GstTunerInterface {
|
||||
GTypeInterface iface;
|
||||
|
||||
/* virtual functions */
|
||||
const GList * (* list_channels) (GstTuner *tuner);
|
||||
void (* set_channel) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
GstTunerChannel *
|
||||
(* get_channel) (GstTuner *tuner);
|
||||
|
||||
const GList * (* list_norms) (GstTuner *tuner);
|
||||
void (* set_norm) (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
GstTunerNorm *(* get_norm) (GstTuner *tuner);
|
||||
|
||||
void (* set_frequency) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
gulong (* get_frequency) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
gint (* signal_strength) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
|
||||
/* signals */
|
||||
void (*channel_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void (*norm_changed) (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
void (*frequency_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void (*signal_changed) (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gint signal);
|
||||
};
|
||||
|
||||
GType gst_tuner_get_type (void);
|
||||
|
||||
/* virtual class function wrappers */
|
||||
const GList * gst_tuner_list_channels (GstTuner *tuner);
|
||||
void gst_tuner_set_channel (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
GstTunerChannel *
|
||||
gst_tuner_get_channel (GstTuner *tuner);
|
||||
|
||||
const GList * gst_tuner_list_norms (GstTuner *tuner);
|
||||
void gst_tuner_set_norm (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
GstTunerNorm * gst_tuner_get_norm (GstTuner *tuner);
|
||||
|
||||
void gst_tuner_set_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
gulong gst_tuner_get_frequency (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
gint gst_tuner_signal_strength (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
|
||||
/* helper functions */
|
||||
GstTunerNorm * gst_tuner_find_norm_by_name (GstTuner *tuner,
|
||||
gchar *norm);
|
||||
GstTunerChannel *gst_tuner_find_channel_by_name (GstTuner *tuner,
|
||||
gchar *channel);
|
||||
|
||||
/* trigger signals */
|
||||
void gst_tuner_channel_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel);
|
||||
void gst_tuner_norm_changed (GstTuner *tuner,
|
||||
GstTunerNorm *norm);
|
||||
void gst_tuner_frequency_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void gst_tuner_signal_changed (GstTuner *tuner,
|
||||
GstTunerChannel *channel,
|
||||
gint signal);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_H__ */
|
148
sys/v4l2/tunerchannel.c
Normal file
148
sys/v4l2/tunerchannel.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tunerchannel.c: tuner channel object design
|
||||
*
|
||||
* 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 "tunerchannel.h"
|
||||
|
||||
/**
|
||||
* SECTION:gsttunerchannel
|
||||
* @short_description: A channel from an element implementing the #GstTuner
|
||||
* interface.
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>The #GstTunerChannel object is provided by an element implementing
|
||||
* the #GstTuner interface.
|
||||
* </para>
|
||||
* <para>
|
||||
* GstTunerChannel provides a name and flags to determine the type and
|
||||
* capabilities of the channel. If the GST_TUNER_CHANNEL_FREQUENCY flag is
|
||||
* set, then the channel also information about the minimum and maximum
|
||||
* frequency, and range of the reported signal strength.
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
SIGNAL_FREQUENCY_CHANGED,
|
||||
SIGNAL_SIGNAL_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_channel_class_init (GstTunerChannelClass * klass);
|
||||
static void gst_tuner_channel_init (GstTunerChannel * channel);
|
||||
static void gst_tuner_channel_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
GType
|
||||
gst_tuner_channel_get_type (void)
|
||||
{
|
||||
static GType gst_tuner_channel_type = 0;
|
||||
|
||||
if (!gst_tuner_channel_type) {
|
||||
static const GTypeInfo tuner_channel_info = {
|
||||
sizeof (GstTunerChannelClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_tuner_channel_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstTunerChannel),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_tuner_channel_init,
|
||||
NULL
|
||||
};
|
||||
|
||||
gst_tuner_channel_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstTunerChannel", &tuner_channel_info, 0);
|
||||
}
|
||||
|
||||
return gst_tuner_channel_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_class_init (GstTunerChannelClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
/**
|
||||
* GstTunerChannel::frequency-changed:
|
||||
* @tunerchannel: The #GstTunerChannel
|
||||
* @frequency: The new frequency (an unsigned long)
|
||||
*
|
||||
* Reports that the current frequency has changed.
|
||||
*/
|
||||
signals[SIGNAL_FREQUENCY_CHANGED] =
|
||||
g_signal_new ("frequency-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerChannelClass,
|
||||
frequency_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__ULONG, G_TYPE_NONE, 1, G_TYPE_ULONG);
|
||||
/**
|
||||
* GstTunerChannel::signal-changed:
|
||||
* @tunerchannel: The #GstTunerChannel
|
||||
* @signal: The new signal strength (an integer)
|
||||
*
|
||||
* Reports that the signal strength has changed.
|
||||
*
|
||||
* See Also: gst_tuner_signal_strength()
|
||||
*/
|
||||
signals[SIGNAL_SIGNAL_CHANGED] =
|
||||
g_signal_new ("signal-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstTunerChannelClass,
|
||||
signal_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
object_klass->dispose = gst_tuner_channel_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_init (GstTunerChannel * channel)
|
||||
{
|
||||
channel->label = NULL;
|
||||
channel->flags = 0;
|
||||
channel->min_frequency = channel->max_frequency = 0;
|
||||
channel->min_signal = channel->max_signal = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_channel_dispose (GObject * object)
|
||||
{
|
||||
GstTunerChannel *channel = GST_TUNER_CHANNEL (object);
|
||||
|
||||
if (channel->label) {
|
||||
g_free (channel->label);
|
||||
channel->label = NULL;
|
||||
}
|
||||
|
||||
if (parent_class->dispose)
|
||||
parent_class->dispose (object);
|
||||
}
|
116
sys/v4l2/tunerchannel.h
Normal file
116
sys/v4l2/tunerchannel.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tunerchannel.h: tuner channel object design
|
||||
*
|
||||
* 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_TUNER_CHANNEL_H__
|
||||
#define __GST_TUNER_CHANNEL_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER_CHANNEL \
|
||||
(gst_tuner_channel_get_type ())
|
||||
#define GST_TUNER_CHANNEL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_CHANNEL, \
|
||||
GstTunerChannel))
|
||||
#define GST_TUNER_CHANNEL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_CHANNEL, \
|
||||
GstTunerChannelClass))
|
||||
#define GST_IS_TUNER_CHANNEL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_CHANNEL))
|
||||
#define GST_IS_TUNER_CHANNEL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_CHANNEL))
|
||||
|
||||
typedef struct _GstTunerChannel GstTunerChannel;
|
||||
typedef struct _GstTunerChannelClass GstTunerChannelClass;
|
||||
|
||||
/**
|
||||
* GstTunerChannelFlags:
|
||||
* @GST_TUNER_CHANNEL_INPUT: The channel is for input
|
||||
* @GST_TUNER_CHANNEL_OUTPUT: The channel is for output
|
||||
* @GST_TUNER_CHANNEL_FREQUENCY: The channel has a frequency setting
|
||||
* and signal strength.
|
||||
* @GST_TUNER_CHANNEL_AUDIO: The channel carries audio.
|
||||
*
|
||||
* An enumeration for flags indicating the available capabilities
|
||||
* of a #GstTunerChannel.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_TUNER_CHANNEL_INPUT = (1<<0),
|
||||
GST_TUNER_CHANNEL_OUTPUT = (1<<1),
|
||||
GST_TUNER_CHANNEL_FREQUENCY = (1<<2),
|
||||
GST_TUNER_CHANNEL_AUDIO = (1<<3)
|
||||
} GstTunerChannelFlags;
|
||||
|
||||
/**
|
||||
* GST_TUNER_CHANNEL_HAS_FLAG:
|
||||
* @channel: A #GstTunerChannel
|
||||
* @flag: The flag to check for
|
||||
*
|
||||
* Macro to check if the given flag is set on a channel
|
||||
*/
|
||||
#define GST_TUNER_CHANNEL_HAS_FLAG(channel, flag) \
|
||||
((channel)->flags & flag)
|
||||
|
||||
/**
|
||||
* GstTunerChannel:
|
||||
* @label: A string containing a descriptive name for this channel
|
||||
* @flags: A set of #GstTunerChannelFlags for this channel
|
||||
* @freq_multiplicator: The step size (in Hz) for the frequency setting.
|
||||
* @min_frequency: Minimum valid frequency setting (in Hz).
|
||||
* @max_frequency: Maximum valid frequency setting (in Hz).
|
||||
* @min_signal: Minimum reported signal strength value.
|
||||
* @max_signal: Maximum reported signal strength value.
|
||||
*/
|
||||
struct _GstTunerChannel {
|
||||
GObject parent;
|
||||
|
||||
/*< public >*/
|
||||
gchar *label;
|
||||
GstTunerChannelFlags flags;
|
||||
gfloat freq_multiplicator;
|
||||
gulong min_frequency;
|
||||
gulong max_frequency;
|
||||
gint min_signal;
|
||||
gint max_signal;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstTunerChannelClass {
|
||||
GObjectClass parent;
|
||||
|
||||
/*< private >*/
|
||||
/* signals */
|
||||
void (*frequency_changed) (GstTunerChannel *channel,
|
||||
gulong frequency);
|
||||
void (*signal_changed) (GstTunerChannel *channel,
|
||||
gint signal);
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_tuner_channel_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_CHANNEL_H__ */
|
111
sys/v4l2/tunernorm.c
Normal file
111
sys/v4l2/tunernorm.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tunernorm.c: tuner norm object design
|
||||
*
|
||||
* 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 "tunernorm.h"
|
||||
|
||||
/**
|
||||
* SECTION:gsttunernorm
|
||||
* @short_description: Encapsulates information about the data format(s)
|
||||
* for a #GstTunerChannel.
|
||||
*
|
||||
* <refsect2>
|
||||
* <para>The #GstTunerNorm object is created by an element implementing the
|
||||
* #GstTuner interface and encapsulates the selection of a capture/output format
|
||||
* for a selected #GstTunerChannel.
|
||||
* </para>
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gst_tuner_norm_class_init (GstTunerNormClass * klass);
|
||||
static void gst_tuner_norm_init (GstTunerNorm * norm);
|
||||
static void gst_tuner_norm_dispose (GObject * object);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/*static guint signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
||||
GType
|
||||
gst_tuner_norm_get_type (void)
|
||||
{
|
||||
static GType gst_tuner_norm_type = 0;
|
||||
|
||||
if (!gst_tuner_norm_type) {
|
||||
static const GTypeInfo tuner_norm_info = {
|
||||
sizeof (GstTunerNormClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_tuner_norm_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstTunerNorm),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_tuner_norm_init,
|
||||
NULL
|
||||
};
|
||||
|
||||
gst_tuner_norm_type =
|
||||
g_type_register_static (G_TYPE_OBJECT,
|
||||
"GstTunerNorm", &tuner_norm_info, 0);
|
||||
}
|
||||
|
||||
return gst_tuner_norm_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_class_init (GstTunerNormClass * klass)
|
||||
{
|
||||
GObjectClass *object_klass = (GObjectClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_klass->dispose = gst_tuner_norm_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_init (GstTunerNorm * norm)
|
||||
{
|
||||
norm->label = NULL;
|
||||
g_value_init (&norm->framerate, GST_TYPE_FRACTION);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_tuner_norm_dispose (GObject * object)
|
||||
{
|
||||
GstTunerNorm *norm = GST_TUNER_NORM (object);
|
||||
|
||||
if (norm->label) {
|
||||
g_free (norm->label);
|
||||
norm->label = NULL;
|
||||
}
|
||||
|
||||
if (parent_class->dispose)
|
||||
parent_class->dispose (object);
|
||||
}
|
70
sys/v4l2/tunernorm.h
Normal file
70
sys/v4l2/tunernorm.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* GStreamer Tuner
|
||||
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
*
|
||||
* tunernorm.h: tuner norm object design
|
||||
*
|
||||
* 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_TUNER_NORM_H__
|
||||
#define __GST_TUNER_NORM_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_TUNER_NORM \
|
||||
(gst_tuner_norm_get_type ())
|
||||
#define GST_TUNER_NORM(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_NORM, GstTunerNorm))
|
||||
#define GST_TUNER_NORM_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_NORM, GstTunerNormClass))
|
||||
#define GST_IS_TUNER_NORM(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_NORM))
|
||||
#define GST_IS_TUNER_NORM_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_NORM))
|
||||
|
||||
typedef struct _GstTunerNorm GstTunerNorm;
|
||||
typedef struct _GstTunerNormClass GstTunerNormClass;
|
||||
|
||||
/**
|
||||
* GstTunerNorm:
|
||||
* @label: A string containing a descriptive name for the norm
|
||||
* @framerate: A GValue containing the framerate associated with this norm,
|
||||
* if any. (May be unset).
|
||||
*/
|
||||
struct _GstTunerNorm {
|
||||
GObject parent;
|
||||
|
||||
/*< public >*/
|
||||
gchar *label;
|
||||
GValue framerate;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstTunerNormClass {
|
||||
GObjectClass parent;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_tuner_norm_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_TUNER_NORM_H__ */
|
|
@ -294,7 +294,7 @@ elements_sunaudio_CFLAGS = \
|
|||
$(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) \
|
||||
$(AM_CFLAGS)
|
||||
elements_sunaudio_LDADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-@GST_API_VERSION@ \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
$(LDADD)
|
||||
|
||||
elements_udpsrc_CFLAGS = $(AM_CFLAGS) $(GIO_CFLAGS)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
noinst_PROGRAMS = pulse
|
||||
pulse_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
pulse_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_API_VERSION) $(GST_BASE_LIBS) $(GST_LIBS)
|
||||
pulse_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
|
||||
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ V4L2_TESTS = v4l2src-test
|
|||
v4l2src_test_SOURCES = v4l2src-test.c
|
||||
v4l2src_test_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
v4l2src_test_LDADD = $(GST_PLUGINS_BASE_LIBS) \
|
||||
-lgstvideo-$(GST_API_VERSION) \
|
||||
-lgstinterfaces-$(GST_API_VERSION) $(GST_LIBS)
|
||||
-lgstvideo-$(GST_API_VERSION)
|
||||
|
||||
else
|
||||
V4L2_TESTS =
|
||||
|
@ -25,7 +24,7 @@ OSS4_TESTS=test-oss4
|
|||
|
||||
test_oss4_SOURCES = test-oss4.c
|
||||
test_oss4_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
test_oss4_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_API_VERSION) $(GST_LIBS)
|
||||
test_oss4_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS)
|
||||
test_oss4_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
else
|
||||
OSS4_TESTS=
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <getopt.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/tuner.h>
|
||||
#include <gst/video/colorbalance.h>
|
||||
#include <gst/video/videoorientation.h>
|
||||
|
||||
|
@ -49,6 +48,7 @@ run_options (char opt)
|
|||
int res;
|
||||
|
||||
switch (opt) {
|
||||
#if 0
|
||||
case 'f':
|
||||
{
|
||||
GstTuner *tuner = GST_TUNER (source);
|
||||
|
@ -143,6 +143,7 @@ run_options (char opt)
|
|||
gst_tuner_set_channel (tuner, channel);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'e':
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
g_main_loop_quit (loop);
|
||||
|
|
Loading…
Reference in a new issue