alsaspdif: remove alsaspdifsink element

Remove alsaspdifsink, it's not needed any longer. alsasink in -base
has been able to handle SPDIF for a while now.
This commit is contained in:
Tim-Philipp Müller 2010-10-05 11:42:42 +01:00
parent 716e430fd5
commit a3f9fab72f
11 changed files with 3 additions and 1151 deletions

View File

@ -43,11 +43,12 @@ include $(top_srcdir)/common/coverage/lcov.mak
CRUFT_FILES = \ CRUFT_FILES = \
$(top_builddir)/common/shave \ $(top_builddir)/common/shave \
$(top_builddir)/common/shave-libtool \ $(top_builddir)/common/shave-libtool \
$(top_builddir)/ext/alsaspdif/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/ext/ivorbis/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/aacparse/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/aacparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/amrparse/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/amrparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/flacparse/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/flacparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/shapewipe/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/shapewipe/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/ext/ivorbis/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/imagefreeze/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/imagefreeze/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/sys/oss4/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/sys/oss4/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/tests/check/elements/capssetter \ $(top_builddir)/tests/check/elements/capssetter \
@ -62,6 +63,7 @@ CRUFT_DIRS = \
$(top_srcdir)/gst/imagefreeze \ $(top_srcdir)/gst/imagefreeze \
$(top_srcdir)/gst/shapewipe \ $(top_srcdir)/gst/shapewipe \
$(top_srcdir)/tests/examples/shapewipe $(top_srcdir)/tests/examples/shapewipe
$(top_srcdir)/ext/alsaspdif \
$(top_srcdir)/ext/ivorbis \ $(top_srcdir)/ext/ivorbis \
$(top_srcdir)/ext/metadata $(top_srcdir)/ext/metadata

View File

@ -499,18 +499,6 @@ dnl keep this list sorted alphabetically !
if test "x$BUILD_EXTERNAL" = "xyes"; then if test "x$BUILD_EXTERNAL" = "xyes"; then
dnl *** alsa ***
translit(dnm, m, l) AM_CONDITIONAL(USE_ALSA, true)
AG_GST_CHECK_FEATURE(ALSA, [alsa plug-ins], gstalsa, [
PKG_CHECK_MODULES(ALSA, alsa >= 0.9.1, [
HAVE_ALSA="yes"
AC_SUBST(ALSA_CFLAGS)
AC_SUBST(ALSA_LIBS)
], [
AM_PATH_ALSA(0.9.1, HAVE_ALSA="yes", HAVE_ALSA="no")
])
])
dnl *** assrender *** dnl *** assrender ***
translit(dnm, m, l) AM_CONDITIONAL(USE_ASSRENDER, true) translit(dnm, m, l) AM_CONDITIONAL(USE_ASSRENDER, true)
AG_GST_CHECK_FEATURE(ASSRENDER, [ASS/SSA renderer], assrender, [ AG_GST_CHECK_FEATURE(ASSRENDER, [ASS/SSA renderer], assrender, [
@ -1555,7 +1543,6 @@ else
dnl not building plugins with external dependencies, dnl not building plugins with external dependencies,
dnl but we still need to set the conditionals dnl but we still need to set the conditionals
AM_CONDITIONAL(USE_ALSA, false)
AM_CONDITIONAL(USE_ASSRENDER, false) AM_CONDITIONAL(USE_ASSRENDER, false)
AM_CONDITIONAL(USE_AMRWB, false) AM_CONDITIONAL(USE_AMRWB, false)
AM_CONDITIONAL(USE_APEXSINK, false) AM_CONDITIONAL(USE_APEXSINK, false)
@ -1777,7 +1764,6 @@ tests/examples/scaletempo/Makefile
tests/examples/switch/Makefile tests/examples/switch/Makefile
tests/examples/jack/Makefile tests/examples/jack/Makefile
tests/icles/Makefile tests/icles/Makefile
ext/alsaspdif/Makefile
ext/amrwbenc/Makefile ext/amrwbenc/Makefile
ext/assrender/Makefile ext/assrender/Makefile
ext/apexsink/Makefile ext/apexsink/Makefile

View File

@ -138,7 +138,6 @@
<xi:include href="xml/plugin-audioparsersbad.xml" /> <xi:include href="xml/plugin-audioparsersbad.xml" />
<xi:include href="xml/plugin-autoconvert.xml" /> <xi:include href="xml/plugin-autoconvert.xml" />
<xi:include href="xml/plugin-legacyresample.xml" /> <xi:include href="xml/plugin-legacyresample.xml" />
<xi:include href="xml/plugin-alsaspdif.xml" />
<xi:include href="xml/plugin-amrwbenc.xml" /> <xi:include href="xml/plugin-amrwbenc.xml" />
<xi:include href="xml/plugin-assrender.xml" /> <xi:include href="xml/plugin-assrender.xml" />
<xi:include href="xml/plugin-bayer.xml" /> <xi:include href="xml/plugin-bayer.xml" />

View File

@ -1,28 +0,0 @@
<plugin>
<name>alsaspdif</name>
<description>Alsa plugin for S/PDIF output</description>
<filename>../../ext/alsaspdif/.libs/libgstalsaspdif.so</filename>
<basename>libgstalsaspdif.so</basename>
<version>0.10.20.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>alsaspdifsink</name>
<longname>S/PDIF ALSA audiosink</longname>
<class>Sink/Audio</class>
<description>Feeds audio to S/PDIF interfaces through the ALSA sound driver</description>
<author>Martin Soto &lt;martinsoto@users.sourceforge.net&gt;, Michael Smith &lt;msmith@fluendo.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-iec958</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View File

@ -1,9 +1,3 @@
if USE_ALSA
ALSASPDIF_DIR = alsaspdif
else
ALSASPDIF_DIR =
endif
if USE_ASSRENDER if USE_ASSRENDER
ASSRENDER_DIR = assrender ASSRENDER_DIR = assrender
else else
@ -380,7 +374,6 @@ endif
SUBDIRS=\ SUBDIRS=\
$(ALSASPDIF_DIR) \
$(ASSRENDER_DIR) \ $(ASSRENDER_DIR) \
$(AMRWB_DIR) \ $(AMRWB_DIR) \
$(APEXSINK_DIR) \ $(APEXSINK_DIR) \
@ -444,7 +437,6 @@ SUBDIRS=\
$(RTMP_DIR) $(RTMP_DIR)
DIST_SUBDIRS = \ DIST_SUBDIRS = \
alsaspdif \
amrwbenc \ amrwbenc \
assrender \ assrender \
apexsink \ apexsink \

View File

@ -1,15 +0,0 @@
plugin_LTLIBRARIES = libgstalsaspdif.la
# sources used to compile this plugin
libgstalsaspdif_la_SOURCES = alsaspdifsink.c
# flags used to compile this plugin
# we use the GST_LIBS flags because we might be using plug-in libs
libgstalsaspdif_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(ALSA_CFLAGS)
libgstalsaspdif_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(GST_BASE_LIBS) $(GST_LIBS) $(ALSA_LIBS)
libgstalsaspdif_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstalsaspdif_la_LIBTOOLFLAGS = --tag=disable-static
# headers we need but don't want installed
noinst_HEADERS = alsaspdifsink.h

View File

@ -1,846 +0,0 @@
/* Based on a plugin from Martin Soto's Seamless DVD Player.
* Copyright (C) 2003, 2004 Martin Soto <martinsoto@users.sourceforge.net>
* 2005-6 Michael Smith <msmith@fluendo.com>
*
* 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 <string.h>
#include <unistd.h>
#include <gst/gst.h>
#include <gst/audio/gstaudioclock.h>
#include <gst/base/gstbasesink.h>
#include "alsaspdifsink.h"
GST_DEBUG_CATEGORY_STATIC (alsaspdifsink_debug);
#define GST_CAT_DEFAULT (alsaspdifsink_debug)
/* The magic audio-type we pretend to be for AC3 output */
#define AC3_CHANNELS 2
#define AC3_BITS 16
/* Define AC3 FORMAT as big endian. Fall back to swapping
* on sound devices that don't support it */
#define AC3_FORMAT_BE SND_PCM_FORMAT_S16_BE
#define AC3_FORMAT_LE SND_PCM_FORMAT_S16_LE
/* The size in bytes of an IEC958 frame. */
#define IEC958_FRAME_SIZE 6144
/* Size in bytes of an ALSA PCM frame (4, for this case). */
#define ALSASPDIFSINK_BYTES_PER_FRAME ((AC3_BITS / 8) * AC3_CHANNELS)
#define IEC958_SAMPLES_PER_FRAME (IEC958_FRAME_SIZE / ALSASPDIFSINK_BYTES_PER_FRAME)
#if 0
/* The duration of a single IEC958 frame. */
#define IEC958_FRAME_DURATION (32 * GST_MSECOND)
/* Maximal synchronization difference. Measures will be taken if
block timestamps differ from actual playing time in more than this
value. */
#define MAX_SYNC_DIFF (IEC958_FRAME_DURATION * 0.8)
/* Playing time for the given number of ALSA PCM frames. */
#define ALSASPDIFSINK_TIME_PER_FRAMES(sink, frames) \
(((GstClockTime) (frames) * GST_SECOND) / AC3_RATE)
/* Number of ALSA PCM frames for the given playing time. */
#define ALSASPDIFSINK_FRAMES_PER_TIME(sink, time) \
(((GstClockTime) AC3_RATE * (time)) / GST_SECOND)
#endif
/* AlsaSPDIFSink signals and args */
enum
{
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_CARD,
PROP_DEVICE
};
static GstStaticPadTemplate alsaspdifsink_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-iec958")
);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (alsaspdifsink_debug, "alsaspdifsink", 0, \
"ALSA S/PDIF audio sink element");
GST_BOILERPLATE_FULL (AlsaSPDIFSink, alsaspdifsink, GstBaseSink,
GST_TYPE_BASE_SINK, _do_init);
static void alsaspdifsink_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void alsaspdifsink_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
static gboolean alsaspdifsink_event (GstBaseSink * bsink, GstEvent * event);
static GstFlowReturn alsaspdifsink_render (GstBaseSink * bsink,
GstBuffer * buf);
static void alsaspdifsink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end);
static gboolean alsaspdifsink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static gboolean alsaspdifsink_open (AlsaSPDIFSink * sink);
static void alsaspdifsink_close (AlsaSPDIFSink * sink);
static GstClock *alsaspdifsink_provide_clock (GstElement * elem);
static GstClockTime alsaspdifsink_get_time (GstClock * clock,
gpointer user_data);
static void alsaspdifsink_dispose (GObject * object);
static void alsaspdifsink_finalize (GObject * object);
static GstStateChangeReturn alsaspdifsink_change_state (GstElement * element,
GstStateChange transition);
static int alsaspdifsink_find_pcm_device (AlsaSPDIFSink * sink);
static gboolean alsaspdifsink_set_params (AlsaSPDIFSink * sink);
static snd_pcm_sframes_t alsaspdifsink_delay (AlsaSPDIFSink * sink);
/* Alsa error handler to suppress messages from within the ALSA library */
static void ignore_alsa_err (const char *file, int line, const char *function,
int err, const char *fmt, ...);
static void
alsaspdifsink_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details_simple (element_class, "S/PDIF ALSA audiosink",
"Sink/Audio",
"Feeds audio to S/PDIF interfaces through the ALSA sound driver",
"Martin Soto <martinsoto@users.sourceforge.net>, "
"Michael Smith <msmith@fluendo.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&alsaspdifsink_sink_factory));
}
static void
alsaspdifsink_class_init (AlsaSPDIFSinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSinkClass *gstbasesink_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass;
gobject_class->set_property = alsaspdifsink_set_property;
gobject_class->get_property = alsaspdifsink_get_property;
gobject_class->dispose = alsaspdifsink_dispose;
gobject_class->finalize = alsaspdifsink_finalize;
gstelement_class->change_state = alsaspdifsink_change_state;
gstelement_class->provide_clock = alsaspdifsink_provide_clock;
gstbasesink_class->event = alsaspdifsink_event;
gstbasesink_class->render = alsaspdifsink_render;
gstbasesink_class->get_times = alsaspdifsink_get_times;
gstbasesink_class->set_caps = alsaspdifsink_set_caps;
#if 0
/* We ignore the device property anyway, so don't install it
* we don't want the user supplying just any device string for us.
* At most we might want a card number and an iec958.%d device name
* to attempt */
g_object_class_install_property (gobject_class, PROP_DEVICE,
g_param_spec_string ("device", "Device",
"ALSA device, as defined in an asound configuration file",
"default", G_PARAM_READWRITE));
#endif
g_object_class_install_property (gobject_class, PROP_CARD,
g_param_spec_int ("card", "Card",
"ALSA card number for the SPDIF device to use",
0, G_MAXINT, 0, G_PARAM_READWRITE));
snd_lib_error_set_handler (ignore_alsa_err);
}
static void
alsaspdifsink_init (AlsaSPDIFSink * sink, AlsaSPDIFSinkClass * g_class)
{
/* Create the provided clock. */
#if GST_CHECK_VERSION(0, 10, 31) || (GST_CHECK_VERSION(0, 10, 30) && GST_VERSION_NANO > 0)
sink->clock =
gst_audio_clock_new_full ("clock", alsaspdifsink_get_time,
gst_object_ref (sink), (GDestroyNotify) gst_object_unref);
#else
sink->clock = gst_audio_clock_new ("clock", alsaspdifsink_get_time, sink);
#endif
sink->card = 0;
sink->device = g_strdup ("default");
}
static void
alsaspdifsink_dispose (GObject * object)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (object);
if (sink->clock)
gst_object_unref (sink->clock);
sink->clock = NULL;
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
alsaspdifsink_finalize (GObject * object)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (object);
g_free (sink->device);
sink->device = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
alsaspdifsink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
AlsaSPDIFSink *sink;
sink = ALSASPDIFSINK (object);
switch (prop_id) {
/*
case PROP_DEVICE:
if(sink->device)
g_free(sink->device);
sink->device = g_strdup(g_value_get_string(value));
break;
*/
case PROP_CARD:
sink->card = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
alsaspdifsink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
AlsaSPDIFSink *sink;
sink = ALSASPDIFSINK (object);
switch (prop_id) {
/*
case PROP_DEVICE:
g_value_set_string(value, sink->device);
break;
*/
case PROP_CARD:
g_value_set_int (value, sink->card);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
alsaspdifsink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (bsink);
if (!gst_structure_get_int (gst_caps_get_structure (caps, 0), "rate",
&sink->rate))
sink->rate = 48000;
if (!alsaspdifsink_set_params (sink)) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Cannot set ALSA hardware parameters"), GST_ERROR_SYSTEM);
return FALSE;
}
return TRUE;
}
static GstClock *
alsaspdifsink_provide_clock (GstElement * elem)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (elem);
return GST_CLOCK (gst_object_ref (sink->clock));
}
static GstClockTime
alsaspdifsink_get_time (GstClock * clock, gpointer user_data)
{
GstClockTime result;
snd_pcm_sframes_t raw, delay, samples;
AlsaSPDIFSink *sink = ALSASPDIFSINK (user_data);
raw = samples = sink->frames * IEC958_SAMPLES_PER_FRAME;
delay = alsaspdifsink_delay (sink);
if (samples > delay)
samples -= delay;
else
samples = 0;
result = gst_util_uint64_scale_int (samples, GST_SECOND, sink->rate);
GST_LOG_OBJECT (sink, "Samples raw: %d, delay: %d, real: %d, "
"Time: %" GST_TIME_FORMAT, (int) raw, (int) delay, (int) samples,
GST_TIME_ARGS (result));
return result;
}
static gboolean
alsaspdifsink_open (AlsaSPDIFSink * sink)
{
char *pcm_name = sink->device;
int err;
char devstr[256]; /* Storage for local 'default' device string */
/*
* Try and open our default iec958 device. Fall back to searching on card x
* if this fails, which should only happen on older alsa setups
*/
/* The string will be one of these:
* SPDIF_CON: Non-audio flag not set:
* spdif:{AES0 0x0 AES1 0x82 AES2 0x0 AES3 0x2}
* SPDIF_CON: Non-audio flag set:
* spdif:{AES0 0x2 AES1 0x82 AES2 0x0 AES3 0x2}
*/
sprintf (devstr,
"iec958:{CARD %d AES0 0x%02x AES1 0x%02x AES2 0x%02x AES3 0x%02x}",
sink->card,
IEC958_AES0_NONAUDIO,
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
0, IEC958_AES3_CON_FS_48000);
GST_DEBUG_OBJECT (sink, "Generated device string \"%s\"", devstr);
pcm_name = devstr;
err = snd_pcm_open (&(sink->pcm), pcm_name, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
GST_DEBUG_OBJECT (sink,
"Open failed for %s - searching for IEC958 manually\n", pcm_name);
err = alsaspdifsink_find_pcm_device (sink);
if (err == 0 && sink->pcm == NULL)
goto open_failed;
}
if (err < 0)
goto failed;
return TRUE;
/* ERRORS */
open_failed:
{
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Could not open IEC958/SPDIF output device"), GST_ERROR_SYSTEM);
return FALSE;
}
failed:
{
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("snd_pcm_open: %s", snd_strerror (err)), GST_ERROR_SYSTEM);
return FALSE;
}
}
static gboolean
alsaspdifsink_set_params (AlsaSPDIFSink * sink)
{
snd_pcm_hw_params_t *params;
unsigned int rate;
int err;
snd_pcm_hw_params_malloc (&params);
err = snd_pcm_hw_params_any (sink->pcm, params);
if (err < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Broken configuration for this PCM: "
"no configurations available"), GST_ERROR_SYSTEM);
goto __error;
}
/* Set interleaved access. */
err = snd_pcm_hw_params_set_access (sink->pcm, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Access type not available"), GST_ERROR_SYSTEM);
goto __error;
}
err = snd_pcm_hw_params_set_format (sink->pcm, params, AC3_FORMAT_BE);
if (err < 0) {
/* Try LE output and swap data */
GST_DEBUG_OBJECT (sink, "PCM format S16_BE not supported, trying S16_LE");
err = snd_pcm_hw_params_set_format (sink->pcm, params, AC3_FORMAT_LE);
sink->need_swap = TRUE;
} else
sink->need_swap = FALSE;
if (err < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Sample format not available"), GST_ERROR_SYSTEM);
goto __error;
}
err = snd_pcm_hw_params_set_channels (sink->pcm, params, AC3_CHANNELS);
if (err < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Channels count not available"), GST_ERROR_SYSTEM);
goto __error;
}
rate = sink->rate;
GST_DEBUG_OBJECT (sink, "Setting S/PDIF sample rate: %d", rate);
err = snd_pcm_hw_params_set_rate_near (sink->pcm, params, &rate, 0);
if (err != 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("Rate not available"), GST_ERROR_SYSTEM);
goto __error;
}
err = snd_pcm_hw_params (sink->pcm, params);
if (err < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("PCM hw_params failed: %s", snd_strerror (err)), GST_ERROR_SYSTEM);
goto __error;
}
snd_pcm_hw_params_free (params);
return TRUE;
/* ERRORS */
__error:
{
snd_pcm_hw_params_free (params);
return FALSE;
}
}
static void
alsaspdifsink_close (AlsaSPDIFSink * sink)
{
if (sink->pcm) {
snd_pcm_close (sink->pcm);
sink->pcm = NULL;
}
}
/* Try and find an IEC958 PCM device and mixer on card 0 and open it
* This function is only used on older ALSA installs that don't have the
* correct iec958 alias stuff set up, and relies on there being only
* one IEC958 PCM device (relies IEC958 in the device name) and one IEC958
* mixer control for doing the settings.
*/
static int
alsaspdifsink_find_pcm_device (AlsaSPDIFSink * sink)
{
int err = -1, dev, idx, count;
const gchar *ctl_name = "hw:0";
const gchar *spdif_name = SND_CTL_NAME_IEC958 ("", PLAYBACK, NONE);
int card = sink->card;
gchar pcm_name[24];
snd_pcm_t *pcm = NULL;
snd_ctl_t *ctl = NULL;
snd_ctl_card_info_t *info = NULL;
snd_ctl_elem_list_t *clist = NULL;
snd_ctl_elem_id_t *cid = NULL;
snd_pcm_info_t *pinfo = NULL;
GST_WARNING ("Opening IEC958 named device failed. Trying to autodetect");
if ((err = snd_ctl_open (&ctl, ctl_name, card)) < 0)
return err;
snd_ctl_card_info_malloc (&info);
snd_pcm_info_malloc (&pinfo);
/* Find a mixer for IEC958 settings */
snd_ctl_elem_list_malloc (&clist);
if ((err = snd_ctl_elem_list (ctl, clist)) < 0)
goto beach;
if ((err =
snd_ctl_elem_list_alloc_space (clist,
snd_ctl_elem_list_get_count (clist))) < 0)
goto beach;
if ((err = snd_ctl_elem_list (ctl, clist)) < 0)
goto beach;
count = snd_ctl_elem_list_get_used (clist);
for (idx = 0; idx < count; idx++) {
if (strstr (snd_ctl_elem_list_get_name (clist, idx), spdif_name) != NULL)
break;
}
if (idx == count) {
/* No SPDIF mixer availble */
err = 0;
goto beach;
}
snd_ctl_elem_id_malloc (&cid);
snd_ctl_elem_list_get_id (clist, idx, cid);
/* Now find a PCM device for IEC 958 */
if ((err = snd_ctl_card_info (ctl, info)) < 0)
goto beach;
dev = -1;
do {
if (snd_ctl_pcm_next_device (ctl, &dev) < 0)
goto beach;
if (dev < 0)
break; /* No more devices */
/* Filter for playback devices */
snd_pcm_info_set_device (pinfo, dev);
snd_pcm_info_set_subdevice (pinfo, 0);
snd_pcm_info_set_stream (pinfo, SND_PCM_STREAM_PLAYBACK);
if ((err = snd_ctl_pcm_info (ctl, pinfo)) < 0) {
if (err != -ENOENT)
goto beach; /* Genuine error */
/* Device has no playback streams */
continue;
}
if (strstr (snd_pcm_info_get_name (pinfo), "IEC958") == NULL)
continue; /* Not the device we are looking for */
count = snd_pcm_info_get_subdevices_count (pinfo);
GST_LOG_OBJECT (sink, "Device %d has %d subdevices\n", dev,
snd_pcm_info_get_subdevices_count (pinfo));
for (idx = 0; idx < count; idx++) {
snd_pcm_info_set_subdevice (pinfo, idx);
if ((err = snd_ctl_pcm_info (ctl, pinfo)) < 0)
goto beach;
g_assert (snd_pcm_info_get_stream (pinfo) == SND_PCM_STREAM_PLAYBACK);
GST_LOG_OBJECT (sink, "Found playback stream on dev %d sub-d %d\n", dev,
idx);
/* Found a suitable PCM device, let's open it */
g_snprintf (pcm_name, 24, "hw:%d,%d", card, dev);
if ((err =
snd_pcm_open (&(pcm), pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
goto beach;
break;
}
} while (pcm == NULL);
if (pcm != NULL) {
snd_ctl_elem_value_t *cval;
snd_aes_iec958_t iec958;
/* Have a PCM device and a mixer, set things up */
snd_ctl_elem_value_malloc (&cval);
snd_ctl_elem_value_set_id (cval, cid);
snd_ctl_elem_value_get_iec958 (cval, &iec958);
iec958.status[0] = IEC958_AES0_NONAUDIO;
iec958.status[1] = IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER;
iec958.status[2] = 0;
iec958.status[3] = IEC958_AES3_CON_FS_48000;
snd_ctl_elem_value_set_iec958 (cval, &iec958);
snd_ctl_elem_value_free (cval);
sink->pcm = pcm;
pcm = NULL;
err = 0;
}
beach:
if (pcm)
snd_pcm_close (pcm);
if (clist)
snd_ctl_elem_list_clear (clist);
if (ctl)
snd_ctl_close (ctl);
if (clist)
snd_ctl_elem_list_free (clist);
if (cid)
snd_ctl_elem_id_free (cid);
if (info)
snd_ctl_card_info_free (info);
if (pinfo)
snd_pcm_info_free (pinfo);
return err;
}
static void
alsaspdifsink_write_frame (AlsaSPDIFSink * sink, guchar * buf)
{
snd_pcm_sframes_t res;
int num_frames = IEC958_FRAME_SIZE / ALSASPDIFSINK_BYTES_PER_FRAME;
/* If we couldn't output big endian when we opened the devic, then
* we need to swap here */
if (sink->need_swap) {
int i;
guchar tmp;
for (i = 0; i < IEC958_FRAME_SIZE; i += 2) {
tmp = buf[i];
buf[i] = buf[i + 1];
buf[i + 1] = tmp;
}
}
res = 0;
do {
if (res == -EPIPE) {
/* Underrun. */
GST_INFO_OBJECT (sink, "buffer underrun");
res = snd_pcm_prepare (sink->pcm);
} else if (res == -ESTRPIPE) {
/* Suspend. */
while ((res = snd_pcm_resume (sink->pcm)) == -EAGAIN) {
GST_DEBUG_OBJECT (sink, "sleeping for suspend");
g_usleep (100000);
}
if (res < 0) {
res = snd_pcm_prepare (sink->pcm);
}
}
if (res >= 0) {
res = snd_pcm_writei (sink->pcm, (void *) buf, num_frames);
}
if (res > 0) {
num_frames -= res;
}
} while (res == -EPIPE || num_frames > 0);
sink->frames++;
if (res < 0) {
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
("writei returned error: %s", snd_strerror (res)), GST_ERROR_SYSTEM);
return;
}
}
static gboolean
alsaspdifsink_event (GstBaseSink * bsink, GstEvent * event)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (bsink);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
snd_pcm_drop (sink->pcm);
break;
case GST_EVENT_FLUSH_STOP:
snd_pcm_start (sink->pcm);
break;
default:
break;
}
return TRUE;
}
static void
alsaspdifsink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end)
{
/* Like GstBaseAudioSink, we set these to NONE */
*start = GST_CLOCK_TIME_NONE;
*end = GST_CLOCK_TIME_NONE;
}
static snd_pcm_sframes_t
alsaspdifsink_delay (AlsaSPDIFSink * sink)
{
snd_pcm_sframes_t delay;
int err;
err = snd_pcm_delay (sink->pcm, &delay);
if (err < 0 || delay < 0) {
return 0;
}
return delay;
}
#if 0
static void
generate_iec958_zero_frame (guchar * buffer)
{
/* 2 sync words, 16 bits each */
buffer[0] = 0xF8;
buffer[1] = 0x72;
buffer[2] = 0x4E;
buffer[3] = 0x1F;
/* 16-bit burst-info. Contains data type (zero here, for 'null data'),
stream number (we output '0' for this always), and a few other bits.
As it happens, all-zero is the correct value.
*/
buffer[4] = 0;
buffer[5] = 0;
/* 16-bit frame size. Also zero */
buffer[6] = 0;
buffer[7] = 0;
memset (buffer + 8, 0, IEC958_FRAME_SIZE - 8);
}
#endif
static GstFlowReturn
alsaspdifsink_render (GstBaseSink * bsink, GstBuffer * buf)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (bsink);
#if 0
GstClockTime next_write;
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buf)))
sink->cur_ts = GST_BUFFER_TIMESTAMP (buf);
next_write = gst_element_get_time (GST_ELEMENT (sink)) +
alsaspdifsink_current_delay (sink);
/*
fprintf (stderr, "Drift: % 0.6fs, delay: % 0.6fs\r",
GST_TIME_ARGS (GST_CLOCK_DIFF (sink->cur_ts, next_write)),
GST_TIME_ARGS (alsaspdifsink_current_delay (sink)));
*/
/* If we're too far behind, send empty IEC958 frames. */
if (sink->cur_ts > next_write + MAX_SYNC_DIFF) {
int frames = (int) (
((double) (sink->cur_ts - next_write)) /
(double) IEC958_FRAME_DURATION + 0.5);
int i;
for (i = 0; i < frames; i++) {
static guchar frame[IEC958_FRAME_SIZE];
generate_iec958_zero_frame (frame);
alsaspdifsink_write_frame (sink, frame);
}
}
/* If we're too far ahead, just drop this buffer */
else if (sink->cur_ts + MAX_SYNC_DIFF < next_write) {
goto end;
}
#endif
GST_LOG_OBJECT (sink, "Writing %d bytes to spdif out", GST_BUFFER_SIZE (buf));
if (GST_BUFFER_SIZE (buf) == IEC958_FRAME_SIZE)
alsaspdifsink_write_frame (sink, GST_BUFFER_DATA (buf));
else
GST_WARNING_OBJECT (sink, "Ignoring buffer of incorrect size");
#if 0
end:
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buf)))
sink->cur_ts = GST_BUFFER_DURATION (buf);
#endif
return GST_FLOW_OK;
}
/* Drop error output from within alsalib on the floor */
static void
ignore_alsa_err (const char *file, int line, const char *function,
int err, const char *fmt, ...)
{
}
static GstStateChangeReturn
alsaspdifsink_change_state (GstElement * element, GstStateChange transition)
{
AlsaSPDIFSink *sink = ALSASPDIFSINK (element);
GstStateChangeReturn ret;
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
sink->frames = 0;
gst_audio_clock_reset (GST_AUDIO_CLOCK (sink->clock), 0);
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!alsaspdifsink_open (sink)) {
GST_WARNING_OBJECT (sink, "Failed to open alsa device");
return GST_STATE_CHANGE_FAILURE;
}
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
default:
break;
}
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
GST_INFO_OBJECT (sink, "Parent change_state returned %d", ret);
switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_NULL:
alsaspdifsink_close (sink);
break;
default:
break;
}
return ret;
}
static gboolean
plugin_init (GstPlugin * plugin)
{
/* no rank so it doesn't get autoplugged by autoaudiosink */
if (!gst_element_register (plugin, "alsaspdifsink", GST_RANK_NONE,
GST_TYPE_ALSASPDIFSINK)) {
return FALSE;
}
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"alsaspdif",
"Alsa plugin for S/PDIF output",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);

View File

@ -1,86 +0,0 @@
/* Based on a plugin from Martin Soto's Seamless DVD Player.
* Copyright (C) 2003, 2004 Martin Soto <martinsoto@users.sourceforge.net>
* 2005-6 Michael Smith <msmith@fluendo.com>
*
* 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 __ALSASPDIFSINK_H__
#define __ALSASPDIFSINK_H__
#include <gst/gst.h>
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
G_BEGIN_DECLS
#define GST_TYPE_ALSASPDIFSINK \
(alsaspdifsink_get_type())
#define ALSASPDIFSINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSASPDIFSINK,AlsaSPDIFSink))
#define ALSASPDIFSINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSASPDIFSINK,AlsaSPDIFSinkClass))
#define GST_IS_ALSASPDIFSINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSASPDIFSINK))
#define GST_IS_ALSASPDIFSINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSASPDIFSINK))
#define GST_TYPE_ALSASPDIFSINK (alsaspdifsink_get_type())
typedef struct _AlsaSPDIFSink AlsaSPDIFSink;
typedef struct _AlsaSPDIFSinkClass AlsaSPDIFSinkClass;
typedef enum {
ALSASPDIFSINK_OPEN = GST_ELEMENT_FLAG_LAST,
ALSASPDIFSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
} AlsaSPDIFSinkFlags;
/* ALSA spdif types. */
enum {
SPDIF_NONE = 0,
SPDIF_CON,
SPDIF_PRO,
SPDIF_PCM
};
struct _AlsaSPDIFSink {
GstBaseSink basesink;
GstClockTime cur_ts; /* Current time stamp. */
snd_pcm_t *pcm; /* ALSA output device. */
gint card; /* ALSA card number to use */
char *device; /* ALSA device name */
GstClock *clock; /* The clock for this element. */
guint64 frames; /* Number of complete frames written */
gboolean need_swap; /* Whether to byte swap outgoing data */
gint rate; /* Sampling rate of data */
};
struct _AlsaSPDIFSinkClass {
GstBaseSinkClass parent_class;
};
extern GType alsaspdifsink_get_type (void);
G_END_DECLS
#endif /* __DXR3AUDIOINK_H__ */

View File

@ -159,7 +159,6 @@ rm -rf $RPM_BUILD_ROOT
@USE_XVID_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstxvid.so @USE_XVID_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstxvid.so
@USE_BZ2_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstbz2.so @USE_BZ2_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstbz2.so
@USE_NEON_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstneonhttpsrc.so @USE_NEON_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstneonhttpsrc.so
@USE_ALSA_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstalsaspdif.so
@USE_MUSEPACK_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstmusepack.so @USE_MUSEPACK_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstmusepack.so
@USE_GSM_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstgsm.so @USE_GSM_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstgsm.so
@USE_DTS_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstdtsdec.so @USE_DTS_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstdtsdec.so

View File

@ -13,7 +13,6 @@ EXTRA_DIST = \
gettext.m4 \ gettext.m4 \
glibc21.m4 \ glibc21.m4 \
glib.m4 \ glib.m4 \
gst-alsa.m4 \
gst-artsc.m4 \ gst-artsc.m4 \
gst-fionread.m4 \ gst-fionread.m4 \
gst-matroska.m4 \ gst-matroska.m4 \

View File

@ -1,150 +0,0 @@
dnl Configure Paths for Alsa
dnl Some modifications by Richard Boulton <richard-alsa@tartarus.org>
dnl Christopher Lansdown <lansdoct@cs.alfred.edu>
dnl Jaroslav Kysela <perex@suse.cz>
dnl Last modification: alsa.m4,v 1.23 2004/01/16 18:14:22 tiwai Exp
dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate.
dnl enables arguments --with-alsa-prefix=
dnl --with-alsa-enc-prefix=
dnl --disable-alsatest
dnl
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
dnl
AC_DEFUN([AM_PATH_ALSA],
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
alsa_save_CFLAGS="$CFLAGS"
alsa_save_LDFLAGS="$LDFLAGS"
alsa_save_LIBS="$LIBS"
alsa_found=yes
dnl
dnl Get the cflags and libraries for alsa
dnl
AC_ARG_WITH(alsa-prefix,
AC_HELP_STRING([--with-alsa-prefix=PFX],
[prefix where Alsa library is installed(optional)]),
[alsa_prefix="$withval"], [alsa_prefix=""])
AC_ARG_WITH(alsa-inc-prefix,
AC_HELP_STRING([--with-alsa-inc-prefix=PFX],
[prefix where include libraries are (optional)]),
[alsa_inc_prefix="$withval"], [alsa_inc_prefix=""])
dnl FIXME: this is not yet implemented
dnl AC_ARG_ENABLE(alsatest,
dnl AC_HELP_STRING([--disable-alsatest],
dnl [do not try to compile and run a test Alsa program],
dnl [enable_alsatest=no], [enable_alsatest=yes])
dnl Add any special include directories
AC_MSG_CHECKING(for ALSA CFLAGS)
if test "$alsa_inc_prefix" != "" ; then
ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix"
CFLAGS="$CFLAGS -I$alsa_inc_prefix"
fi
AC_MSG_RESULT($ALSA_CFLAGS)
dnl add any special lib dirs
AC_MSG_CHECKING(for ALSA LDFLAGS)
if test "$alsa_prefix" != "" ; then
ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix"
LDFLAGS="$LDFLAGS $ALSA_LIBS"
fi
dnl add the alsa library
ALSA_LIBS="$ALSA_LIBS -lasound -lm -ldl -lpthread"
LIBS=`echo $LIBS | sed 's/-lm//'`
LIBS=`echo $LIBS | sed 's/-ldl//'`
LIBS=`echo $LIBS | sed 's/-lpthread//'`
LIBS=`echo $LIBS | sed 's/ //'`
LIBS="$ALSA_LIBS $LIBS"
AC_MSG_RESULT($ALSA_LIBS)
dnl Check for a working version of libasound that is of the right version.
min_alsa_version=ifelse([$1], ,0.1.1,$1)
AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version)
no_alsa=""
alsa_min_major_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
alsa_min_minor_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
alsa_min_micro_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
AC_LANG_SAVE
AC_LANG_C
AC_TRY_COMPILE([
#include <alsa/asoundlib.h>
], [
void main(void)
{
/* ensure backward compatibility */
#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR)
#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR
#endif
#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR)
#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR
#endif
#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR)
#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR
#endif
# if(SND_LIB_MAJOR > $alsa_min_major_version)
exit(0);
# else
# if(SND_LIB_MAJOR < $alsa_min_major_version)
# error not present
# endif
# if(SND_LIB_MINOR > $alsa_min_minor_version)
exit(0);
# else
# if(SND_LIB_MINOR < $alsa_min_minor_version)
# error not present
# endif
# if(SND_LIB_SUBMINOR < $alsa_min_micro_version)
# error not present
# endif
# endif
# endif
exit(0);
}
],
[AC_MSG_RESULT(found.)],
[AC_MSG_RESULT(not present.)
ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)])
alsa_found=no]
)
AC_LANG_RESTORE
dnl Now that we know that we have the right version, let's see if we have the library and not just the headers.
if test "x$enable_alsatest" = "xyes"; then
AC_CHECK_LIB([asound], [snd_ctl_open],,
[ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)])
alsa_found=no]
)
fi
if test "x$alsa_found" = "xyes" ; then
ifelse([$2], , :, [$2])
LIBS=`echo $LIBS | sed 's/-lasound//g'`
LIBS=`echo $LIBS | sed 's/ //'`
LIBS="-lasound $LIBS"
fi
if test "x$alsa_found" = "xno" ; then
ifelse([$3], , :, [$3])
CFLAGS="$alsa_save_CFLAGS"
LDFLAGS="$alsa_save_LDFLAGS"
LIBS="$alsa_save_LIBS"
ALSA_CFLAGS=""
ALSA_LIBS=""
fi
dnl That should be it. Now just export out symbols:
AC_SUBST(ALSA_CFLAGS)
AC_SUBST(ALSA_LIBS)
])