summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-12-21 11:00:47 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-12-21 11:17:11 +0200
commit9b5de053995488d5ddc78c1bf4df651101271d70 (patch)
tree07755463428bf4460852180dc4d3155cc28bf488 /ext
parent0fdd4e2539cc8c2c794419b13594ed7761d5fccd (diff)
downloadgstreamer-plugins-bad-9b5de053995488d5ddc78c1bf4df651101271d70.tar.gz
Remove various unported plugins
If they were not ported after 4+ years it seems unlikely that anybody is ever going to need them again. They're still in the GIT history if needed. https://bugzilla.gnome.org/show_bug.cgi?id=774530
Diffstat (limited to 'ext')
-rw-r--r--ext/Makefile.am62
-rw-r--r--ext/apexsink/LGPL-3.0.txt165
-rw-r--r--ext/apexsink/Makefile.am12
-rw-r--r--ext/apexsink/gstapexplugin.c44
-rw-r--r--ext/apexsink/gstapexraop.c798
-rw-r--r--ext/apexsink/gstapexraop.h148
-rw-r--r--ext/apexsink/gstapexsink.c665
-rw-r--r--ext/apexsink/gstapexsink.h98
-rw-r--r--ext/libvisual/Makefile.am15
-rw-r--r--ext/libvisual/visual-gl.c1248
-rw-r--r--ext/meson.build9
-rw-r--r--ext/nas/Makefile.am11
-rw-r--r--ext/nas/nassink.c583
-rw-r--r--ext/nas/nassink.h72
-rw-r--r--ext/sdl/Makefile.am19
-rw-r--r--ext/sdl/gstsdl.c45
-rw-r--r--ext/sdl/sdlaudiosink.c439
-rw-r--r--ext/sdl/sdlaudiosink.h65
-rw-r--r--ext/sdl/sdlvideosink.c1006
-rw-r--r--ext/sdl/sdlvideosink.h82
-rw-r--r--ext/sndio/Makefile.am11
-rw-r--r--ext/sndio/gstsndio.c53
-rw-r--r--ext/sndio/sndiosink.c527
-rw-r--r--ext/sndio/sndiosink.h67
-rw-r--r--ext/sndio/sndiosrc.c524
-rw-r--r--ext/sndio/sndiosrc.h67
-rw-r--r--ext/timidity/gsttimidity.c821
-rw-r--r--ext/timidity/gsttimidity.h84
-rw-r--r--ext/wildmidi/Makefile.am (renamed from ext/timidity/Makefile.am)16
-rw-r--r--ext/wildmidi/README (renamed from ext/timidity/README)0
-rw-r--r--ext/wildmidi/gstwildmidi.c (renamed from ext/timidity/gstwildmidi.c)0
-rw-r--r--ext/wildmidi/gstwildmidi.h (renamed from ext/timidity/gstwildmidi.h)0
-rw-r--r--ext/xvid/Makefile.am9
-rw-r--r--ext/xvid/gstxvid.c371
-rw-r--r--ext/xvid/gstxvid.h57
-rw-r--r--ext/xvid/gstxviddec.c673
-rw-r--r--ext/xvid/gstxviddec.h73
-rw-r--r--ext/xvid/gstxvidenc.c1403
-rw-r--r--ext/xvid/gstxvidenc.h137
39 files changed, 6 insertions, 10473 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am
index fdce19efe..534b9ac7b 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -10,12 +10,6 @@ else
VOAMRWBENC_DIR =
endif
-if USE_APEXSINK
-APEXSINK_DIR = apexsink
-else
-APEXSINK_DIR =
-endif
-
if USE_BS2B
BS2B_DIR=bs2b
else
@@ -178,12 +172,6 @@ else
LIBMMS_DIR=
endif
-if USE_LIBVISUAL
-LIBVISUAL_DIR=libvisual
-else
-LIBVISUAL_DIR=
-endif
-
if USE_MODPLUG
MODPLUG_DIR=modplug
else
@@ -208,12 +196,6 @@ else
MUSEPACK_DIR=
endif
-if USE_NAS
-NAS_DIR=nas
-else
-NAS_DIR=
-endif
-
if USE_NEON
NEON_DIR=neon
else
@@ -274,18 +256,12 @@ else
RSVG_DIR=
endif
-if USE_TIMIDITY
-TIMIDITY_DIR=timidity
-endif
-
if USE_WILDMIDI
-TIMIDITY_DIR=timidity
+WILDMIDI_DIR=wildmidi
endif
if !USE_WILDMIDI
-if !USE_TIMIDITY
-TIMIDITY_DIR=
-endif
+WILDMIDI_DIR=
endif
if USE_FLUIDSYNTH
@@ -304,12 +280,6 @@ else
SCHRO_DIR=
endif
-if USE_SDL
-SDL_DIR=sdl
-else
-SDL_DIR=
-endif
-
if USE_SMOOTHSTREAMING
SMOOTHSTREAMING_DIR = smoothstreaming
else
@@ -328,12 +298,6 @@ else
SNDFILE_DIR=
endif
-if USE_SNDIO
-SNDIO_DIR = sndio
-else
-SNDIO_DIR =
-endif
-
if USE_SOUNDTOUCH
SOUNDTOUCH_DIR=soundtouch
else
@@ -370,12 +334,6 @@ else
TELETEXTDEC_DIR=
endif
-if USE_XVID
-XVID_DIR=xvid
-else
-XVID_DIR=
-endif
-
if USE_ZBAR
ZBAR_DIR=zbar
else
@@ -434,7 +392,6 @@ SUBDIRS=\
$(VOAACENC_DIR) \
$(ASSRENDER_DIR) \
$(VOAMRWBENC_DIR) \
- $(APEXSINK_DIR) \
$(AUDIOFILE_DIR) \
$(BS2B_DIR) \
$(BZ2_DIR) \
@@ -463,12 +420,10 @@ SUBDIRS=\
$(LV2_DIR) \
$(LIBDE265_DIR) \
$(LIBMMS_DIR) \
- $(LIBVISUAL_DIR) \
$(MODPLUG_DIR) \
$(MPEG2ENC_DIR) \
$(MPLEX_DIR) \
$(MUSEPACK_DIR) \
- $(NAS_DIR) \
$(NEON_DIR) \
$(OFA_DIR) \
$(OPENAL_DIR) \
@@ -481,19 +436,16 @@ SUBDIRS=\
$(RSVG_DIR) \
$(SBC_DIR) \
$(SCHRO_DIR) \
- $(SDL_DIR) \
$(SMOOTHSTREAMING_DIR) \
$(SMOOTHWAVE_DIR) \
$(SNDFILE_DIR) \
- $(SNDIO_DIR) \
$(SOUNDTOUCH_DIR) \
$(SPANDSP_DIR) \
$(GME_DIR) \
$(SPC_DIR) \
$(SRTP_DIR) \
$(TELETEXTDEC_DIR) \
- $(TIMIDITY_DIR) \
- $(XVID_DIR) \
+ $(WILDMIDI_DIR) \
$(ZBAR_DIR) \
$(RTMP_DIR) \
$(HLS_DIR) \
@@ -506,7 +458,6 @@ SUBDIRS=\
DIST_SUBDIRS = \
assrender \
- apexsink \
bs2b \
bz2 \
chromaprint \
@@ -527,7 +478,6 @@ DIST_SUBDIRS = \
kate \
libde265 \
libmms \
- libvisual \
lv2 \
daala \
dts \
@@ -538,7 +488,6 @@ DIST_SUBDIRS = \
mpeg2enc \
mplex \
musepack \
- nas \
neon \
ofa \
openal \
@@ -552,20 +501,17 @@ DIST_SUBDIRS = \
resindvd \
sbc \
schroedinger \
- sdl \
smoothstreaming \
sndfile \
- sndio \
soundtouch \
spandsp \
spc \
srtp \
gme \
teletextdec \
- timidity \
+ wildmidi \
voaacenc \
voamrwbenc \
- xvid \
zbar \
rtmp \
webp \
diff --git a/ext/apexsink/LGPL-3.0.txt b/ext/apexsink/LGPL-3.0.txt
deleted file mode 100644
index fc8a5de7e..000000000
--- a/ext/apexsink/LGPL-3.0.txt
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/ext/apexsink/Makefile.am b/ext/apexsink/Makefile.am
deleted file mode 100644
index f799c0794..000000000
--- a/ext/apexsink/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-plugin_LTLIBRARIES = libgstapexsink.la
-
-libgstapexsink_la_SOURCES = gstapexplugin.c gstapexraop.c gstapexsink.c
-libgstapexsink_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
- $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(APEXSINK_CFLAGS)
-libgstapexsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
- -lgstaudio-$(GST_API_VERSION) -lgstinterfaces-$(GST_API_VERSION) \
- $(GST_BASE_LIBS) $(GST_LIBS) $(APEXSINK_LIBS)
-libgstapexsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstapexsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = gstapexraop.h gstapexsink.h
diff --git a/ext/apexsink/gstapexplugin.c b/ext/apexsink/gstapexplugin.c
deleted file mode 100644
index a6d64a86b..000000000
--- a/ext/apexsink/gstapexplugin.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* GStreamer AirPort Express Plugin
- *
- * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
- *
- * gstapexpugin.c
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gstapexsink.h>
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, GST_APEX_SINK_NAME, GST_RANK_NONE,
- GST_TYPE_APEX_SINK);
-}
-
-/* plugin export resolution */
-GST_PLUGIN_DEFINE
- (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- apexsink,
- "Apple AirPort Express Plugin",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/apexsink/gstapexraop.c b/ext/apexsink/gstapexraop.c
deleted file mode 100644
index af4f573c0..000000000
--- a/ext/apexsink/gstapexraop.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/* GStreamer - Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
- *
- * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
- * This interface accepts RAW PCM data and set it as AES encrypted ALAC while performing emission.
- *
- * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
- *
- * gstapexraop.c
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstapexraop.h"
-
-/* private constants */
-#define GST_APEX_RAOP_VOLUME_MIN -144
-#define GST_APEX_RAOP_VOLUME_MAX 0
-
-#define GST_APEX_RAOP_HDR_DEFAULT_LENGTH 1024
-#define GST_APEX_RAOP_SDP_DEFAULT_LENGTH 2048
-
-const static gchar GST_APEX_RAOP_RSA_PUBLIC_MOD[] =
- "59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUtwC"
- "5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDR"
- "KSKv6kDqnw4UwPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuB"
- "OitnZ/bDzPHrTOZz0Dew0uowxf/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJ"
- "Q+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/UAaHqn9JdsBWLUEpVviYnh"
- "imNVvYFZeCXg/IdTQ+x4IRdiXNv5hEew==";
-
-const static gchar GST_APEX_RAOP_RSA_PUBLIC_EXP[] = "AQAB";
-
-const static gchar GST_APEX_RAOP_USER_AGENT[] =
- "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)";
-
-const static guchar GST_APEX_RAOP_FRAME_HEADER[] = { // Used by gen. 1
- 0x24, 0x00, 0x00, 0x00,
- 0xF0, 0xFF, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
-};
-
-const static int GST_APEX_RAOP_FRAME_HEADER_SIZE = 16; // Used by gen. 1
-const static int GST_APEX_RTP_FRAME_HEADER_SIZE = 12; // Used by gen. 2
-
-const static int GST_APEX_RAOP_ALAC_HEADER_SIZE = 3;
-
-/* string extra utility */
-static gint
-g_strdel (gchar * str, gchar rc)
-{
- int i = 0, j = 0, len, num = 0;
- len = strlen (str);
- while (i < len) {
- if (str[i] == rc) {
- for (j = i; j < len; j++)
- str[j] = str[j + 1];
- len--;
- num++;
- } else {
- i++;
- }
- }
- return num;
-}
-
-/* socket utilities */
-static int
-gst_apexraop_send (int desc, void *data, size_t len)
-{
- int total = 0, bytesleft = len, n = 0;
-
- while (total < len) {
- n = send (desc, ((const char *) data) + total, bytesleft, 0);
- if (n == -1)
- break;
- total += n;
- bytesleft -= n;
- }
-
- return n == -1 ? -1 : total;
-}
-
-static int
-gst_apexraop_recv (int desc, void *data, size_t len)
-{
- memset (data, 0, len);
- return recv (desc, data, len, 0);
-}
-
-/* public opaque handle resolution */
-typedef struct
-{
- guchar aes_ky[AES_BLOCK_SIZE]; /* AES random key */
- guchar aes_iv[AES_BLOCK_SIZE]; /* AES random initial vector */
-
- guchar url_abspath[16]; /* header url random absolute path addon, ANNOUNCE id */
- gint cseq; /* header rtsp inc cseq */
- guchar cid[24]; /* header client instance id */
- gchar *session; /* header raop negotiated session id, once SETUP performed */
- gchar *ua; /* header user agent */
-
- GstApExJackType jack_type; /* APEX connected jack type, once ANNOUNCE performed */
- GstApExJackStatus jack_status; /* APEX connected jack status, once ANNOUNCE performed */
-
- GstApExGeneration generation; /* Different devices accept different audio streams */
- GstApExTransportProtocol transport_protocol; /* For media stream, not RAOP/RTSP */
-
- gchar *host; /* APEX target ip */
- guint ctrl_port; /* APEX target control port */
- guint data_port; /* APEX negotiated data port, once SETUP performed */
-
- int ctrl_sd; /* control socket */
- struct sockaddr_in ctrl_sd_in;
-
- int data_sd; /* data socket */
- struct sockaddr_in data_sd_in;
-
- short rtp_seq_num; /* RTP sequence number, used by gen. 2 */
- int rtp_timestamp; /* RTP timestamp, used by gen. 2 */
-}
-_GstApExRAOP;
-
-/* raop apex struct allocation */
-GstApExRAOP *
-gst_apexraop_new (const gchar * host,
- const guint16 port,
- const GstApExGeneration generation,
- const GstApExTransportProtocol transport_protocol)
-{
- _GstApExRAOP *apexraop;
-
- apexraop = (_GstApExRAOP *) g_malloc0 (sizeof (_GstApExRAOP));
-
- apexraop->host = g_strdup (host);
- apexraop->ctrl_port = port;
- apexraop->ua = g_strdup (GST_APEX_RAOP_USER_AGENT);
- apexraop->jack_type = GST_APEX_JACK_TYPE_UNDEFINED;
- apexraop->jack_status = GST_APEX_JACK_STATUS_DISCONNECTED;
- apexraop->generation = generation;
- apexraop->transport_protocol = transport_protocol;
- apexraop->rtp_seq_num = 0;
- apexraop->rtp_timestamp = 0;
-
- return (GstApExRAOP *) apexraop;
-}
-
-/* raop apex struct freeing */
-void
-gst_apexraop_free (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- g_free (conn->host);
- g_free (conn->session);
- g_free (conn->ua);
- g_free (conn);
-}
-
-/* host affectation */
-void
-gst_apexraop_set_host (GstApExRAOP * con, const gchar * host)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- g_free (conn->host);
- conn->host = g_strdup (host);
-}
-
-/* host reader */
-gchar *
-gst_apexraop_get_host (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- return g_strdup (conn->host);
-}
-
-/* control port affectation */
-void
-gst_apexraop_set_port (GstApExRAOP * con, const guint16 port)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- conn->ctrl_port = port;
-}
-
-/* control port reader */
-guint16
-gst_apexraop_get_port (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- return conn->ctrl_port;
-}
-
-/* user agent affectation */
-void
-gst_apexraop_set_useragent (GstApExRAOP * con, const gchar * useragent)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- g_free (conn->ua);
- conn->ua = g_strdup (useragent);
-}
-
-/* user agent reader */
-gchar *
-gst_apexraop_get_useragent (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
- conn = (_GstApExRAOP *) con;
-
- return g_strdup (conn->ua);
-}
-
-/* raop apex connection sequence */
-GstRTSPStatusCode
-gst_apexraop_connect (GstApExRAOP * con)
-{
- gchar *ac, *ky, *iv, *s, inaddr[INET_ADDRSTRLEN],
- creq[GST_APEX_RAOP_SDP_DEFAULT_LENGTH],
- hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH], *req;
- RSA *rsa;
- guchar *mod, *exp, rsakey[512];
- union gst_randbytes
- {
- struct asvals
- {
- guint32 url_key;
- guint64 conn_id;
- guchar challenge[16];
- } v;
- guchar buf[4 + 8 + 16];
- } randbuf;
- gsize size;
- struct sockaddr_in ioaddr;
- socklen_t iolen;
- GstRTSPStatusCode res;
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- if ((conn->ctrl_sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
-
- conn->ctrl_sd_in.sin_family = AF_INET;
- conn->ctrl_sd_in.sin_port = htons (conn->ctrl_port);
-
- if (!inet_aton (conn->host, &conn->ctrl_sd_in.sin_addr)) {
- struct hostent *hp = (struct hostent *) gethostbyname (conn->host);
- if (hp == NULL)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
- memcpy (&conn->ctrl_sd_in.sin_addr, hp->h_addr, hp->h_length);
- }
-
- if (connect (conn->ctrl_sd, (struct sockaddr *) &conn->ctrl_sd_in,
- sizeof (conn->ctrl_sd_in)) < 0)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
-
- RAND_bytes (randbuf.buf, sizeof (randbuf));
- sprintf ((gchar *) conn->url_abspath, "%u", randbuf.v.url_key);
- sprintf ((char *) conn->cid, "%16" G_GINT64_MODIFIER "x", randbuf.v.conn_id);
-
- RAND_bytes (conn->aes_ky, AES_BLOCK_SIZE);
- RAND_bytes (conn->aes_iv, AES_BLOCK_SIZE);
-
- rsa = RSA_new ();
- mod = g_base64_decode (GST_APEX_RAOP_RSA_PUBLIC_MOD, &size);
- rsa->n = BN_bin2bn (mod, size, NULL);
- exp = g_base64_decode (GST_APEX_RAOP_RSA_PUBLIC_EXP, &size);
- rsa->e = BN_bin2bn (exp, size, NULL);
- size =
- RSA_public_encrypt (AES_BLOCK_SIZE, conn->aes_ky, rsakey, rsa,
- RSA_PKCS1_OAEP_PADDING);
-
- ky = g_base64_encode (rsakey, size);
- iv = g_base64_encode (conn->aes_iv, AES_BLOCK_SIZE);
- g_strdel (ky, '=');
- g_strdel (iv, '=');
-
- iolen = sizeof (struct sockaddr);
- getsockname (conn->ctrl_sd, (struct sockaddr *) &ioaddr, &iolen);
- inet_ntop (AF_INET, &(ioaddr.sin_addr), inaddr, INET_ADDRSTRLEN);
-
- ac = g_base64_encode (randbuf.v.challenge, 16);
- g_strdel (ac, '=');
-
- sprintf (creq,
- "v=0\r\n"
- "o=iTunes %s 0 IN IP4 %s\r\n"
- "s=iTunes\r\n"
- "c=IN IP4 %s\r\n"
- "t=0 0\r\n"
- "m=audio 0 RTP/AVP 96\r\n"
- "a=rtpmap:96 AppleLossless\r\n"
- "a=fmtp:96 %d 0 %d 40 10 14 %d 255 0 0 %d\r\n"
- "a=rsaaeskey:%s\r\n"
- "a=aesiv:%s\r\n",
- conn->url_abspath,
- inaddr,
- conn->host,
- conn->generation == GST_APEX_GENERATION_ONE
- ? GST_APEX_RAOP_V1_SAMPLES_PER_FRAME
- : GST_APEX_RAOP_V2_SAMPLES_PER_FRAME,
- GST_APEX_RAOP_BYTES_PER_CHANNEL * 8,
- GST_APEX_RAOP_CHANNELS, GST_APEX_RAOP_BITRATE, ky, iv);
-
- sprintf (hreq,
- "ANNOUNCE rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Content-Type: application/sdp\r\n"
- "Content-Length: %u\r\n"
- "Apple-Challenge: %s\r\n",
- conn->host,
- conn->url_abspath, ++conn->cseq, conn->cid, conn->ua,
- (guint) strlen (creq), ac);
-
- RSA_free (rsa);
- g_free (ky);
- g_free (iv);
- g_free (ac);
- g_free (mod);
- g_free (exp);
-
- req = g_strconcat (hreq, "\r\n", creq, NULL);
-
- if (gst_apexraop_send (conn->ctrl_sd, req, strlen (req)) <= 0) {
- g_free (req);
- return GST_RTSP_STS_GONE;
- }
-
- g_free (req);
-
- if (gst_apexraop_recv (conn->ctrl_sd, hreq,
- GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
- return GST_RTSP_STS_GONE;
-
- {
- int tmp;
- sscanf (hreq, "%*s %d", &tmp);
- res = (GstRTSPStatusCode) tmp;
- }
-
- if (res != GST_RTSP_STS_OK)
- return res;
-
- s = g_strrstr (hreq, "Audio-Jack-Status");
-
- if (s != NULL) {
- gchar status[128];
- sscanf (s, "%*s %s", status);
-
- if (strcmp (status, "connected;") == 0)
- conn->jack_status = GST_APEX_JACK_STATUS_CONNECTED;
- else if (strcmp (status, "disconnected;") == 0)
- conn->jack_status = GST_APEX_JACK_STATUS_DISCONNECTED;
- else
- conn->jack_status = GST_APEX_JACK_STATUS_UNDEFINED;
-
- s = g_strrstr (s, "type=");
-
- if (s != NULL) {
- strtok (s, "=");
- s = strtok (NULL, "\n");
-
- if (strcmp (s, "analog"))
- conn->jack_type = GST_APEX_JACK_TYPE_ANALOG;
- else if (strcmp (s, "digital"))
- conn->jack_type = GST_APEX_JACK_TYPE_DIGITAL;
- else
- conn->jack_type = GST_APEX_JACK_TYPE_UNDEFINED;
- }
- }
-
- sprintf (hreq,
- "SETUP rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Transport: RTP/AVP/TCP;unicast;interleaved=0-1;mode=record\r\n"
- "\r\n", conn->host, conn->url_abspath, ++conn->cseq, conn->cid, conn->ua);
-
- if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
- return GST_RTSP_STS_GONE;
-
- if (gst_apexraop_recv (conn->ctrl_sd, hreq,
- GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
- return GST_RTSP_STS_GONE;
-
- {
- int tmp;
- sscanf (hreq, "%*s %d", &tmp);
- res = (GstRTSPStatusCode) tmp;
- }
-
- if (res != GST_RTSP_STS_OK)
- return res;
-
- s = g_strrstr (hreq, "Session");
-
- if (s != NULL) {
- gchar session[128];
- sscanf (s, "%*s %s", session);
- conn->session = g_strdup (session);
- } else
- return GST_RTSP_STS_PRECONDITION_FAILED;
-
- s = g_strrstr (hreq, "server_port");
- if (s != NULL) {
- sscanf (s, "server_port=%d", &conn->data_port);
- } else
- return GST_RTSP_STS_PRECONDITION_FAILED;
-
- sprintf (hreq,
- "RECORD rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Session: %s\r\n"
- "Range: npt=0-\r\n"
- "RTP-Info: seq=0;rtptime=0\r\n"
- "\r\n",
- conn->host,
- conn->url_abspath, ++conn->cseq, conn->cid, conn->ua, conn->session);
-
- if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
- return GST_RTSP_STS_GONE;
-
- if (gst_apexraop_recv (conn->ctrl_sd, hreq,
- GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
- return GST_RTSP_STS_GONE;
-
- {
- int tmp;
- sscanf (hreq, "%*s %d", &tmp);
- res = (GstRTSPStatusCode) tmp;
- }
-
- if (res != GST_RTSP_STS_OK)
- return res;
-
- if (conn->transport_protocol == GST_APEX_TCP) {
- if ((conn->data_sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
- } else if (conn->transport_protocol == GST_APEX_UDP) {
- if ((conn->data_sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
- } else
- return GST_RTSP_STS_METHOD_NOT_ALLOWED;
-
- conn->data_sd_in.sin_family = AF_INET;
- conn->data_sd_in.sin_port = htons (conn->data_port);
-
- memcpy (&conn->data_sd_in.sin_addr, &conn->ctrl_sd_in.sin_addr,
- sizeof (conn->ctrl_sd_in.sin_addr));
-
- if (connect (conn->data_sd, (struct sockaddr *) &conn->data_sd_in,
- sizeof (conn->data_sd_in)) < 0)
- return GST_RTSP_STS_DESTINATION_UNREACHABLE;
-
- return res;
-}
-
-/* raop apex jack type access */
-GstApExJackType
-gst_apexraop_get_jacktype (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- if (!conn)
- return GST_APEX_JACK_TYPE_UNDEFINED;
-
- return conn->jack_type;
-}
-
-/* raop apex jack status access */
-GstApExJackStatus
-gst_apexraop_get_jackstatus (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- if (!conn)
- return GST_APEX_JACK_STATUS_UNDEFINED;
-
- return conn->jack_status;
-}
-
-/* raop apex generation access */
-GstApExGeneration
-gst_apexraop_get_generation (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- if (!conn)
- return GST_APEX_GENERATION_ONE;
-
- return conn->generation;
-}
-
-/* raop apex transport protocol access */
-GstApExTransportProtocol
-gst_apexraop_get_transport_protocol (GstApExRAOP * con)
-{
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- if (!conn)
- return GST_APEX_TCP;
-
- return conn->transport_protocol;
-}
-
-/* raop apex sockets close */
-void
-gst_apexraop_close (GstApExRAOP * con)
-{
- gchar hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH];
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- sprintf (hreq,
- "TEARDOWN rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Session: %s\r\n"
- "\r\n",
- conn->host,
- conn->url_abspath, ++conn->cseq, conn->cid, conn->ua, conn->session);
-
- gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq));
- gst_apexraop_recv (conn->ctrl_sd, hreq, GST_APEX_RAOP_HDR_DEFAULT_LENGTH);
-
- if (conn->ctrl_sd != 0)
- close (conn->ctrl_sd);
- if (conn->data_sd != 0)
- close (conn->data_sd);
-}
-
-/* raop apex volume set */
-GstRTSPStatusCode
-gst_apexraop_set_volume (GstApExRAOP * con, const guint volume)
-{
- gint v;
- gchar creq[GST_APEX_RAOP_SDP_DEFAULT_LENGTH],
- hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH], *req, vol[128];
- GstRTSPStatusCode res;
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- v = GST_APEX_RAOP_VOLUME_MIN + (GST_APEX_RAOP_VOLUME_MAX -
- GST_APEX_RAOP_VOLUME_MIN) * volume / 100.;
- sprintf (vol, "volume: %d.000000\r\n", v);
-
- sprintf (creq, "%s\r\n", vol);
-
- sprintf (hreq,
- "SET_PARAMETER rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Session: %s\r\n"
- "Content-Type: text/parameters\r\n"
- "Content-Length: %u\r\n",
- conn->host,
- conn->url_abspath,
- ++conn->cseq, conn->cid, conn->ua, conn->session, (guint) strlen (creq)
- );
-
- req = g_strconcat (hreq, "\r\n", creq, NULL);
-
- if (gst_apexraop_send (conn->ctrl_sd, req, strlen (req)) <= 0) {
- g_free (req);
- return GST_RTSP_STS_GONE;
- }
-
- g_free (req);
-
- if (gst_apexraop_recv (conn->ctrl_sd, hreq,
- GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
- return GST_RTSP_STS_GONE;
-
- {
- int tmp;
- sscanf (hreq, "%*s %d", &tmp);
- res = (GstRTSPStatusCode) tmp;
- }
-
- return res;
-}
-
-/* raop apex raw data alac encapsulation, encryption and emission, http://wiki.multimedia.cx/index.php?title=Apple_Lossless_Audio_Coding */
-static void inline
-gst_apexraop_write_bits (guchar * buffer, int data, int numbits,
- int *bit_offset, int *byte_offset)
-{
- const static guchar masks[] =
- { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
-
- if (((*bit_offset) != 0) && (((*bit_offset) + numbits) > 8)) {
- gint numwritebits;
- guchar bitstowrite;
-
- numwritebits = 8 - (*bit_offset);
- bitstowrite =
- (guchar) ((data >> (numbits - numwritebits)) << (8 - (*bit_offset) -
- numwritebits));
- buffer[(*byte_offset)] |= bitstowrite;
- numbits -= numwritebits;
- (*bit_offset) = 0;
- (*byte_offset)++;
- }
-
- while (numbits >= 8) {
- guchar bitstowrite;
-
- bitstowrite = (guchar) ((data >> (numbits - 8)) & 0xFF);
- buffer[(*byte_offset)] |= bitstowrite;
- numbits -= 8;
- (*bit_offset) = 0;
- (*byte_offset)++;
- }
-
- if (numbits > 0) {
- guchar bitstowrite;
- bitstowrite =
- (guchar) ((data & masks[numbits]) << (8 - (*bit_offset) - numbits));
- buffer[(*byte_offset)] |= bitstowrite;
- (*bit_offset) += numbits;
- if ((*bit_offset) == 8) {
- (*byte_offset)++;
- (*bit_offset) = 0;
- }
- }
-}
-
-guint
-gst_apexraop_write (GstApExRAOP * con, gpointer rawdata, guint length)
-{
- guchar *buffer, *frame_data;
- gushort len;
- gint bit_offset, byte_offset, i, out_len, res;
- EVP_CIPHER_CTX aes_ctx;
- _GstApExRAOP *conn = (_GstApExRAOP *) con;
- const int frame_header_size = conn->generation == GST_APEX_GENERATION_ONE
- ? GST_APEX_RAOP_FRAME_HEADER_SIZE : GST_APEX_RTP_FRAME_HEADER_SIZE;
-
- buffer =
- (guchar *) g_malloc0 (frame_header_size +
- GST_APEX_RAOP_ALAC_HEADER_SIZE + length);
-
- if (conn->generation == GST_APEX_GENERATION_ONE) {
- g_assert (frame_header_size == GST_APEX_RAOP_FRAME_HEADER_SIZE);
- memcpy (buffer, GST_APEX_RAOP_FRAME_HEADER, frame_header_size);
-
- len = length + frame_header_size + GST_APEX_RAOP_ALAC_HEADER_SIZE - 4;
-
- buffer[2] = len >> 8;
- buffer[3] = len & 0xff;
- } else {
- /* Gen. 2 uses RTP-like header (RFC 3550). */
- short network_seq_num;
- int network_timestamp, unknown_const;
- static gboolean first = TRUE;
-
- buffer[0] = 0x80;
- if (first) {
- buffer[1] = 0xe0;
- first = FALSE;
- } else
- buffer[1] = 0x60;
-
- network_seq_num = htons (conn->rtp_seq_num++);
- memcpy (buffer + 2, &network_seq_num, 2);
-
- network_timestamp = htons (conn->rtp_timestamp);
- memcpy (buffer + 4, &network_timestamp, 4);
- conn->rtp_timestamp += GST_APEX_RAOP_V2_SAMPLES_PER_FRAME;
-
- unknown_const = 0xdeadbeef;
- memcpy (buffer + 8, &unknown_const, 4);
- }
-
- bit_offset = 0;
- byte_offset = 0;
- frame_data = buffer + frame_header_size;
-
- gst_apexraop_write_bits (frame_data, 1, 3, &bit_offset, &byte_offset); /* channels, 0 mono, 1 stereo */
- gst_apexraop_write_bits (frame_data, 0, 4, &bit_offset, &byte_offset); /* unknown */
- gst_apexraop_write_bits (frame_data, 0, 8, &bit_offset, &byte_offset); /* unknown (12 bits) */
- gst_apexraop_write_bits (frame_data, 0, 4, &bit_offset, &byte_offset);
- gst_apexraop_write_bits (frame_data, 0, 1, &bit_offset, &byte_offset); /* has size flag */
- gst_apexraop_write_bits (frame_data, 0, 2, &bit_offset, &byte_offset); /* unknown */
- gst_apexraop_write_bits (frame_data, 1, 1, &bit_offset, &byte_offset); /* no compression flag */
-
- for (i = 0; i < length; i += 2) {
- gst_apexraop_write_bits (frame_data, ((guchar *) rawdata)[i + 1], 8,
- &bit_offset, &byte_offset);
- gst_apexraop_write_bits (frame_data, ((guchar *) rawdata)[i], 8,
- &bit_offset, &byte_offset);
- }
-
- EVP_CIPHER_CTX_init (&aes_ctx);
- EVP_CipherInit_ex (&aes_ctx, EVP_aes_128_cbc (), NULL, conn->aes_ky,
- conn->aes_iv, AES_ENCRYPT);
- EVP_CipherUpdate (&aes_ctx, frame_data, &out_len, frame_data, /*( */
- GST_APEX_RAOP_ALAC_HEADER_SIZE +
- length /*) / AES_BLOCK_SIZE * AES_BLOCK_SIZE */ );
- EVP_CIPHER_CTX_cleanup (&aes_ctx);
-
- res =
- gst_apexraop_send (conn->data_sd, buffer,
- frame_header_size + GST_APEX_RAOP_ALAC_HEADER_SIZE + length);
-
- g_free (buffer);
-
- return (guint) ((res >=
- (frame_header_size +
- GST_APEX_RAOP_ALAC_HEADER_SIZE)) ? (res -
- frame_header_size - GST_APEX_RAOP_ALAC_HEADER_SIZE) : 0);
-}
-
-/* raop apex buffer flush */
-GstRTSPStatusCode
-gst_apexraop_flush (GstApExRAOP * con)
-{
- gchar hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH];
- GstRTSPStatusCode res;
- _GstApExRAOP *conn;
-
- conn = (_GstApExRAOP *) con;
-
- sprintf (hreq,
- "FLUSH rtsp://%s/%s RTSP/1.0\r\n"
- "CSeq: %d\r\n"
- "Client-Instance: %s\r\n"
- "User-Agent: %s\r\n"
- "Session: %s\r\n"
- "RTP-Info: seq=%d;rtptime=%d\r\n"
- "\r\n",
- conn->host,
- conn->url_abspath,
- ++conn->cseq,
- conn->cid,
- conn->ua, conn->session, conn->rtp_seq_num, conn->rtp_timestamp);
-
- if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
- return GST_RTSP_STS_GONE;
-
- if (gst_apexraop_recv (conn->ctrl_sd, hreq,
- GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
- return GST_RTSP_STS_GONE;
-
- {
- int tmp;
- sscanf (hreq, "%*s %d", &tmp);
- res = (GstRTSPStatusCode) tmp;
- }
-
- return res;
-}
diff --git a/ext/apexsink/gstapexraop.h b/ext/apexsink/gstapexraop.h
deleted file mode 100644
index a4f947e4f..000000000
--- a/ext/apexsink/gstapexraop.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* GStreamer - Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
- *
- * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
- * This interface accepts RAW PCM data and set it as AES encrypted ALAC while performing emission.
- *
- * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
- *
- * gstapexraop.h
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef __GST_APEXRAOP_H__
-#define __GST_APEXRAOP_H__
-
-#include <gst/gst.h>
-#include <gst/rtsp/gstrtspdefs.h>
-
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <arpa/inet.h>
-
-G_BEGIN_DECLS
-
-/* raop fixed parameters */
-#define GST_APEX_RAOP_BITRATE 44100
-#define GST_APEX_RAOP_V1_SAMPLES_PER_FRAME 4096
-#define GST_APEX_RAOP_V2_SAMPLES_PER_FRAME 352
-#define GST_APEX_RAOP_BYTES_PER_CHANNEL 2
-#define GST_APEX_RAOP_CHANNELS 2
-#define GST_APEX_RAOP_BYTES_PER_SAMPLE (GST_APEX_RAOP_CHANNELS * GST_APEX_RAOP_BYTES_PER_CHANNEL)
-
-/* gst associated caps fields specification */
-#define GST_APEX_RAOP_INPUT_TYPE "audio/x-raw-int"
-#define GST_APEX_RAOP_INPUT_WIDTH "16"
-#define GST_APEX_RAOP_INPUT_DEPTH GST_APEX_RAOP_INPUT_WIDTH
-#define GST_APEX_RAOP_INPUT_ENDIAN "LITTLE_ENDIAN"
-#define GST_APEX_RAOP_INPUT_CHANNELS "2"
-#define GST_APEX_RAOP_INPUT_BIT_RATE "44100"
-#define GST_APEX_RAOP_INPUT_SIGNED "TRUE"
-
-typedef enum
-{
- GST_APEX_JACK_TYPE_UNDEFINED = 0,
- GST_APEX_JACK_TYPE_ANALOG,
- GST_APEX_JACK_TYPE_DIGITAL,
-}
-GstApExJackType;
-
-typedef enum
-{
- GST_APEX_JACK_STATUS_UNDEFINED = 0,
- GST_APEX_JACK_STATUS_DISCONNECTED,
- GST_APEX_JACK_STATUS_CONNECTED,
-}
-GstApExJackStatus;
-
-typedef enum
-{
- GST_APEX_GENERATION_ONE = 1,
- GST_APEX_GENERATION_TWO,
-}
-GstApExGeneration;
-
-typedef enum
-{
- GST_APEX_TCP = 0,
- GST_APEX_UDP,
-}
-GstApExTransportProtocol;
-
-/* raop context handle */
-typedef struct
-{
-} GstApExRAOP;
-
-/* host might be null and port might be 0 while instanciating */
-GstApExRAOP *gst_apexraop_new (const gchar * host,
- const guint16 port,
- const GstApExGeneration generation,
- const GstApExTransportProtocol transport_protocol);
-void gst_apexraop_free (GstApExRAOP * conn);
-
-/* must not be connected yet while setting the host target */
-void gst_apexraop_set_host (GstApExRAOP * conn, const gchar * host);
-gchar *gst_apexraop_get_host (GstApExRAOP * conn);
-
-/* must not be connected yet while setting the port target */
-void gst_apexraop_set_port (GstApExRAOP * conn, const guint16 port);
-guint16 gst_apexraop_get_port (GstApExRAOP * conn);
-
-/* optional affectation, default iTunes user agent internaly used */
-void gst_apexraop_set_useragent (GstApExRAOP * conn, const gchar * useragent);
-gchar *gst_apexraop_get_useragent (GstApExRAOP * conn);
-
-/* once allocation and configuration performed, manages the raop ANNOUNCE, SETUP and RECORD sequences,
- * open both ctrl and data channels */
-GstRTSPStatusCode gst_apexraop_connect (GstApExRAOP * conn);
-
-/* close the currently used session, manages raop TEARDOWN sequence and closes the used sockets */
-void gst_apexraop_close (GstApExRAOP * conn);
-
-/* once connected, set the apex target volume, manages SET_PARAMETER sequence */
-GstRTSPStatusCode gst_apexraop_set_volume (GstApExRAOP * conn,
- const guint volume);
-
-/* write raw samples typed as defined by the fixed raop parameters, flush the apex buffer */
-guint gst_apexraop_write (GstApExRAOP * conn, gpointer rawdata, guint length);
-GstRTSPStatusCode gst_apexraop_flush (GstApExRAOP * conn);
-
-/* retrieve the connected apex jack type and status */
-GstApExJackType gst_apexraop_get_jacktype (GstApExRAOP * conn);
-GstApExJackStatus gst_apexraop_get_jackstatus (GstApExRAOP * conn);
-
-/* retrieve the generation */
-GstApExGeneration gst_apexraop_get_generation (GstApExRAOP * conn);
-
-/* retrieve the transport protocol */
-GstApExTransportProtocol gst_apexraop_get_transport_protocol (GstApExRAOP * conn);
-
-G_END_DECLS
-
-#endif
-
diff --git a/ext/apexsink/gstapexsink.c b/ext/apexsink/gstapexsink.c
deleted file mode 100644
index df5c5f256..000000000
--- a/ext/apexsink/gstapexsink.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/* GStreamer - AirPort Express Audio Sink -
- *
- * Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
- * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
- *
- * RAW PCM input only as defined by the following GST_STATIC_PAD_TEMPLATE
- *
- * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
- *
- * gstapexsink.c
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "gstapexsink.h"
-
-GST_DEBUG_CATEGORY_STATIC (apexsink_debug);
-#define GST_CAT_DEFAULT apexsink_debug
-
-static GstStaticPadTemplate gst_apexsink_sink_factory = GST_STATIC_PAD_TEMPLATE
- ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS
- (GST_APEX_RAOP_INPUT_TYPE ","
- "width = (int) " GST_APEX_RAOP_INPUT_WIDTH ","
- "depth = (int) " GST_APEX_RAOP_INPUT_DEPTH ","
- "endianness = (int) " GST_APEX_RAOP_INPUT_ENDIAN ","
- "channels = (int) " GST_APEX_RAOP_INPUT_CHANNELS ","
- "rate = (int) " GST_APEX_RAOP_INPUT_BIT_RATE ","
- "signed = (boolean) " GST_APEX_RAOP_INPUT_SIGNED)
- );
-
-
-enum
-{
- APEX_PROP_HOST = 1,
- APEX_PROP_PORT,
- APEX_PROP_VOLUME,
- APEX_PROP_JACK_TYPE,
- APEX_PROP_JACK_STATUS,
- APEX_PROP_GENERATION,
- APEX_PROP_TRANSPORT_PROTOCOL,
-};
-
-#define DEFAULT_APEX_HOST ""
-#define DEFAULT_APEX_PORT 5000
-#define DEFAULT_APEX_VOLUME 1.0
-#define DEFAULT_APEX_JACK_TYPE GST_APEX_JACK_TYPE_UNDEFINED
-#define DEFAULT_APEX_JACK_STATUS GST_APEX_JACK_STATUS_UNDEFINED
-#define DEFAULT_APEX_GENERATION GST_APEX_GENERATION_ONE
-#define DEFAULT_APEX_TRANSPORT_PROTOCOL GST_APEX_TCP
-
-/* genum apex jack resolution */
-GType
-gst_apexsink_jackstatus_get_type (void)
-{
- static GType jackstatus_type = 0;
- static const GEnumValue jackstatus[] = {
- {GST_APEX_JACK_STATUS_UNDEFINED, "GST_APEX_JACK_STATUS_UNDEFINED",
- "Jack status undefined"},
- {GST_APEX_JACK_STATUS_DISCONNECTED, "GST_APEX_JACK_STATUS_DISCONNECTED",
- "Jack disconnected"},
- {GST_APEX_JACK_STATUS_CONNECTED, "GST_APEX_JACK_STATUS_CONNECTED",
- "Jack connected"},
- {0, NULL, NULL},
- };
-
- if (!jackstatus_type) {
- jackstatus_type = g_enum_register_static ("GstApExJackStatus", jackstatus);
- }
-
- return jackstatus_type;
-}
-
-GType
-gst_apexsink_jacktype_get_type (void)
-{
- static GType jacktype_type = 0;
- static const GEnumValue jacktype[] = {
- {GST_APEX_JACK_TYPE_UNDEFINED, "GST_APEX_JACK_TYPE_UNDEFINED",
- "Undefined jack type"},
- {GST_APEX_JACK_TYPE_ANALOG, "GST_APEX_JACK_TYPE_ANALOG", "Analog jack"},
- {GST_APEX_JACK_TYPE_DIGITAL, "GST_APEX_JACK_TYPE_DIGITAL", "Digital jack"},
- {0, NULL, NULL},
- };
-
- if (!jacktype_type) {
- jacktype_type = g_enum_register_static ("GstApExJackType", jacktype);
- }
-
- return jacktype_type;
-}
-
-GType
-gst_apexsink_generation_get_type (void)
-{
- static GType generation_type = 0;
- static const GEnumValue generation[] = {
- {GST_APEX_GENERATION_ONE, "generation-one",
- "First generation (e.g., original AirPort Express)"},
- {GST_APEX_GENERATION_TWO, "generation-two",
- "Second generation (e.g., Apple TV v2)"},
- {0, NULL, NULL},
- };
-
- if (!generation_type) {
- generation_type = g_enum_register_static ("GstApExGeneration", generation);
- }
-
- return generation_type;
-}
-
-GType
-gst_apexsink_transport_protocol_get_type (void)
-{
- static GType transport_protocol_type = 0;
- static const GEnumValue transport_protocol[] = {
- {GST_APEX_TCP, "tcp", "TCP"},
- {GST_APEX_UDP, "udp", "UDP"},
- {0, NULL, NULL},
- };
-
- if (!transport_protocol_type) {
- transport_protocol_type =
- g_enum_register_static ("GstApExTransportProtocol", transport_protocol);
- }
-
- return transport_protocol_type;
-}
-
-
-static void gst_apexsink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_apexsink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_apexsink_finalise (GObject * object);
-
-static gboolean gst_apexsink_open (GstAudioSink * asink);
-static gboolean gst_apexsink_prepare (GstAudioSink * asink,
- GstRingBufferSpec * spec);
-static guint gst_apexsink_write (GstAudioSink * asink, gpointer data,
- guint length);
-static gboolean gst_apexsink_unprepare (GstAudioSink * asink);
-static guint gst_apexsink_delay (GstAudioSink * asink);
-static void gst_apexsink_reset (GstAudioSink * asink);
-static gboolean gst_apexsink_close (GstAudioSink * asink);
-static GstStateChangeReturn gst_apexsink_change_state (GstElement * element,
- GstStateChange transition);
-
-/* mixer interface standard api */
-static void gst_apexsink_interfaces_init (GType type);
-static void gst_apexsink_implements_interface_init (GstImplementsInterfaceClass
- * iface);
-static void gst_apexsink_mixer_interface_init (GstMixerInterface * iface);
-
-static gboolean gst_apexsink_interface_supported (GstImplementsInterface *
- iface, GType iface_type);
-static const GList *gst_apexsink_mixer_list_tracks (GstMixer * mixer);
-static void gst_apexsink_mixer_set_volume (GstMixer * mixer,
- GstMixerTrack * track, gint * volumes);
-static void gst_apexsink_mixer_get_volume (GstMixer * mixer,
- GstMixerTrack * track, gint * volumes);
-
-GST_BOILERPLATE_FULL (GstApExSink, gst_apexsink, GstAudioSink,
- GST_TYPE_AUDIO_SINK, gst_apexsink_interfaces_init);
-
-/* apex sink interface(s) stuff */
-static void
-gst_apexsink_interfaces_init (GType type)
-{
- static const GInterfaceInfo implements_interface_info =
- { (GInterfaceInitFunc) gst_apexsink_implements_interface_init, NULL,
- NULL
- };
- static const GInterfaceInfo mixer_interface_info =
- { (GInterfaceInitFunc) gst_apexsink_mixer_interface_init, NULL, NULL };
-
- g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
- &implements_interface_info);
- g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_interface_info);
-}
-
-static void
-gst_apexsink_implements_interface_init (GstImplementsInterfaceClass * iface)
-{
- iface->supported = gst_apexsink_interface_supported;
-}
-
-static void
-gst_apexsink_mixer_interface_init (GstMixerInterface * iface)
-{
- GST_MIXER_TYPE (iface) = GST_MIXER_SOFTWARE;
-
- iface->list_tracks = gst_apexsink_mixer_list_tracks;
- iface->set_volume = gst_apexsink_mixer_set_volume;
- iface->get_volume = gst_apexsink_mixer_get_volume;
-}
-
-static gboolean
-gst_apexsink_interface_supported (GstImplementsInterface * iface,
- GType iface_type)
-{
- g_return_val_if_fail (iface_type == GST_TYPE_MIXER, FALSE);
-
- return TRUE;
-}
-
-static const GList *
-gst_apexsink_mixer_list_tracks (GstMixer * mixer)
-{
- GstApExSink *apexsink = GST_APEX_SINK (mixer);
-
- return apexsink->tracks;
-}
-
-static void
-gst_apexsink_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track,
- gint * volumes)
-{
- GstApExSink *apexsink = GST_APEX_SINK (mixer);
-
- apexsink->volume = volumes[0];
-
- if (apexsink->gst_apexraop != NULL)
- gst_apexraop_set_volume (apexsink->gst_apexraop, apexsink->volume);
-}
-
-static void
-gst_apexsink_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track,
- gint * volumes)
-{
- GstApExSink *apexsink = GST_APEX_SINK (mixer);
-
- volumes[0] = apexsink->volume;
-}
-
-/* sink base init */
-static void
-gst_apexsink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_static_metadata (element_class,
- "Apple AirPort Express Audio Sink", "Sink/Audio/Wireless",
- "Output stream to an AirPort Express",
- "Jérémie Bernard [GRemi] <gremimail@gmail.com>");
- gst_element_class_add_static_pad_template (element_class,
- &gst_apexsink_sink_factory);
-}
-
-/* sink class init */
-static void
-gst_apexsink_class_init (GstApExSinkClass * klass)
-{
- GST_DEBUG_CATEGORY_INIT (apexsink_debug, GST_APEX_SINK_NAME, 0,
- "AirPort Express sink");
-
- parent_class = g_type_class_peek_parent (klass);
-
- ((GObjectClass *) klass)->get_property =
- GST_DEBUG_FUNCPTR (gst_apexsink_get_property);
- ((GObjectClass *) klass)->set_property =
- GST_DEBUG_FUNCPTR (gst_apexsink_set_property);
- ((GObjectClass *) klass)->finalize =
- GST_DEBUG_FUNCPTR (gst_apexsink_finalise);
-
- ((GstAudioSinkClass *) klass)->open = GST_DEBUG_FUNCPTR (gst_apexsink_open);
- ((GstAudioSinkClass *) klass)->prepare =
- GST_DEBUG_FUNCPTR (gst_apexsink_prepare);
- ((GstAudioSinkClass *) klass)->write = GST_DEBUG_FUNCPTR (gst_apexsink_write);
- ((GstAudioSinkClass *) klass)->unprepare =
- GST_DEBUG_FUNCPTR (gst_apexsink_unprepare);
- ((GstAudioSinkClass *) klass)->delay = GST_DEBUG_FUNCPTR (gst_apexsink_delay);
- ((GstAudioSinkClass *) klass)->reset = GST_DEBUG_FUNCPTR (gst_apexsink_reset);
- ((GstAudioSinkClass *) klass)->close = GST_DEBUG_FUNCPTR (gst_apexsink_close);
-
- ((GstElementClass *) klass)->change_state =
- GST_DEBUG_FUNCPTR (gst_apexsink_change_state);
-
- g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_HOST,
- g_param_spec_string ("host", "Host", "AirPort Express target host",
- DEFAULT_APEX_HOST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_PORT,
- g_param_spec_uint ("port", "Port", "AirPort Express target port", 0,
- 32000, DEFAULT_APEX_PORT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /* we need to expose the volume as a double for playbin. Internally we keep
- * it as an int between 0 and 100, where 75 corresponds to 1.0.
- * FIXME we should store the volume as a double. */
- g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_VOLUME,
- g_param_spec_double ("volume", "Volume", "AirPort Express target volume",
- 0.0, 10.0, DEFAULT_APEX_VOLUME,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property ((GObjectClass *) klass, APEX_PROP_JACK_TYPE,
- g_param_spec_enum ("jack-type", "Jack Type",
- "AirPort Express connected jack type", GST_APEX_SINK_JACKTYPE_TYPE,
- DEFAULT_APEX_JACK_TYPE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property ((GObjectClass *) klass,
- APEX_PROP_JACK_STATUS, g_param_spec_enum ("jack-status", "Jack Status",
- "AirPort Express jack connection status",
- GST_APEX_SINK_JACKSTATUS_TYPE, DEFAULT_APEX_JACK_STATUS,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property ((GObjectClass *) klass,
- APEX_PROP_GENERATION, g_param_spec_enum ("generation", "Generation",
- "AirPort device generation",
- GST_APEX_SINK_GENERATION_TYPE, DEFAULT_APEX_GENERATION,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property ((GObjectClass *) klass,
- APEX_PROP_TRANSPORT_PROTOCOL, g_param_spec_enum ("transport-protocol",
- "Transport Protocol", "AirPort transport protocol",
- GST_APEX_SINK_TRANSPORT_PROTOCOL_TYPE,
- DEFAULT_APEX_TRANSPORT_PROTOCOL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-/* sink plugin instance init */
-static void
-gst_apexsink_init (GstApExSink * apexsink, GstApExSinkClass * g_class)
-{
- GstMixerTrack *track = NULL;
-
- track = g_object_new (GST_TYPE_MIXER_TRACK, NULL);
- track->label = g_strdup ("Airport Express");
- track->num_channels = GST_APEX_RAOP_CHANNELS;
- track->min_volume = 0;
- track->max_volume = 100;
- track->flags = GST_MIXER_TRACK_OUTPUT;
-
- apexsink->host = g_strdup (DEFAULT_APEX_HOST);
- apexsink->port = DEFAULT_APEX_PORT;
- apexsink->volume = CLAMP (DEFAULT_APEX_VOLUME * 75, 0, 100);
- apexsink->gst_apexraop = NULL;
- apexsink->tracks = g_list_append (apexsink->tracks, track);
- apexsink->clock = gst_system_clock_obtain ();
- apexsink->clock_id = NULL;
-
- GST_INFO_OBJECT (apexsink,
- "ApEx sink default initialization, target=\"%s\", port=\"%d\", volume=\"%d%%\"",
- apexsink->host, apexsink->port, apexsink->volume);
-}
-
-/* apex sink set property */
-static void
-gst_apexsink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstApExSink *sink = GST_APEX_SINK (object);
-
- switch (prop_id) {
- case APEX_PROP_HOST:
- if (sink->gst_apexraop == NULL) {
- g_free (sink->host);
- sink->host = g_value_dup_string (value);
-
- GST_INFO_OBJECT (sink, "ApEx sink target set to \"%s\"", sink->host);
- } else {
- G_OBJECT_WARN_INVALID_PSPEC (object, "host", prop_id, pspec);
- }
- break;
- case APEX_PROP_PORT:
- if (sink->gst_apexraop == NULL) {
- sink->port = g_value_get_uint (value);
-
- GST_INFO_OBJECT (sink, "ApEx port set to \"%d\"", sink->port);
- } else {
- G_OBJECT_WARN_INVALID_PSPEC (object, "port", prop_id, pspec);
- }
- break;
- case APEX_PROP_VOLUME:
- {
- gdouble volume;
-
- volume = g_value_get_double (value);
- volume *= 75.0;
-
- sink->volume = CLAMP (volume, 0, 100);
-
- if (sink->gst_apexraop != NULL)
- gst_apexraop_set_volume (sink->gst_apexraop, sink->volume);
-
- GST_INFO_OBJECT (sink, "ApEx volume set to \"%d%%\"", sink->volume);
- break;
- }
- case APEX_PROP_GENERATION:
- if (sink->gst_apexraop == NULL) {
- sink->generation = g_value_get_enum (value);
-
- GST_INFO_OBJECT (sink, "ApEx generation set to \"%d\"",
- sink->generation);
- } else {
- GST_WARNING_OBJECT (sink,
- "SET-PROPERTY : generation property may not be set when apexsink opened !");
- }
- break;
- case APEX_PROP_TRANSPORT_PROTOCOL:
- if (sink->gst_apexraop == NULL) {
- sink->transport_protocol = g_value_get_enum (value);
-
- GST_INFO_OBJECT (sink, "ApEx transport protocol set to \"%d\"",
- sink->transport_protocol);
- } else {
- GST_WARNING_OBJECT (sink,
- "SET-PROPERTY : transport protocol property may not be set when apexsink opened !");
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* apex sink get property */
-static void
-gst_apexsink_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstApExSink *sink = GST_APEX_SINK (object);
-
- switch (prop_id) {
- case APEX_PROP_HOST:
- g_value_set_string (value, sink->host);
- break;
- case APEX_PROP_PORT:
- g_value_set_uint (value, sink->port);
- break;
- case APEX_PROP_VOLUME:
- g_value_set_double (value, ((gdouble) sink->volume) / 75.0);
- break;
- case APEX_PROP_JACK_TYPE:
- g_value_set_enum (value, gst_apexraop_get_jacktype (sink->gst_apexraop));
- break;
- case APEX_PROP_JACK_STATUS:
- g_value_set_enum (value,
- gst_apexraop_get_jackstatus (sink->gst_apexraop));
- break;
- case APEX_PROP_GENERATION:
- g_value_set_enum (value,
- gst_apexraop_get_generation (sink->gst_apexraop));
- break;
- case APEX_PROP_TRANSPORT_PROTOCOL:
- g_value_set_enum (value,
- gst_apexraop_get_transport_protocol (sink->gst_apexraop));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* apex sink finalize */
-static void
-gst_apexsink_finalise (GObject * object)
-{
- GstApExSink *sink = GST_APEX_SINK (object);
-
- if (sink->tracks) {
- g_list_foreach (sink->tracks, (GFunc) g_object_unref, NULL);
- g_list_free (sink->tracks);
- sink->tracks = NULL;
- }
-
- gst_object_unref (sink->clock);
-
- g_free (sink->host);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/* sink open : open the device */
-static gboolean
-gst_apexsink_open (GstAudioSink * asink)
-{
- int res;
- GstApExSink *apexsink = (GstApExSink *) asink;
-
- apexsink->gst_apexraop = gst_apexraop_new (apexsink->host,
- apexsink->port, apexsink->generation, apexsink->transport_protocol);
-
- if ((res = gst_apexraop_connect (apexsink->gst_apexraop)) != GST_RTSP_STS_OK) {
- GST_ERROR_OBJECT (apexsink,
- "%s : network or RAOP failure, connection refused or timeout, RTSP code=%d",
- apexsink->host, res);
- return FALSE;
- }
-
- GST_INFO_OBJECT (apexsink,
- "OPEN : ApEx sink successfully connected to \"%s:%d\", ANNOUNCE, SETUP and RECORD requests performed",
- apexsink->host, apexsink->port);
-
- switch (gst_apexraop_get_jackstatus (apexsink->gst_apexraop)) {
- case GST_APEX_JACK_STATUS_CONNECTED:
- GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack is connected");
- break;
- case GST_APEX_JACK_STATUS_DISCONNECTED:
- GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack is disconnected !");
- break;
- default:
- GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack status is undefined !");
- break;
- }
-
- switch (gst_apexraop_get_jacktype (apexsink->gst_apexraop)) {
- case GST_APEX_JACK_TYPE_ANALOG:
- GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack type is analog");
- break;
- case GST_APEX_JACK_TYPE_DIGITAL:
- GST_INFO_OBJECT (apexsink, "OPEN : ApEx jack type is digital");
- break;
- default:
- GST_WARNING_OBJECT (apexsink, "OPEN : ApEx jack type is undefined !");
- break;
- }
-
- if ((res =
- gst_apexraop_set_volume (apexsink->gst_apexraop,
- apexsink->volume)) != GST_RTSP_STS_OK) {
- GST_WARNING_OBJECT (apexsink,
- "%s : could not set initial volume to \"%d%%\", RTSP code=%d",
- apexsink->host, apexsink->volume, res);
- } else {
- GST_INFO_OBJECT (apexsink,
- "OPEN : ApEx sink successfully set volume to \"%d%%\"",
- apexsink->volume);
- }
-
- return TRUE;
-}
-
-/* prepare sink : configure the device with the specified format */
-static gboolean
-gst_apexsink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
-{
- GstApExSink *apexsink = (GstApExSink *) asink;
- GstApExGeneration gen = gst_apexraop_get_generation (apexsink->gst_apexraop);
-
- apexsink->latency_time = spec->latency_time;
-
- spec->segsize = gen == GST_APEX_GENERATION_ONE
- ? GST_APEX_RAOP_V1_SAMPLES_PER_FRAME * GST_APEX_RAOP_BYTES_PER_SAMPLE
- : GST_APEX_RAOP_V2_SAMPLES_PER_FRAME * GST_APEX_RAOP_BYTES_PER_SAMPLE;
- spec->segtotal = 2;
-
- memset (spec->silence_sample, 0, sizeof (spec->silence_sample));
-
- GST_INFO_OBJECT (apexsink,
- "PREPARE : ApEx sink ready to stream at %dHz, %d bytes per sample, %d channels, %d bytes segments (%dkB/s)",
- spec->rate, spec->bytes_per_sample, spec->channels, spec->segsize,
- spec->rate * spec->bytes_per_sample / 1000);
-
- return TRUE;
-}
-
-/* sink write : write samples to the device */
-static guint
-gst_apexsink_write (GstAudioSink * asink, gpointer data, guint length)
-{
- guint written;
- GstApExSink *apexsink = (GstApExSink *) asink;
-
- if ((written =
- gst_apexraop_write (apexsink->gst_apexraop, data,
- length)) != length) {
- GST_INFO_OBJECT (apexsink,
- "WRITE : %d of %d bytes sent, skipping frame samples...", written,
- length);
- } else {
- GST_INFO_OBJECT (apexsink, "WRITE : %d bytes sent", length);
- /* NOTE, previous calculation subtracted apexsink->latency_time from this;
- * however, the value below is less than apexsink->latency_time for generation 2.
- * In this case, the number went negative (actualy wrapped around into a big number).
- */
- apexsink->clock_id = gst_clock_new_single_shot_id (apexsink->clock,
- (GstClockTime) (gst_clock_get_time (apexsink->clock) +
- ((length * 1000000000.)
- / (GST_APEX_RAOP_BITRATE * GST_APEX_RAOP_BYTES_PER_SAMPLE))));
- gst_clock_id_wait (apexsink->clock_id, NULL);
- gst_clock_id_unref (apexsink->clock_id);
- apexsink->clock_id = NULL;
- }
-
- return length;
-}
-
-/* unprepare sink : undo operations done by prepare */
-static gboolean
-gst_apexsink_unprepare (GstAudioSink * asink)
-{
- GST_INFO_OBJECT (asink, "UNPREPARE");
-
- return TRUE;
-}
-
-/* delay sink : get the estimated number of samples written but not played yet by the device */
-static guint
-gst_apexsink_delay (GstAudioSink * asink)
-{
- GST_LOG_OBJECT (asink, "DELAY");
-
- return 0;
-}
-
-/* reset sink : unblock writes and flush the device */
-static void
-gst_apexsink_reset (GstAudioSink * asink)
-{
- int res;
- GstApExSink *apexsink = (GstApExSink *) asink;
-
- GST_INFO_OBJECT (apexsink, "RESET : flushing buffer...");
-
- if ((res = gst_apexraop_flush (apexsink->gst_apexraop)) == GST_RTSP_STS_OK) {
- GST_INFO_OBJECT (apexsink, "RESET : ApEx buffer flush success");
- } else {
- GST_WARNING_OBJECT (apexsink,
- "RESET : could not flush ApEx buffer, RTSP code=%d", res);
- }
-}
-
-/* sink close : close the device */
-static gboolean
-gst_apexsink_close (GstAudioSink * asink)
-{
- GstApExSink *apexsink = (GstApExSink *) asink;
-
- gst_apexraop_close (apexsink->gst_apexraop);
- gst_apexraop_free (apexsink->gst_apexraop);
-
- GST_INFO_OBJECT (apexsink, "CLOSE : ApEx sink closed connection");
-
- return TRUE;
-}
-
-static GstStateChangeReturn
-gst_apexsink_change_state (GstElement * element, GstStateChange transition)
-{
- GstApExSink *apexsink = (GstApExSink *) element;
-
- if (apexsink->clock_id && transition == GST_STATE_CHANGE_PAUSED_TO_READY) {
- gst_clock_id_unschedule (apexsink->clock_id);
- gst_clock_id_unref (apexsink->clock_id);
- apexsink->clock_id = NULL;
- }
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-}
diff --git a/ext/apexsink/gstapexsink.h b/ext/apexsink/gstapexsink.h
deleted file mode 100644
index 711cd3725..000000000
--- a/ext/apexsink/gstapexsink.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* GStreamer - AirPort Express (ApEx) Audio Sink -
- *
- * Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
- * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
- *
- * RAW PCM input only as defined by the following GST_STATIC_PAD_TEMPLATE regarding the expected gstapexraop input format.
- *
- * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
- *
- * gstapexsink.h
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef __GST_APEXSINK_H__
-#define __GST_APEXSINK_H__
-
-#include "gstapexraop.h"
-
-#include <gst/audio/gstaudiosink.h>
-#include <gst/interfaces/mixer.h>
-
-G_BEGIN_DECLS
-
-/* standard gstreamer macros */
-#define GST_TYPE_APEX_SINK (gst_apexsink_get_type())
-#define GST_APEX_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_APEX_SINK,GstApExSink))
-#define GST_APEX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_APEX_SINK,GstApExSinkClass))
-#define GST_IS_APEX_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_APEX_SINK))
-#define GST_IS_APEX_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_APEX_SINK))
-#define GST_APEX_SINK_CAST(obj) ((GstApExSink*)(obj))
-#define GST_APEX_SINK_NAME "apexsink"
-#define GST_APEX_SINK_JACKTYPE_TYPE (gst_apexsink_jacktype_get_type())
-#define GST_APEX_SINK_JACKSTATUS_TYPE (gst_apexsink_jackstatus_get_type())
-#define GST_APEX_SINK_GENERATION_TYPE (gst_apexsink_generation_get_type())
-#define GST_APEX_SINK_TRANSPORT_PROTOCOL_TYPE (gst_apexsink_transport_protocol_get_type())
-/* ApEx classes declaration */
-typedef struct _GstApExSink GstApExSink;
-typedef struct _GstApExSinkClass GstApExSinkClass;
-
-struct _GstApExSink
-{
- /* base definition */
- GstAudioSink sink;
-
- /* public read/write sink properties */
- gchar *host;
- guint port;
- guint volume;
- GstApExGeneration generation;
- GstApExTransportProtocol transport_protocol;
-
- /* private attributes :
- * latency time local copy
- * tracks list of the mixer interface
- * clock for sleeping
- * clock ID for sleeping / canceling sleep
- */
- guint64 latency_time;
- GList *tracks;
- GstClock *clock;
- GstClockID clock_id;
-
- /* private apex client */
- GstApExRAOP *gst_apexraop;
-};
-
-struct _GstApExSinkClass
-{
- GstAudioSinkClass parent_class;
-};
-
-/* genums */
-GType gst_apexsink_jackstatus_get_type (void);
-GType gst_apexsink_jacktype_get_type (void);
-GType gst_apexsink_generation_get_type (void);
-GType gst_apexsink_transport_protocol_get_type (void);
-
-/* audio sink standard api */
-GType gst_apexsink_get_type (void);
-
-G_END_DECLS
-
-#endif
diff --git a/ext/libvisual/Makefile.am b/ext/libvisual/Makefile.am
deleted file mode 100644
index 1eba9af2f..000000000
--- a/ext/libvisual/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-plugin_LTLIBRARIES = libgstlibvisualgl.la
-
-libgstlibvisualgl_la_SOURCES = visual-gl.c
-
-libgstlibvisualgl_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(LIBVISUAL_CFLAGS) \
- -I$(top_srcdir)/gst-libs \
- -I$(top_srcdir)/gst-libs/gst/gl
-
-libgstlibvisualgl_la_LIBADD = \
- $(top_builddir)/gst-libs/gst/gl/libgstgl-$(GST_API_VERSION).la \
- $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) $(LIBVISUAL_LIBS)
-
-libgstlibvisualgl_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstlibvisualgl_la_LIBTOOLFLAGS = --tag=disable-static
-
diff --git a/ext/libvisual/visual-gl.c b/ext/libvisual/visual-gl.c
deleted file mode 100644
index c796d4b47..000000000
--- a/ext/libvisual/visual-gl.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/* GStreamer
- * Copyright (C) 2004 Benjamin Otte <otte@gnome.org>
- * Copyright (C) 2009 Jonathan Matthew <notverysmart@gmail.com>
- * Copyright (C) 2011 Julien Isorce <julien.isorce@gmail.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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/**
- * SECTION:element-libvisualgl
- *
- * Wrapper for libvisual plugins that use OpenGL
- *
- * <refsect2>
- * <title>Examples</title>
- * |[
- * gst-launch-1.0 -v audiotestsrc ! libvisual_gl_lv_flower ! glimagesink
- * ]|
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-#include <gst/video/video.h>
-#include <gst/audio/audio.h>
-#include <gst/gl/gstglbuffer.h>
-#include <gst/gl/gstgldisplay.h>
-
-#include <libvisual/libvisual.h>
-
-#define GST_TYPE_VISUAL_GL (gst_visual_gl_get_type())
-#define GST_IS_VISUAL_GL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VISUAL_GL))
-#define GST_VISUAL_GL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VISUAL_GL,GstVisualGL))
-#define GST_IS_VISUAL_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VISUAL_GL))
-#define GST_VISUAL_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VISUAL_GL,GstVisualGLClass))
-#define GST_VISUAL_GL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VISUAL_GL, GstVisualGLClass))
-
-typedef struct _GstVisualGL GstVisualGL;
-typedef struct _GstVisualGLClass GstVisualGLClass;
-
-/* XXX use same category as libvisual plugin in -base? */
-GST_DEBUG_CATEGORY_STATIC (libvisual_debug);
-#define GST_CAT_DEFAULT (libvisual_debug)
-
-/* amounf of samples before we can feed libvisual */
-#define VISUAL_SAMPLES 512
-
-#define DEFAULT_WIDTH 320
-#define DEFAULT_HEIGHT 240
-#define DEFAULT_FPS_N 25
-#define DEFAULT_FPS_D 1
-
-struct _GstVisualGL
-{
- GstElement element;
-
- /* pads */
- GstPad *sinkpad;
- GstPad *srcpad;
- GstSegment segment;
-
- /* GL stuff */
- GstGLDisplay *display;
- GLuint fbo;
- GLuint depthbuffer;
- GLuint midtexture;
- GLdouble actor_projection_matrix[16];
- GLdouble actor_modelview_matrix[16];
- GLboolean is_enabled_gl_depth_test;
- GLint gl_depth_func;
- GLboolean is_enabled_gl_blend;
- GLint gl_blend_src_alpha;
-
- /* libvisual stuff */
- VisAudio *audio;
- VisVideo *video;
- VisActor *actor;
- int actor_setup_result;
-
- /* audio/video state */
- gint channels;
- gint rate; /* Input samplerate */
- gint bps;
- VisAudioSampleRateType libvisual_rate;
-
- /* framerate numerator & denominator */
- gint fps_n;
- gint fps_d;
- gint width;
- gint height;
- GstClockTime duration;
- guint outsize;
-
- /* samples per frame based on caps */
- guint spf;
-
- /* state stuff */
- GstAdapter *adapter;
- guint count;
-
- /* QoS stuff *//* with LOCK */
- gdouble proportion;
- GstClockTime earliest_time;
-};
-
-struct _GstVisualGLClass
-{
- GstElementClass parent_class;
-
- VisPluginRef *plugin;
-};
-
-GType gst_visual_gl_get_type (void);
-
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
- );
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "endianness = (int) BYTE_ORDER, "
- "signed = (boolean) TRUE, " "channels = (int) { 1, 2 }, "
- "rate = (int) { 8000, 11250, 22500, 32000, 44100, 48000, 96000 }")
- );
-
-
-static void gst_visual_gl_class_init (gpointer g_class, gpointer class_data);
-static void gst_visual_gl_init (GstVisualGL * visual);
-static void gst_visual_gl_dispose (GObject * object);
-
-static GstStateChangeReturn gst_visual_gl_change_state (GstElement * element,
- GstStateChange transition);
-static GstFlowReturn gst_visual_gl_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_visual_gl_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_visual_gl_src_event (GstPad * pad, GstEvent * event);
-
-static gboolean gst_visual_gl_src_query (GstPad * pad, GstQuery * query);
-
-static gboolean gst_visual_gl_sink_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_visual_gl_src_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_visual_gl_getcaps (GstPad * pad);
-static void libvisual_log_handler (const char *message, const char *funcname,
- void *priv);
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_visual_gl_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo info = {
- sizeof (GstVisualGLClass),
- NULL,
- NULL,
- gst_visual_gl_class_init,
- NULL,
- NULL,
- sizeof (GstVisualGL),
- 0,
- (GInstanceInitFunc) gst_visual_gl_init,
- };
-
- type = g_type_register_static (GST_TYPE_ELEMENT, "GstVisualGL", &info, 0);
- }
- return type;
-}
-
-static void
-libvisual_log_handler (const char *message, const char *funcname, void *priv)
-{
- GST_CAT_LEVEL_LOG (libvisual_debug, (GstDebugLevel) (priv), NULL, "%s - %s",
- funcname, message);
-}
-
-static void
-gst_visual_gl_class_init (gpointer g_class, gpointer class_data)
-{
- GstVisualGLClass *klass = GST_VISUAL_GL_CLASS (g_class);
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- GObjectClass *object = G_OBJECT_CLASS (g_class);
-
- klass->plugin = class_data;
-
- element_class->change_state = gst_visual_gl_change_state;
-
- if (class_data == NULL) {
- parent_class = g_type_class_peek_parent (g_class);
- } else {
- char *longname = g_strdup_printf ("libvisual %s plugin v.%s",
- klass->plugin->info->name, klass->plugin->info->version);
-
- /* FIXME: improve to only register what plugin supports? */
- gst_element_class_add_static_pad_template (element_class, &src_template);
- gst_element_class_add_static_pad_template (element_class, &sink_template);
-
- gst_element_class_set_metadata (element_class,
- longname, "Visualization", klass->plugin->info->about,
- "Benjamin Otte <otte@gnome.org>");
-
- g_free (longname);
- }
-
- object->dispose = gst_visual_gl_dispose;
-}
-
-static void
-gst_visual_gl_init (GstVisualGL * visual)
-{
- /* create the sink and src pads */
- visual->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
- gst_pad_set_setcaps_function (visual->sinkpad, gst_visual_gl_sink_setcaps);
- gst_pad_set_chain_function (visual->sinkpad, gst_visual_gl_chain);
- gst_pad_set_event_function (visual->sinkpad, gst_visual_gl_sink_event);
- gst_element_add_pad (GST_ELEMENT (visual), visual->sinkpad);
-
- visual->srcpad = gst_pad_new_from_static_template (&src_template, "src");
- gst_pad_set_setcaps_function (visual->srcpad, gst_visual_gl_src_setcaps);
- gst_pad_set_getcaps_function (visual->srcpad, gst_visual_gl_getcaps);
- gst_pad_set_event_function (visual->srcpad, gst_visual_gl_src_event);
- gst_pad_set_query_function (visual->srcpad, gst_visual_gl_src_query);
- gst_element_add_pad (GST_ELEMENT (visual), visual->srcpad);
-
- visual->adapter = gst_adapter_new ();
-
- visual->actor = NULL;
-
- visual->display = NULL;
- visual->fbo = 0;
- visual->depthbuffer = 0;
- visual->midtexture = 0;
-
- visual->is_enabled_gl_depth_test = GL_FALSE;
- visual->gl_depth_func = GL_LESS;
- visual->is_enabled_gl_blend = GL_FALSE;
- visual->gl_blend_src_alpha = GL_ONE;
-}
-
-static void
-gst_visual_gl_clear_actors (GstVisualGL * visual)
-{
- if (visual->actor) {
- visual_object_unref (VISUAL_OBJECT (visual->actor));
- visual->actor = NULL;
- }
- if (visual->video) {
- visual_object_unref (VISUAL_OBJECT (visual->video));
- visual->video = NULL;
- }
- if (visual->audio) {
- visual_object_unref (VISUAL_OBJECT (visual->audio));
- visual->audio = NULL;
- }
-}
-
-static void
-gst_visual_gl_dispose (GObject * object)
-{
- GstVisualGL *visual = GST_VISUAL_GL (object);
-
- if (visual->adapter) {
- gst_object_unref (visual->adapter);
- visual->adapter = NULL;
- }
-
- GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
-}
-
-static void
-gst_visual_gl_reset (GstVisualGL * visual)
-{
- gst_adapter_clear (visual->adapter);
- gst_segment_init (&visual->segment, GST_FORMAT_UNDEFINED);
-
- GST_OBJECT_LOCK (visual);
- visual->proportion = 1.0;
- visual->earliest_time = -1;
- GST_OBJECT_UNLOCK (visual);
-}
-
-static GstCaps *
-gst_visual_gl_getcaps (GstPad * pad)
-{
- GstCaps *ret;
- GstVisualGL *visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
- int depths;
-
- if (!visual->actor) {
- ret = gst_caps_copy (gst_pad_get_pad_template_caps (visual->srcpad));
- goto beach;
- }
-
- ret = gst_caps_new_empty ();
- depths = visual_actor_get_supported_depth (visual->actor);
- if (depths < 0) {
- /* FIXME: set an error */
- goto beach;
- }
- if ((depths & VISUAL_VIDEO_DEPTH_GL) == 0) {
- /* We don't handle non-GL plugins */
- goto beach;
- }
-
- GST_DEBUG_OBJECT (visual, "libvisual-gl plugin supports depths %u (0x%04x)",
- depths, depths);
- /* only do GL output */
- gst_caps_append (ret, gst_caps_from_string (GST_GL_VIDEO_CAPS));
-
-beach:
-
- GST_DEBUG_OBJECT (visual, "returning caps %" GST_PTR_FORMAT, ret);
- gst_object_unref (visual);
- return ret;
-}
-
-static gboolean
-gst_visual_gl_src_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstVisualGL *visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
- GstStructure *structure;
-
- structure = gst_caps_get_structure (caps, 0);
-
- GST_DEBUG_OBJECT (visual, "src pad got caps %" GST_PTR_FORMAT, caps);
-
- if (!gst_structure_get_int (structure, "width", &visual->width))
- goto error;
- if (!gst_structure_get_int (structure, "height", &visual->height))
- goto error;
- if (!gst_structure_get_fraction (structure, "framerate", &visual->fps_n,
- &visual->fps_d))
- goto error;
-
- /* precalc some values */
- visual->spf =
- gst_util_uint64_scale_int (visual->rate, visual->fps_d, visual->fps_n);
- visual->duration =
- gst_util_uint64_scale_int (GST_SECOND, visual->fps_d, visual->fps_n);
-
- gst_gl_display_gen_texture (visual->display, &visual->midtexture,
- visual->width, visual->height);
-
- gst_gl_display_gen_fbo (visual->display, visual->width, visual->height,
- &visual->fbo, &visual->depthbuffer);
-
- gst_object_unref (visual);
- return TRUE;
-
- /* ERRORS */
-error:
- {
- GST_DEBUG_OBJECT (visual, "error parsing caps");
- gst_object_unref (visual);
- return FALSE;
- }
-}
-
-static gboolean
-gst_visual_gl_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstVisualGL *visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
- GstStructure *structure;
-
- structure = gst_caps_get_structure (caps, 0);
-
- gst_structure_get_int (structure, "channels", &visual->channels);
- gst_structure_get_int (structure, "rate", &visual->rate);
-
- switch (visual->rate) {
- case 8000:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_8000;
- break;
- case 11250:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_11250;
- break;
- case 22500:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_22500;
- break;
- case 32000:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_32000;
- break;
- case 44100:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_44100;
- break;
- case 48000:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_48000;
- break;
- case 96000:
- visual->libvisual_rate = VISUAL_AUDIO_SAMPLE_RATE_96000;
- break;
- default:
- gst_object_unref (visual);
- return FALSE;
- }
-
- /* this is how many samples we need to fill one frame at the requested
- * framerate. */
- if (visual->fps_n != 0) {
- visual->spf =
- gst_util_uint64_scale_int (visual->rate, visual->fps_d, visual->fps_n);
- }
- visual->bps = visual->channels * sizeof (gint16);
-
- gst_object_unref (visual);
- return TRUE;
-}
-
-static gboolean
-gst_vis_gl_src_negotiate (GstVisualGL * visual)
-{
- GstCaps *othercaps, *target;
- GstStructure *structure;
- GstCaps *caps;
-
- caps = gst_pad_get_caps (visual->srcpad);
-
- /* see what the peer can do */
- othercaps = gst_pad_peer_get_caps (visual->srcpad);
- if (othercaps) {
- target = gst_caps_intersect (othercaps, caps);
- gst_caps_unref (othercaps);
- gst_caps_unref (caps);
-
- if (gst_caps_is_empty (target))
- goto no_format;
-
- gst_caps_truncate (target);
- } else {
- /* need a copy, we'll be modifying it when fixating */
- target = gst_caps_copy (caps);
- gst_caps_unref (caps);
- }
-
- /* fixate in case something is not fixed. This does nothing if the value is
- * already fixed. For video we always try to fixate to something like
- * 320x240x25 by convention. */
- structure = gst_caps_get_structure (target, 0);
- gst_structure_fixate_field_nearest_int (structure, "width", DEFAULT_WIDTH);
- gst_structure_fixate_field_nearest_int (structure, "height", DEFAULT_HEIGHT);
- gst_structure_fixate_field_nearest_fraction (structure, "framerate",
- DEFAULT_FPS_N, DEFAULT_FPS_D);
-
- gst_pad_set_caps (visual->srcpad, target);
- gst_caps_unref (target);
-
- return TRUE;
-
- /* ERRORS */
-no_format:
- {
- GST_ELEMENT_ERROR (visual, STREAM, FORMAT, (NULL),
- ("could not negotiate output format"));
- gst_caps_unref (target);
- return FALSE;
- }
-}
-
-static gboolean
-gst_visual_gl_sink_event (GstPad * pad, GstEvent * event)
-{
- GstVisualGL *visual;
- gboolean res;
-
- visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_FLUSH_START:
- res = gst_pad_push_event (visual->srcpad, event);
- break;
- case GST_EVENT_FLUSH_STOP:
- /* reset QoS and adapter. */
- gst_visual_gl_reset (visual);
- res = gst_pad_push_event (visual->srcpad, event);
- break;
- case GST_EVENT_NEWSEGMENT:
- {
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
- gboolean update;
-
- /* the newsegment values are used to clip the input samples
- * and to convert the incomming timestamps to running time so
- * we can do QoS */
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
-
- /* now configure the values */
- gst_segment_set_newsegment_full (&visual->segment, update,
- rate, arate, format, start, stop, time);
-
- /* and forward */
- res = gst_pad_push_event (visual->srcpad, event);
- break;
- }
- default:
- res = gst_pad_push_event (visual->srcpad, event);
- break;
- }
-
- gst_object_unref (visual);
- return res;
-}
-
-static gboolean
-gst_visual_gl_src_event (GstPad * pad, GstEvent * event)
-{
- GstVisualGL *visual;
- gboolean res;
-
- visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_QOS:
- {
- gdouble proportion;
- GstClockTimeDiff diff;
- GstClockTime timestamp;
-
- gst_event_parse_qos (event, &proportion, &diff, &timestamp);
-
- /* save stuff for the _chain function */
- GST_OBJECT_LOCK (visual);
- visual->proportion = proportion;
- if (diff >= 0)
- /* we're late, this is a good estimate for next displayable
- * frame (see part-qos.txt) */
- visual->earliest_time = timestamp + 2 * diff + visual->duration;
- else
- visual->earliest_time = timestamp + diff;
-
- GST_OBJECT_UNLOCK (visual);
-
- res = gst_pad_push_event (visual->sinkpad, event);
- break;
- }
- default:
- res = gst_pad_push_event (visual->sinkpad, event);
- break;
- }
-
- gst_object_unref (visual);
- return res;
-}
-
-static gboolean
-gst_visual_gl_src_query (GstPad * pad, GstQuery * query)
-{
- gboolean res;
- GstVisualGL *visual;
-
- visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_LATENCY:
- {
- /* We need to send the query upstream and add the returned latency to our
- * own */
- GstClockTime min_latency, max_latency;
- gboolean us_live;
- GstClockTime our_latency;
- guint max_samples;
-
- if ((res = gst_pad_peer_query (visual->sinkpad, query))) {
- gst_query_parse_latency (query, &us_live, &min_latency, &max_latency);
-
- GST_DEBUG_OBJECT (visual, "Peer latency: min %"
- GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
- GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
- /* the max samples we must buffer buffer */
- max_samples = MAX (VISUAL_SAMPLES, visual->spf);
- our_latency =
- gst_util_uint64_scale_int (max_samples, GST_SECOND, visual->rate);
-
- GST_DEBUG_OBJECT (visual, "Our latency: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (our_latency));
-
- /* we add some latency but only if we need to buffer more than what
- * upstream gives us */
- min_latency += our_latency;
- if (max_latency != -1)
- max_latency += our_latency;
-
- GST_DEBUG_OBJECT (visual, "Calculated total latency : min %"
- GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
- GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
- gst_query_set_latency (query, TRUE, min_latency, max_latency);
- }
- break;
- }
- case GST_QUERY_CUSTOM:
- {
- GstStructure *structure = gst_query_get_structure (query);
- gchar *name = gst_element_get_name (visual);
-
- res = g_strcmp0 (name, gst_structure_get_name (structure)) == 0;
- g_free (name);
-
- if (!res)
- res = gst_pad_query_default (pad, query);
- break;
- }
- default:
- res = gst_pad_peer_query (visual->sinkpad, query);
- break;
- }
-
- gst_object_unref (visual);
-
- return res;
-}
-
-/* allocate and output buffer, if no format was negotiated, this
- * function will negotiate one. After calling this function, a
- * reverse negotiation could have happened. */
-static GstFlowReturn
-get_buffer (GstVisualGL * visual, GstGLBuffer ** outbuf)
-{
- /* we don't know an output format yet, pick one */
- if (GST_PAD_CAPS (visual->srcpad) == NULL) {
- if (!gst_vis_gl_src_negotiate (visual))
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- GST_DEBUG_OBJECT (visual, "allocating output buffer with caps %"
- GST_PTR_FORMAT, GST_PAD_CAPS (visual->srcpad));
-
- *outbuf = gst_gl_buffer_new (visual->display, visual->width, visual->height);
- if (*outbuf == NULL)
- return GST_FLOW_ERROR;
-
- gst_buffer_set_caps (GST_BUFFER (*outbuf), GST_PAD_CAPS (visual->srcpad));
- return GST_FLOW_OK;
-}
-
-static void
-actor_setup (GstGLDisplay * display, GstVisualGL * visual)
-{
- /* save and clear top of the stack */
- glPushAttrib (GL_ALL_ATTRIB_BITS);
-
- glMatrixMode (GL_PROJECTION);
- glPushMatrix ();
- glLoadIdentity ();
-
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix ();
- glLoadIdentity ();
-
- visual->actor_setup_result = visual_actor_realize (visual->actor);
- if (visual->actor_setup_result == 0) {
- /* store the actor's matrices for rendering the first frame */
- glGetDoublev (GL_MODELVIEW_MATRIX, visual->actor_modelview_matrix);
- glGetDoublev (GL_PROJECTION_MATRIX, visual->actor_projection_matrix);
-
- visual->is_enabled_gl_depth_test = glIsEnabled (GL_DEPTH_TEST);
- glGetIntegerv (GL_DEPTH_FUNC, &visual->gl_depth_func);
-
- visual->is_enabled_gl_blend = glIsEnabled (GL_BLEND);
- glGetIntegerv (GL_BLEND_SRC_ALPHA, &visual->gl_blend_src_alpha);
-
- /* retore matrix */
- glMatrixMode (GL_PROJECTION);
- glPopMatrix ();
-
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix ();
-
- glPopAttrib ();
- }
-}
-
-static void
-actor_negotiate (GstGLDisplay * display, GstVisualGL * visual)
-{
- gint err = VISUAL_OK;
-
- err = visual_video_set_depth (visual->video, VISUAL_VIDEO_DEPTH_GL);
- if (err != VISUAL_OK)
- g_warning ("failed to visual_video_set_depth\n");
-
- err =
- visual_video_set_dimension (visual->video, visual->width, visual->height);
- if (err != VISUAL_OK)
- g_warning ("failed to visual_video_set_dimension\n");
-
- err = visual_actor_video_negotiate (visual->actor, 0, FALSE, FALSE);
- if (err != VISUAL_OK)
- g_warning ("failed to visual_actor_video_negotiate\n");
-}
-
-static void
-check_gl_matrix (void)
-{
- GLdouble projection_matrix[16];
- GLdouble modelview_matrix[16];
- gint i = 0;
- gint j = 0;
-
- glGetDoublev (GL_PROJECTION_MATRIX, projection_matrix);
- glGetDoublev (GL_MODELVIEW_MATRIX, modelview_matrix);
-
- for (j = 0; j < 4; ++j) {
- for (i = 0; i < 4; ++i) {
- if (projection_matrix[i + 4 * j] != projection_matrix[i + 4 * j])
- g_warning ("invalid projection matrix at coordiante %dx%d: %f\n", i, j,
- projection_matrix[i + 4 * j]);
- if (modelview_matrix[i + 4 * j] != modelview_matrix[i + 4 * j])
- g_warning ("invalid modelview_matrix matrix at coordiante %dx%d: %f\n",
- i, j, modelview_matrix[i + 4 * j]);
- }
- }
-}
-
-static void
-render_frame (GstVisualGL * visual)
-{
- const guint16 *data;
- VisBuffer *lbuf, *rbuf;
- guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES];
- guint i;
- gcahr *name;
-
- /* Read VISUAL_SAMPLES samples per channel */
- data =
- (const guint16 *) gst_adapter_peek (visual->adapter,
- VISUAL_SAMPLES * visual->bps);
-
- lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL);
- rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL);
-
- if (visual->channels == 2) {
- for (i = 0; i < VISUAL_SAMPLES; i++) {
- ldata[i] = *data++;
- rdata[i] = *data++;
- }
- } else {
- for (i = 0; i < VISUAL_SAMPLES; i++) {
- ldata[i] = *data;
- rdata[i] = *data++;
- }
- }
-
- visual_audio_samplepool_input_channel (visual->audio->samplepool,
- lbuf, visual->libvisual_rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
- VISUAL_AUDIO_CHANNEL_LEFT);
- visual_audio_samplepool_input_channel (visual->audio->samplepool,
- rbuf, visual->libvisual_rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
- VISUAL_AUDIO_CHANNEL_RIGHT);
-
- visual_object_unref (VISUAL_OBJECT (lbuf));
- visual_object_unref (VISUAL_OBJECT (rbuf));
-
- visual_audio_analyze (visual->audio);
-
- /* apply the matrices that the actor set up */
- glPushAttrib (GL_ALL_ATTRIB_BITS);
-
- glMatrixMode (GL_PROJECTION);
- glPushMatrix ();
- glLoadMatrixd (visual->actor_projection_matrix);
-
- glMatrixMode (GL_MODELVIEW);
- glPushMatrix ();
- glLoadMatrixd (visual->actor_modelview_matrix);
-
- /* This line try to hacks compatiblity with libprojectM
- * If libprojectM version <= 2.0.0 then we have to unbind our current
- * fbo to see something. But it's incorrect and we cannot use fbo chainning (append other glfilters
- * after libvisual_gl_projectM will not work)
- * To have full compatibility, libprojectM needs to take care of our fbo.
- * Indeed libprojectM has to unbind it before the first rendering pass
- * and then rebind it before the final pass. It's done from 2.0.1
- */
- name = gst_element_get_name (GST_ELEMENT (visual));
- if (g_ascii_strncasecmp (name, "visualglprojectm", 16) == 0
- && !HAVE_PROJECTM_TAKING_CARE_OF_EXTERNAL_FBO)
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
- g_free (name);
-
- actor_negotiate (visual->display, visual);
-
- if (visual->is_enabled_gl_depth_test) {
- glEnable (GL_DEPTH_TEST);
- glDepthFunc (visual->gl_depth_func);
- }
-
- if (visual->is_enabled_gl_blend) {
- glEnable (GL_BLEND);
- glBlendFunc (visual->gl_blend_src_alpha, GL_ZERO);
- }
-
- visual_actor_run (visual->actor, visual->audio);
-
- check_gl_matrix ();
-
- glMatrixMode (GL_PROJECTION);
- glPopMatrix ();
-
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix ();
-
- glPopAttrib ();
-
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_BLEND);
-
- /*glDisable (GL_LIGHT0);
- glDisable (GL_LIGHTING);
- glDisable (GL_POLYGON_OFFSET_FILL);
- glDisable (GL_COLOR_MATERIAL);
- glDisable (GL_CULL_FACE); */
-
- GST_DEBUG_OBJECT (visual, "rendered one frame");
-}
-
-static void
-bottom_up_to_top_down (gint width, gint height, guint texture,
- GstVisualGL * visual)
-{
-
- glEnable (GL_TEXTURE_2D);
- glBindTexture (GL_TEXTURE_2D, texture);
-
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
-
- glBegin (GL_QUADS);
- glTexCoord2i (0, 0);
- glVertex2i (-1, 1);
- glTexCoord2i (width, 0);
- glVertex2i (1, 1);
- glTexCoord2i (width, height);
- glVertex2i (1, -1);
- glTexCoord2i (0, height);
- glVertex2i (-1, -1);
- glEnd ();
-
- glBindTexture (GL_TEXTURE_2D, 0);
- glDisable (GL_TEXTURE_2D);
-
- GST_DEBUG_OBJECT (visual, "bottom up to top down");
-}
-
-static GstFlowReturn
-gst_visual_gl_chain (GstPad * pad, GstBuffer * buffer)
-{
- GstGLBuffer *outbuf = NULL;
- GstVisualGL *visual = GST_VISUAL_GL (gst_pad_get_parent (pad));
- GstFlowReturn ret = GST_FLOW_OK;
- guint avail;
-
- GST_DEBUG_OBJECT (visual, "chain function called");
-
- /* If we don't have an output format yet, preallocate a buffer to try and
- * set one */
- if (GST_PAD_CAPS (visual->srcpad) == NULL) {
- ret = get_buffer (visual, &outbuf);
- if (ret != GST_FLOW_OK) {
- gst_buffer_unref (buffer);
- goto beach;
- }
- }
-
- /* resync on DISCONT */
- if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
- gst_adapter_clear (visual->adapter);
- }
-
- GST_DEBUG_OBJECT (visual,
- "Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
- GST_BUFFER_SIZE (buffer) / visual->bps, GST_BUFFER_TIMESTAMP (buffer));
-
- gst_adapter_push (visual->adapter, buffer);
-
- while (TRUE) {
- gboolean need_skip;
- guint64 dist, timestamp;
-
- GST_DEBUG_OBJECT (visual, "processing buffer");
-
- avail = gst_adapter_available (visual->adapter);
- GST_DEBUG_OBJECT (visual, "avail now %u", avail);
-
- /* we need at least VISUAL_SAMPLES samples */
- if (avail < VISUAL_SAMPLES * visual->bps)
- break;
-
- /* we need at least enough samples to make one frame */
- if (avail < visual->spf * visual->bps)
- break;
-
- /* get timestamp of the current adapter byte */
- timestamp = gst_adapter_prev_timestamp (visual->adapter, &dist);
- if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
- /* convert bytes to time */
- dist /= visual->bps;
- timestamp += gst_util_uint64_scale_int (dist, GST_SECOND, visual->rate);
- }
-
- if (timestamp != -1) {
- gint64 qostime;
-
- /* QoS is done on running time */
- qostime = gst_segment_to_running_time (&visual->segment, GST_FORMAT_TIME,
- timestamp);
- qostime += visual->duration;
-
- GST_OBJECT_LOCK (visual);
- /* check for QoS, don't compute buffers that are known to be late */
- need_skip = visual->earliest_time != -1 &&
- qostime <= visual->earliest_time;
- GST_OBJECT_UNLOCK (visual);
-
- if (need_skip) {
- GST_WARNING_OBJECT (visual,
- "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (qostime), GST_TIME_ARGS (visual->earliest_time));
- goto skip;
- }
- }
-
- /* alloc a buffer if we don't have one yet, this happens
- * when we pushed a buffer in this while loop before */
- if (outbuf == NULL) {
- ret = get_buffer (visual, &outbuf);
- if (ret != GST_FLOW_OK) {
- goto beach;
- }
- }
-
- /* render libvisual plugin to our target */
- gst_gl_display_use_fbo_v2 (visual->display,
- visual->width, visual->height, visual->fbo, visual->depthbuffer,
- visual->midtexture, (GLCB_V2) render_frame, (gpointer *) visual);
-
- /* gst video is top-down whereas opengl plan is bottom up */
- gst_gl_display_use_fbo (visual->display,
- visual->width, visual->height, visual->fbo, visual->depthbuffer,
- outbuf->texture, (GLCB) bottom_up_to_top_down,
- visual->width, visual->height, visual->midtexture,
- 0, visual->width, 0, visual->height, GST_GL_DISPLAY_PROJECTION_ORTHO2D,
- (gpointer *) visual);
-
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- GST_BUFFER_DURATION (outbuf) = visual->duration;
-
- ret = gst_pad_push (visual->srcpad, GST_BUFFER (outbuf));
- outbuf = NULL;
-
- skip:
- GST_DEBUG_OBJECT (visual, "finished frame, flushing %u samples from input",
- visual->spf);
-
- /* Flush out the number of samples per frame */
- gst_adapter_flush (visual->adapter, visual->spf * visual->bps);
-
- /* quit the loop if something was wrong */
- if (ret != GST_FLOW_OK)
- break;
- }
-
-beach:
-
- if (outbuf != NULL)
- gst_gl_buffer_unref (outbuf);
-
- gst_object_unref (visual);
-
- return ret;
-}
-
-static GstStateChangeReturn
-gst_visual_gl_change_state (GstElement * element, GstStateChange transition)
-{
- GstVisualGL *visual = GST_VISUAL_GL (element);
- GstStateChangeReturn ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- {
- GstElement *parent = GST_ELEMENT (gst_element_get_parent (visual));
- GstStructure *structure = NULL;
- GstQuery *query = NULL;
- gboolean isPerformed = FALSE;
- gchar *name;
-
- if (!parent) {
- GST_ELEMENT_ERROR (visual, CORE, STATE_CHANGE, (NULL),
- ("A parent bin is required"));
- return FALSE;
- }
-
- name = gst_element_get_name (visual);
- structure = gst_structure_new (name, NULL);
- query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
- g_free (name);
-
- isPerformed = gst_element_query (parent, query);
-
- if (isPerformed) {
- const GValue *id_value =
- gst_structure_get_value (structure, "gstgldisplay");
- if (G_VALUE_HOLDS_POINTER (id_value))
- /* at least one gl element is after in our gl chain */
- visual->display =
- gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
- else {
- /* this gl filter is a sink in terms of the gl chain */
- visual->display = gst_gl_display_new ();
- gst_gl_display_create_context (visual->display, 0);
- //TODO visual->external_gl_context);
- }
-
- gst_visual_gl_reset (visual);
-
- visual->actor =
- visual_actor_new (GST_VISUAL_GL_GET_CLASS (visual)->plugin->info->
- plugname);
- visual->video = visual_video_new ();
- visual->audio = visual_audio_new ();
-
- if (!visual->actor || !visual->video)
- goto actor_setup_failed;
-
- gst_gl_display_thread_add (visual->display,
- (GstGLDisplayThreadFunc) actor_setup, visual);
-
- if (visual->actor_setup_result != 0)
- goto actor_setup_failed;
- else
- visual_actor_set_video (visual->actor, visual->video);
- }
-
- gst_query_unref (query);
- gst_object_unref (GST_OBJECT (parent));
-
- if (!isPerformed)
- 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);
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- {
- if (visual->fbo) {
- gst_gl_display_del_fbo (visual->display, visual->fbo,
- visual->depthbuffer);
- visual->fbo = 0;
- visual->depthbuffer = 0;
- }
- if (visual->midtexture) {
- gst_gl_display_del_texture (visual->display, visual->midtexture,
- visual->width, visual->height);
- visual->midtexture = 0;
- }
- if (visual->display) {
- gst_object_unref (visual->display);
- visual->display = NULL;
- }
-
- gst_visual_gl_clear_actors (visual);
- }
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
-
- return ret;
-
- /* ERRORS */
-actor_setup_failed:
- {
- GST_ELEMENT_ERROR (visual, LIBRARY, INIT, (NULL),
- ("could not set up actor"));
- gst_visual_gl_clear_actors (visual);
- return GST_STATE_CHANGE_FAILURE;
- }
-}
-
-static void
-make_valid_name (char *name)
-{
- /*
- * Replace invalid chars with _ in the type name
- */
- static const gchar extra_chars[] = "-_+";
- gchar *p = name;
-
- for (; *p; p++) {
- int valid = ((p[0] >= 'A' && p[0] <= 'Z') ||
- (p[0] >= 'a' && p[0] <= 'z') ||
- (p[0] >= '0' && p[0] <= '9') || strchr (extra_chars, p[0]));
- if (!valid)
- *p = '_';
- }
-}
-
-static gboolean
-gst_visual_gl_actor_plugin_is_gl (VisObject * plugin, const gchar * name)
-{
- gboolean is_gl;
- gint depth;
-
- depth = VISUAL_ACTOR_PLUGIN (plugin)->vidoptions.depth;
- is_gl = (depth & VISUAL_VIDEO_DEPTH_GL) != 0;
-
- if (!is_gl) {
- GST_DEBUG ("plugin %s is not a GL plugin (%d), ignoring", name, depth);
- } else {
- GST_DEBUG ("plugin %s is a GL plugin (%d), registering", name, depth);
- }
-
- return is_gl;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- guint i, count;
- VisList *list;
-
- GST_DEBUG_CATEGORY_INIT (libvisual_debug, "libvisual", 0,
- "libvisual audio visualisations");
-
-#ifdef LIBVISUAL_PLUGINSBASEDIR
- gst_plugin_add_dependency_simple (plugin, "HOME/.libvisual/actor",
- LIBVISUAL_PLUGINSBASEDIR "/actor", NULL, GST_PLUGIN_DEPENDENCY_FLAG_NONE);
-#endif
-
- visual_log_set_verboseness (VISUAL_LOG_VERBOSENESS_LOW);
- visual_log_set_info_handler (libvisual_log_handler, (void *) GST_LEVEL_INFO);
- visual_log_set_warning_handler (libvisual_log_handler,
- (void *) GST_LEVEL_WARNING);
- visual_log_set_critical_handler (libvisual_log_handler,
- (void *) GST_LEVEL_ERROR);
- visual_log_set_error_handler (libvisual_log_handler,
- (void *) GST_LEVEL_ERROR);
-
- if (!visual_is_initialized ())
- if (visual_init (NULL, NULL) != 0)
- return FALSE;
-
- list = visual_actor_get_list ();
-
- count = visual_collection_size (VISUAL_COLLECTION (list));
-
- for (i = 0; i < count; i++) {
- VisPluginRef *ref = visual_list_get (list, i);
- VisPluginData *visplugin = NULL;
- gboolean skip = FALSE;
- GType type;
- gchar *name;
- GTypeInfo info = {
- sizeof (GstVisualGLClass),
- NULL,
- NULL,
- gst_visual_gl_class_init,
- NULL,
- ref,
- sizeof (GstVisualGL),
- 0,
- NULL
- };
-
- visplugin = visual_plugin_load (ref);
-
- if (ref->info->plugname == NULL)
- continue;
-
- /* Blacklist some plugins */
- if (strcmp (ref->info->plugname, "gstreamer") == 0 ||
- strcmp (ref->info->plugname, "gdkpixbuf") == 0) {
- skip = TRUE;
- } else {
- /* only register plugins that support GL */
- skip = !(gst_visual_gl_actor_plugin_is_gl (visplugin->info->plugin,
- visplugin->info->plugname));
- }
-
- visual_plugin_unload (visplugin);
-
- if (!skip) {
- name = g_strdup_printf ("GstVisualGL%s", ref->info->plugname);
- make_valid_name (name);
- type = g_type_register_static (GST_TYPE_VISUAL_GL, name, &info, 0);
- g_free (name);
-
- name = g_strdup_printf ("libvisual_gl_%s", ref->info->plugname);
- make_valid_name (name);
- if (!gst_element_register (plugin, name, GST_RANK_NONE, type)) {
- g_free (name);
- return FALSE;
- }
- g_free (name);
- }
- }
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "libvisual-gl",
- "libvisual-gl visualization plugins",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/meson.build b/ext/meson.build
index 62af78950..0eba7b49a 100644
--- a/ext/meson.build
+++ b/ext/meson.build
@@ -1,4 +1,3 @@
-#subdir('apexsink')
subdir('assrender')
#subdir('bs2b')
subdir('bz2')
@@ -25,13 +24,11 @@ subdir('kate')
#subdir('ladspa')
subdir('libde265')
subdir('libmms')
-#subdir('libvisual')
#subdir('lv2')
#subdir('modplug')
#subdir('mpeg2enc')
#subdir('mplex')
#subdir('musepack')
-#subdir('nas')
#subdir('neon')
#subdir('ofa')
#subdir('openal')
@@ -41,16 +38,13 @@ subdir('openh264')
subdir('openjpeg')
#subdir('openni2')
subdir('opus')
-#subdir('qt')
subdir('resindvd')
subdir('rsvg')
subdir('rtmp')
subdir('sbc')
subdir('schroedinger')
-#subdir('sdl')
subdir('smoothstreaming')
#subdir('sndfile')
-#subdir('sndio')
if cc.get_id() != 'msvc'
# soundtouch doesn't do exporting of symbols for DLLs and I'm not sure how to
# do that for C++ classes. -- Nirbheek
@@ -62,7 +56,7 @@ endif
#subdir('spc')
subdir('srtp')
#subdir('teletextdec')
-#subdir('timidity')
+#subdir('wildmidi')
subdir('ttml')
subdir('voaacenc')
#subdir('voamrwbenc')
@@ -71,5 +65,4 @@ subdir('wayland')
#subdir('webrtcdsp')
subdir('webp')
subdir('x265')
-#subdir('xvid')
subdir('zbar')
diff --git a/ext/nas/Makefile.am b/ext/nas/Makefile.am
deleted file mode 100644
index ef1162abc..000000000
--- a/ext/nas/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-plugin_LTLIBRARIES = libgstnassink.la
-
-libgstnassink_la_SOURCES = nassink.c
-libgstnassink_la_CFLAGS = \
- $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(NAS_CFLAGS)
-libgstnassink_la_LIBADD = \
- $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) $(NAS_LIBS)
-libgstnassink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstnassink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = nassink.h
diff --git a/ext/nas/nassink.c b/ext/nas/nassink.c
deleted file mode 100644
index 2d6404b8b..000000000
--- a/ext/nas/nassink.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/* GStreamer
- * Copyright (C) <2003> Laurent Vivier <Laurent.Vivier@bull.net>
- * Copyright (C) <2004> Arwed v. Merkatz <v.merkatz@gmx.net>
- *
- * Based on esdsink.c:
- * Copyright (C) <2001> Richard Boulton <richard-gst@tartarus.org>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <string.h>
-#include <audio/audiolib.h>
-#include <audio/soundlib.h>
-#include "nassink.h"
-
-#define NAS_SOUND_PORT_DURATION (2)
-
-GST_DEBUG_CATEGORY_STATIC (nas_debug);
-#define GST_CAT_DEFAULT nas_debug
-
-enum
-{
- ARG_0,
- ARG_MUTE,
- ARG_HOST
-};
-
-#define DEFAULT_MUTE FALSE
-#define DEFAULT_HOST NULL
-
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) BYTE_ORDER, "
- "signed = (boolean) TRUE, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "rate = (int) [ 1000, 96000 ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/x-raw-int, "
- "signed = (boolean) FALSE, "
- "width = (int) 8, "
- "depth = (int) 8, "
- "rate = (int) [ 1000, 96000 ], " "channels = (int) [ 1, 2 ]")
- );
-
-static void gst_nas_sink_finalize (GObject * object);
-
-static gboolean gst_nas_sink_open (GstAudioSink * sink);
-static gboolean gst_nas_sink_close (GstAudioSink * sink);
-static gboolean gst_nas_sink_prepare (GstAudioSink * sink,
- GstRingBufferSpec * spec);
-static gboolean gst_nas_sink_unprepare (GstAudioSink * sink);
-static guint gst_nas_sink_write (GstAudioSink * asink, gpointer data,
- guint length);
-static guint gst_nas_sink_delay (GstAudioSink * asink);
-static void gst_nas_sink_reset (GstAudioSink * asink);
-static GstCaps *gst_nas_sink_getcaps (GstBaseSink * pad);
-
-static void gst_nas_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_nas_sink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static void NAS_flush (GstNasSink * sink);
-static void NAS_sendData (GstNasSink * sink, AuUint32 numBytes);
-static AuBool NAS_EventHandler (AuServer * aud, AuEvent * ev,
- AuEventHandlerRec * handler);
-static AuDeviceID NAS_getDevice (AuServer * aud, int numTracks);
-
-GST_BOILERPLATE (GstNasSink, gst_nas_sink, GstAudioSink, GST_TYPE_AUDIO_SINK);
-
-static void
-gst_nas_sink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_static_pad_template (element_class, &sink_factory);
- gst_element_class_set_static_metadata (element_class, "NAS audio sink",
- "Sink/Audio",
- "Plays audio to a Network Audio Server",
- "Laurent Vivier <Laurent.Vivier@bull.net>, "
- "Arwed v. Merkatz <v.merkatz@gmx.net>");
-}
-
-static void
-gst_nas_sink_class_init (GstNasSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSinkClass *gstbasesink_class;
- GstAudioSinkClass *gstaudiosink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- gstaudiosink_class = (GstAudioSinkClass *) klass;
-
- gobject_class->set_property = gst_nas_sink_set_property;
- gobject_class->get_property = gst_nas_sink_get_property;
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_nas_sink_finalize);
-
- g_object_class_install_property (gobject_class, ARG_MUTE,
- g_param_spec_boolean ("mute", "mute", "Whether to mute playback",
- DEFAULT_MUTE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (gobject_class, ARG_HOST,
- g_param_spec_string ("host", "host",
- "host running the NAS daemon (name of X/Terminal, default is "
- "$AUDIOSERVER or $DISPLAY)", DEFAULT_HOST,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_nas_sink_getcaps);
-
- gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_nas_sink_open);
- gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_nas_sink_close);
- gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_nas_sink_prepare);
- gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_nas_sink_unprepare);
- gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_nas_sink_write);
- gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_nas_sink_delay);
- gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_nas_sink_reset);
-}
-
-static void
-gst_nas_sink_init (GstNasSink * nassink, GstNasSinkClass * klass)
-{
- /* properties will automatically be set to their default values */
- nassink->audio = NULL;
- nassink->flow = AuNone;
- nassink->need_data = 0;
-}
-
-static void
-gst_nas_sink_finalize (GObject * object)
-{
- GstNasSink *nassink = GST_NAS_SINK (object);
-
- g_free (nassink->host);
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static GstCaps *
-gst_nas_sink_getcaps (GstBaseSink * bsink)
-{
- GstNasSink *nassink = GST_NAS_SINK (bsink);
- const GstCaps *templatecaps;
- AuServer *server;
- GstCaps *fixated, *caps;
- int i;
-
- server = nassink->audio;
-
- templatecaps = gst_static_pad_template_get_caps (&sink_factory);
-
- if (server == NULL)
- return gst_caps_copy (templatecaps);
-
- fixated = gst_caps_copy (templatecaps);
- for (i = 0; i < gst_caps_get_size (fixated); i++) {
- GstStructure *structure;
- gint min, max;
-
- min = AuServerMinSampleRate (server);
- max = AuServerMaxSampleRate (server);
-
- structure = gst_caps_get_structure (fixated, i);
-
- if (min == max)
- gst_structure_set (structure, "rate", G_TYPE_INT, max, NULL);
- else
- gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min, max, NULL);
- }
-
- caps = gst_caps_intersect (fixated, templatecaps);
- gst_caps_unref (fixated);
-
- if (nassink->audio == NULL)
- AuCloseServer (server);
-
- return caps;
-}
-
-static gint
-gst_nas_sink_sink_get_format (const GstRingBufferSpec * spec)
-{
- gint result;
-
- switch (spec->format) {
- case GST_U8:
- result = AuFormatLinearUnsigned8;
- break;
- case GST_S8:
- result = AuFormatLinearSigned8;
- break;
- case GST_S16_LE:
- result = AuFormatLinearSigned16LSB;
- break;
- case GST_S16_BE:
- result = AuFormatLinearSigned16MSB;
- break;
- case GST_U16_LE:
- result = AuFormatLinearUnsigned16LSB;
- break;
- case GST_U16_BE:
- result = AuFormatLinearUnsigned16MSB;
- break;
- default:
- result = 0;
- break;
- }
- return result;
-}
-
-static gboolean
-gst_nas_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
-{
- GstNasSink *sink = GST_NAS_SINK (asink);
- AuElement elements[2];
- AuUint32 buf_samples;
- unsigned char format;
-
- format = gst_nas_sink_sink_get_format (spec);
- if (format == 0) {
- GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
- ("Unable to get format %d", spec->format));
- return FALSE;
- }
- GST_DEBUG_OBJECT (sink, "Format: %d %d\n", spec->format, format);
-
- sink->flow = AuGetScratchFlow (sink->audio, NULL);
- if (sink->flow == 0) {
- GST_DEBUG_OBJECT (sink, "couldn't get flow");
- return FALSE;
- }
-
- buf_samples = spec->rate * NAS_SOUND_PORT_DURATION;
- /*
- spec->segsize = gst_util_uint64_scale (buf_samples * spec->bytes_per_sample,
- spec->latency_time, GST_SECOND / GST_USECOND);
- spec->segsize -= spec->segsize % spec->bytes_per_sample;
- spec->segtotal = spec->buffer_time / spec->latency_time;
- */
- spec->segsize = buf_samples * spec->bytes_per_sample;
- spec->segtotal = 1;
-
- memset (spec->silence_sample, 0, spec->bytes_per_sample);
- GST_DEBUG_OBJECT (sink, "Bytes per sample %d", spec->bytes_per_sample);
-
- GST_DEBUG_OBJECT (sink, "Rate %d Format %d tracks %d bufs %d %d/%d w %d",
- spec->rate, format, spec->channels, (gint) buf_samples, spec->segsize,
- spec->segtotal, spec->width);
- AuMakeElementImportClient (&elements[0], /* element */
- spec->rate, /* rate */
- format, /* format */
- spec->channels, /* number of tracks */
- AuTrue, /* discart */
- buf_samples, /* max samples */
- (AuUint32) (buf_samples / 100 * AuSoundPortLowWaterMark),
- /* low water mark */
- 0, /* num actions */
- NULL);
-
- sink->device = NAS_getDevice (sink->audio, spec->channels);
- if (sink->device == AuNone) {
- GST_DEBUG_OBJECT (sink, "no device with %i tracks found", spec->channels);
- return FALSE;
- }
-
- AuMakeElementExportDevice (&elements[1], /* element */
- 0, /* input */
- sink->device, /* device */
- spec->rate, /* rate */
- AuUnlimitedSamples, /* num samples */
- 0, /* num actions */
- NULL); /* actions */
-
- AuSetElements (sink->audio, /* server */
- sink->flow, /* flow ID */
- AuTrue, /* clocked */
- 2, /* num elements */
- elements, /* elements */
- NULL);
-
- AuRegisterEventHandler (sink->audio, /* server */
- AuEventHandlerIDMask, /* value mask */
- 0, /* type */
- sink->flow, /* flow ID */
- NAS_EventHandler, /* callback */
- (AuPointer) sink); /* data */
-
- AuStartFlow (sink->audio, sink->flow, NULL);
-
- return TRUE;
-}
-
-static gboolean
-gst_nas_sink_unprepare (GstAudioSink * asink)
-{
- GstNasSink *sink = GST_NAS_SINK (asink);
-
- if (sink->flow != AuNone) {
- AuBool clocked;
- int num_elements;
- AuStatus status;
- AuElement *oldelems;
-
- GST_DEBUG_OBJECT (sink, "flushing buffer");
- NAS_flush (sink);
-
- oldelems =
- AuGetElements (sink->audio, sink->flow, &clocked, &num_elements,
- &status);
- if (num_elements > 0) {
- GST_DEBUG_OBJECT (sink, "GetElements status: %i", status);
- if (oldelems)
- AuFreeElements (sink->audio, num_elements, oldelems);
- }
-
- AuStopFlow (sink->audio, sink->flow, NULL);
- AuReleaseScratchFlow (sink->audio, sink->flow, NULL);
- sink->flow = AuNone;
- }
- sink->need_data = 0;
-
- return TRUE;
-}
-
-static guint
-gst_nas_sink_delay (GstAudioSink * asink)
-{
- GST_DEBUG_OBJECT (asink, "nas_sink_delay");
- return 0;
-}
-
-static void
-gst_nas_sink_reset (GstAudioSink * asink)
-{
- GstNasSink *sink = GST_NAS_SINK (asink);
-
- GST_DEBUG_OBJECT (sink, "reset");
-
- if (sink->flow != AuNone)
- AuStopFlow (sink->audio, sink->flow, NULL);
-}
-
-static guint
-gst_nas_sink_write (GstAudioSink * asink, gpointer data, guint length)
-{
- GstNasSink *nassink = GST_NAS_SINK (asink);
- int used = 0;
-
- NAS_flush (nassink);
- if (!nassink->mute && nassink->audio != NULL && nassink->flow != AuNone) {
-
- if (nassink->need_data == 0)
- return 0;
-
- used = nassink->need_data > length ? length : nassink->need_data;
- AuWriteElement (nassink->audio, nassink->flow, 0, used, data, AuFalse,
- NULL);
- nassink->need_data -= used;
- if (used == length)
- AuSync (nassink->audio, AuFalse);
- } else
- used = length;
- return used;
-}
-
-static void
-gst_nas_sink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstNasSink *nassink;
-
- nassink = GST_NAS_SINK (object);
-
- switch (prop_id) {
- case ARG_MUTE:
- nassink->mute = g_value_get_boolean (value);
- break;
- case ARG_HOST:
- g_free (nassink->host);
- nassink->host = g_value_dup_string (value);
- if (nassink->host == NULL)
- nassink->host = g_strdup (g_getenv ("AUDIOSERVER"));
- if (nassink->host == NULL)
- nassink->host = g_strdup (g_getenv ("DISPLAY"));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_nas_sink_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstNasSink *nassink;
-
- nassink = GST_NAS_SINK (object);
-
- switch (prop_id) {
- case ARG_MUTE:
- g_value_set_boolean (value, nassink->mute);
- break;
- case ARG_HOST:
- g_value_set_string (value, nassink->host);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-gst_nas_sink_open (GstAudioSink * asink)
-{
- GstNasSink *sink = GST_NAS_SINK (asink);
-
- GST_DEBUG_OBJECT (sink, "opening, host = '%s'", GST_STR_NULL (sink->host));
-
- /* Open Server */
- sink->audio = AuOpenServer (sink->host, 0, NULL, 0, NULL, NULL);
- if (sink->audio == NULL) {
- GST_DEBUG_OBJECT (sink, "opening failed");
- return FALSE;
- }
- sink->flow = AuNone;
- sink->need_data = 0;
-
- /* Start a flow */
- GST_DEBUG_OBJECT (asink, "opened audio device");
- return TRUE;
-}
-
-static gboolean
-gst_nas_sink_close (GstAudioSink * asink)
-{
- GstNasSink *sink = GST_NAS_SINK (asink);
-
- if (sink->audio) {
- AuCloseServer (sink->audio);
- sink->audio = NULL;
- }
-
- GST_DEBUG_OBJECT (sink, "closed audio device");
- return TRUE;
-}
-
-static void
-NAS_flush (GstNasSink * sink)
-{
- AuEvent ev;
-
- AuNextEvent (sink->audio, AuTrue, &ev);
- AuDispatchEvent (sink->audio, &ev);
-}
-
-static void
-NAS_sendData (GstNasSink * sink, AuUint32 numBytes)
-{
- sink->need_data += numBytes;
- return;
-}
-
-static AuBool
-NAS_EventHandler (AuServer * aud, AuEvent * ev, AuEventHandlerRec * handler)
-{
- GstNasSink *sink = (GstNasSink *) handler->data;
- AuElementNotifyEvent *notify;
-
- switch (ev->type) {
-
- case AuEventTypeElementNotify:
-
- notify = (AuElementNotifyEvent *) ev;
-
- switch (notify->kind) {
-
- case AuElementNotifyKindLowWater:
- NAS_sendData (sink, notify->num_bytes);
- break;
-
- case AuElementNotifyKindState:
-
- switch (notify->cur_state) {
-
- case AuStateStop:
-
- if (sink->flow != AuNone) {
- if (notify->reason == AuReasonEOF)
- AuStopFlow (handler->aud, sink->flow, NULL);
- AuReleaseScratchFlow (handler->aud, sink->flow, NULL);
- sink->flow = AuNone;
- }
- AuUnregisterEventHandler (handler->aud, handler);
- break;
-
- case AuStatePause:
-
- switch (notify->reason) {
- case AuReasonUnderrun:
- case AuReasonOverrun:
- case AuReasonEOF:
- case AuReasonWatermark:
-
- NAS_sendData (sink, notify->num_bytes);
-
- break;
-
- case AuReasonHardware:
-
- if (AuSoundRestartHardwarePauses)
- AuStartFlow (handler->aud, sink->flow, NULL);
- else
- AuStopFlow (handler->aud, sink->flow, NULL);
-
- break;
- }
- break;
- }
- break;
- }
- break;
- }
-
- return AuTrue;
-}
-
-static AuDeviceID
-NAS_getDevice (AuServer * aud, int numTracks)
-{
- int i;
-
- for (i = 0; i < AuServerNumDevices (aud); i++) {
- if ((AuDeviceKind (AuServerDevice (aud, i))
- == AuComponentKindPhysicalOutput) &&
- (AuDeviceNumTracks (AuServerDevice (aud, i)) == numTracks)) {
-
- return AuDeviceIdentifier (AuServerDevice (aud, i));
-
- }
- }
-
- return AuNone;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- GST_DEBUG_CATEGORY_INIT (nas_debug, "NAS", 0, NULL);
-
- if (!gst_element_register (plugin, "nassink", GST_RANK_NONE,
- GST_TYPE_NAS_SINK)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- nas,
- "NAS (Network Audio System) support for GStreamer",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
diff --git a/ext/nas/nassink.h b/ext/nas/nassink.h
deleted file mode 100644
index 14ab5fd93..000000000
--- a/ext/nas/nassink.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#ifndef __GST_NAS_SINK_H__
-#define __GST_NAS_SINK_H__
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiosink.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_NAS_SINK \
- (gst_nas_sink_get_type())
-#define GST_NAS_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NAS_SINK,GstNasSink))
-#define GST_NAS_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NAS_SINK,GstNasSinkClass))
-#define GST_IS_NAS_SINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NAS_SINK))
-#define GST_IS_NAS_SINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NAS_SINK))
-
-typedef struct _GstNasSink GstNasSink;
-typedef struct _GstNasSinkClass GstNasSinkClass;
-
-struct _GstNasSink {
- GstAudioSink audiosink;
-
- /*< private >*/
-
- /* instance properties */
-
- gboolean mute;
- gchar* host;
-
- /* Server info */
-
- AuServer *audio;
- AuFlowID flow;
- AuDeviceID device;
-
- /* buffer */
-
- AuUint32 need_data;
-};
-
-struct _GstNasSinkClass {
- GstAudioSinkClass parent_class;
-};
-
-GType gst_nas_sink_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_NAS_SINK_H__ */
diff --git a/ext/sdl/Makefile.am b/ext/sdl/Makefile.am
deleted file mode 100644
index d0c5b1a95..000000000
--- a/ext/sdl/Makefile.am
+++ /dev/null
@@ -1,19 +0,0 @@
-plugin_LTLIBRARIES = libgstsdl.la
-
-libgstsdl_la_SOURCES = \
- gstsdl.c \
- sdlvideosink.c \
- sdlaudiosink.c
-
-libgstsdl_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(SDL_CFLAGS)
-libgstsdl_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
- -lgstvideo-$(GST_API_VERSION) \
- -lgstaudio-$(GST_API_VERSION) \
- -lgstinterfaces-$(GST_API_VERSION) \
- $(SDL_LIBS)
-libgstsdl_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstsdl_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = \
- sdlvideosink.h \
- sdlaudiosink.h
diff --git a/ext/sdl/gstsdl.c b/ext/sdl/gstsdl.c
deleted file mode 100644
index 8813edb95..000000000
--- a/ext/sdl/gstsdl.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
- *
- * 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
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sdlvideosink.h"
-#include "sdlaudiosink.h"
-
-
-GST_DEBUG_CATEGORY (sdl_debug);
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-
- if (!gst_element_register (plugin, "sdlvideosink", GST_RANK_NONE,
- GST_TYPE_SDLVIDEOSINK) ||
- !gst_element_register (plugin, "sdlaudiosink", GST_RANK_NONE,
- GST_TYPE_SDLAUDIOSINK)) {
- return FALSE;
- }
-
- GST_DEBUG_CATEGORY_INIT (sdl_debug, "sdl", 0, "SDL elements");
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- sdl,
- "SDL (Simple DirectMedia Layer) support for GStreamer",
- plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/sdl/sdlaudiosink.c b/ext/sdl/sdlaudiosink.c
deleted file mode 100644
index ff03782d1..000000000
--- a/ext/sdl/sdlaudiosink.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
- *
- * 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
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sdlaudiosink.h"
-
-#include <SDL_byteorder.h>
-#include <string.h>
-
-#include <unistd.h>
-
-#include <gst/glib-compat-private.h>
-
-GST_DEBUG_CATEGORY_EXTERN (sdl_debug);
-#define GST_CAT_DEFAULT sdl_debug
-
-static void gst_sdlaudio_sink_dispose (GObject * object);
-
-static GstCaps *gst_sdlaudio_sink_getcaps (GstBaseSink * bsink);
-
-static gboolean gst_sdlaudio_sink_open (GstAudioSink * asink);
-static gboolean gst_sdlaudio_sink_close (GstAudioSink * asink);
-static gboolean gst_sdlaudio_sink_prepare (GstAudioSink * asink,
- GstRingBufferSpec * spec);
-static gboolean gst_sdlaudio_sink_unprepare (GstAudioSink * asink);
-static guint gst_sdlaudio_sink_write (GstAudioSink * asink, gpointer data,
- guint length);
-
-#if 0
-static guint gst_sdlaudio_sink_delay (GstAudioSink * asink);
-static void gst_sdlaudio_sink_reset (GstAudioSink * asink);
-#endif
-
-
-/* SdlaudioSink signals and args */
-enum
-{
- LAST_SIGNAL
-};
-
-#define SEMAPHORE_INIT(s,f) \
- do { \
- s.cond = g_cond_new(); \
- s.mutex = g_mutex_new(); \
- s.mutexflag = f; \
- } while(0)
-
-#define SEMAPHORE_CLOSE(s) \
- do { \
- if ( s.cond ) { \
- g_cond_free(s.cond); \
- s.cond = NULL; \
- } \
- if ( s.mutex ) { \
- g_mutex_free(s.mutex); \
- s.mutex = NULL; \
- } \
- } while(0)
-
-#define SEMAPHORE_UP(s) \
- do \
- { \
- g_mutex_lock(s.mutex); \
- s.mutexflag = TRUE; \
- g_mutex_unlock(s.mutex); \
- g_cond_signal(s.cond); \
- } while(0)
-
-#define SEMAPHORE_DOWN(s, e) \
- do \
- { \
- while (1) { \
- g_mutex_lock(s.mutex); \
- if (!s.mutexflag) { \
- if ( e ) { \
- g_mutex_unlock(s.mutex); \
- break; \
- } \
- g_cond_wait(s.cond,s.mutex); \
- } \
- else { \
- s.mutexflag = FALSE; \
- g_mutex_unlock(s.mutex); \
- break; \
- } \
- g_mutex_unlock(s.mutex); \
- } \
- } while(0)
-
-
-static GstStaticPadTemplate sdlaudiosink_sink_factory =
- GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, "
- "signed = (boolean) { TRUE, FALSE }, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 2 ]; "
- "audio/x-raw-int, "
- "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, "
- "signed = (boolean) { TRUE, FALSE }, "
- "width = (int) 8, "
- "depth = (int) 8, "
- "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")
- );
-
-GST_BOILERPLATE (GstSDLAudioSink, gst_sdlaudio_sink, GstAudioSink,
- GST_TYPE_AUDIO_SINK);
-
-static void
-gst_sdlaudio_sink_dispose (GObject * object)
-{
- GstSDLAudioSink *sdlaudiosink = GST_SDLAUDIOSINK (object);
-
- SEMAPHORE_CLOSE (sdlaudiosink->semB);
-
- SEMAPHORE_CLOSE (sdlaudiosink->semA);
-
- if (sdlaudiosink->buffer) {
- g_free (sdlaudiosink->buffer);
- }
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-
-}
-
-static void
-gst_sdlaudio_sink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_static_metadata (element_class, "SDL audio sink",
- "Sink/Audio",
- "Output to a sound card via SDLAUDIO",
- "Edgard Lima <edgard.lima@indt.org.br>");
-
- gst_element_class_add_static_pad_template (element_class,
- &sdlaudiosink_sink_factory);
-}
-
-static void
-gst_sdlaudio_sink_class_init (GstSDLAudioSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSinkClass *gstbasesink_class;
- GstAudioSinkClass *gstaudiosink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- gstaudiosink_class = (GstAudioSinkClass *) klass;
-
- gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_dispose);
-
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_getcaps);
-
- gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_open);
- gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_close);
- gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_prepare);
- gstaudiosink_class->unprepare =
- GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_unprepare);
- gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_write);
-
-#if 0
- gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_delay);
- gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sdlaudio_sink_reset);
-#endif
-
-}
-
-static void
-gst_sdlaudio_sink_init (GstSDLAudioSink * sdlaudiosink,
- GstSDLAudioSinkClass * g_class)
-{
- GST_DEBUG ("initializing sdlaudiosink");
-
- memset (&sdlaudiosink->fmt, 0, sizeof (SDL_AudioSpec));
-
- sdlaudiosink->buffer = NULL;
- sdlaudiosink->eos = FALSE;
-
- SEMAPHORE_INIT (sdlaudiosink->semA, TRUE);
-
- SEMAPHORE_INIT (sdlaudiosink->semB, FALSE);
-
-}
-
-static GstCaps *
-gst_sdlaudio_sink_getcaps (GstBaseSink * bsink)
-{
- return gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
- (bsink)));
-}
-
-static gint
-gst_sdlaudio_sink_get_format (GstBufferFormat fmt)
-{
- gint result = GST_UNKNOWN;
-
- switch (fmt) {
- case GST_U8:
- result = AUDIO_U8;
- break;
- case GST_S8:
- result = AUDIO_S8;
- break;
- case GST_S16_LE:
- result = AUDIO_S16LSB;
- break;
- case GST_S16_BE:
- result = AUDIO_S16MSB;
- break;
- case GST_U16_LE:
- result = AUDIO_U16LSB;
- break;
- case GST_U16_BE:
- result = AUDIO_U16MSB;
- break;
- default:
- break;
- }
- return result;
-}
-
-static gboolean
-gst_sdlaudio_sink_open (GstAudioSink * asink)
-{
- GstSDLAudioSink *sdlaudio;
-
- sdlaudio = GST_SDLAUDIOSINK (asink);
-
- if (SDL_Init (SDL_INIT_AUDIO) < 0) {
- goto open_failed;
- }
-
- return TRUE;
-
-open_failed:
- {
- GST_ELEMENT_ERROR (sdlaudio, LIBRARY, INIT,
- ("Unable to init SDL: %s\n", SDL_GetError ()), (NULL));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sdlaudio_sink_close (GstAudioSink * asink)
-{
- GstSDLAudioSink *sdlaudio = GST_SDLAUDIOSINK (asink);
-
- sdlaudio->eos = TRUE;
- SEMAPHORE_UP (sdlaudio->semA);
- SEMAPHORE_UP (sdlaudio->semB);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return TRUE;
-}
-
-static guint
-gst_sdlaudio_sink_write (GstAudioSink * asink, gpointer data, guint length)
-{
- GstSDLAudioSink *sdlaudio = GST_SDLAUDIOSINK (asink);
-
- if (sdlaudio->fmt.size != length) {
- GST_ERROR ("ring buffer segment length (%u) != sdl buffer len (%u)", length,
- sdlaudio->fmt.size);
- }
-
- SEMAPHORE_DOWN (sdlaudio->semA, sdlaudio->eos);
-
- if (!sdlaudio->eos)
- memcpy (sdlaudio->buffer, data, length);
-
- SEMAPHORE_UP (sdlaudio->semB);
-
- return sdlaudio->fmt.size;
-}
-
-
-static void
-mixaudio (void *unused, Uint8 * stream, int len)
-{
- GstSDLAudioSink *sdlaudio;
-
- sdlaudio = GST_SDLAUDIOSINK (unused);
-
- if (sdlaudio->fmt.size != len) {
- GST_ERROR ("fmt buffer len (%u) != sdl callback len (%d)",
- sdlaudio->fmt.size, len);
- }
-
- SEMAPHORE_DOWN (sdlaudio->semB, sdlaudio->eos);
-
- if (!sdlaudio->eos)
- SDL_MixAudio (stream, sdlaudio->buffer, sdlaudio->fmt.size,
- SDL_MIX_MAXVOLUME);
-
- SEMAPHORE_UP (sdlaudio->semA);
-
-}
-
-static gboolean
-gst_sdlaudio_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
-{
- GstSDLAudioSink *sdlaudio;
- gint power2 = -1;
-
- sdlaudio = GST_SDLAUDIOSINK (asink);
-
- sdlaudio->fmt.format = gst_sdlaudio_sink_get_format (spec->format);
- if (sdlaudio->fmt.format == 0)
- goto wrong_format;
-
- if (spec->width != 16 && spec->width != 8)
- goto dodgy_width;
-
- sdlaudio->fmt.freq = spec->rate;
- sdlaudio->fmt.channels = spec->channels;
- sdlaudio->fmt.samples =
- spec->segsize / (spec->channels * ((sdlaudio->fmt.format & 0xFF) >> 3));
- sdlaudio->fmt.callback = mixaudio;
- sdlaudio->fmt.userdata = sdlaudio;
-
- GST_DEBUG ("set segsize: %d, segtotal: %d, samples: %d", spec->segsize,
- spec->segtotal, sdlaudio->fmt.samples);
-
- while (sdlaudio->fmt.samples) {
- sdlaudio->fmt.samples >>= 1;
- ++power2;
- }
-
- sdlaudio->fmt.samples = 1;
- sdlaudio->fmt.samples <<= power2;
-
- GST_DEBUG ("set segsize: %d, segtotal: %d, samples: %d", spec->segsize,
- spec->segtotal, sdlaudio->fmt.samples);
-
- if (SDL_OpenAudio (&sdlaudio->fmt, NULL) < 0) {
- goto unable_open;
- }
-
- spec->segsize = sdlaudio->fmt.size;
-
- sdlaudio->buffer = g_malloc (sdlaudio->fmt.size);
- memset (sdlaudio->buffer, sdlaudio->fmt.silence, sdlaudio->fmt.size);
-
- GST_DEBUG ("set segsize: %d, segtotal: %d, samples: %d", spec->segsize,
- spec->segtotal, sdlaudio->fmt.samples);
-
- spec->bytes_per_sample =
- spec->channels * ((sdlaudio->fmt.format & 0xFF) >> 3);
- memset (spec->silence_sample, sdlaudio->fmt.silence, spec->bytes_per_sample);
-
- SDL_PauseAudio (0);
-
- return TRUE;
-
-unable_open:
- {
- GST_ELEMENT_ERROR (sdlaudio, RESOURCE, OPEN_READ,
- ("Unable to open audio: %s", SDL_GetError ()), (NULL));
- return FALSE;
- }
-wrong_format:
- {
- GST_ELEMENT_ERROR (sdlaudio, RESOURCE, OPEN_READ,
- ("Unable to get format %d", spec->format), (NULL));
- return FALSE;
- }
-dodgy_width:
- {
- GST_ELEMENT_ERROR (sdlaudio, RESOURCE, OPEN_READ,
- ("unexpected width %d", spec->width), (NULL));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sdlaudio_sink_unprepare (GstAudioSink * asink)
-{
-
- SDL_CloseAudio ();
-
- return TRUE;
-
-#if 0
- if (!gst_sdlaudio_sink_close (asink))
- goto couldnt_close;
-
- if (!gst_sdlaudio_sink_open (asink))
- goto couldnt_reopen;
-
- return TRUE;
-
-couldnt_close:
- {
- GST_DEBUG ("Could not close the audio device");
- return FALSE;
- }
-couldnt_reopen:
- {
- GST_DEBUG ("Could not reopen the audio device");
- return FALSE;
- }
-#endif
-
-}
-
-#if 0
-static guint
-gst_sdlaudio_sink_delay (GstAudioSink * asink)
-{
- GstSDLAudioSink *sdlaudio;
-
- sdlaudio = GST_SDLAUDIOSINK (asink);
-
- return 0;
-}
-
-static void
-gst_sdlaudio_sink_reset (GstAudioSink * asink)
-{
-}
-#endif
diff --git a/ext/sdl/sdlaudiosink.h b/ext/sdl/sdlaudiosink.h
deleted file mode 100644
index 8532f3ffd..000000000
--- a/ext/sdl/sdlaudiosink.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
- *
- * 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
- */
-
-#ifndef __GST_SDLAUDIOSINK_H__
-#define __GST_SDLAUDIOSINK_H__
-
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiosink.h>
-
-#include <SDL.h>
-#include <SDL_audio.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SDLAUDIOSINK (gst_sdlaudio_sink_get_type())
-#define GST_SDLAUDIOSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SDLAUDIOSINK,GstSDLAudioSink))
-#define GST_SDLAUDIOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SDLAUDIOSINK,GstSDLAudioSinkClass))
-#define GST_IS_SDLAUDIOSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SDLAUDIOSINK))
-#define GST_IS_SDLAUDIOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SDLAUDIOSINK))
-
-typedef struct _GstSDLAudioSink GstSDLAudioSink;
-typedef struct _GstSDLAudioSinkClass GstSDLAudioSinkClass;
-
-typedef struct _gstsdl_semaphore {
- GCond *cond;
- GMutex *mutex;
- gboolean mutexflag;
-
-} gstsdl_semaphore;
-
-struct _GstSDLAudioSink {
- GstAudioSink sink;
-
- SDL_AudioSpec fmt;
- guint8 *buffer;
-
- gstsdl_semaphore semA;
-
- gstsdl_semaphore semB;
-
- gboolean eos;
-
-};
-
-struct _GstSDLAudioSinkClass {
- GstAudioSinkClass parent_class;
-};
-
-GType gst_sdlaudio_sink_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_SDLAUDIOSINK_H__ */
diff --git a/ext/sdl/sdlvideosink.c b/ext/sdl/sdlvideosink.c
deleted file mode 100644
index 7f05dcad8..000000000
--- a/ext/sdl/sdlvideosink.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/* GStreamer SDL plugin
- * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/* let's not forget to mention that all this was based on aasink ;-) */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <signal.h>
-#include <string.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <stdlib.h>
-
-#include <gst/glib-compat-private.h>
-#include <gst/interfaces/xoverlay.h>
-#include <gst/interfaces/navigation.h>
-
-#include "sdlvideosink.h"
-
-GST_DEBUG_CATEGORY_EXTERN (sdl_debug);
-#define GST_CAT_DEFAULT sdl_debug
-
-/* These macros are adapted from videotestsrc.c
- * and/or gst-plugins/gst/games/gstvideoimage.c */
-#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
-#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
-#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
-
-#define I420_Y_OFFSET(w,h) (0)
-#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
-#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-
-enum
-{
- PROP_0,
- PROP_FULLSCREEN
-};
-
-static void gst_sdlvideosink_interface_init (GstImplementsInterfaceClass *
- klass);
-static gboolean gst_sdlvideosink_supported (GstImplementsInterface * iface,
- GType type);
-
-static void gst_sdlvideosink_xoverlay_init (GstXOverlayClass * klass);
-static void gst_sdlvideosink_xoverlay_set_window_handle
- (GstXOverlay * overlay, guintptr parent);
-
-static gboolean gst_sdlvideosink_lock (GstSDLVideoSink * sdl);
-static void gst_sdlvideosink_unlock (GstSDLVideoSink * sdl);
-
-static gboolean gst_sdlvideosink_initsdl (GstSDLVideoSink * sdl);
-static void gst_sdlvideosink_deinitsdl (GstSDLVideoSink * sdl);
-
-static gboolean gst_sdlvideosink_create (GstSDLVideoSink * sdl);
-static void gst_sdlvideosink_destroy (GstSDLVideoSink * sdl);
-
-static gboolean gst_sdlvideosink_setcaps (GstBaseSink * bsink, GstCaps * caps);
-
-static GstFlowReturn gst_sdlvideosink_show_frame (GstBaseSink * bsink,
- GstBuffer * buff);
-
-static void gst_sdlvideosink_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_sdlvideosink_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn
-gst_sdlvideosink_change_state (GstElement * element, GstStateChange transition);
-
-static void gst_sdlvideosink_navigation_init (GstNavigationInterface * iface);
-
-static void gst_sdlv_process_events (GstSDLVideoSink * sdlvideosink);
-
-static GstPadTemplate *sink_template;
-
-static void
-_do_init (GType type)
-{
- static const GInterfaceInfo iface_info = {
- (GInterfaceInitFunc) gst_sdlvideosink_interface_init,
- NULL,
- NULL,
- };
- static const GInterfaceInfo xoverlay_info = {
- (GInterfaceInitFunc) gst_sdlvideosink_xoverlay_init,
- NULL,
- NULL,
- };
- static const GInterfaceInfo navigation_info = {
- (GInterfaceInitFunc) gst_sdlvideosink_navigation_init,
- NULL,
- NULL,
- };
-
- g_type_add_interface_static (type,
- GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
- g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &xoverlay_info);
- g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &navigation_info);
-
-}
-
-GST_BOILERPLATE_FULL (GstSDLVideoSink, gst_sdlvideosink, GstVideoSink,
- GST_TYPE_VIDEO_SINK, _do_init);
-
-static void
-gst_sdlvideosink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- GstCaps *capslist;
- gint i;
- guint32 formats[] = {
- GST_MAKE_FOURCC ('I', '4', '2', '0'),
- GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
- GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
- GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'),
- GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y')
- };
-
- /* make a list of all available caps */
- capslist = gst_caps_new_empty ();
- for (i = 0; i < G_N_ELEMENTS (formats); i++) {
- gst_caps_append_structure (capslist,
- gst_structure_new ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, formats[i],
- "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL));
- }
-
- sink_template = gst_pad_template_new ("sink",
- GST_PAD_SINK, GST_PAD_ALWAYS, capslist);
-
- gst_element_class_add_pad_template (element_class, sink_template);
- gst_element_class_set_static_metadata (element_class, "SDL video sink",
- "Sink/Video", "An SDL-based videosink",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
- "Edgard Lima <edgard.lima@indt.org.br>, "
- "Jan Schmidt <thaytan@mad.scientist.com>");
-}
-
-static void
-gst_sdlvideosink_finalize (GObject * obj)
-{
- g_mutex_free (GST_SDLVIDEOSINK (obj)->lock);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-gst_sdlvideosink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
- GstClockTime * start, GstClockTime * end)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (basesink);
- GstClockTime timestamp, duration;
-
- timestamp = GST_BUFFER_TIMESTAMP (buffer);
- if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
- *start = timestamp;
- duration = GST_BUFFER_DURATION (buffer);
- if (GST_CLOCK_TIME_IS_VALID (duration)) {
- *end = timestamp + duration;
- } else {
- if (sdlvideosink->framerate_n > 0) {
- *end = timestamp +
- gst_util_uint64_scale_int (GST_SECOND, sdlvideosink->framerate_d,
- sdlvideosink->framerate_n);
- }
- }
- }
-}
-
-static void
-gst_sdlvideosink_class_init (GstSDLVideoSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseSinkClass *gstvs_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstvs_class = (GstBaseSinkClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->set_property = gst_sdlvideosink_set_property;
- gobject_class->get_property = gst_sdlvideosink_get_property;
-
- gobject_class->finalize = gst_sdlvideosink_finalize;
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_sdlvideosink_change_state);
-
- gstvs_class->set_caps = GST_DEBUG_FUNCPTR (gst_sdlvideosink_setcaps);
- gstvs_class->get_times = GST_DEBUG_FUNCPTR (gst_sdlvideosink_get_times);
- gstvs_class->preroll = GST_DEBUG_FUNCPTR (gst_sdlvideosink_show_frame);
- gstvs_class->render = GST_DEBUG_FUNCPTR (gst_sdlvideosink_show_frame);
-
- g_object_class_install_property (gobject_class, PROP_FULLSCREEN,
- g_param_spec_boolean ("fullscreen", "Fullscreen",
- "If true it will be Full screen", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /*gstvs_class->set_video_out = gst_sdlvideosink_set_video_out;
- gstvs_class->push_ui_event = gst_sdlvideosink_push_ui_event;
- gstvs_class->set_geometry = gst_sdlvideosink_set_geometry; */
-}
-
-#if 0
-/* FIXME */
-static GstBuffer *
-gst_sdlvideosink_buffer_new (GstBufferPool * pool,
- gint64 location, guint size, gpointer user_data)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (user_data);
- GstBuffer *buffer;
-
- if (!sdlvideosink->overlay)
- return NULL;
-
- if (!gst_sdlvideosink_lock (sdlvideosink)) {
- return NULL;
- }
-
- /* this protects the buffer from being written over multiple times */
- g_mutex_lock (sdlvideosink->lock);
-
- buffer = gst_buffer_new ();
- GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_DONTFREE);
- GST_BUFFER_DATA (buffer) = sdlvideosink->overlay->pixels[0];
- if (sdlvideosink->format == SDL_YV12_OVERLAY ||
- sdlvideosink->format == SDL_IYUV_OVERLAY) {
- GST_BUFFER_SIZE (buffer) =
- sdlvideosink->width * sdlvideosink->height * 3 / 2;
- } else {
- GST_BUFFER_SIZE (buffer) = sdlvideosink->width * sdlvideosink->height * 2;
- }
- GST_BUFFER_MAXSIZE (buffer) = GST_BUFFER_SIZE (buffer);
-
- return buffer;
-}
-
-static void
-gst_sdlvideosink_buffer_free (GstBufferPool * pool,
- GstBuffer * buffer, gpointer user_data)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (user_data);
-
- g_mutex_unlock (sdlvideosink->lock);
- gst_sdlvideosink_unlock (sdlvideosink);
-
- gst_buffer_default_free (buffer);
-}
-
-
-static GstBufferPool *
-gst_sdlvideosink_get_bufferpool (GstPad * pad)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (gst_pad_get_parent (pad));
-
- if (sdlvideosink->overlay)
- return sdlvideosink->bufferpool;
-
- return NULL;
-}
-#endif
-
-static void
-gst_sdlvideosink_init (GstSDLVideoSink * sdlvideosink,
- GstSDLVideoSinkClass * g_class)
-{
-
- sdlvideosink->width = -1;
- sdlvideosink->height = -1;
- sdlvideosink->framerate_n = 0;
- sdlvideosink->framerate_d = 1;
- sdlvideosink->full_screen = FALSE;
-
- sdlvideosink->overlay = NULL;
- sdlvideosink->screen = NULL;
-
- sdlvideosink->xwindow_id = 0;
-
- //sdlvideosink->capslist = capslist;
-
- sdlvideosink->init = FALSE;
-
- sdlvideosink->event_thread = NULL;
- sdlvideosink->running = FALSE;
-
- sdlvideosink->lock = g_mutex_new ();
-}
-
-static void
-gst_sdlvideosink_interface_init (GstImplementsInterfaceClass * klass)
-{
- klass->supported = gst_sdlvideosink_supported;
-}
-
-static gboolean
-gst_sdlvideosink_supported (GstImplementsInterface * interface,
- GType iface_type)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (interface);
- gboolean result = FALSE;
-
- /* check SDL for whether it was compiled against X, FB, etc. */
- if (iface_type == GST_TYPE_X_OVERLAY) {
- gchar tmp[4];
-
- if (!sdlvideosink->init) {
- g_mutex_lock (sdlvideosink->lock);
- SDL_Init (SDL_INIT_VIDEO);
-
- /* True if the video driver is X11 */
- result = (strcmp ("x11", SDL_VideoDriverName (tmp, 4)) == 0);
- SDL_QuitSubSystem (SDL_INIT_VIDEO);
- g_mutex_unlock (sdlvideosink->lock);
- } else
- result = sdlvideosink->is_xwindows;
- } else if (iface_type == GST_TYPE_NAVIGATION)
- result = TRUE;
-
- return result;
-}
-
-/* SDL Video sink and X overlay:
- *
- * SDL supports creating an Xv window/overlay within an existing X window
- * through the horrible mechanism of setting the WINDOWID environment
- * variable.
- * It will then display the x overlay within that window, but not at the
- * full window size. Instead, we need to explicitly tell SDL the size.
- *
- * Unfortunately, the XOverlay interface in GStreamer doesn't supply
- * that information. The only way to get it would be to do what X[v]imagesink
- * does and retrieve it using X11 calls, and linking to Xlib. That would
- * defeat the whole purpose of using the SDL abstraction and plugin entirely
- * however.
- *
- * I have no nice solution to this problem for you, dear readers.
- */
-static void
-gst_sdlvideosink_xoverlay_init (GstXOverlayClass * klass)
-{
- klass->set_window_handle = gst_sdlvideosink_xoverlay_set_window_handle;
-}
-
-static void
-gst_sdlvideosink_xoverlay_set_window_handle (GstXOverlay * overlay,
- guintptr handle)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (overlay);
- unsigned long parent = (unsigned long) handle;
-
- if (sdlvideosink->xwindow_id == parent)
- return;
-
- sdlvideosink->xwindow_id = parent;
-
- /* are we running yet? */
- if (sdlvideosink->init) {
- gboolean negotiated;
-
- g_mutex_lock (sdlvideosink->lock);
-
- negotiated = (sdlvideosink->overlay != NULL);
-
- if (negotiated)
- gst_sdlvideosink_destroy (sdlvideosink);
-
- /* Call initsdl to set the WINDOWID env var urk */
- gst_sdlvideosink_initsdl (sdlvideosink);
-
- if (negotiated)
- gst_sdlvideosink_create (sdlvideosink);
-
- g_mutex_unlock (sdlvideosink->lock);
- }
-}
-
-static guint32
-gst_sdlvideosink_get_sdl_from_fourcc (GstSDLVideoSink * sdlvideosink,
- guint32 code)
-{
- switch (code) {
- /* Note: SDL_IYUV_OVERLAY does not always work for I420 */
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- return SDL_YV12_OVERLAY;
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
- return SDL_YV12_OVERLAY;
- case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
- return SDL_YUY2_OVERLAY;
- case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
- return SDL_UYVY_OVERLAY;
- case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
- return SDL_YVYU_OVERLAY;
- default:
- return 0;
- }
-}
-
-static gboolean
-gst_sdlvideosink_lock (GstSDLVideoSink * sdlvideosink)
-{
- /* assure that we've got a screen */
- if (!sdlvideosink->screen || !sdlvideosink->overlay)
- goto no_setup;
-
- /* Lock SDL/yuv-overlay */
- if (SDL_MUSTLOCK (sdlvideosink->screen)) {
- if (SDL_LockSurface (sdlvideosink->screen) < 0)
- goto could_not_lock;
- }
- if (SDL_LockYUVOverlay (sdlvideosink->overlay) < 0)
- goto lock_yuv;
-
- return TRUE;
-
- /* ERRORS */
-no_setup:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
- ("Tried to lock screen without being set-up"));
- return FALSE;
- }
-could_not_lock:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
- ("SDL: couldn't lock the SDL video window: %s", SDL_GetError ()));
- return FALSE;
- }
-lock_yuv:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
- ("SDL: couldn\'t lock the SDL YUV overlay: %s", SDL_GetError ()));
- return FALSE;
- }
-}
-
-
-static void
-gst_sdlvideosink_unlock (GstSDLVideoSink * sdlvideosink)
-{
- /* Unlock SDL_overlay */
- SDL_UnlockYUVOverlay (sdlvideosink->overlay);
- if (SDL_MUSTLOCK (sdlvideosink->screen))
- SDL_UnlockSurface (sdlvideosink->screen);
-}
-
-/* Must be called with ->lock held */
-static void
-gst_sdlvideosink_deinitsdl (GstSDLVideoSink * sdlvideosink)
-{
- if (sdlvideosink->init) {
- sdlvideosink->running = FALSE;
- if (sdlvideosink->event_thread) {
- g_mutex_unlock (sdlvideosink->lock);
- g_thread_join (sdlvideosink->event_thread);
- g_mutex_lock (sdlvideosink->lock);
- sdlvideosink->event_thread = NULL;
- }
-
- SDL_QuitSubSystem (SDL_INIT_VIDEO);
- sdlvideosink->init = FALSE;
-
- }
-}
-
-/* Process pending events. Call with ->lock held */
-static void
-gst_sdlv_process_events (GstSDLVideoSink * sdlvideosink)
-{
- SDL_Event event;
- int numevents;
- char *keysym = NULL;
-
- do {
- SDL_PumpEvents ();
- numevents = SDL_PeepEvents (&event, 1, SDL_GETEVENT,
- SDL_KEYDOWNMASK | SDL_KEYUPMASK |
- SDL_MOUSEMOTIONMASK | SDL_MOUSEBUTTONDOWNMASK |
- SDL_MOUSEBUTTONUPMASK | SDL_QUITMASK | SDL_VIDEORESIZEMASK);
-
- if (numevents > 0 && (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN)) {
- keysym = SDL_GetKeyName (event.key.keysym.sym);
- }
-
- if (numevents > 0) {
- g_mutex_unlock (sdlvideosink->lock);
- switch (event.type) {
- case SDL_MOUSEMOTION:
- gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
- "mouse-move", 0, event.motion.x, event.motion.y);
- break;
- case SDL_MOUSEBUTTONDOWN:
- gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
- "mouse-button-press",
- event.button.button, event.button.x, event.button.y);
- break;
- case SDL_MOUSEBUTTONUP:
- gst_navigation_send_mouse_event (GST_NAVIGATION (sdlvideosink),
- "mouse-button-release",
- event.button.button, event.button.x, event.button.y);
- break;
- case SDL_KEYUP:
- GST_DEBUG ("key press event %s !",
- SDL_GetKeyName (event.key.keysym.sym));
- gst_navigation_send_key_event (GST_NAVIGATION (sdlvideosink),
- "key-release", keysym);
- break;
- case SDL_KEYDOWN:
- if (SDLK_ESCAPE != event.key.keysym.sym) {
- GST_DEBUG ("key press event %s !",
- SDL_GetKeyName (event.key.keysym.sym));
- gst_navigation_send_key_event (GST_NAVIGATION (sdlvideosink),
- "key-press", keysym);
- break;
- } else {
- /* fall through */
- }
- case SDL_QUIT:
- sdlvideosink->running = FALSE;
- GST_ELEMENT_ERROR (sdlvideosink, RESOURCE, OPEN_WRITE,
- ("Video output device is gone."),
- ("We were running fullscreen and user "
- "pressed the ESC key, stopping playback."));
- break;
- case SDL_VIDEORESIZE:
- /* create a SDL window of the size requested by the user */
- g_mutex_lock (sdlvideosink->lock);
- GST_VIDEO_SINK_WIDTH (sdlvideosink) = event.resize.w;
- GST_VIDEO_SINK_HEIGHT (sdlvideosink) = event.resize.h;
- gst_sdlvideosink_create (sdlvideosink);
- g_mutex_unlock (sdlvideosink->lock);
- break;
- }
- g_mutex_lock (sdlvideosink->lock);
- }
- } while (numevents > 0);
-}
-
-static gpointer
-gst_sdlvideosink_event_thread (GstSDLVideoSink * sdlvideosink)
-{
- g_mutex_lock (sdlvideosink->lock);
- while (sdlvideosink->running) {
- gst_sdlv_process_events (sdlvideosink);
-
- /* Done events, sleep for 50 ms */
- g_mutex_unlock (sdlvideosink->lock);
- g_usleep (50000);
- g_mutex_lock (sdlvideosink->lock);
- }
- g_mutex_unlock (sdlvideosink->lock);
-
- return NULL;
-}
-
-/* Must be called with the SDL lock held */
-static gboolean
-gst_sdlvideosink_initsdl (GstSDLVideoSink * sdlvideosink)
-{
- gst_sdlvideosink_deinitsdl (sdlvideosink);
-
- if (sdlvideosink->is_xwindows && !sdlvideosink->xwindow_id) {
- g_mutex_unlock (sdlvideosink->lock);
- gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (sdlvideosink));
- g_mutex_lock (sdlvideosink->lock);
- }
-
- if (!sdlvideosink->xwindow_id) {
- g_unsetenv ("SDL_WINDOWID");
- } else {
- char SDL_hack[32];
-
- sprintf (SDL_hack, "%lu", sdlvideosink->xwindow_id);
- g_setenv ("SDL_WINDOWID", SDL_hack, 1);
- }
-
- /* Initialize the SDL library */
- if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
- goto init_failed;
-
- sdlvideosink->init = TRUE;
-
- sdlvideosink->running = TRUE;
- sdlvideosink->event_thread =
- g_thread_create ((GThreadFunc) gst_sdlvideosink_event_thread,
- sdlvideosink, TRUE, NULL);
-
- return TRUE;
-
- /* ERRORS */
-init_failed:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, INIT, (NULL),
- ("Couldn't initialize SDL: %s", SDL_GetError ()));
- return FALSE;
- }
-}
-
-/* Must be called with the sdl lock held */
-static void
-gst_sdlvideosink_destroy (GstSDLVideoSink * sdlvideosink)
-{
- if (sdlvideosink->overlay) {
- SDL_FreeYUVOverlay (sdlvideosink->overlay);
- sdlvideosink->overlay = NULL;
- }
-
- if (sdlvideosink->screen) {
- SDL_FreeSurface (sdlvideosink->screen);
- sdlvideosink->screen = NULL;
- }
- sdlvideosink->xwindow_id = 0;
-}
-
-/* Must be called with the sdl lock held */
-static gboolean
-gst_sdlvideosink_create (GstSDLVideoSink * sdlvideosink)
-{
- if (GST_VIDEO_SINK_HEIGHT (sdlvideosink) <= 0)
- GST_VIDEO_SINK_HEIGHT (sdlvideosink) = sdlvideosink->height;
- if (GST_VIDEO_SINK_WIDTH (sdlvideosink) <= 0)
- GST_VIDEO_SINK_WIDTH (sdlvideosink) = sdlvideosink->width;
-
- gst_sdlvideosink_destroy (sdlvideosink);
-
- if (sdlvideosink->is_xwindows && !sdlvideosink->xwindow_id) {
- g_mutex_unlock (sdlvideosink->lock);
- gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (sdlvideosink));
- g_mutex_lock (sdlvideosink->lock);
- }
-
- /* create a SDL window of the size requested by the user */
- if (sdlvideosink->full_screen) {
- sdlvideosink->screen =
- SDL_SetVideoMode (GST_VIDEO_SINK_WIDTH (sdlvideosink),
- GST_VIDEO_SINK_HEIGHT (sdlvideosink), 0,
- SDL_SWSURFACE | SDL_FULLSCREEN);
- } else {
- sdlvideosink->screen =
- SDL_SetVideoMode (GST_VIDEO_SINK_WIDTH (sdlvideosink),
- GST_VIDEO_SINK_HEIGHT (sdlvideosink), 0, SDL_HWSURFACE | SDL_RESIZABLE);
- }
- if (sdlvideosink->screen == NULL)
- goto no_screen;
-
- /* create a new YUV overlay */
- sdlvideosink->overlay = SDL_CreateYUVOverlay (sdlvideosink->width,
- sdlvideosink->height, sdlvideosink->format, sdlvideosink->screen);
- if (sdlvideosink->overlay == NULL)
- goto no_overlay;
-
-
- GST_DEBUG ("Using a %dx%d %dbpp SDL screen with a %dx%d \'%"
- GST_FOURCC_FORMAT "\' YUV overlay", GST_VIDEO_SINK_WIDTH (sdlvideosink),
- GST_VIDEO_SINK_HEIGHT (sdlvideosink),
- sdlvideosink->screen->format->BitsPerPixel, sdlvideosink->width,
- sdlvideosink->height, GST_FOURCC_ARGS (sdlvideosink->format));
-
- sdlvideosink->rect.x = 0;
- sdlvideosink->rect.y = 0;
- sdlvideosink->rect.w = GST_VIDEO_SINK_WIDTH (sdlvideosink);
- sdlvideosink->rect.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink);
-
- /*SDL_DisplayYUVOverlay (sdlvideosink->overlay, &(sdlvideosink->rect)); */
-
- GST_DEBUG ("sdlvideosink: setting %08x (%" GST_FOURCC_FORMAT ")",
- sdlvideosink->format, GST_FOURCC_ARGS (sdlvideosink->format));
-
- return TRUE;
-
- /* ERRORS */
-no_screen:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
- ("SDL: Couldn't set %dx%d: %s", GST_VIDEO_SINK_WIDTH (sdlvideosink),
- GST_VIDEO_SINK_HEIGHT (sdlvideosink), SDL_GetError ()));
- return FALSE;
- }
-no_overlay:
- {
- GST_ELEMENT_ERROR (sdlvideosink, LIBRARY, TOO_LAZY, (NULL),
- ("SDL: Couldn't create SDL YUV overlay (%dx%d \'%" GST_FOURCC_FORMAT
- "\'): %s", sdlvideosink->width, sdlvideosink->height,
- GST_FOURCC_ARGS (sdlvideosink->format), SDL_GetError ()));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sdlvideosink_setcaps (GstBaseSink * bsink, GstCaps * vscapslist)
-{
- GstSDLVideoSink *sdlvideosink;
- GstStructure *structure;
- gboolean res = TRUE;
-
- sdlvideosink = GST_SDLVIDEOSINK (bsink);
-
- structure = gst_caps_get_structure (vscapslist, 0);
- gst_structure_get_fourcc (structure, "format", &sdlvideosink->fourcc);
- sdlvideosink->format =
- gst_sdlvideosink_get_sdl_from_fourcc (sdlvideosink, sdlvideosink->fourcc);
- gst_structure_get_int (structure, "width", &sdlvideosink->width);
- gst_structure_get_int (structure, "height", &sdlvideosink->height);
- gst_structure_get_fraction (structure, "framerate",
- &sdlvideosink->framerate_n, &sdlvideosink->framerate_d);
-
- g_mutex_lock (sdlvideosink->lock);
- if (!sdlvideosink->format || !gst_sdlvideosink_create (sdlvideosink))
- res = FALSE;
- g_mutex_unlock (sdlvideosink->lock);
-
- return res;
-}
-
-
-static GstFlowReturn
-gst_sdlvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
-{
-
- GstSDLVideoSink *sdlvideosink;
-
- sdlvideosink = GST_SDLVIDEOSINK (bsink);
-
- g_mutex_lock (sdlvideosink->lock);
- if (!sdlvideosink->init ||
- !sdlvideosink->overlay || !sdlvideosink->overlay->pixels)
- goto not_init;
-
- /* if (GST_BUFFER_DATA (buf) != sdlvideosink->overlay->pixels[0]) */
- if (TRUE) {
- guint8 *out;
- gint l;
-
- if (!gst_sdlvideosink_lock (sdlvideosink))
- goto cannot_lock;
-
- /* buf->yuv - FIXME: bufferpool! */
- if (sdlvideosink->format == SDL_YV12_OVERLAY) {
- guint8 *y, *u, *v;
-
- switch (sdlvideosink->fourcc) {
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- y = GST_BUFFER_DATA (buf);
- /* I420 is YV12 with switched colour planes and different offsets */
- v = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
- u = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
- break;
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
- y = GST_BUFFER_DATA (buf);
- u = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
- v = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
- break;
- default:
- gst_sdlvideosink_unlock (sdlvideosink);
- g_mutex_unlock (sdlvideosink->lock);
- g_return_val_if_reached (GST_FLOW_ERROR);
- }
-
- /* Y Plane */
- out = sdlvideosink->overlay->pixels[0];
- for (l = 0; l < sdlvideosink->height; l++) {
- memcpy (out, y, I420_Y_ROWSTRIDE (sdlvideosink->width));
- out += sdlvideosink->overlay->pitches[0];
- y += I420_Y_ROWSTRIDE (sdlvideosink->width);
- }
-
- /* U plane */
- out = sdlvideosink->overlay->pixels[1];
- for (l = 0; l < (sdlvideosink->height / 2); l++) {
- memcpy (out, u, I420_U_ROWSTRIDE (sdlvideosink->width));
- out += sdlvideosink->overlay->pitches[1];
- u += I420_U_ROWSTRIDE (sdlvideosink->width);
- }
-
- /* V plane */
- out = sdlvideosink->overlay->pixels[2];
- for (l = 0; l < (sdlvideosink->height / 2); l++) {
- memcpy (out, v, I420_V_ROWSTRIDE (sdlvideosink->width));
- out += sdlvideosink->overlay->pitches[2];
- v += I420_V_ROWSTRIDE (sdlvideosink->width);
- }
- } else {
- guint8 *in = GST_BUFFER_DATA (buf);
- gint in_stride = sdlvideosink->width * 2;
-
- out = sdlvideosink->overlay->pixels[0];
-
- for (l = 0; l < sdlvideosink->height; l++) {
- memcpy (out, in, in_stride);
- out += sdlvideosink->overlay->pitches[0];
- in += in_stride;
- }
- }
- gst_sdlvideosink_unlock (sdlvideosink);
- }
-
- /* Show, baby, show! */
- SDL_DisplayYUVOverlay (sdlvideosink->overlay, &(sdlvideosink->rect));
-
- /* Handle any resize */
- gst_sdlv_process_events (sdlvideosink);
-
- g_mutex_unlock (sdlvideosink->lock);
-
- return GST_FLOW_OK;
-
- /* ERRORS */
-not_init:
- {
- GST_ELEMENT_ERROR (sdlvideosink, CORE, NEGOTIATION, (NULL),
- ("not negotiated."));
- g_mutex_unlock (sdlvideosink->lock);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-cannot_lock:
- {
- /* lock function posted detailed message */
- g_mutex_unlock (sdlvideosink->lock);
- return GST_FLOW_ERROR;
- }
-}
-
-
-static void
-gst_sdlvideosink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstSDLVideoSink *sdlvideosink;
-
- sdlvideosink = GST_SDLVIDEOSINK (object);
-
- switch (prop_id) {
- case PROP_FULLSCREEN:
- sdlvideosink->full_screen = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-static void
-gst_sdlvideosink_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstSDLVideoSink *sdlvideosink;
-
- sdlvideosink = GST_SDLVIDEOSINK (object);
-
- switch (prop_id) {
- case PROP_FULLSCREEN:
- g_value_set_boolean (value, sdlvideosink->full_screen);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-static GstStateChangeReturn
-gst_sdlvideosink_change_state (GstElement * element, GstStateChange transition)
-{
- GstSDLVideoSink *sdlvideosink;
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-
- g_return_val_if_fail (GST_IS_SDLVIDEOSINK (element),
- GST_STATE_CHANGE_FAILURE);
- sdlvideosink = GST_SDLVIDEOSINK (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- sdlvideosink->is_xwindows = GST_IS_X_OVERLAY (sdlvideosink);
- g_mutex_lock (sdlvideosink->lock);
- if (!gst_sdlvideosink_initsdl (sdlvideosink)) {
- g_mutex_unlock (sdlvideosink->lock);
- goto init_failed;
- }
- GST_OBJECT_FLAG_SET (sdlvideosink, GST_SDLVIDEOSINK_OPEN);
- g_mutex_unlock (sdlvideosink->lock);
- break;
- default: /* do nothing */
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- sdlvideosink->framerate_n = 0;
- sdlvideosink->framerate_d = 1;
- g_mutex_lock (sdlvideosink->lock);
- gst_sdlvideosink_destroy (sdlvideosink);
- g_mutex_unlock (sdlvideosink->lock);
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- g_mutex_lock (sdlvideosink->lock);
- gst_sdlvideosink_deinitsdl (sdlvideosink);
- GST_OBJECT_FLAG_UNSET (sdlvideosink, GST_SDLVIDEOSINK_OPEN);
- g_mutex_unlock (sdlvideosink->lock);
- break;
- default: /* do nothing */
- break;
- }
- return ret;
-
-init_failed:
- {
- /* method posted detailed error message */
- GST_DEBUG_OBJECT (sdlvideosink, "init failed");
- return GST_STATE_CHANGE_FAILURE;
- }
-}
-
-
-static void
-gst_sdlvideosink_navigation_send_event (GstNavigation * navigation,
- GstStructure * structure)
-{
- GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (navigation);
- GstEvent *event;
- GstVideoRectangle dst = { 0, };
- GstVideoRectangle src = { 0, };
- GstVideoRectangle result;
- double x, y, old_x, old_y;
- GstPad *pad = NULL;
-
- src.w = GST_VIDEO_SINK_WIDTH (sdlvideosink);
- src.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink);
- dst.w = sdlvideosink->width;
- dst.h = sdlvideosink->height;
- gst_video_sink_center_rect (src, dst, &result, FALSE);
-
- event = gst_event_new_navigation (structure);
-
- /* Our coordinates can be wrong here if we centered the video */
-
- /* Converting pointer coordinates to the non scaled geometry */
- if (gst_structure_get_double (structure, "pointer_x", &old_x)) {
- x = old_x;
-
- if (x >= result.x && x <= (result.x + result.w)) {
- x -= result.x;
- x *= sdlvideosink->width;
- x /= result.w;
- } else {
- x = 0;
- }
- GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event x "
- "coordinate from %f to %f", old_x, x);
- gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
- }
- if (gst_structure_get_double (structure, "pointer_y", &old_y)) {
- y = old_y;
-
- if (y >= result.y && y <= (result.y + result.h)) {
- y -= result.y;
- y *= sdlvideosink->height;
- y /= result.h;
- } else {
- y = 0;
- }
- GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event y "
- "coordinate from %f to %f", old_y, y);
- gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
- }
-
- pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sdlvideosink));
-
- if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
- gst_pad_send_event (pad, event);
-
- gst_object_unref (pad);
- }
-}
-
-static void
-gst_sdlvideosink_navigation_init (GstNavigationInterface * iface)
-{
- iface->send_event = gst_sdlvideosink_navigation_send_event;
-}
diff --git a/ext/sdl/sdlvideosink.h b/ext/sdl/sdlvideosink.h
deleted file mode 100644
index eff752f38..000000000
--- a/ext/sdl/sdlvideosink.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* GStreamer SDL plugin
- * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_SDLVIDEOSINK_H__
-#define __GST_SDLVIDEOSINK_H__
-
-#include <gst/video/gstvideosink.h>
-
-#include <SDL.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SDLVIDEOSINK \
- (gst_sdlvideosink_get_type())
-#define GST_SDLVIDEOSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SDLVIDEOSINK,GstSDLVideoSink))
-#define GST_SDLVIDEOSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SDLVIDEOSINK,GstSDLVideoSinkClass))
-#define GST_IS_SDLVIDEOSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SDLVIDEOSINK))
-#define GST_IS_SDLVIDEOSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SDLVIDEOSINK))
-
-typedef enum {
- GST_SDLVIDEOSINK_OPEN = (GST_ELEMENT_FLAG_LAST << 0),
-
- GST_SDLVIDEOSINK_FLAG_LAST = (GST_ELEMENT_FLAG_LAST << 2),
-} GstSDLVideoSinkFlags;
-
-typedef struct _GstSDLVideoSink GstSDLVideoSink;
-typedef struct _GstSDLVideoSinkClass GstSDLVideoSinkClass;
-
-struct _GstSDLVideoSink {
- GstVideoSink videosink;
-
- guint32 format; /* the SDL format */
- guint32 fourcc; /* our fourcc from the caps */
-
- gint width, height; /* the size of the incoming YUV stream */
- unsigned long xwindow_id;
- gboolean is_xwindows;
-
- gint framerate_n;
- gint framerate_d;
-
- gboolean full_screen;
- gboolean init;
- gboolean running;
- GThread *event_thread;
- SDL_Surface *screen;
- SDL_Overlay *overlay;
- SDL_Rect rect;
-
- GMutex *lock;
-};
-
-struct _GstSDLVideoSinkClass {
- GstVideoSinkClass parent_class;
-
-};
-
-GType gst_sdlvideosink_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_SDLVIDEOSINK_H__ */
diff --git a/ext/sndio/Makefile.am b/ext/sndio/Makefile.am
deleted file mode 100644
index 03a42b1a5..000000000
--- a/ext/sndio/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-plugin_LTLIBRARIES = libgstsndio.la
-
-libgstsndio_la_SOURCES = gstsndio.c sndiosink.c sndiosrc.c
-libgstsndio_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
-libgstsndio_la_LIBADD = \
- $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) \
- $(SNDIO_LIBS)
-libgstsndio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-
-noinst_HEADERS = sndiosink.h sndiosrc.h
-EXTRA_DIST =
diff --git a/ext/sndio/gstsndio.c b/ext/sndio/gstsndio.c
deleted file mode 100644
index af8252ec0..000000000
--- a/ext/sndio/gstsndio.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "sndiosink.h"
-#include "sndiosrc.h"
-
-#include "gst/gst-i18n-plugin.h"
-
-GST_DEBUG_CATEGORY (gst_sndio_debug);
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_element_register (plugin, "sndiosrc", GST_RANK_PRIMARY,
- GST_TYPE_SNDIOSRC) ||
- !gst_element_register (plugin, "sndiosink", GST_RANK_PRIMARY,
- GST_TYPE_SNDIOSINK)) {
- return FALSE;
- }
-
- GST_DEBUG_CATEGORY_INIT (gst_sndio_debug, "sndio", 0, "sndio elements");
-
-#ifdef ENABLE_NLS
- GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
- LOCALEDIR);
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif /* ENABLE_NLS */
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "sndio",
- "sndio support for GStreamer",
- plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/sndio/sndiosink.c b/ext/sndio/sndiosink.c
deleted file mode 100644
index c9d0f719a..000000000
--- a/ext/sndio/sndiosink.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/**
- * SECTION:element-sndiosink
- * @see_also: #GstAutoAudioSink
- *
- * <refsect2>
- * <para>
- * This element outputs sound to a sound card using sndio.
- * </para>
- * <para>
- * Simple example pipeline that plays an Ogg/Vorbis file via sndio:
- * <programlisting>
- * gst-launch-1.0 -v filesrc location=foo.ogg ! decodebin ! audioconvert ! audioresample ! sndiosink
- * </programlisting>
- * </para>
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sndiosink.h"
-#include <unistd.h>
-#include <errno.h>
-
-#include <gst/gst-i18n-plugin.h>
-
-GST_DEBUG_CATEGORY_EXTERN (gst_sndio_debug);
-#define GST_CAT_DEFAULT gst_sndio_debug
-
-enum
-{
- PROP_0,
- PROP_HOST
-};
-
-static GstStaticPadTemplate sndio_sink_factory =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { 1234, 4321 }, "
- "signed = (boolean) { TRUE, FALSE }, "
- "width = (int) { 8, 16, 24, 32 }, "
- "depth = (int) { 8, 16, 24, 32 }, "
- "rate = (int) [ 8000, 192000 ], " "channels = (int) [ 1, 16 ] ")
- );
-
-static void gst_sndiosink_finalize (GObject * object);
-
-static GstCaps *gst_sndiosink_getcaps (GstBaseSink * bsink);
-
-static gboolean gst_sndiosink_open (GstAudioSink * asink);
-static gboolean gst_sndiosink_close (GstAudioSink * asink);
-static gboolean gst_sndiosink_prepare (GstAudioSink * asink,
- GstRingBufferSpec * spec);
-static gboolean gst_sndiosink_unprepare (GstAudioSink * asink);
-static guint gst_sndiosink_write (GstAudioSink * asink, gpointer data,
- guint length);
-static guint gst_sndiosink_delay (GstAudioSink * asink);
-static void gst_sndiosink_reset (GstAudioSink * asink);
-
-static void gst_sndiosink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_sndiosink_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_sndiosink_cb (void *addr, int delta);
-
-GST_BOILERPLATE (GstSndioSink, gst_sndiosink, GstAudioSink,
- GST_TYPE_AUDIO_SINK);
-
-static void
-gst_sndiosink_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_static_metadata (element_class,
- "Sndio audio sink",
- "Sink/Audio",
- "Plays audio through sndio", "Jacob Meuser <jakemsr@sdf.lonestar.org>");
-
- gst_element_class_add_static_pad_template (element_class,
- &sndio_sink_factory);
-}
-
-static void
-gst_sndiosink_class_init (GstSndioSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSinkClass *gstbasesink_class;
- GstBaseAudioSinkClass *gstbaseaudiosink_class;
- GstAudioSinkClass *gstaudiosink_class;
-
- gobject_class = (GObjectClass *) klass;
- gstbasesink_class = (GstBaseSinkClass *) klass;
- gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
- gstaudiosink_class = (GstAudioSinkClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_sndiosink_finalize;
-
- gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosink_getcaps);
-
- gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sndiosink_open);
- gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sndiosink_close);
- gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosink_prepare);
- gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosink_unprepare);
- gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sndiosink_write);
- gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosink_delay);
- gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosink_reset);
-
- gobject_class->set_property = gst_sndiosink_set_property;
- gobject_class->get_property = gst_sndiosink_get_property;
-
- /* default value is filled in the _init method */
- g_object_class_install_property (gobject_class, PROP_HOST,
- g_param_spec_string ("host", "Host",
- "Device or socket sndio will access", NULL, G_PARAM_READWRITE));
-}
-
-static void
-gst_sndiosink_init (GstSndioSink * sndiosink, GstSndioSinkClass * klass)
-{
- sndiosink->hdl = NULL;
- sndiosink->host = g_strdup (g_getenv ("AUDIODEVICE"));
-}
-
-static void
-gst_sndiosink_finalize (GObject * object)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- gst_caps_replace (&sndiosink->cur_caps, NULL);
- g_free (sndiosink->host);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static GstCaps *
-gst_sndiosink_getcaps (GstBaseSink * bsink)
-{
- GstSndioSink *sndiosink;
-
- sndiosink = GST_SNDIOSINK (bsink);
-
- /* no hdl, we're done with the template caps */
- if (sndiosink->cur_caps == NULL) {
- GST_LOG_OBJECT (sndiosink, "getcaps called, returning template caps");
- return NULL;
- }
-
- GST_LOG_OBJECT (sndiosink, "returning %" GST_PTR_FORMAT, sndiosink->cur_caps);
-
- return gst_caps_ref (sndiosink->cur_caps);
-}
-
-static gboolean
-gst_sndiosink_open (GstAudioSink * asink)
-{
- GstPadTemplate *pad_template;
- GstSndioSink *sndiosink;
- struct sio_par par;
- struct sio_cap cap;
- GArray *rates, *chans;
- GValue rates_v = { 0 };
- GValue chans_v = { 0 };
- GValue value = { 0 };
- struct sio_enc enc;
- struct sio_conf conf;
- int confs[SIO_NCONF];
- int rate, chan;
- int i, j, k;
- int nconfs;
-
- sndiosink = GST_SNDIOSINK (asink);
-
- GST_DEBUG_OBJECT (sndiosink, "open");
-
- /* conect */
- sndiosink->hdl = sio_open (sndiosink->host, SIO_PLAY, 0);
-
- if (sndiosink->hdl == NULL)
- goto couldnt_connect;
-
- /* Use sndio defaults as the only encodings, but get the supported
- * sample rates and number of channels.
- */
-
- if (!sio_getpar (sndiosink->hdl, &par))
- goto no_server_info;
-
- if (!sio_getcap (sndiosink->hdl, &cap))
- goto no_server_info;
-
- rates = g_array_new (FALSE, FALSE, sizeof (int));
- chans = g_array_new (FALSE, FALSE, sizeof (int));
-
- /* find confs that have the default encoding */
- nconfs = 0;
- for (i = 0; i < cap.nconf; i++) {
- for (j = 0; j < SIO_NENC; j++) {
- if (cap.confs[i].enc & (1 << j)) {
- enc = cap.enc[j];
- if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
- confs[nconfs] = i;
- nconfs++;
- break;
- }
- }
- }
- }
-
- /* find the rates and channels of the confs that have the default encoding */
- for (i = 0; i < nconfs; i++) {
- conf = cap.confs[confs[i]];
- /* rates */
- for (j = 0; j < SIO_NRATE; j++) {
- if (conf.rate & (1 << j)) {
- rate = cap.rate[j];
- for (k = 0; k < rates->len && rate; k++) {
- if (rate == g_array_index (rates, int, k))
- rate = 0;
- }
- /* add in ascending order */
- if (rate) {
- for (k = 0; k < rates->len; k++) {
- if (rate < g_array_index (rates, int, k))
- {
- g_array_insert_val (rates, k, rate);
- break;
- }
- }
- if (k == rates->len)
- g_array_append_val (rates, rate);
- }
- }
- }
- /* channels */
- for (j = 0; j < SIO_NCHAN; j++) {
- if (conf.pchan & (1 << j)) {
- chan = cap.pchan[j];
- for (k = 0; k < chans->len && chan; k++) {
- if (chan == g_array_index (chans, int, k))
- chan = 0;
- }
- /* add in ascending order */
- if (chan) {
- for (k = 0; k < chans->len; k++) {
- if (chan < g_array_index (chans, int, k))
- {
- g_array_insert_val (chans, k, chan);
- break;
- }
- }
- if (k == chans->len)
- g_array_append_val (chans, chan);
- }
- }
- }
- }
- /* not sure how this can happen, but it might */
- if (cap.nconf == 0) {
- g_array_append_val (rates, par.rate);
- g_array_append_val (chans, par.pchan);
- }
-
- g_value_init (&rates_v, GST_TYPE_LIST);
- g_value_init (&chans_v, GST_TYPE_LIST);
- g_value_init (&value, G_TYPE_INT);
-
- for (i = 0; i < rates->len; i++) {
- g_value_set_int (&value, g_array_index (rates, int, i));
- gst_value_list_append_value (&rates_v, &value);
- }
- for (i = 0; i < chans->len; i++) {
- g_value_set_int (&value, g_array_index (chans, int, i));
- gst_value_list_append_value (&chans_v, &value);
- }
-
- g_array_free (rates, TRUE);
- g_array_free (chans, TRUE);
-
- pad_template = gst_static_pad_template_get (&sndio_sink_factory);
- sndiosink->cur_caps =
- gst_caps_copy (gst_pad_template_get_caps (pad_template));
- gst_object_unref (pad_template);
-
- for (i = 0; i < sndiosink->cur_caps->structs->len; i++) {
- GstStructure *s;
-
- s = gst_caps_get_structure (sndiosink->cur_caps, i);
- gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, NULL);
- gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE,
- NULL);
- gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
- // gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX */
- gst_structure_set_value (s, "rate", &rates_v);
- gst_structure_set_value (s, "channels", &chans_v);
- }
-
- return TRUE;
-
- /* ERRORS */
-couldnt_connect:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not establish connection to sndio")),
- ("can't open connection to sndio"));
- return FALSE;
- }
-no_server_info:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Failed to query sndio capabilities")),
- ("couldn't get sndio info!"));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sndiosink_close (GstAudioSink * asink)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- GST_DEBUG_OBJECT (sndiosink, "close");
-
- gst_caps_replace (&sndiosink->cur_caps, NULL);
- sio_close (sndiosink->hdl);
- sndiosink->hdl = NULL;
-
- return TRUE;
-}
-
-static void
-gst_sndiosink_cb (void *addr, int delta)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK ((GstAudioSink *) addr);
-
- sndiosink->realpos += delta;
-
- if (sndiosink->realpos >= sndiosink->playpos)
- sndiosink->latency = 0;
- else
- sndiosink->latency = sndiosink->playpos - sndiosink->realpos;
-}
-
-static gboolean
-gst_sndiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
- struct sio_par par;
- int spec_bpf;
-
- GST_DEBUG_OBJECT (sndiosink, "prepare");
-
- sndiosink->playpos = sndiosink->realpos = sndiosink->latency = 0;
-
- sio_initpar (&par);
- par.sig = spec->sign;
- par.le = !spec->bigend;
- par.bits = spec->width;
- // par.bps = spec->depth / 8; /* XXX */
- par.rate = spec->rate;
- par.pchan = spec->channels;
-
- spec_bpf = ((spec->width / 8) * spec->channels);
-
- par.appbufsz = (spec->segsize * spec->segtotal) / spec_bpf;
-
- if (!sio_setpar (sndiosink->hdl, &par))
- goto cannot_configure;
-
- sio_getpar (sndiosink->hdl, &par);
-
- spec->sign = par.sig;
- spec->bigend = !par.le;
- spec->width = par.bits;
- // spec->depth = par.bps * 8; /* XXX */
- spec->rate = par.rate;
- spec->channels = par.pchan;
-
- sndiosink->bpf = par.bps * par.pchan;
-
- spec->segsize = par.round * par.pchan * par.bps;
- spec->segtotal = par.bufsz / par.round;
-
- /* FIXME: this is wrong for signed ints (and the
- * audioringbuffers should do it for us anyway) */
- spec->silence_sample[0] = 0;
- spec->silence_sample[1] = 0;
- spec->silence_sample[2] = 0;
- spec->silence_sample[3] = 0;
-
- sio_onmove (sndiosink->hdl, gst_sndiosink_cb, sndiosink);
-
- if (!sio_start (sndiosink->hdl))
- goto cannot_start;
-
- GST_INFO_OBJECT (sndiosink, "successfully opened connection to sndio");
-
- return TRUE;
-
- /* ERRORS */
-cannot_configure:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not configure sndio")), ("can't configure sndio"));
- return FALSE;
- }
-cannot_start:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
- (_("Could not start sndio")), ("can't start sndio"));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sndiosink_unprepare (GstAudioSink * asink)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- if (sndiosink->hdl == NULL)
- return TRUE;
-
- sio_stop (sndiosink->hdl);
-
- return TRUE;
-}
-
-static guint
-gst_sndiosink_write (GstAudioSink * asink, gpointer data, guint length)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
- guint done;
-
- done = sio_write (sndiosink->hdl, data, length);
-
- if (done == 0)
- goto write_error;
-
- sndiosink->playpos += (done / sndiosink->bpf);
-
- data = (char *) data + done;
-
- return done;
-
- /* ERRORS */
-write_error:
- {
- GST_ELEMENT_ERROR (sndiosink, RESOURCE, WRITE,
- ("Failed to write data to sndio"), GST_ERROR_SYSTEM);
- return 0;
- }
-}
-
-static guint
-gst_sndiosink_delay (GstAudioSink * asink)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
-
- if (sndiosink->latency == (guint) - 1) {
- GST_WARNING_OBJECT (asink, "couldn't get latency");
- return 0;
- }
-
- GST_DEBUG_OBJECT (asink, "got latency: %u", sndiosink->latency);
-
- return sndiosink->latency;
-}
-
-static void
-gst_sndiosink_reset (GstAudioSink * asink)
-{
- /* no way to flush the buffers with sndio ? */
-
- GST_DEBUG_OBJECT (asink, "reset called");
-}
-
-static void
-gst_sndiosink_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_free (sndiosink->host);
- sndiosink->host = g_value_dup_string (value);
- break;
- default:
- break;
- }
-}
-
-static void
-gst_sndiosink_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstSndioSink *sndiosink = GST_SNDIOSINK (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_value_set_string (value, sndiosink->host);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
diff --git a/ext/sndio/sndiosink.h b/ext/sndio/sndiosink.h
deleted file mode 100644
index 25bb8799b..000000000
--- a/ext/sndio/sndiosink.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef __GST_SNDIOSINK_H__
-#define __GST_SNDIOSINK_H__
-
-#include <sndio.h>
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiosink.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SNDIOSINK \
- (gst_sndiosink_get_type())
-#define GST_SNDIOSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SNDIOSINK,GstSndioSink))
-#define GST_SNDIOSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SNDIOSINK,GstSndioSinkClass))
-#define GST_IS_SNDIOSINK(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SNDIOSINK))
-#define GST_IS_SNDIOSINK_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SNDIOSINK))
-
-typedef struct _GstSndioSink GstSndioSink;
-typedef struct _GstSndioSinkClass GstSndioSinkClass;
-
-struct _GstSndioSink {
- GstAudioSink sink;
-
- struct sio_hdl *hdl;
- gchar *host;
-
- /* bytes per frame */
- int bpf;
-
- /* frames counts */
- volatile long long realpos;
- volatile long long playpos;
- volatile guint latency;
-
- GstCaps *cur_caps;
-};
-
-struct _GstSndioSinkClass {
- GstAudioSinkClass parent_class;
-};
-
-GType gst_sndiosink_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_SNDIOSINK_H__ */
diff --git a/ext/sndio/sndiosrc.c b/ext/sndio/sndiosrc.c
deleted file mode 100644
index 5721f42d1..000000000
--- a/ext/sndio/sndiosrc.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/**
- * SECTION:element-sndiosrc
- * @see_also: #GstAutoAudioSrc
- *
- * <refsect2>
- * <para>
- * This element retrieves samples from a sound card using sndio.
- * </para>
- * <para>
- * Simple example pipeline that records an Ogg/Vorbis file via sndio:
- * <programlisting>
- * gst-launch-1.0 -v sndiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=foo.ogg
- * </programlisting>
- * </para>
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sndiosrc.h"
-#include <unistd.h>
-#include <errno.h>
-
-#include <gst/gst-i18n-plugin.h>
-
-GST_DEBUG_CATEGORY_EXTERN (gst_sndio_debug);
-#define GST_CAT_DEFAULT gst_sndio_debug
-
-enum
-{
- PROP_0,
- PROP_HOST
-};
-
-static GstStaticPadTemplate sndio_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { 1234, 4321 }, "
- "signed = (boolean) { TRUE, FALSE }, "
- "width = (int) { 8, 16, 24, 32 }, "
- "depth = (int) { 8, 16, 24, 32 }, "
- "rate = (int) [ 8000, 192000 ], " "channels = (int) [ 1, 16 ] ")
- );
-
-static void gst_sndiosrc_finalize (GObject * object);
-
-static GstCaps *gst_sndiosrc_getcaps (GstBaseSrc * bsrc);
-
-static gboolean gst_sndiosrc_open (GstAudioSrc * asrc);
-static gboolean gst_sndiosrc_close (GstAudioSrc * asrc);
-static gboolean gst_sndiosrc_prepare (GstAudioSrc * asrc,
- GstRingBufferSpec * spec);
-static gboolean gst_sndiosrc_unprepare (GstAudioSrc * asrc);
-static guint gst_sndiosrc_read (GstAudioSrc * asrc, gpointer data,
- guint length);
-static guint gst_sndiosrc_delay (GstAudioSrc * asrc);
-static void gst_sndiosrc_reset (GstAudioSrc * asrc);
-
-static void gst_sndiosrc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_sndiosrc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void gst_sndiosrc_cb (void *addr, int delta);
-
-GST_BOILERPLATE (GstSndioSrc, gst_sndiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
-
-static void
-gst_sndiosrc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_static_metadata (element_class,
- "Sndio audio source",
- "Source/Audio",
- "Records audio through sndio", "Jacob Meuser <jakemsr@sdf.lonestar.org>");
-
- gst_element_class_add_static_pad_template (element_class, &sndio_src_factory);
-}
-
-static void
-gst_sndiosrc_class_init (GstSndioSrcClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSrcClass *gstbasesrc_class;
- GstBaseAudioSrcClass *gstbaseaudiosrc_class;
- GstAudioSrcClass *gstaudiosrc_class;
-
- gobject_class = (GObjectClass *) klass;
- gstbasesrc_class = (GstBaseSrcClass *) klass;
- gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
- gstaudiosrc_class = (GstAudioSrcClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_sndiosrc_finalize;
-
- gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosrc_getcaps);
-
- gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_sndiosrc_open);
- gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_sndiosrc_close);
- gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosrc_prepare);
- gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosrc_unprepare);
- gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_sndiosrc_read);
- gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosrc_delay);
- gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosrc_reset);
-
- gobject_class->set_property = gst_sndiosrc_set_property;
- gobject_class->get_property = gst_sndiosrc_get_property;
-
- /* default value is filled in the _init method */
- g_object_class_install_property (gobject_class, PROP_HOST,
- g_param_spec_string ("host", "Host",
- "Device or socket sndio will access", NULL, G_PARAM_READWRITE));
-}
-
-static void
-gst_sndiosrc_init (GstSndioSrc * sndiosrc, GstSndioSrcClass * klass)
-{
- sndiosrc->hdl = NULL;
- sndiosrc->host = g_strdup (g_getenv ("AUDIODEVICE"));
-}
-
-static void
-gst_sndiosrc_finalize (GObject * object)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);
-
- gst_caps_replace (&sndiosrc->cur_caps, NULL);
- g_free (sndiosrc->host);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static GstCaps *
-gst_sndiosrc_getcaps (GstBaseSrc * bsrc)
-{
- GstSndioSrc *sndiosrc;
-
- sndiosrc = GST_SNDIOSRC (bsrc);
-
- /* no hdl, we're done with the template caps */
- if (sndiosrc->cur_caps == NULL) {
- GST_LOG_OBJECT (sndiosrc, "getcaps called, returning template caps");
- return NULL;
- }
-
- GST_LOG_OBJECT (sndiosrc, "returning %" GST_PTR_FORMAT, sndiosrc->cur_caps);
-
- return gst_caps_ref (sndiosrc->cur_caps);
-}
-
-static gboolean
-gst_sndiosrc_open (GstAudioSrc * asrc)
-{
- GstPadTemplate *pad_template;
- GstSndioSrc *sndiosrc;
- struct sio_par par;
- struct sio_cap cap;
- GArray *rates, *chans;
- GValue rates_v = { 0 };
- GValue chans_v = { 0 };
- GValue value = { 0 };
- struct sio_enc enc;
- struct sio_conf conf;
- int confs[SIO_NCONF];
- int rate, chan;
- int i, j, k;
- int nconfs;
-
- sndiosrc = GST_SNDIOSRC (asrc);
-
- GST_DEBUG_OBJECT (sndiosrc, "open");
-
- /* connect */
- sndiosrc->hdl = sio_open (sndiosrc->host, SIO_REC, 0);
-
- if (sndiosrc->hdl == NULL)
- goto couldnt_connect;
-
- /* Use sndio defaults as the only encodings, but get the supported
- * sample rates and number of channels.
- */
-
- if (!sio_getpar (sndiosrc->hdl, &par))
- goto no_server_info;
-
- if (!sio_getcap (sndiosrc->hdl, &cap))
- goto no_server_info;
-
- rates = g_array_new (FALSE, FALSE, sizeof (int));
- chans = g_array_new (FALSE, FALSE, sizeof (int));
-
- /* find confs that have the default encoding */
- nconfs = 0;
- for (i = 0; i < cap.nconf; i++) {
- for (j = 0; j < SIO_NENC; j++) {
- if (cap.confs[i].enc & (1 << j)) {
- enc = cap.enc[j];
- if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
- confs[nconfs] = i;
- nconfs++;
- break;
- }
- }
- }
- }
-
- /* find the rates and channels of the confs that have the default encoding */
- for (i = 0; i < nconfs; i++) {
- conf = cap.confs[confs[i]];
- /* rates */
- for (j = 0; j < SIO_NRATE; j++) {
- if (conf.rate & (1 << j)) {
- rate = cap.rate[j];
- for (k = 0; k < rates->len && rate; k++) {
- if (rate == g_array_index (rates, int, k))
- rate = 0;
- }
- /* add in ascending order */
- if (rate) {
- for (k = 0; k < rates->len; k++) {
- if (rate < g_array_index (rates, int, k))
- {
- g_array_insert_val (rates, k, rate);
- break;
- }
- }
- if (k == rates->len)
- g_array_append_val (rates, rate);
- }
- }
- }
- /* channels */
- for (j = 0; j < SIO_NCHAN; j++) {
- if (conf.rchan & (1 << j)) {
- chan = cap.rchan[j];
- for (k = 0; k < chans->len && chan; k++) {
- if (chan == g_array_index (chans, int, k))
- chan = 0;
- }
- /* add in ascending order */
- if (chan) {
- for (k = 0; k < chans->len; k++) {
- if (chan < g_array_index (chans, int, k))
- {
- g_array_insert_val (chans, k, chan);
- break;
- }
- }
- if (k == chans->len)
- g_array_append_val (chans, chan);
- }
- }
- }
- }
- /* not sure how this can happen, but it might */
- if (cap.nconf == 0) {
- g_array_append_val (rates, par.rate);
- g_array_append_val (chans, par.rchan);
- }
-
- g_value_init (&rates_v, GST_TYPE_LIST);
- g_value_init (&chans_v, GST_TYPE_LIST);
- g_value_init (&value, G_TYPE_INT);
-
- for (i = 0; i < rates->len; i++) {
- g_value_set_int (&value, g_array_index (rates, int, i));
- gst_value_list_append_value (&rates_v, &value);
- }
- for (i = 0; i < chans->len; i++) {
- g_value_set_int (&value, g_array_index (chans, int, i));
- gst_value_list_append_value (&chans_v, &value);
- }
-
- g_array_free (rates, TRUE);
- g_array_free (chans, TRUE);
-
- pad_template = gst_static_pad_template_get (&sndio_src_factory);
- sndiosrc->cur_caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
- gst_object_unref (pad_template);
-
- for (i = 0; i < sndiosrc->cur_caps->structs->len; i++) {
- GstStructure *s;
-
- s = gst_caps_get_structure (sndiosrc->cur_caps, i);
- gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, NULL);
- gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE,
- NULL);
- gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
- // gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX */
- gst_structure_set_value (s, "rate", &rates_v);
- gst_structure_set_value (s, "channels", &chans_v);
- }
-
- return TRUE;
-
- /* ERRORS */
-couldnt_connect:
- {
- GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
- (_("Could not establish connection to sndio")),
- ("can't open connection to sndio"));
- return FALSE;
- }
-no_server_info:
- {
- GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
- (_("Failed to query sndio capabilities")),
- ("couldn't get sndio info!"));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sndiosrc_close (GstAudioSrc * asrc)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
-
- GST_DEBUG_OBJECT (sndiosrc, "close");
-
- gst_caps_replace (&sndiosrc->cur_caps, NULL);
- sio_close (sndiosrc->hdl);
- sndiosrc->hdl = NULL;
-
- return TRUE;
-}
-
-static void
-gst_sndiosrc_cb (void *addr, int delta)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC ((GstAudioSrc *) addr);
-
- sndiosrc->realpos += delta;
-
- if (sndiosrc->readpos >= sndiosrc->realpos)
- sndiosrc->latency = 0;
- else
- sndiosrc->latency = sndiosrc->realpos - sndiosrc->readpos;
-}
-
-static gboolean
-gst_sndiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
- struct sio_par par;
- int spec_bpf;
-
- GST_DEBUG_OBJECT (sndiosrc, "prepare");
-
- sndiosrc->readpos = sndiosrc->realpos = sndiosrc->latency = 0;
-
- sio_initpar (&par);
- par.sig = spec->sign;
- par.le = !spec->bigend;
- par.bits = spec->width;
- // par.bps = spec->depth / 8; /* XXX */
- par.rate = spec->rate;
- par.rchan = spec->channels;
-
- spec_bpf = ((spec->width / 8) * spec->channels);
-
- par.round = spec->segsize / spec_bpf;
- par.appbufsz = (spec->segsize * spec->segtotal) / spec_bpf;
-
- if (!sio_setpar (sndiosrc->hdl, &par))
- goto cannot_configure;
-
- sio_getpar (sndiosrc->hdl, &par);
-
- spec->sign = par.sig;
- spec->bigend = !par.le;
- spec->width = par.bits;
- // spec->depth = par.bps * 8; /* XXX */
- spec->rate = par.rate;
- spec->channels = par.rchan;
-
- sndiosrc->bpf = par.bps * par.rchan;
-
- spec->segsize = par.round * par.rchan * par.bps;
- spec->segtotal = par.bufsz / par.round;
-
- /* FIXME: this is wrong for signed ints (and the
- * audioringbuffers should do it for us anyway) */
- spec->silence_sample[0] = 0;
- spec->silence_sample[1] = 0;
- spec->silence_sample[2] = 0;
- spec->silence_sample[3] = 0;
-
- sio_onmove (sndiosrc->hdl, gst_sndiosrc_cb, sndiosrc);
-
- if (!sio_start (sndiosrc->hdl))
- goto cannot_start;
-
- GST_INFO_OBJECT (sndiosrc, "successfully opened connection to sndio");
-
- return TRUE;
-
- /* ERRORS */
-cannot_configure:
- {
- GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
- (_("Could not configure sndio")), ("can't configure sndio"));
- return FALSE;
- }
-cannot_start:
- {
- GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
- (_("Could not start sndio")), ("can't start sndio"));
- return FALSE;
- }
-}
-
-static gboolean
-gst_sndiosrc_unprepare (GstAudioSrc * asrc)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
-
- if (sndiosrc->hdl == NULL)
- return TRUE;
-
- sio_stop (sndiosrc->hdl);
-
- return TRUE;
-}
-
-static guint
-gst_sndiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
- guint done;
-
- done = sio_read (sndiosrc->hdl, data, length);
-
- if (done == 0)
- goto read_error;
-
- sndiosrc->readpos += (done / sndiosrc->bpf);
-
- data = (char *) data + done;
-
- return done;
-
- /* ERRORS */
-read_error:
- {
- GST_ELEMENT_ERROR (sndiosrc, RESOURCE, READ,
- ("Failed to read data from sndio"), GST_ERROR_SYSTEM);
- return 0;
- }
-}
-
-static guint
-gst_sndiosrc_delay (GstAudioSrc * asrc)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
-
- if (sndiosrc->latency == (guint) - 1) {
- GST_WARNING_OBJECT (asrc, "couldn't get latency");
- return 0;
- }
-
- GST_DEBUG_OBJECT (asrc, "got latency: %u", sndiosrc->latency);
-
- return sndiosrc->latency;
-}
-
-static void
-gst_sndiosrc_reset (GstAudioSrc * asrc)
-{
- /* no way to flush the buffers with sndio ? */
-
- GST_DEBUG_OBJECT (asrc, "reset called");
-}
-
-static void
-gst_sndiosrc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_free (sndiosrc->host);
- sndiosrc->host = g_value_dup_string (value);
- break;
- default:
- break;
- }
-}
-
-static void
-gst_sndiosrc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);
-
- switch (prop_id) {
- case PROP_HOST:
- g_value_set_string (value, sndiosrc->host);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
diff --git a/ext/sndio/sndiosrc.h b/ext/sndio/sndiosrc.h
deleted file mode 100644
index 48e7a2606..000000000
--- a/ext/sndio/sndiosrc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef __GST_SNDIOSRC_H__
-#define __GST_SNDIOSRC_H__
-
-#include <sndio.h>
-
-#include <gst/gst.h>
-#include <gst/audio/gstaudiosrc.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_SNDIOSRC \
- (gst_sndiosrc_get_type())
-#define GST_SNDIOSRC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SNDIOSRC,GstSndioSrc))
-#define GST_SNDIOSRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SNDIOSRC,GstSndioSrcClass))
-#define GST_IS_SNDIOSRC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SNDIOSRC))
-#define GST_IS_SNDIOSRC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SNDIOSRC))
-
-typedef struct _GstSndioSrc GstSndioSrc;
-typedef struct _GstSndioSrcClass GstSndioSrcClass;
-
-struct _GstSndioSrc {
- GstAudioSrc src;
-
- struct sio_hdl *hdl;
- gchar *host;
-
- /* bytes per frame */
- int bpf;
-
- /* frames counts */
- volatile long long realpos;
- volatile long long readpos;
- volatile guint latency;
-
- GstCaps *cur_caps;
-};
-
-struct _GstSndioSrcClass {
- GstAudioSrcClass parent_class;
-};
-
-GType gst_sndiosrc_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GST_SNDIOSRC_H__ */
diff --git a/ext/timidity/gsttimidity.c b/ext/timidity/gsttimidity.c
deleted file mode 100644
index 0b3f3769a..000000000
--- a/ext/timidity/gsttimidity.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- * gsttimdity - timidity plugin for gstreamer
- *
- * Copyright 2007 Wouter Paesen <wouter@blue-gate.be>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/**
- * SECTION:element-timidity
- * @see_also: wildmidi
- *
- * This element renders midi-files as audio streams using
- * <ulink url="http://timidity.sourceforge.net/">Timidity</ulink>.
- *
- * <refsect2>
- * <title>Example pipeline</title>
- * |[
- * gst-launch filesrc location=song.mid ! timidity ! alsasink
- * ]| This example pipeline will parse the midi and render to raw audio which is
- * played via alsa.
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <gst/gst.h>
-#include <string.h>
-
-#include "gsttimidity.h"
-
-#ifndef TIMIDITY_CFG
-#define TIMIDITY_CFG "/etc/timidity.cfg"
-#endif
-
-GST_DEBUG_CATEGORY_STATIC (gst_timidity_debug);
-#define GST_CAT_DEFAULT gst_timidity_debug
-
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- ARG_0,
- /* FILL ME */
-};
-
-static gboolean gst_timidity_src_event (GstPad * pad, GstEvent * event);
-static GstStateChangeReturn gst_timidity_change_state (GstElement * element,
- GstStateChange transition);
-static gboolean gst_timidity_activate (GstPad * pad);
-static gboolean gst_timidity_activatepull (GstPad * pad, gboolean active);
-static void gst_timidity_loop (GstPad * sinkpad);
-static gboolean gst_timidity_src_query (GstPad * pad, GstQuery * query);
-static gboolean gst_timidity_set_song_options (GstTimidity * timidity,
- MidSongOptions * options);
-
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/midi; audio/riff-midi")
- );
-
-static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "rate = (int) 44100, "
- "channels = (int) 2, "
- "endianness = (int) LITTLE_ENDIAN, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true"));
-
-GST_BOILERPLATE (GstTimidity, gst_timidity, GstElement, GST_TYPE_ELEMENT);
-
-static void
-gst_timidity_base_init (gpointer gclass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
- gst_element_class_add_static_pad_template (element_class, &src_factory);
- gst_element_class_add_static_pad_template (element_class, &sink_factory);
- gst_element_class_set_static_metadata (element_class, "Timidity",
- "Codec/Decoder/Audio",
- "Midi Synthesizer Element", "Wouter Paesen <wouter@blue-gate.be>");
-}
-
-/* initialize the plugin's class */
-static void
-gst_timidity_class_init (GstTimidityClass * klass)
-{
- GstElementClass *gstelement_class;
-
- gstelement_class = (GstElementClass *) klass;
- gstelement_class->change_state = gst_timidity_change_state;
-}
-
-/* initialize the new element
- * instantiate pads and add them to element
- * set functions
- * initialize structure
- */
-static void
-gst_timidity_init (GstTimidity * filter, GstTimidityClass * g_class)
-{
- GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);
-
- /* initialise timidity library */
- if (mid_init ((char *) TIMIDITY_CFG) == 0) {
- filter->initialized = TRUE;
- } else {
- GST_WARNING ("can't initialize timidity with config: " TIMIDITY_CFG);
- }
-
- filter->sinkpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "sink"), "sink");
-
- gst_pad_set_activatepull_function (filter->sinkpad,
- gst_timidity_activatepull);
- gst_pad_set_activate_function (filter->sinkpad, gst_timidity_activate);
- gst_pad_set_setcaps_function (filter->sinkpad, gst_pad_set_caps);
- gst_pad_use_fixed_caps (filter->sinkpad);
- gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
-
- filter->srcpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "src"), "src");
-
- gst_pad_set_query_function (filter->srcpad, gst_timidity_src_query);
- gst_pad_set_event_function (filter->srcpad, gst_timidity_src_event);
- gst_pad_use_fixed_caps (filter->srcpad);
- gst_pad_set_setcaps_function (filter->srcpad, gst_pad_set_caps);
-
- gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
-
- filter->song_options->buffer_size = 2048;
- filter->song_options->rate = 44100;
- filter->song_options->format = MID_AUDIO_S16LSB;
- filter->song_options->channels = 2;
-
- gst_timidity_set_song_options (filter, filter->song_options);
-
- gst_segment_init (filter->o_segment, GST_FORMAT_DEFAULT);
-}
-
-static gboolean
-gst_timidity_set_song_options (GstTimidity * timidity, MidSongOptions * options)
-{
- gint64 bps;
-
- switch (options->format) {
- case MID_AUDIO_U8:
- case MID_AUDIO_S8:
- bps = 1;
- break;
- case MID_AUDIO_U16LSB:
- case MID_AUDIO_S16LSB:
- case MID_AUDIO_U16MSB:
- case MID_AUDIO_S16MSB:
- bps = 2;
- break;
- default:
- return FALSE;
- }
-
- bps *= options->channels;
-
- if (options != timidity->song_options)
- memcpy (timidity->song_options, options, sizeof (MidSongOptions));
-
- timidity->bytes_per_frame = bps;
- timidity->time_per_frame = GST_SECOND / (GstClockTime) options->rate;
-
- return TRUE;
-}
-
-static gboolean
-gst_timidity_src_convert (GstTimidity * timidity,
- GstFormat src_format, gint64 src_value,
- GstFormat * dest_format, gint64 * dest_value)
-{
- gboolean res = TRUE;
- gint64 frames;
-
- if (src_format == *dest_format) {
- *dest_value = src_value;
- goto done;
- }
-
- switch (src_format) {
- case GST_FORMAT_TIME:
- frames = src_value / timidity->time_per_frame;
- break;
- case GST_FORMAT_BYTES:
- frames = src_value / (timidity->bytes_per_frame);
- break;
- case GST_FORMAT_DEFAULT:
- frames = src_value;
- break;
- default:
- res = FALSE;
- goto done;
- }
-
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = frames * timidity->time_per_frame;
- break;
- case GST_FORMAT_BYTES:
- *dest_value = frames * timidity->bytes_per_frame;
- break;
- case GST_FORMAT_DEFAULT:
- *dest_value = frames;
- break;
- default:
- res = FALSE;
- break;
- }
-
-done:
- return res;
-}
-
-static gboolean
-gst_timidity_src_query (GstPad * pad, GstQuery * query)
-{
- gboolean res = TRUE;
- GstTimidity *timidity = GST_TIMIDITY (gst_pad_get_parent (pad));
- GstFormat src_format, dst_format;
- gint64 src_value, dst_value;
-
- if (!timidity->song) {
- gst_object_unref (timidity);
- return FALSE;
- }
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_DURATION:
- gst_query_set_duration (query, GST_FORMAT_TIME,
- GST_MSECOND * (gint64) mid_song_get_total_time (timidity->song));
- break;
- case GST_QUERY_POSITION:
- gst_query_set_position (query, GST_FORMAT_TIME,
- timidity->o_segment->last_stop * timidity->time_per_frame);
- break;
- case GST_QUERY_CONVERT:
- gst_query_parse_convert (query, &src_format, &src_value,
- &dst_format, NULL);
-
- res =
- gst_timidity_src_convert (timidity, src_format, src_value,
- &dst_format, &dst_value);
- if (res)
- gst_query_set_convert (query, src_format, src_value, dst_format,
- dst_value);
-
- break;
- case GST_QUERY_FORMATS:
- gst_query_set_formats (query, 3,
- GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
- break;
- case GST_QUERY_SEGMENT:{
- GstFormat format;
- gint64 start, stop;
-
- format = timidity->o_segment->format;
-
- start =
- gst_segment_to_stream_time (timidity->o_segment, format,
- timidity->o_segment->start);
- if ((stop = timidity->o_segment->stop) == -1)
- stop = timidity->o_segment->duration;
- else
- stop = gst_segment_to_stream_time (timidity->o_segment, format, stop);
-
- gst_query_set_segment (query, timidity->o_segment->rate, format, start,
- stop);
- res = TRUE;
- break;
- }
- case GST_QUERY_SEEKING:
- gst_query_set_seeking (query, timidity->o_segment->format,
- TRUE, 0, timidity->o_len);
- break;
- default:
- res = FALSE;
- break;
- }
-
- gst_object_unref (timidity);
- return res;
-}
-
-static gboolean
-gst_timidity_get_upstream_size (GstTimidity * timidity, gint64 * size)
-{
- GstFormat format = GST_FORMAT_BYTES;
- gboolean res = FALSE;
- GstPad *peer = gst_pad_get_peer (timidity->sinkpad);
-
- if (peer != NULL)
- res = gst_pad_query_duration (peer, &format, size) && *size >= 0;
-
- gst_object_unref (peer);
- return res;
-}
-
-static GstSegment *
-gst_timidity_get_segment (GstTimidity * timidity, GstFormat format,
- gboolean update)
-{
- gint64 start = 0, stop = 0, time = 0;
-
- GstSegment *segment = gst_segment_new ();
-
- gst_timidity_src_convert (timidity,
- timidity->o_segment->format, timidity->o_segment->start, &format, &start);
-
- if (timidity->o_segment->stop == GST_CLOCK_TIME_NONE) {
- stop = GST_CLOCK_TIME_NONE;
- } else {
- gst_timidity_src_convert (timidity,
- timidity->o_segment->format, timidity->o_segment->stop, &format, &stop);
- }
-
- gst_timidity_src_convert (timidity,
- timidity->o_segment->format, timidity->o_segment->time, &format, &time);
-
- gst_segment_set_newsegment_full (segment, update,
- timidity->o_segment->rate, timidity->o_segment->applied_rate,
- format, start, stop, time);
-
- segment->last_stop = time;
-
- return segment;
-}
-
-static GstEvent *
-gst_timidity_get_new_segment_event (GstTimidity * timidity, GstFormat format,
- gboolean update)
-{
- GstSegment *segment;
- GstEvent *event;
-
- segment = gst_timidity_get_segment (timidity, format, update);
-
- event = gst_event_new_new_segment_full (update,
- segment->rate, segment->applied_rate, segment->format,
- segment->start, segment->stop, segment->time);
-
- gst_segment_free (segment);
-
- return event;
-}
-
-static gboolean
-gst_timidity_src_event (GstPad * pad, GstEvent * event)
-{
- gboolean res = FALSE;
- GstTimidity *timidity = GST_TIMIDITY (gst_pad_get_parent (pad));
-
- GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEEK:
- {
- gdouble rate;
- GstFormat src_format, dst_format;
- GstSeekFlags flags;
- GstSeekType start_type, stop_type;
- gint64 orig_start, start = 0, stop = 0;
- gboolean flush, update;
-
- if (!timidity->song)
- break;
-
- gst_event_parse_seek (event, &rate, &src_format, &flags,
- &start_type, &orig_start, &stop_type, &stop);
-
- dst_format = GST_FORMAT_DEFAULT;
-
- gst_timidity_src_convert (timidity, src_format, orig_start,
- &dst_format, &start);
- gst_timidity_src_convert (timidity, src_format, stop, &dst_format, &stop);
-
- flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
-
- if (flush) {
- GST_DEBUG ("performing flush");
- gst_pad_push_event (timidity->srcpad, gst_event_new_flush_start ());
- } else {
- gst_pad_stop_task (timidity->sinkpad);
- }
-
- GST_PAD_STREAM_LOCK (timidity->sinkpad);
-
- if (flush) {
- gst_pad_push_event (timidity->srcpad, gst_event_new_flush_stop ());
- }
-
- gst_segment_set_seek (timidity->o_segment, rate, dst_format, flags,
- start_type, start, stop_type, stop, &update);
-
- if (flags & GST_SEEK_FLAG_SEGMENT) {
- GST_DEBUG_OBJECT (timidity, "received segment seek %d, %d",
- (gint) start_type, (gint) stop_type);
- } else {
- GST_DEBUG_OBJECT (timidity, "received normal seek %d",
- (gint) start_type);
- update = FALSE;
- }
-
- gst_pad_push_event (timidity->srcpad,
- gst_timidity_get_new_segment_event (timidity, GST_FORMAT_TIME,
- update));
-
- timidity->o_seek = TRUE;
-
- gst_pad_start_task (timidity->sinkpad,
- (GstTaskFunction) gst_timidity_loop, timidity->sinkpad, NULL);
-
- GST_PAD_STREAM_UNLOCK (timidity->sinkpad);
- GST_DEBUG ("seek done");
- }
- res = TRUE;
- break;
- default:
- break;
- }
-
- g_object_unref (timidity);
- return res;
-}
-
-static gboolean
-gst_timidity_activate (GstPad * sinkpad)
-{
- if (gst_pad_check_pull_range (sinkpad))
- return gst_pad_activate_pull (sinkpad, TRUE);
-
- return FALSE;
-}
-
-static gboolean
-gst_timidity_activatepull (GstPad * pad, gboolean active)
-{
- if (active) {
- return gst_pad_start_task (pad, (GstTaskFunction) gst_timidity_loop, pad,
- NULL);
- } else {
- return gst_pad_stop_task (pad);
- }
-}
-
-static GstBuffer *
-gst_timidity_allocate_buffer (GstTimidity * timidity, gint64 samples)
-{
- return gst_buffer_new_and_alloc (samples * timidity->bytes_per_frame);
-}
-
-static GstBuffer *
-gst_timidity_clip_buffer (GstTimidity * timidity, GstBuffer * buffer)
-{
- gint64 new_start, new_stop;
- gint64 offset, length;
- GstBuffer *out;
-
- return buffer;
-
- if (!gst_segment_clip (timidity->o_segment, GST_FORMAT_DEFAULT,
- GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET_END (buffer),
- &new_start, &new_stop)) {
- gst_buffer_unref (buffer);
- return NULL;
- }
-
- if (GST_BUFFER_OFFSET (buffer) == new_start &&
- GST_BUFFER_OFFSET_END (buffer) == new_stop)
- return buffer;
-
- offset = new_start - GST_BUFFER_OFFSET (buffer);
- length = new_stop - new_start;
-
- out = gst_buffer_create_sub (buffer, offset * timidity->bytes_per_frame,
- length * timidity->bytes_per_frame);
-
- GST_BUFFER_OFFSET (out) = new_start;
- GST_BUFFER_OFFSET_END (out) = new_stop;
- GST_BUFFER_TIMESTAMP (out) = new_start * timidity->time_per_frame;
- GST_BUFFER_DURATION (out) = (new_stop - new_start) * timidity->time_per_frame;
-
- gst_buffer_unref (buffer);
-
- return out;
-}
-
-/* generate audio data and advance internal timers */
-static GstBuffer *
-gst_timidity_fill_buffer (GstTimidity * timidity, GstBuffer * buffer)
-{
- size_t bytes_read;
- gint64 samples;
-
- bytes_read = mid_song_read_wave (timidity->song, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-
- if (bytes_read == 0) {
- gst_buffer_unref (buffer);
- return NULL;
- }
-
- GST_BUFFER_OFFSET (buffer) =
- timidity->o_segment->last_stop * timidity->bytes_per_frame;
- GST_BUFFER_TIMESTAMP (buffer) =
- timidity->o_segment->last_stop * timidity->time_per_frame;
-
- if (bytes_read < GST_BUFFER_SIZE (buffer)) {
- GstBuffer *old = buffer;
-
- buffer = gst_buffer_create_sub (buffer, 0, bytes_read);
- gst_buffer_unref (old);
- }
-
- samples = GST_BUFFER_SIZE (buffer) / timidity->bytes_per_frame;
-
- timidity->o_segment->last_stop += samples;
-
- GST_BUFFER_OFFSET_END (buffer) =
- timidity->o_segment->last_stop * timidity->bytes_per_frame;
- GST_BUFFER_DURATION (buffer) = samples * timidity->time_per_frame;
-
- GST_DEBUG_OBJECT (timidity,
- "generated buffer %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT
- " (%" G_GINT64_FORMAT " samples)",
- GST_TIME_ARGS ((guint64) GST_BUFFER_TIMESTAMP (buffer)),
- GST_TIME_ARGS (((guint64) (GST_BUFFER_TIMESTAMP (buffer) +
- GST_BUFFER_DURATION (buffer)))), samples);
-
- return buffer;
-}
-
-static GstBuffer *
-gst_timidity_get_buffer (GstTimidity * timidity)
-{
- GstBuffer *out;
-
- out =
- gst_timidity_fill_buffer (timidity,
- gst_timidity_allocate_buffer (timidity, 256));
-
- if (!out)
- return NULL;
-
- return gst_timidity_clip_buffer (timidity, out);
-}
-
-static void
-gst_timidity_loop (GstPad * sinkpad)
-{
- GstTimidity *timidity = GST_TIMIDITY (GST_PAD_PARENT (sinkpad));
- GstBuffer *out;
- GstFlowReturn ret;
-
- if (timidity->mididata_size == 0) {
- if (!gst_timidity_get_upstream_size (timidity, &timidity->mididata_size)) {
- GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL),
- ("Unable to get song length"));
- goto paused;
- }
-
- g_free (timidity->mididata);
-
- timidity->mididata = g_malloc (timidity->mididata_size);
- timidity->mididata_offset = 0;
- return;
- }
-
- if (timidity->mididata_offset < timidity->mididata_size) {
- GstBuffer *buffer = NULL;
- gint64 size;
-
- GST_DEBUG_OBJECT (timidity, "loading song");
-
- ret =
- gst_pad_pull_range (timidity->sinkpad, timidity->mididata_offset,
- -1, &buffer);
- if (ret != GST_FLOW_OK) {
- GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL),
- ("Unable to load song"));
- goto paused;
- }
-
- size = timidity->mididata_size - timidity->mididata_offset;
- if (GST_BUFFER_SIZE (buffer) < size)
- size = GST_BUFFER_SIZE (buffer);
-
- memmove (timidity->mididata + timidity->mididata_offset,
- GST_BUFFER_DATA (buffer), size);
- gst_buffer_unref (buffer);
-
- timidity->mididata_offset += size;
- GST_DEBUG_OBJECT (timidity, "Song loaded");
- return;
- }
-
- if (!timidity->song) {
- MidIStream *stream;
- GstTagList *tags = NULL;
- gchar *text;
-
- GST_DEBUG_OBJECT (timidity, "Parsing song");
-
-#if defined(LIBTIMIDITY_VERSION) && LIBTIMIDITY_VERSION < 0x000200L
- stream =
- mid_istream_open_mem (timidity->mididata, timidity->mididata_size, 0);
-#else
- stream = mid_istream_open_mem (timidity->mididata, timidity->mididata_size);
-#endif
-
- timidity->song = mid_song_load (stream, timidity->song_options);
- mid_istream_close (stream);
-
- if (!timidity->song) {
- GST_ELEMENT_ERROR (timidity, STREAM, DECODE, (NULL),
- ("Unable to parse midi"));
- goto paused;
- }
-
- mid_song_start (timidity->song);
- timidity->o_len = (GST_MSECOND *
- (GstClockTime) mid_song_get_total_time (timidity->song)) /
- timidity->time_per_frame;
- gst_segment_set_newsegment (timidity->o_segment, FALSE, 1.0,
- GST_FORMAT_DEFAULT, 0, GST_CLOCK_TIME_NONE, 0);
-
-
- gst_pad_push_event (timidity->srcpad,
- gst_timidity_get_new_segment_event (timidity, GST_FORMAT_TIME, FALSE));
-
- /* extract tags */
- text = mid_song_get_meta (timidity->song, MID_SONG_TEXT);
- if (text) {
- tags = gst_tag_list_new ();
- gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text, NULL);
-
- //g_free (text);
- }
-
- text = mid_song_get_meta (timidity->song, MID_SONG_COPYRIGHT);
- if (text) {
- if (tags == NULL)
- tags = gst_tag_list_new ();
- gst_tag_list_add (tags, GST_TAG_MERGE_APPEND,
- GST_TAG_COPYRIGHT, text, NULL);
-
- //g_free (text);
- }
-
- if (tags) {
- gst_element_found_tags (GST_ELEMENT (timidity), tags);
- }
-
- GST_DEBUG_OBJECT (timidity, "Parsing song done");
- return;
- }
-
- if (timidity->o_segment_changed) {
- GstSegment *segment = gst_timidity_get_segment (timidity, GST_FORMAT_TIME,
- !timidity->o_new_segment);
-
- GST_LOG_OBJECT (timidity,
- "sending newsegment from %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT
- ", pos=%" GST_TIME_FORMAT, GST_TIME_ARGS ((guint64) segment->start),
- GST_TIME_ARGS ((guint64) segment->stop),
- GST_TIME_ARGS ((guint64) segment->time));
-
- if (timidity->o_segment->flags & GST_SEEK_FLAG_SEGMENT) {
- gst_element_post_message (GST_ELEMENT (timidity),
- gst_message_new_segment_start (GST_OBJECT (timidity),
- segment->format, segment->start));
- }
-
- gst_segment_free (segment);
- timidity->o_segment_changed = FALSE;
- return;
- }
-
- if (timidity->o_seek) {
- /* perform a seek internally */
- timidity->o_segment->last_stop = timidity->o_segment->time;
- mid_song_seek (timidity->song,
- (timidity->o_segment->last_stop * timidity->time_per_frame) /
- GST_MSECOND);
- }
-
- out = gst_timidity_get_buffer (timidity);
- if (!out) {
- GST_LOG_OBJECT (timidity, "Song ended, generating eos");
- gst_pad_push_event (timidity->srcpad, gst_event_new_eos ());
- timidity->o_seek = FALSE;
- goto paused;
- }
-
- if (timidity->o_seek) {
- GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT);
- timidity->o_seek = FALSE;
- }
-
- gst_buffer_set_caps (out, timidity->out_caps);
- ret = gst_pad_push (timidity->srcpad, out);
-
- if (ret == GST_FLOW_UNEXPECTED)
- goto eos;
- else if (ret < GST_FLOW_UNEXPECTED || ret == GST_FLOW_NOT_LINKED)
- goto error;
-
- return;
-
-paused:
- {
- GST_DEBUG_OBJECT (timidity, "pausing task");
- gst_pad_pause_task (timidity->sinkpad);
- return;
- }
-eos:
- {
- gst_pad_push_event (timidity->srcpad, gst_event_new_eos ());
- goto paused;
- }
-error:
- {
- GST_ELEMENT_FLOW_ERROR (timidity, ret);
- gst_pad_push_event (timidity->srcpad, gst_event_new_eos ());
- goto paused;
- }
-}
-
-static GstStateChangeReturn
-gst_timidity_change_state (GstElement * element, GstStateChange transition)
-{
- GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
- GstTimidity *timidity = GST_TIMIDITY (element);
-
- if (!timidity->initialized) {
- GST_WARNING ("Timidity renderer is not initialized");
- return GST_STATE_CHANGE_FAILURE;
- }
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- timidity->out_caps =
- gst_caps_copy (gst_pad_get_pad_template_caps (timidity->srcpad));
- timidity->mididata = NULL;
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- timidity->mididata_size = 0;
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (timidity->song)
- mid_song_free (timidity->song);
- timidity->song = NULL;
- timidity->mididata_size = 0;
- if (timidity->mididata) {
- g_free (timidity->mididata);
- timidity->mididata = NULL;
- }
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_caps_unref (timidity->out_caps);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- GST_DEBUG_CATEGORY_INIT (gst_timidity_debug, "timidity",
- 0, "Timidity plugin");
-
- return gst_element_register (plugin, "timidity",
- GST_RANK_PRIMARY, GST_TYPE_TIMIDITY);
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- timidity,
- "Timidity Plugin",
- plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/timidity/gsttimidity.h b/ext/timidity/gsttimidity.h
deleted file mode 100644
index 4e9350b73..000000000
--- a/ext/timidity/gsttimidity.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * gsttimdity - timidity plugin for gstreamer
- *
- * Copyright 2007 Wouter Paesen <wouter@blue-gate.be>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- * Wrapper element for libtimidity. This element works in pull
- * based mode because that's essentially how libtimidity works.
- * We create a libtimidity stream that operates on the srcpad.
- * The sinkpad is in pull mode.
- */
-
-#ifndef __GST_TIMIDITY_H__
-#define __GST_TIMIDITY_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-#include <timidity.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_TIMIDITY \
- (gst_timidity_get_type())
-#define GST_TIMIDITY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TIMIDITY,GstTimidity))
-#define GST_TIMIDITY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TIMIDITY,GstTimidityClass))
-#define GST_IS_TIMIDITY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIMIDITY))
-#define GST_IS_TIMIDITY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIMIDITY))
-typedef struct _GstTimidity GstTimidity;
-typedef struct _GstTimidityClass GstTimidityClass;
-
-struct _GstTimidity
-{
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
-
- gboolean initialized;
-
- /* input stream properties */
- gint64 mididata_size, mididata_offset;
- gchar *mididata;
- gboolean mididata_filled;
-
- MidSong *song;
-
- /* output data */
- gboolean o_new_segment, o_segment_changed, o_seek;
- GstSegment o_segment[1];
- gint64 o_len;
-
- /* format of the stream */
- MidSongOptions song_options[1];
- gint64 bytes_per_frame;
- GstClockTime time_per_frame;
-
- GstCaps *out_caps;
-};
-
-struct _GstTimidityClass
-{
- GstElementClass parent_class;
-};
-
-GType gst_timidity_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_TIMIDITY_H__ */
diff --git a/ext/timidity/Makefile.am b/ext/wildmidi/Makefile.am
index 9ec7bbd83..7dfdc883f 100644
--- a/ext/timidity/Makefile.am
+++ b/ext/wildmidi/Makefile.am
@@ -1,20 +1,6 @@
# plugindir is set in configure
plugin_LTLIBRARIES =
-if USE_TIMIDITY
-plugin_LTLIBRARIES += libgsttimidity.la
-
-# sources used to compile this plug-in
-libgsttimidity_la_SOURCES = gsttimidity.c
-
-# flags used to compile this plugin
-# add other _CFLAGS and _LIBS as needed
-libgsttimidity_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(TIMIDITY_CFLAGS)
-libgsttimidity_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(TIMIDITY_LIBS)
-libgsttimidity_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgsttimidity_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-endif
-
if USE_WILDMIDI
plugin_LTLIBRARIES += libgstwildmidi.la
@@ -29,5 +15,5 @@ libgstwildmidi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstwildmidi_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
endif
-noinst_HEADERS = gsttimidity.h gstwildmidi.h
+noinst_HEADERS = gstwildmidi.h
diff --git a/ext/timidity/README b/ext/wildmidi/README
index f883cd002..f883cd002 100644
--- a/ext/timidity/README
+++ b/ext/wildmidi/README
diff --git a/ext/timidity/gstwildmidi.c b/ext/wildmidi/gstwildmidi.c
index 7f380d6da..7f380d6da 100644
--- a/ext/timidity/gstwildmidi.c
+++ b/ext/wildmidi/gstwildmidi.c
diff --git a/ext/timidity/gstwildmidi.h b/ext/wildmidi/gstwildmidi.h
index 54a915b30..54a915b30 100644
--- a/ext/timidity/gstwildmidi.h
+++ b/ext/wildmidi/gstwildmidi.h
diff --git a/ext/xvid/Makefile.am b/ext/xvid/Makefile.am
deleted file mode 100644
index 016f3736a..000000000
--- a/ext/xvid/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-plugin_LTLIBRARIES = libgstxvid.la
-
-libgstxvid_la_SOURCES = gstxvidenc.c gstxviddec.c gstxvid.c
-libgstxvid_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(XVID_CFLAGS)
-libgstxvid_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(XVID_LIBS)
-libgstxvid_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstxvid_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = gstxvidenc.h gstxviddec.h gstxvid.h
diff --git a/ext/xvid/gstxvid.c b/ext/xvid/gstxvid.c
deleted file mode 100644
index 9d0d150cc..000000000
--- a/ext/xvid/gstxvid.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* GStreamer xvid encoder/decoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <xvid.h>
-
-#include <gst/video/video.h>
-#include "gstxviddec.h"
-#include "gstxvidenc.h"
-
-gboolean
-gst_xvid_init (void)
-{
- xvid_gbl_init_t xinit;
- gint ret;
- static gboolean is_init = FALSE;
-
- /* only init once */
- if (is_init == TRUE) {
- return TRUE;
- }
-
- /* set up xvid initially (function pointers, CPU flags) */
- gst_xvid_init_struct (xinit);
-
- if ((ret = xvid_global (NULL, XVID_GBL_INIT, &xinit, NULL)) < 0) {
- g_warning ("Failed to initialize XviD: %s (%d)", gst_xvid_error (ret), ret);
- return FALSE;
- }
-
- GST_LOG ("Initted XviD version %d.%d.%d (API %d.%d)",
- XVID_VERSION_MAJOR (XVID_VERSION),
- XVID_VERSION_MINOR (XVID_VERSION),
- XVID_VERSION_PATCH (XVID_VERSION),
- XVID_API_MAJOR (XVID_API), XVID_API_MINOR (XVID_API));
-
- is_init = TRUE;
- return TRUE;
-}
-
-const gchar *
-gst_xvid_error (int errorcode)
-{
- const gchar *error;
-
- switch (errorcode) {
- case XVID_ERR_FAIL:
- error = "Operation failed";
- break;
- case 0:
- error = "No error";
- break;
- case XVID_ERR_MEMORY:
- error = "Memory allocation error";
- break;
- case XVID_ERR_FORMAT:
- error = "File format not supported";
- break;
- case XVID_ERR_VERSION:
- error = "Structure version not supported";
- break;
- default:
- error = "Unknown error";
- break;
- }
-
- return error;
-}
-
-gint
-gst_xvid_structure_to_csp (GstStructure * structure)
-{
- const gchar *mime = gst_structure_get_name (structure);
- gint xvid_cs = -1;
-
- if (!strcmp (mime, "video/x-raw-yuv")) {
- guint32 fourcc;
-
- gst_structure_get_fourcc (structure, "format", &fourcc);
- switch (fourcc) {
- case GST_MAKE_FOURCC ('I', '4', '2', '0'):
- xvid_cs = XVID_CSP_I420;
- break;
- case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
- xvid_cs = XVID_CSP_YUY2;
- break;
- case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
- xvid_cs = XVID_CSP_YV12;
- break;
- case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
- xvid_cs = XVID_CSP_UYVY;
- break;
- case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
- xvid_cs = XVID_CSP_YVYU;
- break;
- }
- } else {
- gint depth, bpp, r_mask;
-
- gst_structure_get_int (structure, "depth", &depth);
- gst_structure_get_int (structure, "bpp", &bpp);
- gst_structure_get_int (structure, "red_mask", &r_mask);
-
- switch (depth) {
- case 15:
- xvid_cs = XVID_CSP_RGB555;
- break;
- case 16:
- xvid_cs = XVID_CSP_RGB565;
- break;
- case 24:
- if (bpp == 24) {
- xvid_cs = XVID_CSP_BGR;
- } else {
- switch (r_mask) {
- case 0xff000000:
- xvid_cs = XVID_CSP_RGBA;
- break;
-#ifdef XVID_CSP_ARGB
- case 0x00ff0000:
- xvid_cs = XVID_CSP_ARGB;
- break;
-#endif
- case 0x0000ff00:
- xvid_cs = XVID_CSP_BGRA;
- break;
- case 0x000000ff:
- xvid_cs = XVID_CSP_ABGR;
- break;
- }
- }
- break;
- default:
- break;
- }
-
- }
-
- return xvid_cs;
-}
-
-GstCaps *
-gst_xvid_csp_to_caps (gint csp, gint w, gint h)
-{
- GstStructure *structure = NULL;
-
- switch (csp) {
- case XVID_CSP_RGB555:
- case XVID_CSP_RGB565:
- case XVID_CSP_BGR:
- case XVID_CSP_ABGR:
- case XVID_CSP_BGRA:
-#ifdef XVID_CSP_ARGB
- case XVID_CSP_ARGB:
-#endif
- case XVID_CSP_RGBA:{
- gint r_mask = 0, b_mask = 0, g_mask = 0,
- endianness = 0, bpp = 0, depth = 0;
-
- switch (csp) {
- case XVID_CSP_RGB555:
- r_mask = GST_VIDEO_COMP1_MASK_15_INT;
- g_mask = GST_VIDEO_COMP2_MASK_15_INT;
- b_mask = GST_VIDEO_COMP3_MASK_15_INT;
- endianness = G_BYTE_ORDER;
- depth = 15;
- bpp = 16;
- break;
- case XVID_CSP_RGB565:
- r_mask = GST_VIDEO_COMP1_MASK_16_INT;
- g_mask = GST_VIDEO_COMP2_MASK_16_INT;
- b_mask = GST_VIDEO_COMP3_MASK_16_INT;
- endianness = G_BYTE_ORDER;
- depth = 16;
- bpp = 16;
- break;
- case XVID_CSP_BGR:
- r_mask = 0x0000ff;
- g_mask = 0x00ff00;
- b_mask = 0xff0000;
- endianness = G_BIG_ENDIAN;
- depth = 24;
- bpp = 24;
- break;
- case XVID_CSP_ABGR:
- r_mask = 0x000000ff;
- g_mask = 0x0000ff00;
- b_mask = 0x00ff0000;
- endianness = G_BIG_ENDIAN;
- depth = 24;
- bpp = 32;
- break;
- case XVID_CSP_BGRA:
- r_mask = 0x0000ff00;
- g_mask = 0x00ff0000;
- b_mask = 0xff000000;
- endianness = G_BIG_ENDIAN;
- depth = 24;
- bpp = 32;
- break;
-#ifdef XVID_CSP_ARGB
- case XVID_CSP_ARGB:
- r_mask = 0x00ff0000;
- g_mask = 0x0000ff00;
- b_mask = 0x000000ff;
- endianness = G_BIG_ENDIAN;
- depth = 24;
- bpp = 32;
- break;
-#endif
- case XVID_CSP_RGBA:
- r_mask = 0xff000000;
- g_mask = 0x00ff0000;
- b_mask = 0x0000ff00;
- endianness = G_BIG_ENDIAN;
- depth = 24;
- bpp = 32;
- break;
- }
-
- structure = gst_structure_new ("video/x-raw-rgb",
- "width", G_TYPE_INT, w,
- "height", G_TYPE_INT, h,
- "depth", G_TYPE_INT, depth,
- "bpp", G_TYPE_INT, bpp,
- "endianness", G_TYPE_INT, endianness,
- "red_mask", G_TYPE_INT, r_mask,
- "green_mask", G_TYPE_INT, g_mask,
- "blue_mask", G_TYPE_INT, b_mask, NULL);
- break;
- }
-
- case XVID_CSP_YUY2:
- case XVID_CSP_YVYU:
- case XVID_CSP_UYVY:
- case XVID_CSP_I420:
- case XVID_CSP_YV12:{
- guint32 fourcc = 0;
-
- switch (csp) {
- case XVID_CSP_YUY2:
- fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
- break;
- case XVID_CSP_YVYU:
- fourcc = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
- break;
- case XVID_CSP_UYVY:
- fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
- break;
- case XVID_CSP_I420:
- fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
- break;
- case XVID_CSP_YV12:
- fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
- break;
- }
-
- structure = gst_structure_new ("video/x-raw-yuv",
- "width", G_TYPE_INT, w,
- "height", G_TYPE_INT, h, "format", GST_TYPE_FOURCC, fourcc, NULL);
- break;
- }
- }
-
- return gst_caps_new_full (structure, NULL);
-}
-
-
-gint
-gst_xvid_image_get_size (gint csp, gint width, gint height)
-{
- xvid_image_t dummy_im;
-
- return gst_xvid_image_fill (&dummy_im, NULL, csp, width, height);
-}
-
-gint
-gst_xvid_image_fill (xvid_image_t * im, void *ptr, gint csp,
- gint width, gint height)
-{
- gint stride, h2, size = 0;
-
- im->csp = csp;
-
- switch (csp) {
- case XVID_CSP_I420:
- case XVID_CSP_YV12:
- /* planar */
- /* luma */
- stride = GST_ROUND_UP_4 (width);
- h2 = GST_ROUND_UP_2 (height);
- im->stride[0] = stride;
- im->plane[0] = ptr;
- /* chroma */
- im->plane[1] = ((guint8 *) im->plane[0]) + (stride * h2);
- size += stride * height;
- stride = GST_ROUND_UP_8 (width) / 2;
- h2 = GST_ROUND_UP_2 (height) / 2;
- im->stride[1] = stride;
-
- im->plane[2] = ((guint8 *) im->plane[1]) + (stride * h2);
- im->stride[2] = stride;
- size += 2 * (stride * h2);
- break;
- case XVID_CSP_RGB555:
- case XVID_CSP_RGB565:
- case XVID_CSP_YUY2:
- case XVID_CSP_UYVY:
- case XVID_CSP_YVYU:
- /* packed */
- stride = GST_ROUND_UP_4 (width * 2);
- im->plane[0] = ptr;
- im->stride[0] = stride;
- size = stride * height;
- break;
- case XVID_CSP_BGR:
- stride = GST_ROUND_UP_4 (width * 3);
- im->plane[0] = ptr;
- im->stride[0] = stride;
- size = stride * height * 2;
- break;
- case XVID_CSP_ABGR:
- case XVID_CSP_BGRA:
- case XVID_CSP_RGBA:
-#ifdef XVID_CSP_ARGB
- case XVID_CSP_ARGB:
-#endif
- stride = width * 4;
- im->plane[0] = ptr;
- im->stride[0] = stride;
- size = stride * height;
- break;
- }
-
- return size;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- return (gst_element_register (plugin, "xvidenc",
- GST_RANK_SECONDARY, GST_TYPE_XVIDENC) &&
- gst_element_register (plugin, "xviddec",
- GST_RANK_NONE, GST_TYPE_XVIDDEC));
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- xvid,
- "XviD plugin library", plugin_init, VERSION, "GPL", GST_PACKAGE_NAME,
- GST_PACKAGE_ORIGIN)
diff --git a/ext/xvid/gstxvid.h b/ext/xvid/gstxvid.h
deleted file mode 100644
index fd08ba90e..000000000
--- a/ext/xvid/gstxvid.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* GStreamer xvid encoder/decoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_XVID_H__
-#define __GST_XVID_H__
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define gst_xvid_init_struct(s) \
- do { \
- memset (&s, 0, sizeof(s)); \
- s.version = XVID_VERSION; \
- } while (0);
-
-#define RGB_24_32_STATIC_CAPS(bpp, r_mask,g_mask,b_mask) \
- "video/x-raw-rgb, " \
- "width = (int) [ 0, MAX ], " \
- "height = (int) [ 0, MAX], " \
- "framerate = (fraction) [ 0, MAX], " \
- "depth = (int) 24, " \
- "bpp = (int) " G_STRINGIFY (bpp) ", " \
- "endianness = (int) BIG_ENDIAN, " \
- "red_mask = (int) " G_STRINGIFY (r_mask) ", " \
- "green_mask = (int) " G_STRINGIFY (g_mask) ", " \
- "blue_mask = (int) " G_STRINGIFY (b_mask)
-
-extern const gchar *gst_xvid_error (int errorcode);
-extern gboolean gst_xvid_init (void);
-
-extern gint gst_xvid_structure_to_csp (GstStructure *structure);
-extern GstCaps * gst_xvid_csp_to_caps (gint csp, gint w, gint h);
-extern gint gst_xvid_image_get_size (gint csp,
- gint width, gint height);
-extern gint gst_xvid_image_fill (xvid_image_t * im, void * ptr, gint csp,
- gint width, gint height);
-
-G_END_DECLS
-
-#endif /* __GST_XVID_H__ */
diff --git a/ext/xvid/gstxviddec.c b/ext/xvid/gstxviddec.c
deleted file mode 100644
index b49cf2fad..000000000
--- a/ext/xvid/gstxviddec.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/* GStreamer xvid decoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * (C) 2006 Mark Nauwelaerts <manauw@skynet.be>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <xvid.h>
-
-#include <gst/video/video.h>
-#include "gstxviddec.h"
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-xvid, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0/1, MAX ]; "
- "video/mpeg, "
- "mpegversion = (int) 4, "
- "systemstream = (boolean) FALSE, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0/1, MAX ]")
- );
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, YV12, YVYU, UYVY }")
- "; " RGB_24_32_STATIC_CAPS (32, 0x00ff0000, 0x0000ff00,
- 0x000000ff) "; " RGB_24_32_STATIC_CAPS (32, 0xff000000, 0x00ff0000,
- 0x0000ff00) "; " RGB_24_32_STATIC_CAPS (32, 0x0000ff00, 0x00ff0000,
- 0xff000000) "; " RGB_24_32_STATIC_CAPS (32, 0x000000ff, 0x0000ff00,
- 0x00ff0000) "; " RGB_24_32_STATIC_CAPS (24, 0x0000ff, 0x00ff00,
- 0xff0000) "; " GST_VIDEO_CAPS_RGB_15 "; " GST_VIDEO_CAPS_RGB_16)
- );
-
-GST_DEBUG_CATEGORY_STATIC (xviddec_debug);
-#define GST_CAT_DEFAULT xviddec_debug
-
-static void gst_xviddec_base_init (GstXvidDecClass * klass);
-static void gst_xviddec_class_init (GstXvidDecClass * klass);
-static void gst_xviddec_init (GstXvidDec * dec);
-static void gst_xviddec_reset (GstXvidDec * dec);
-static gboolean gst_xviddec_handle_sink_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_xviddec_chain (GstPad * pad, GstBuffer * buf);
-static gboolean gst_xviddec_setcaps (GstPad * pad, GstCaps * caps);
-static void gst_xviddec_flush_buffers (GstXvidDec * dec, gboolean send);
-static GstStateChangeReturn gst_xviddec_change_state (GstElement * element,
- GstStateChange transition);
-
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_xviddec_get_type (void)
-{
- static GType xviddec_type = 0;
-
- if (!xviddec_type) {
- static const GTypeInfo xviddec_info = {
- sizeof (GstXvidDecClass),
- (GBaseInitFunc) gst_xviddec_base_init,
- NULL,
- (GClassInitFunc) gst_xviddec_class_init,
- NULL,
- NULL,
- sizeof (GstXvidDec),
- 0,
- (GInstanceInitFunc) gst_xviddec_init,
- };
-
- xviddec_type = g_type_register_static (GST_TYPE_ELEMENT,
- "GstXvidDec", &xviddec_info, 0);
- }
- return xviddec_type;
-}
-
-static void
-gst_xviddec_base_init (GstXvidDecClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_static_pad_template (element_class, &sink_template);
- gst_element_class_add_static_pad_template (element_class, &src_template);
-
- gst_element_class_set_static_metadata (element_class, "XviD video decoder",
- "Codec/Decoder/Video",
- "XviD decoder based on xvidcore",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-}
-
-static void
-gst_xviddec_class_init (GstXvidDecClass * klass)
-{
- GstElementClass *gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- GST_DEBUG_CATEGORY_INIT (xviddec_debug, "xviddec", 0, "XviD decoder");
-
- gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_xviddec_change_state);
-}
-
-
-static void
-gst_xviddec_init (GstXvidDec * dec)
-{
- /* create the sink pad */
- dec->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
- gst_pad_set_chain_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xviddec_chain));
- gst_pad_set_setcaps_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xviddec_setcaps));
- gst_pad_set_event_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xviddec_handle_sink_event));
- gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
-
- /* create the src pad */
- dec->srcpad = gst_pad_new_from_static_template (&src_template, "src");
- gst_pad_use_fixed_caps (dec->srcpad);
- gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
-
- gst_xviddec_reset (dec);
-}
-
-
-static void
-gst_xviddec_reset (GstXvidDec * dec)
-{
- /* size, etc. */
- dec->width = dec->height = dec->csp = -1;
- dec->fps_n = dec->par_n = -1;
- dec->fps_d = dec->par_d = 1;
- dec->next_ts = dec->next_dur = GST_CLOCK_TIME_NONE;
- dec->outbuf_size = 0;
-
- /* set xvid handle to NULL */
- dec->handle = NULL;
-
- /* no delayed timestamp to start with */
- dec->have_ts = FALSE;
-
- /* need keyframe to get going */
- dec->waiting_for_key = TRUE;
-}
-
-
-static void
-gst_xviddec_unset (GstXvidDec * dec)
-{
- /* release XviD decoder */
- xvid_decore (dec->handle, XVID_DEC_DESTROY, NULL, NULL);
- dec->handle = NULL;
-}
-
-
-static gboolean
-gst_xviddec_handle_sink_event (GstPad * pad, GstEvent * event)
-{
- GstXvidDec *dec = GST_XVIDDEC (GST_PAD_PARENT (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- gst_xviddec_flush_buffers (dec, TRUE);
- break;
- case GST_EVENT_FLUSH_STOP:
- gst_xviddec_flush_buffers (dec, FALSE);
- break;
- case GST_EVENT_NEWSEGMENT:
- /* don't really mind about the actual segment info,
- * but we do need to recover from this possible jump */
- /* FIXME, NEWSEGMENT is not a discontinuity. A decoder
- * should clip the output to the segment boundaries.
- * Also the rate field of the segment can be used to
- * optimize the decoding, like skipping B frames when
- * playing at double speed.
- * The DISCONT flag on buffers should be used to detect
- * discontinuities.
- */
- dec->waiting_for_key = TRUE;
- break;
- default:
- break;
- }
-
- return gst_pad_push_event (dec->srcpad, event);
-}
-
-
-static gboolean
-gst_xviddec_setup (GstXvidDec * dec)
-{
- xvid_dec_create_t xdec;
- gint ret;
-
- /* initialise parameters, see xvid documentation */
- gst_xvid_init_struct (xdec);
- /* let the decoder handle this, don't trust the container */
- xdec.width = 0;
- xdec.height = 0;
- xdec.handle = NULL;
-
- GST_DEBUG_OBJECT (dec, "Initializing xvid decoder with parameters "
- "%dx%d@%d", dec->width, dec->height, dec->csp);
-
- if ((ret = xvid_decore (NULL, XVID_DEC_CREATE, &xdec, NULL)) < 0) {
- GST_WARNING_OBJECT (dec, "Initializing xvid decoder failed: %s (%d)",
- gst_xvid_error (ret), ret);
- return FALSE;
- }
-
- dec->handle = xdec.handle;
-
- return TRUE;
-}
-
-
-static void
-gst_xviddec_add_par (GstStructure * structure,
- gint mux_par_n, gint mux_par_d, gint dec_par_n, gint dec_par_d)
-{
- /* muxer wins if decoder has nothing interesting to offer */
- if (dec_par_n == dec_par_d) {
- gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION,
- mux_par_n, mux_par_d, NULL);
- } else {
- gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION,
- dec_par_n, dec_par_d, NULL);
- }
-}
-
-
-/* based on the decoder info, if provided, and xviddec info,
- construct a caps and send on to src pad */
-static gboolean
-gst_xviddec_negotiate (GstXvidDec * dec, xvid_dec_stats_t * xstats)
-{
- gboolean ret;
- gint par_width, par_height;
- GstCaps *caps;
-
- /* note: setcaps call with no xstats info,
- so definitely need to negotiate then */
- if (xstats && (xstats->type != XVID_TYPE_VOL
- || (xstats->type == XVID_TYPE_VOL
- && dec->width == xstats->data.vol.width
- && dec->height == xstats->data.vol.height)))
- return TRUE;
-
- switch (xstats ? xstats->data.vol.par : XVID_PAR_11_VGA) {
- case XVID_PAR_11_VGA:
- par_width = par_height = 1;
- break;
- case XVID_PAR_43_PAL:
- case XVID_PAR_43_NTSC:
- par_width = 4;
- par_height = 3;
- break;
- case XVID_PAR_169_PAL:
- case XVID_PAR_169_NTSC:
- par_width = 16;
- par_height = 9;
- break;
- case XVID_PAR_EXT:
- default:
- par_width = xstats->data.vol.par_width;
- par_height = xstats->data.vol.par_height;
- }
-
- caps = gst_xvid_csp_to_caps (dec->csp, dec->width, dec->height);
-
- /* can only provide framerate if we received one */
- if (dec->fps_n != -1) {
- gst_structure_set (gst_caps_get_structure (caps, 0), "framerate",
- GST_TYPE_FRACTION, dec->fps_n, dec->fps_d, NULL);
- }
-
- gst_xviddec_add_par (gst_caps_get_structure (caps, 0),
- dec->par_n, dec->par_d, par_width, par_height);
-
- GST_LOG ("setting caps on source pad: %" GST_PTR_FORMAT, caps);
- ret = gst_pad_set_caps (dec->srcpad, caps);
- gst_caps_unref (caps);
-
- return ret;
-}
-
-static GstFlowReturn
-gst_xviddec_chain (GstPad * pad, GstBuffer * buf)
-{
- GstXvidDec *dec;
- GstBuffer *outbuf = NULL;
- xvid_dec_frame_t xframe;
- xvid_dec_stats_t xstats;
- gint ret;
- guint8 *data, *dupe = NULL;
- guint size;
- GstFlowReturn fret;
-
- dec = GST_XVIDDEC (GST_OBJECT_PARENT (pad));
-
- if (!dec->handle)
- goto not_negotiated;
-
- fret = GST_FLOW_OK;
-
- GST_LOG_OBJECT (dec, "Received buffer of time %" GST_TIME_FORMAT
- " duration %" GST_TIME_FORMAT ", size %d",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_SIZE (buf));
-
- if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
- /* FIXME: should we do anything here, like flush the decoder? */
- }
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- /* xvidcore overreads the input buffer, we need to alloc some extra padding
- * to make things work reliably */
-#define EXTRA_PADDING 16
- if (EXTRA_PADDING > 0) {
- dupe = g_malloc (size + EXTRA_PADDING);
- memcpy (dupe, data, size);
- memset (dupe + size, 0, EXTRA_PADDING);
- data = dupe;
- }
-
- do { /* loop needed because xvidcore may return vol information */
- /* decode and so ... */
- gst_xvid_init_struct (xframe);
- xframe.general = XVID_LOWDELAY;
- xframe.bitstream = (void *) data;
- xframe.length = size;
-
- gst_xvid_init_struct (xstats);
-
- if (outbuf == NULL) {
- fret = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
- dec->outbuf_size, GST_PAD_CAPS (dec->srcpad), &outbuf);
- if (fret != GST_FLOW_OK)
- goto done;
- }
-
- gst_xvid_image_fill (&xframe.output, GST_BUFFER_DATA (outbuf),
- dec->csp, dec->width, dec->height);
-
- ret = xvid_decore (dec->handle, XVID_DEC_DECODE, &xframe, &xstats);
- if (ret < 0)
- goto decode_error;
-
- GST_LOG_OBJECT (dec, "xvid produced output, type %d, consumed %d",
- xstats.type, ret);
-
- if (xstats.type == XVID_TYPE_VOL)
- gst_xviddec_negotiate (dec, &xstats);
-
- data += ret;
- size -= ret;
- } while (xstats.type <= 0 && size > 0);
-
- /* 1 byte is frequently left over */
- if (size > 1) {
- GST_WARNING_OBJECT (dec, "decoder did not consume all input");
- }
-
- /* FIXME, reflow the multiple return exit points */
- if (xstats.type > 0) { /* some real output was produced */
- if (G_UNLIKELY (dec->waiting_for_key)) {
- if (xstats.type != XVID_TYPE_IVOP)
- goto dropping;
-
- dec->waiting_for_key = FALSE;
- }
- /* bframes can cause a delay in frames being returned
- non keyframe timestamps can permute a bit between
- encode and display order, but should match for keyframes */
- if (dec->have_ts) {
- GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
- GST_BUFFER_DURATION (outbuf) = dec->next_dur;
- dec->next_ts = GST_BUFFER_TIMESTAMP (buf);
- dec->next_dur = GST_BUFFER_DURATION (buf);
- } else {
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
- }
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (dec->srcpad));
- GST_LOG_OBJECT (dec, "pushing buffer with pts %" GST_TIME_FORMAT
- " duration %" GST_TIME_FORMAT,
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
- fret = gst_pad_push (dec->srcpad, outbuf);
-
- } else { /* no real output yet, delay in frames being returned */
- if (G_UNLIKELY (dec->have_ts)) {
- GST_WARNING_OBJECT (dec,
- "xvid decoder produced no output, but timestamp %" GST_TIME_FORMAT
- " already queued", GST_TIME_ARGS (dec->next_ts));
- } else {
- dec->have_ts = TRUE;
- dec->next_ts = GST_BUFFER_TIMESTAMP (buf);
- dec->next_dur = GST_BUFFER_DURATION (buf);
- }
- gst_buffer_unref (outbuf);
- }
-
-done:
- g_free (dupe);
- gst_buffer_unref (buf);
-
- return fret;
-
- /* ERRORS */
-not_negotiated:
- {
- GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
- ("format wasn't negotiated before chain function"));
- fret = GST_FLOW_NOT_NEGOTIATED;
- goto done;
- }
-decode_error:
- {
- /* FIXME: shouldn't error out fatally/properly after N decoding errors? */
- GST_ELEMENT_WARNING (dec, STREAM, DECODE, (NULL),
- ("Error decoding xvid frame: %s (%d)", gst_xvid_error (ret), ret));
- if (outbuf)
- gst_buffer_unref (outbuf);
- goto done;
- }
-dropping:
- {
- GST_WARNING_OBJECT (dec, "Dropping non-keyframe (seek/init)");
- if (outbuf)
- gst_buffer_unref (outbuf);
- goto done;
- }
-}
-
-
-/* flush xvid encoder buffers caused by bframe usage;
- not well tested */
-static void
-gst_xviddec_flush_buffers (GstXvidDec * dec, gboolean send)
-{
-#if 0
- gint ret;
- GstBuffer *outbuf = NULL;
- xvid_dec_frame_t xframe;
- xvid_dec_stats_t xstats;
-#endif
-
- GST_DEBUG_OBJECT (dec, "flushing buffers with send %d, have_ts %d",
- send, dec->have_ts);
-
- /* no need to flush if there is no delayed time-stamp */
- if (!dec->have_ts)
- return;
-
- /* flushing must reset the timestamp keeping */
- dec->have_ts = FALSE;
-
- /* also no need to flush if no handle */
- if (!dec->handle)
- return;
-
- /* unlike encoder, decoder does not seem to like flushing, disable for now */
-#if 0
- gst_xvid_init_struct (xframe);
- gst_xvid_init_struct (xstats);
-
- /* init a fake frame to force flushing */
- xframe.bitstream = NULL;
- xframe.length = -1;
-
- ret = gst_xviddec_decode (dec, xframe, &outbuf, &xstats);
- GST_DEBUG_OBJECT (dec, "received frame when flushing, type %d, size %d",
- xstats.type, ret);
-
- if (ret > 0 && send) {
- /* we have some valid return frame, give it the delayed timestamp and send */
- GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
- GST_BUFFER_DURATION (outbuf) = dec->next_dur;
-
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (dec->srcpad));
- gst_pad_push (dec->srcpad, outbuf);
- return;
- }
-
- if (outbuf)
- gst_buffer_unref (outbuf);
-#else
- return;
-#endif
-}
-
-#if 0
-static GstCaps *
-gst_xviddec_src_getcaps (GstPad * pad)
-{
- GstXvidDec *dec = GST_XVIDDEC (GST_PAD_PARENT (pad));
- GstCaps *caps;
- gint csp[] = {
- XVID_CSP_I420,
- XVID_CSP_YV12,
- XVID_CSP_YUY2,
- XVID_CSP_UYVY,
- XVID_CSP_YVYU,
- XVID_CSP_BGRA,
- XVID_CSP_ABGR,
- XVID_CSP_RGBA,
-#ifdef XVID_CSP_ARGB
- XVID_CSP_ARGB,
-#endif
- XVID_CSP_BGR,
- XVID_CSP_RGB555,
- XVID_CSP_RGB565,
- 0
- }, i;
-
- if (!GST_PAD_CAPS (dec->sinkpad)) {
- GstPadTemplate *templ = gst_static_pad_template_get (&src_template);
-
- return gst_caps_copy (gst_pad_template_get_caps (templ));
- }
-
- caps = gst_caps_new_empty ();
- for (i = 0; csp[i] != 0; i++) {
- GstCaps *one = gst_xvid_csp_to_caps (csp[i], dec->width,
- dec->height, dec->fps, dec->par);
-
- gst_caps_append (caps, one);
- }
-
- return caps;
-}
-#endif
-
-static gboolean
-gst_xviddec_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstXvidDec *dec = GST_XVIDDEC (GST_PAD_PARENT (pad));
- GstStructure *structure;
- GstCaps *allowed_caps;
- const GValue *val;
-
- GST_LOG_OBJECT (dec, "caps %" GST_PTR_FORMAT, caps);
-
- /* if there's something old around, remove it */
- if (dec->handle) {
- gst_xviddec_unset (dec);
- }
-
- structure = gst_caps_get_structure (caps, 0);
- gst_structure_get_int (structure, "width", &dec->width);
- gst_structure_get_int (structure, "height", &dec->height);
-
- /* perhaps some fps info */
- val = gst_structure_get_value (structure, "framerate");
- if ((val != NULL) && GST_VALUE_HOLDS_FRACTION (val)) {
- dec->fps_n = gst_value_get_fraction_numerator (val);
- dec->fps_d = gst_value_get_fraction_denominator (val);
- } else {
- dec->fps_n = -1;
- dec->fps_d = 1;
- }
-
- /* perhaps some par info */
- val = gst_structure_get_value (structure, "pixel-aspect-ratio");
- if (val != NULL && GST_VALUE_HOLDS_FRACTION (val)) {
- dec->par_n = gst_value_get_fraction_numerator (val);
- dec->par_d = gst_value_get_fraction_denominator (val);
- } else {
- dec->par_n = 1;
- dec->par_d = 1;
- }
-
- /* we try to find the preferred/accept csp */
- allowed_caps = gst_pad_get_allowed_caps (dec->srcpad);
- if (!allowed_caps) {
- GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
- /* need to copy because get_allowed_caps returns a ref,
- and get_pad_template_caps doesn't */
- allowed_caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
- }
- GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
-
- /* pick the first one ... */
- structure = gst_caps_get_structure (allowed_caps, 0);
- val = gst_structure_get_value (structure, "format");
- if (val != NULL && G_VALUE_TYPE (val) == GST_TYPE_LIST) {
- GValue temp = { 0, };
- gst_value_init_and_copy (&temp, gst_value_list_get_value (val, 0));
- gst_structure_set_value (structure, "format", &temp);
- g_value_unset (&temp);
- }
-
- /* ... and use its info to get the csp */
- dec->csp = gst_xvid_structure_to_csp (structure);
- if (dec->csp == -1) {
- GST_WARNING_OBJECT (dec, "failed to decide on colorspace, using I420");
- dec->csp = XVID_CSP_I420;
- }
-
- dec->outbuf_size =
- gst_xvid_image_get_size (dec->csp, dec->width, dec->height);
-
- GST_LOG_OBJECT (dec, "csp=%d, outbuf_size=%d", dec->csp, dec->outbuf_size);
-
- gst_caps_unref (allowed_caps);
-
- /* now set up xvid ... */
- if (!gst_xviddec_setup (dec)) {
- GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
- return FALSE;
- }
-
- return gst_xviddec_negotiate (dec, NULL);
-}
-
-static GstStateChangeReturn
-gst_xviddec_change_state (GstElement * element, GstStateChange transition)
-{
- GstXvidDec *dec = GST_XVIDDEC (element);
- GstStateChangeReturn ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_xvid_init ())
- return GST_STATE_CHANGE_FAILURE;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto done;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- gst_xviddec_flush_buffers (dec, FALSE);
- if (dec->handle) {
- gst_xviddec_unset (dec);
- }
- gst_xviddec_reset (dec);
- break;
- default:
- break;
- }
-
-done:
- return ret;
-}
diff --git a/ext/xvid/gstxviddec.h b/ext/xvid/gstxviddec.h
deleted file mode 100644
index ac3f0ebb8..000000000
--- a/ext/xvid/gstxviddec.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* GStreamer xvid decoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_XVIDDEC_H__
-#define __GST_XVIDDEC_H__
-
-#include <gst/gst.h>
-#include "gstxvid.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_XVIDDEC \
- (gst_xviddec_get_type())
-#define GST_XVIDDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_XVIDDEC, GstXvidDec))
-#define GST_XVIDDEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_XVIDDEC, GstXvidDecClass))
-#define GST_IS_XVIDDEC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_XVIDDEC))
-#define GST_IS_XVIDDEC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XVIDDEC))
-
-typedef struct _GstXvidDec GstXvidDec;
-typedef struct _GstXvidDecClass GstXvidDecClass;
-
-struct _GstXvidDec {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad, *srcpad;
-
- /* xvid handle */
- void *handle;
-
- /* video (output) settings */
- gint csp;
- gint width, height;
- gint fps_n, fps_d, par_n, par_d;
- gint outbuf_size;
-
- /* whether in need for keyframe */
- gboolean waiting_for_key;
-
- /* retain some info on delayed frame */
- gboolean have_ts;
- GstClockTime next_ts, next_dur;
-};
-
-struct _GstXvidDecClass {
- GstElementClass parent_class;
-};
-
-GType gst_xviddec_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_XVIDDEC_H__ */
diff --git a/ext/xvid/gstxvidenc.c b/ext/xvid/gstxvidenc.c
deleted file mode 100644
index edf89b7db..000000000
--- a/ext/xvid/gstxvidenc.c
+++ /dev/null
@@ -1,1403 +0,0 @@
-/* GStreamer xvid encoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * (C) 2006 Mark Nauwelaerts <manauw@skynet.be>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-/* based on:
- * - the original xvidenc (by Ronald Bultje)
- * - transcode/mplayer's xvid encoder (by Edouard Gomez)
- *
- * TODO some documentation (e.g. on properties)
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <xvid.h>
-
-#include <gst/video/video.h>
-#include "gstxvidenc.h"
-
-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, YV12, YVYU, UYVY }")
- "; " RGB_24_32_STATIC_CAPS (32, 0x00ff0000, 0x0000ff00,
- 0x000000ff) "; " RGB_24_32_STATIC_CAPS (32, 0xff000000, 0x00ff0000,
- 0x0000ff00) "; " RGB_24_32_STATIC_CAPS (32, 0x0000ff00, 0x00ff0000,
- 0xff000000) "; " RGB_24_32_STATIC_CAPS (32, 0x000000ff, 0x0000ff00,
- 0x00ff0000) "; " RGB_24_32_STATIC_CAPS (24, 0x0000ff, 0x00ff00,
- 0xff0000) "; " GST_VIDEO_CAPS_RGB_15 "; " GST_VIDEO_CAPS_RGB_16)
- );
-
-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/mpeg, "
- "mpegversion = (int) 4, "
- "systemstream = (boolean) FALSE, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], "
- "framerate = (fraction) [ 0/1, MAX ], "
- "profile = (string) simple, "
- "level = (string) { 0, 1, 2, 3, 4a, 5, 6 };"
- "video/mpeg, "
- "mpegversion = (int) 4, "
- "systemstream = (boolean) FALSE, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], "
- "framerate = (fraction) [ 0/1, MAX ], "
- "profile = (string) advanced-real-time-simple, "
- "level = (string) { 1, 2, 3, 4 };"
- "video/mpeg, "
- "mpegversion = (int) 4, "
- "systemstream = (boolean) FALSE, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], "
- "framerate = (fraction) [ 0/1, MAX ], "
- "profile = (string) advanced-simple, "
- "level = (string) { 0, 1, 2, 3, 4 };"
- "video/mpeg, "
- "mpegversion = (int) 4, "
- "systemstream = (boolean) FALSE, "
- "width = (int) [ 0, MAX ], " "height = (int) [ 0, MAX ]; "
- "video/x-xvid, "
- "width = (int) [ 0, MAX ], "
- "height = (int) [ 0, MAX ], " "framerate = (fraction) [ 0/1, MAX ];")
- );
-
-
-/* XvidEnc properties */
-
-/* maximum property-id */
-static int xvidenc_prop_count;
-
-/* quark used for named pointer on param specs */
-static GQuark xvidenc_pspec_quark;
-
-GST_DEBUG_CATEGORY_STATIC (xvidenc_debug);
-#define GST_CAT_DEFAULT xvidenc_debug
-
-static void gst_xvidenc_base_init (GstXvidEncClass * klass);
-static void gst_xvidenc_class_init (GstXvidEncClass * klass);
-static void gst_xvidenc_init (GstXvidEnc * xvidenc);
-static void gst_xvidenc_finalize (GObject * object);
-static GstFlowReturn gst_xvidenc_chain (GstPad * pad, GstBuffer * data);
-static gboolean gst_xvidenc_setcaps (GstPad * pad, GstCaps * vscapslist);
-static GstCaps *gst_xvidenc_getcaps (GstPad * pad);
-static void gst_xvidenc_flush_buffers (GstXvidEnc * xvidenc, gboolean send);
-static gboolean gst_xvidenc_handle_sink_event (GstPad * pad, GstEvent * event);
-
-/* properties */
-static void gst_xvidenc_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_xvidenc_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_xvidenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
-
-#define GST_TYPE_XVIDENC_PROFILE (gst_xvidenc_profile_get_type ())
-static GType
-gst_xvidenc_profile_get_type (void)
-{
- static GType xvidenc_profile_type = 0;
-
- if (!xvidenc_profile_type) {
- static const GEnumValue xvidenc_profiles[] = {
- {0, "UNP", "Unrestricted profile"},
- {XVID_PROFILE_S_L0, "S_L0", "Simple profile, L0"},
- {XVID_PROFILE_S_L1, "S_L1", "Simple profile, L1"},
- {XVID_PROFILE_S_L2, "S_L2", "Simple profile, L2"},
- {XVID_PROFILE_S_L3, "S_L3", "Simple profile, L3"},
- {XVID_PROFILE_S_L4a, "S_L4a", "Simple profile, L4a"},
- {XVID_PROFILE_S_L5, "S_L5", "Simple profile, L5"},
- {XVID_PROFILE_S_L6, "S_L6", "Simple profile, L6"},
- {XVID_PROFILE_ARTS_L1, "ARTS_L1",
- "Advanced real-time simple profile, L1"},
- {XVID_PROFILE_ARTS_L2, "ARTS_L2",
- "Advanced real-time simple profile, L2"},
- {XVID_PROFILE_ARTS_L3, "ARTS_L3",
- "Advanced real-time simple profile, L3"},
- {XVID_PROFILE_ARTS_L4, "ARTS_L4",
- "Advanced real-time simple profile, L4"},
- {XVID_PROFILE_AS_L0, "AS_L0", "Advanced simple profile, L0"},
- {XVID_PROFILE_AS_L1, "AS_L1", "Advanced simple profile, L1"},
- {XVID_PROFILE_AS_L2, "AS_L2", "Advanced simple profile, L2"},
- {XVID_PROFILE_AS_L3, "AS_L3", "Advanced simple profile, L3"},
- {XVID_PROFILE_AS_L4, "AS_L4", "Advanced simple profile, L4"},
- {0, NULL, NULL},
- };
-
- xvidenc_profile_type =
- g_enum_register_static ("GstXvidEncProfiles", xvidenc_profiles);
- }
-
- return xvidenc_profile_type;
-}
-
-#define GST_TYPE_XVIDENC_QUANT_TYPE (gst_xvidenc_quant_type_get_type ())
-static GType
-gst_xvidenc_quant_type_get_type (void)
-{
- static GType xvidenc_quant_type_type = 0;
-
- if (!xvidenc_quant_type_type) {
- static const GEnumValue xvidenc_quant_types[] = {
- {0, "H263 quantization", "h263"},
- {XVID_VOL_MPEGQUANT, "MPEG quantization", "mpeg"},
- {0, NULL, NULL},
- };
-
- xvidenc_quant_type_type =
- g_enum_register_static ("GstXvidEncQuantTypes", xvidenc_quant_types);
- }
-
- return xvidenc_quant_type_type;
-}
-
-
-enum
-{
- XVIDENC_CBR,
- XVIDENC_VBR_PASS1,
- XVIDENC_VBR_PASS2,
- XVIDENC_QUANT
-};
-
-#define GST_TYPE_XVIDENC_PASS (gst_xvidenc_pass_get_type ())
-static GType
-gst_xvidenc_pass_get_type (void)
-{
- static GType xvidenc_pass_type = 0;
-
- if (!xvidenc_pass_type) {
- static const GEnumValue xvidenc_passes[] = {
- {XVIDENC_CBR, "Constant Bitrate Encoding", "cbr"},
- {XVIDENC_QUANT, "Constant Quantizer", "quant"},
- {XVIDENC_VBR_PASS1, "VBR Encoding - Pass 1", "pass1"},
- {XVIDENC_VBR_PASS2, "VBR Encoding - Pass 2", "pass2"},
- {0, NULL, NULL},
- };
-
- xvidenc_pass_type =
- g_enum_register_static ("GstXvidEncPasses", xvidenc_passes);
- }
-
- return xvidenc_pass_type;
-}
-
-
-GType
-gst_xvidenc_get_type (void)
-{
- static GType xvidenc_type = 0;
-
- if (!xvidenc_type) {
- static const GTypeInfo xvidenc_info = {
- sizeof (GstXvidEncClass),
- (GBaseInitFunc) gst_xvidenc_base_init,
- NULL,
- (GClassInitFunc) gst_xvidenc_class_init,
- NULL,
- NULL,
- sizeof (GstXvidEnc),
- 0,
- (GInstanceInitFunc) gst_xvidenc_init,
- };
- const GInterfaceInfo preset_interface_info = {
- NULL, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
- xvidenc_type = g_type_register_static (GST_TYPE_ELEMENT,
- "GstXvidEnc", &xvidenc_info, 0);
-
- g_type_add_interface_static (xvidenc_type, GST_TYPE_PRESET,
- &preset_interface_info);
- }
- return xvidenc_type;
-}
-
-static void
-gst_xvidenc_base_init (GstXvidEncClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_static_pad_template (element_class, &sink_template);
- gst_element_class_add_static_pad_template (element_class, &src_template);
- gst_element_class_set_static_metadata (element_class, "XviD video encoder",
- "Codec/Encoder/Video",
- "XviD encoder based on xvidcore",
- "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-}
-
-/* add property pspec to klass using the counter count,
- * and place info based on struct_type and member as a named pointer
- * specified by quark */
-#define gst_xvidenc_add_pspec_full(klass, pspec, count, quark, \
- struct_type, member) \
-G_STMT_START { \
- guint _offset = G_STRUCT_OFFSET (struct_type, member); \
- g_param_spec_set_qdata (pspec, quark, \
- GUINT_TO_POINTER (_offset)); \
- g_object_class_install_property (klass, ++count, pspec); \
-} G_STMT_END
-
-#define gst_xvidenc_add_pspec(klass, pspec, member) \
- gst_xvidenc_add_pspec_full (klass, pspec, xvidenc_prop_count, \
- xvidenc_pspec_quark, GstXvidEnc, member)
-
-/* using the above system, property maintenance is centralized here
- * (_get_property, _set_property and setting of default value in _init)
- * follow automatically, it only remains to actually use it in the code
- * (which may include free-ing in finalize) */
-
-static void
-gst_xvidenc_class_init (GstXvidEncClass * klass)
-{
- GstElementClass *gstelement_class;
- GObjectClass *gobject_class;
- GParamSpec *pspec;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gstelement_class = GST_ELEMENT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- GST_DEBUG_CATEGORY_INIT (xvidenc_debug, "xvidenc", 0, "XviD encoder");
-
- gobject_class->finalize = gst_xvidenc_finalize;
-
- gobject_class->set_property = gst_xvidenc_set_property;
- gobject_class->get_property = gst_xvidenc_get_property;
-
- /* prop handling */
- xvidenc_prop_count = 0;
- xvidenc_pspec_quark = g_quark_from_static_string ("xvid-enc-param-spec-data");
-
- pspec = g_param_spec_enum ("profile", "Profile",
- "XviD/MPEG-4 encoding profile",
- GST_TYPE_XVIDENC_PROFILE, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, profile);
-
- pspec = g_param_spec_enum ("quant-type", "Quantizer Type",
- "Quantizer type", GST_TYPE_XVIDENC_QUANT_TYPE, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, quant_type);
-
- pspec = g_param_spec_enum ("pass", "Encoding pass/type",
- "Encoding pass/type",
- GST_TYPE_XVIDENC_PASS, XVIDENC_CBR,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, pass);
-
- pspec = g_param_spec_int ("bitrate", "Bitrate",
- "[CBR|PASS2] Target video bitrate (bps)",
- 0, G_MAXINT, 1800000, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, bitrate);
-
- pspec = g_param_spec_int ("quantizer", "Quantizer",
- "[QUANT] Quantizer to apply for constant quantizer mode",
- 2, 31, 2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, quant);
-
- pspec = g_param_spec_string ("statsfile", "Statistics Filename",
- "[PASS1|PASS2] Filename to store data for 2-pass encoding",
- "xvid-stats.log", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, filename);
-
- pspec = g_param_spec_int ("max-key-interval", "Max. Key Interval",
- "Maximum number of frames between two keyframes (< 0 is in sec)",
- -100, G_MAXINT, -10, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_key_interval);
-
- pspec = g_param_spec_boolean ("closed-gop", "Closed GOP",
- "Closed GOP", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, closed_gop);
-
- pspec = g_param_spec_int ("motion", "ME Quality",
- "Quality of Motion Estimation", 0, 6, 6,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, motion);
-
- pspec = g_param_spec_boolean ("me-chroma", "ME Chroma",
- "Enable use of Chroma planes for Motion Estimation",
- TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, me_chroma);
-
- pspec = g_param_spec_int ("me-vhq", "ME DCT/Frequency",
- "Extent in which to use DCT to minimize encoding length",
- 0, 4, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, me_vhq);
-
- pspec = g_param_spec_boolean ("me-quarterpel", "ME Quarterpel",
- "Use quarter pixel precision for motion vector search",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, me_quarterpel);
-
- pspec = g_param_spec_boolean ("lumimasking", "Lumimasking",
- "Enable lumimasking - apply more compression to dark or bright areas",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, lumimasking);
-
- pspec = g_param_spec_int ("max-bframes", "Max B-Frames",
- "Maximum B-frames in a row", 0, G_MAXINT, 1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_bframes);
-
- pspec = g_param_spec_int ("bquant-ratio", "B-quantizer ratio",
- "Ratio in B-frame quantizer computation", 0, 200, 150,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, bquant_ratio);
-
- pspec = g_param_spec_int ("bquant-offset", "B-quantizer offset",
- "Offset in B-frame quantizer computation",
- 0, 200, 100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, bquant_offset);
-
- pspec = g_param_spec_int ("bframe-threshold", "B-Frame Threshold",
- "Higher threshold yields more chance that B-frame is used",
- -255, 255, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, bframe_threshold);
-
- pspec = g_param_spec_boolean ("gmc", "Global Motion Compensation",
- "Allow generation of Sprite Frames for Pan/Zoom/Rotating images",
- FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, gmc);
-
- pspec = g_param_spec_boolean ("trellis", "Trellis Quantization",
- "Enable Trellis Quantization", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, trellis);
-
- pspec = g_param_spec_boolean ("interlaced", "Interlaced Material",
- "Enable for interlaced video material", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, interlaced);
-
- pspec = g_param_spec_boolean ("cartoon", "Cartoon Material",
- "Adjust thresholds for flat looking cartoons", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, cartoon);
-
- pspec = g_param_spec_boolean ("greyscale", "Disable Chroma",
- "Do not write chroma data in encoded video", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, greyscale);
-
- pspec = g_param_spec_boolean ("hqacpred", "High quality AC prediction",
- "Enable high quality AC prediction", TRUE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, hqacpred);
-
- pspec = g_param_spec_int ("max-iquant", "Max Quant I-Frames",
- "Upper bound for I-frame quantization", 0, 31, 31,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_iquant);
-
- pspec = g_param_spec_int ("min-iquant", "Min Quant I-Frames",
- "Lower bound for I-frame quantization", 0, 31, 2,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, min_iquant);
-
- pspec = g_param_spec_int ("max-pquant", "Max Quant P-Frames",
- "Upper bound for P-frame quantization", 0, 31, 31,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_pquant);
-
- pspec = g_param_spec_int ("min-pquant", "Min Quant P-Frames",
- "Lower bound for P-frame quantization", 0, 31, 2,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, min_pquant);
-
- pspec = g_param_spec_int ("max-bquant", "Max Quant B-Frames",
- "Upper bound for B-frame quantization", 0, 31, 31,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_bquant);
-
- pspec = g_param_spec_int ("min-bquant", "Min Quant B-Frames",
- "Lower bound for B-frame quantization", 0, 31, 2,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, min_bquant);
-
- pspec = g_param_spec_int ("reaction-delay-factor", "Reaction Delay Factor",
- "[CBR] Reaction delay factor", -1, 100, -1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, reaction_delay_factor);
-
- pspec = g_param_spec_int ("averaging-period", "Averaging Period",
- "[CBR] Number of frames for which XviD averages bitrate",
- -1, 100, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, averaging_period);
-
- pspec = g_param_spec_int ("buffer", "Buffer Size",
- "[CBR] Size of the video buffers", -1, G_MAXINT, -1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, buffer);
-
- pspec = g_param_spec_int ("keyframe-boost", "Keyframe boost",
- "[PASS2] Bitrate boost for keyframes", 0, 100, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, keyframe_boost);
-
- pspec = g_param_spec_int ("curve-compression-high", "Curve Compression High",
- "[PASS2] Shrink factor for upper part of bitrate curve",
- 0, 100, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, curve_compression_high);
-
- pspec = g_param_spec_int ("curve-compression-low", "Curve Compression Low",
- "[PASS2] Growing factor for lower part of bitrate curve",
- 0, 100, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, curve_compression_low);
-
- pspec = g_param_spec_int ("flow-control-strength", "Flow Control Strength",
- "[PASS2] Overflow control strength per frame",
- -1, 100, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, overflow_control_strength);
-
- pspec =
- g_param_spec_int ("max-overflow-improvement", "Max Overflow Improvement",
- "[PASS2] Amount in % that flow control can increase frame size compared to ideal curve",
- -1, 100, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_overflow_improvement);
-
- pspec =
- g_param_spec_int ("max-overflow-degradation", "Max Overflow Degradation",
- "[PASS2] Amount in % that flow control can decrease frame size compared to ideal curve",
- -1, 100, 5, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, max_overflow_degradation);
-
- pspec = g_param_spec_int ("keyframe-reduction", "Keyframe Reduction",
- "[PASS2] Keyframe size reduction in % of those within threshold",
- -1, 100, 20, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, kfreduction);
-
- pspec = g_param_spec_int ("keyframe-threshold", "Keyframe Threshold",
- "[PASS2] Distance between keyframes not to be subject to reduction",
- -1, 100, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, kfthreshold);
-
- pspec =
- g_param_spec_int ("container-frame-overhead", "Container Frame Overhead",
- "[PASS2] Average container overhead per frame", -1, 100, -1,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- gst_xvidenc_add_pspec (gobject_class, pspec, container_frame_overhead);
-
- gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_xvidenc_change_state);
-}
-
-
-static void
-gst_xvidenc_init (GstXvidEnc * xvidenc)
-{
- GParamSpec **pspecs;
- guint i, num_props;
-
- /* create the sink pad */
- xvidenc->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
- gst_element_add_pad (GST_ELEMENT (xvidenc), xvidenc->sinkpad);
-
- gst_pad_set_chain_function (xvidenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xvidenc_chain));
- gst_pad_set_setcaps_function (xvidenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xvidenc_setcaps));
- gst_pad_set_getcaps_function (xvidenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xvidenc_getcaps));
- gst_pad_set_event_function (xvidenc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_xvidenc_handle_sink_event));
-
- /* create the src pad */
- xvidenc->srcpad = gst_pad_new_from_static_template (&src_template, "src");
- gst_element_add_pad (GST_ELEMENT (xvidenc), xvidenc->srcpad);
- gst_pad_use_fixed_caps (xvidenc->srcpad);
-
- /* init properties. */
- xvidenc->width = xvidenc->height = xvidenc->csp = -1;
- xvidenc->par_width = xvidenc->par_height = 1;
-
- /* set defaults for user properties */
- pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (xvidenc),
- &num_props);
-
- for (i = 0; i < num_props; ++i) {
- GValue val = { 0, };
- GParamSpec *pspec = pspecs[i];
-
- /* only touch those that are really ours; i.e. should have some qdata */
- if (!g_param_spec_get_qdata (pspec, xvidenc_pspec_quark))
- continue;
- g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec));
- g_param_value_set_default (pspec, &val);
- g_object_set_property (G_OBJECT (xvidenc), g_param_spec_get_name (pspec),
- &val);
- g_value_unset (&val);
- }
-
- g_free (pspecs);
-
- /* set xvid handle to NULL */
- xvidenc->handle = NULL;
-
- /* get a queue to keep time info if frames get delayed */
- xvidenc->delay = NULL;
-
- /* cache some xvid data so need not rebuild for each frame */
- xvidenc->xframe_cache = NULL;
-}
-
-
-static void
-gst_xvidenc_finalize (GObject * object)
-{
-
- GstXvidEnc *xvidenc = GST_XVIDENC (object);
-
- g_free (xvidenc->filename);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static gboolean
-gst_xvidenc_handle_sink_event (GstPad * pad, GstEvent * event)
-{
- GstXvidEnc *xvidenc = GST_XVIDENC (GST_PAD_PARENT (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- gst_xvidenc_flush_buffers (xvidenc, TRUE);
- break;
- /* no flushing if flush received,
- buffers in encoder are considered (in the) past */
- default:
- break;
- }
-
- return gst_pad_push_event (xvidenc->srcpad, event);
-}
-
-static gboolean
-gst_xvidenc_setup (GstXvidEnc * xvidenc)
-{
- xvid_enc_create_t xenc;
- xvid_enc_plugin_t xplugin[2];
- gint ret;
- GstCaps *allowed_caps;
- gint profile = -1;
-
- /* Negotiate profile/level with downstream */
- allowed_caps = gst_pad_get_allowed_caps (xvidenc->srcpad);
- if (allowed_caps && !gst_caps_is_empty (allowed_caps)) {
- const gchar *profile_str, *level_str;
-
- allowed_caps = gst_caps_make_writable (allowed_caps);
- gst_caps_truncate (allowed_caps);
-
- profile_str =
- gst_structure_get_string (gst_caps_get_structure (allowed_caps, 0),
- "profile");
- level_str =
- gst_structure_get_string (gst_caps_get_structure (allowed_caps, 0),
- "level");
- if (profile_str) {
- if (g_str_equal (profile_str, "simple")) {
- if (!level_str) {
- profile = XVID_PROFILE_S_L0;
- } else if (g_str_equal (level_str, "0")) {
- profile = XVID_PROFILE_S_L0;
- } else if (g_str_equal (level_str, "1")) {
- profile = XVID_PROFILE_S_L1;
- } else if (g_str_equal (level_str, "2")) {
- profile = XVID_PROFILE_S_L2;
- } else if (g_str_equal (level_str, "3")) {
- profile = XVID_PROFILE_S_L3;
- } else if (g_str_equal (level_str, "4a")) {
- profile = XVID_PROFILE_S_L4a;
- } else if (g_str_equal (level_str, "5")) {
- profile = XVID_PROFILE_S_L5;
- } else if (g_str_equal (level_str, "6")) {
- profile = XVID_PROFILE_S_L6;
- } else {
- GST_ERROR_OBJECT (xvidenc,
- "Invalid profile/level combination (%s %s)", profile_str,
- level_str);
- }
- } else if (g_str_equal (profile_str, "advanced-real-time-simple")) {
- if (!level_str) {
- profile = XVID_PROFILE_ARTS_L1;
- } else if (g_str_equal (level_str, "1")) {
- profile = XVID_PROFILE_ARTS_L1;
- } else if (g_str_equal (level_str, "2")) {
- profile = XVID_PROFILE_ARTS_L2;
- } else if (g_str_equal (level_str, "3")) {
- profile = XVID_PROFILE_ARTS_L3;
- } else if (g_str_equal (level_str, "4")) {
- profile = XVID_PROFILE_ARTS_L4;
- } else {
- GST_ERROR_OBJECT (xvidenc,
- "Invalid profile/level combination (%s %s)", profile_str,
- level_str);
- }
- } else if (g_str_equal (profile_str, "advanced-simple")) {
- if (!level_str) {
- profile = XVID_PROFILE_AS_L0;
- } else if (g_str_equal (level_str, "0")) {
- profile = XVID_PROFILE_AS_L0;
- } else if (g_str_equal (level_str, "1")) {
- profile = XVID_PROFILE_AS_L1;
- } else if (g_str_equal (level_str, "2")) {
- profile = XVID_PROFILE_AS_L2;
- } else if (g_str_equal (level_str, "3")) {
- profile = XVID_PROFILE_AS_L3;
- } else if (g_str_equal (level_str, "4")) {
- profile = XVID_PROFILE_AS_L4;
- } else {
- GST_ERROR_OBJECT (xvidenc,
- "Invalid profile/level combination (%s %s)", profile_str,
- level_str);
- }
- } else {
- GST_ERROR_OBJECT (xvidenc, "Invalid profile (%s)", profile_str);
- }
- }
- }
- if (allowed_caps)
- gst_caps_unref (allowed_caps);
-
- if (profile != -1) {
- xvidenc->profile = profile;
- g_object_notify (G_OBJECT (xvidenc), "profile");
- }
-
- /* see xvid.h for the meaning of all this. */
- gst_xvid_init_struct (xenc);
-
- xenc.profile = xvidenc->used_profile = xvidenc->profile;
- xenc.width = xvidenc->width;
- xenc.height = xvidenc->height;
- xenc.max_bframes = xvidenc->max_bframes;
- xenc.global = XVID_GLOBAL_PACKED
- | (xvidenc->closed_gop ? XVID_GLOBAL_CLOSED_GOP : 0);
-
- xenc.bquant_ratio = xvidenc->bquant_ratio;
- xenc.bquant_offset = xvidenc->bquant_offset;
-
- xenc.fbase = xvidenc->fbase;
- xenc.fincr = xvidenc->fincr;
- xenc.max_key_interval = (xvidenc->max_key_interval < 0) ?
- (-xvidenc->max_key_interval * xenc.fbase /
- xenc.fincr) : xvidenc->max_key_interval;
- xenc.handle = NULL;
-
- /* quantizer ranges */
- xenc.min_quant[0] = xvidenc->min_iquant;
- xenc.min_quant[1] = xvidenc->min_pquant;
- xenc.min_quant[2] = xvidenc->min_bquant;
- xenc.max_quant[0] = xvidenc->max_iquant;
- xenc.max_quant[1] = xvidenc->max_pquant;
- xenc.max_quant[2] = xvidenc->max_bquant;
-
- /* cbr, vbr or constant quantizer */
- xenc.num_plugins = 1;
- xenc.plugins = xplugin;
- switch (xvidenc->pass) {
- case XVIDENC_CBR:
- case XVIDENC_QUANT:
- {
- xvid_plugin_single_t xsingle;
- xvid_enc_zone_t xzone;
-
- gst_xvid_init_struct (xsingle);
-
- xenc.plugins[0].func = xvid_plugin_single;
- xenc.plugins[0].param = &xsingle;
-
- xsingle.bitrate = xvidenc->bitrate;
- xsingle.reaction_delay_factor = MAX (0, xvidenc->reaction_delay_factor);
- xsingle.averaging_period = MAX (0, xvidenc->averaging_period);
- xsingle.buffer = MAX (0, xvidenc->buffer);
-
- if (xvidenc->pass == XVIDENC_CBR)
- break;
-
- /* set up a const quantizer zone */
- xzone.mode = XVID_ZONE_QUANT;
- xzone.frame = 0;
- xzone.increment = xvidenc->quant;
- xzone.base = 1;
- xenc.zones = &xzone;
- xenc.num_zones++;
-
- break;
- }
- case XVIDENC_VBR_PASS1:
- {
- xvid_plugin_2pass1_t xpass;
-
- gst_xvid_init_struct (xpass);
-
- xenc.plugins[0].func = xvid_plugin_2pass1;
- xenc.plugins[0].param = &xpass;
-
- xpass.filename = xvidenc->filename;
- break;
- }
- case XVIDENC_VBR_PASS2:
- {
- xvid_plugin_2pass2_t xpass;
-
- gst_xvid_init_struct (xpass);
-
- xenc.plugins[0].func = xvid_plugin_2pass2;
- xenc.plugins[0].param = &xpass;
-
- xpass.bitrate = xvidenc->bitrate;
- xpass.filename = xvidenc->filename;
- xpass.keyframe_boost = xvidenc->keyframe_boost;
- xpass.curve_compression_high = xvidenc->curve_compression_high;
- xpass.curve_compression_low = xvidenc->curve_compression_low;
- xpass.overflow_control_strength =
- MAX (0, xvidenc->overflow_control_strength);
- xpass.max_overflow_improvement =
- MAX (0, xvidenc->max_overflow_improvement);
- xpass.max_overflow_degradation =
- MAX (0, xvidenc->max_overflow_degradation);
- xpass.kfreduction = MAX (0, xvidenc->kfreduction);
- xpass.kfthreshold = MAX (0, xvidenc->kfthreshold);
- xpass.container_frame_overhead =
- MAX (0, xvidenc->container_frame_overhead);
- break;
- }
- }
-
- if (xvidenc->lumimasking) {
- xenc.plugins[1].func = xvid_plugin_lumimasking;
- xenc.plugins[1].param = NULL;
- xenc.num_plugins++;
- }
-
- if ((ret = xvid_encore (NULL, XVID_ENC_CREATE, &xenc, NULL)) < 0) {
- GST_DEBUG_OBJECT (xvidenc, "Error setting up xvid encoder: %s (%d)",
- gst_xvid_error (ret), ret);
- return FALSE;
- }
-
- xvidenc->handle = xenc.handle;
-
- return TRUE;
-}
-
-static gboolean
-gst_xvidenc_setcaps (GstPad * pad, GstCaps * vscaps)
-{
- GstXvidEnc *xvidenc;
- GstStructure *structure;
- gint w, h;
- const GValue *fps, *par;
- gint xvid_cs = -1;
-
- xvidenc = GST_XVIDENC (GST_PAD_PARENT (pad));
-
- /* if there's something old around, remove it */
- if (xvidenc->handle) {
- gst_xvidenc_flush_buffers (xvidenc, TRUE);
- xvid_encore (xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL);
- xvidenc->handle = NULL;
- }
-
- structure = gst_caps_get_structure (vscaps, 0);
-
- if (!gst_structure_get_int (structure, "width", &w) ||
- !gst_structure_get_int (structure, "height", &h)) {
- return FALSE;
- }
-
- fps = gst_structure_get_value (structure, "framerate");
- if (fps == NULL || !GST_VALUE_HOLDS_FRACTION (fps)) {
- GST_WARNING_OBJECT (pad, "no framerate specified, or not a GstFraction");
- return FALSE;
- }
-
- /* optional par info */
- par = gst_structure_get_value (structure, "pixel-aspect-ratio");
-
- xvid_cs = gst_xvid_structure_to_csp (structure);
- if (xvid_cs == -1) {
- gchar *sstr;
-
- sstr = gst_structure_to_string (structure);
- GST_DEBUG_OBJECT (xvidenc, "Did not find xvid colourspace for caps %s",
- sstr);
- g_free (sstr);
- return FALSE;
- }
-
- xvidenc->csp = xvid_cs;
- xvidenc->width = w;
- xvidenc->height = h;
- xvidenc->fbase = gst_value_get_fraction_numerator (fps);
- xvidenc->fincr = gst_value_get_fraction_denominator (fps);
- if ((par != NULL) && GST_VALUE_HOLDS_FRACTION (par)) {
- xvidenc->par_width = gst_value_get_fraction_numerator (par);
- xvidenc->par_height = gst_value_get_fraction_denominator (par);
- } else {
- xvidenc->par_width = 1;
- xvidenc->par_height = 1;
- }
-
- /* wipe xframe cache given possible change caps properties */
- g_free (xvidenc->xframe_cache);
- xvidenc->xframe_cache = NULL;
-
- if (gst_xvidenc_setup (xvidenc)) {
- gboolean ret = FALSE;
- GstCaps *new_caps = NULL, *allowed_caps;
-
- /* please downstream with preferred caps */
- allowed_caps = gst_pad_get_allowed_caps (xvidenc->srcpad);
- GST_DEBUG_OBJECT (xvidenc, "allowed caps: %" GST_PTR_FORMAT, allowed_caps);
-
- if (allowed_caps && !gst_caps_is_empty (allowed_caps)) {
- new_caps = gst_caps_copy_nth (allowed_caps, 0);
- } else {
- new_caps = gst_caps_new_simple ("video/x-xvid", NULL);
- }
- if (allowed_caps)
- gst_caps_unref (allowed_caps);
-
- gst_caps_set_simple (new_caps,
- "width", G_TYPE_INT, w, "height", G_TYPE_INT, h,
- "framerate", GST_TYPE_FRACTION, xvidenc->fbase, xvidenc->fincr,
- "pixel-aspect-ratio", GST_TYPE_FRACTION,
- xvidenc->par_width, xvidenc->par_height, NULL);
- /* just to be sure */
- gst_pad_fixate_caps (xvidenc->srcpad, new_caps);
-
- if (xvidenc->used_profile != 0) {
- switch (xvidenc->used_profile) {
- case XVID_PROFILE_S_L0:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "0", NULL);
- break;
- case XVID_PROFILE_S_L1:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "1", NULL);
- break;
- case XVID_PROFILE_S_L2:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "2", NULL);
- break;
- case XVID_PROFILE_S_L3:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "3", NULL);
- break;
- case XVID_PROFILE_S_L4a:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "4a", NULL);
- break;
- case XVID_PROFILE_S_L5:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "5", NULL);
- break;
- case XVID_PROFILE_S_L6:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple",
- "level", G_TYPE_STRING, "6", NULL);
- break;
- case XVID_PROFILE_ARTS_L1:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-real-time-simple", "level", G_TYPE_STRING, "1", NULL);
- break;
- case XVID_PROFILE_ARTS_L2:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-real-time-simple", "level", G_TYPE_STRING, "2", NULL);
- break;
- case XVID_PROFILE_ARTS_L3:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-real-time-simple", "level", G_TYPE_STRING, "3", NULL);
- break;
- case XVID_PROFILE_ARTS_L4:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-real-time-simple", "level", G_TYPE_STRING, "4", NULL);
- break;
- case XVID_PROFILE_AS_L0:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-simple", "level", G_TYPE_STRING, "0", NULL);
- break;
- case XVID_PROFILE_AS_L1:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-simple", "level", G_TYPE_STRING, "1", NULL);
- break;
- case XVID_PROFILE_AS_L2:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-simple", "level", G_TYPE_STRING, "2", NULL);
- break;
- case XVID_PROFILE_AS_L3:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-simple", "level", G_TYPE_STRING, "3", NULL);
- break;
- case XVID_PROFILE_AS_L4:
- gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING,
- "advanced-simple", "level", G_TYPE_STRING, "4", NULL);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- }
-
- /* src pad should accept anyway */
- ret = gst_pad_set_caps (xvidenc->srcpad, new_caps);
- gst_caps_unref (new_caps);
-
- if (!ret && xvidenc->handle) {
- xvid_encore (xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL);
- xvidenc->handle = NULL;
- }
- return ret;
-
- } else /* setup did not work out */
- return FALSE;
-}
-
-static GstCaps *
-gst_xvidenc_getcaps (GstPad * pad)
-{
- GstXvidEnc *xvidenc;
- GstPad *peer;
- GstCaps *caps;
-
- /* If we already have caps return them */
- if (GST_PAD_CAPS (pad))
- return gst_caps_ref (GST_PAD_CAPS (pad));
-
- xvidenc = GST_XVIDENC (gst_pad_get_parent (pad));
- if (!xvidenc)
- return gst_caps_new_empty ();
-
- peer = gst_pad_get_peer (xvidenc->srcpad);
- if (peer) {
- const GstCaps *templcaps;
- GstCaps *peercaps;
- guint i, n;
-
- peercaps = gst_pad_get_caps (peer);
-
- /* Translate peercaps to YUV */
- peercaps = gst_caps_make_writable (peercaps);
- n = gst_caps_get_size (peercaps);
- for (i = 0; i < n; i++) {
- GstStructure *s = gst_caps_get_structure (peercaps, i);
-
- gst_structure_set_name (s, "video/x-raw-yuv");
- gst_structure_remove_field (s, "mpegversion");
- gst_structure_remove_field (s, "systemstream");
- }
-
- templcaps = gst_pad_get_pad_template_caps (pad);
-
- caps = gst_caps_intersect (peercaps, templcaps);
- gst_caps_unref (peercaps);
- gst_object_unref (peer);
- peer = NULL;
- } else {
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
- }
-
- gst_object_unref (xvidenc);
-
- return caps;
-}
-
-/* encodes frame according to info in xframe;
- - buf is input buffer, can be NULL if dummy
- - buf is disposed of prior to exit
- - resulting buffer is returned, NULL if no encoder output or error
-*/
-static inline GstBuffer *
-gst_xvidenc_encode (GstXvidEnc * xvidenc, GstBuffer * buf,
- xvid_enc_frame_t xframe)
-{
- GstBuffer *outbuf;
- gint ret;
-
- /* compressed frame should fit in the rough size of an uncompressed one */
- outbuf = gst_buffer_new_and_alloc (gst_xvid_image_get_size (xvidenc->csp,
- xvidenc->width, xvidenc->height));
-
- xframe.bitstream = (void *) GST_BUFFER_DATA (outbuf);
- xframe.length = GST_BUFFER_SIZE (outbuf);
-
- /* now provide input image data where-abouts, if needed */
- if (buf)
- gst_xvid_image_fill (&xframe.input, GST_BUFFER_DATA (buf), xvidenc->csp,
- xvidenc->width, xvidenc->height);
-
- GST_DEBUG_OBJECT (xvidenc, "encoding frame into buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
- ret = xvid_encore (xvidenc->handle, XVID_ENC_ENCODE, &xframe, NULL);
-
- if (ret < 0) {
- /* things can be nasty if we are trying to flush, so don't signal error then */
- if (buf) {
- GST_ELEMENT_WARNING (xvidenc, LIBRARY, ENCODE, (NULL),
- ("Error encoding xvid frame: %s (%d)", gst_xvid_error (ret), ret));
- gst_buffer_unref (buf);
- }
- gst_buffer_unref (outbuf);
- return NULL;
- } else if (ret > 0) { /* make sub-buffer */
- GstBuffer *sub;
-
- GST_DEBUG_OBJECT (xvidenc, "xvid produced output of size %d", ret);
- sub = gst_buffer_create_sub (outbuf, 0, ret);
-
- /* parent no longer needed, will go away with child buffer */
- gst_buffer_unref (outbuf);
- outbuf = sub;
- } else { /* encoder did not yet produce something */
- GST_DEBUG_OBJECT (xvidenc, "xvid produced no output");
- gst_buffer_unref (outbuf);
- g_queue_push_tail (xvidenc->delay, buf);
- return NULL;
- }
-
- /* finish decoration and return */
- if (!(xframe.out_flags & XVID_KEYFRAME))
- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (xvidenc->srcpad));
-
- /* now we need the right buf to take timestamps from;
- note that timestamps from a display order input buffer can end up with
- another encode order output buffer, but other than this permutation,
- the overall time progress is tracked,
- and keyframes should have the correct stamp */
- if (!g_queue_is_empty (xvidenc->delay)) {
- if (buf)
- g_queue_push_tail (xvidenc->delay, buf);
- buf = g_queue_pop_head (xvidenc->delay);
- }
- if (buf) {
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
- GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
- gst_buffer_unref (buf);
- }
-
- return outbuf;
-}
-
-static GstFlowReturn
-gst_xvidenc_chain (GstPad * pad, GstBuffer * buf)
-{
- GstXvidEnc *xvidenc = GST_XVIDENC (GST_PAD_PARENT (pad));
- GstBuffer *outbuf;
- xvid_enc_frame_t xframe;
-
- const gint motion_presets[] = {
- 0, 0, 0, 0,
- XVID_ME_HALFPELREFINE16,
- XVID_ME_HALFPELREFINE16 | XVID_ME_ADVANCEDDIAMOND16,
- XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16
- | XVID_ME_HALFPELREFINE8 | XVID_ME_USESQUARES16
- };
-
- if (!xvidenc->handle) {
- GST_ELEMENT_ERROR (xvidenc, CORE, NEGOTIATION, (NULL),
- ("format wasn't negotiated before chain function"));
- gst_buffer_unref (buf);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-
- GST_DEBUG_OBJECT (xvidenc,
- "Received buffer of time %" GST_TIME_FORMAT ", size %d",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_SIZE (buf));
-
- if (xvidenc->xframe_cache)
- memcpy (&xframe, xvidenc->xframe_cache, sizeof (xframe));
- else { /* need to build some inital xframe to be cached */
- /* encode and so ... */
- gst_xvid_init_struct (xframe);
-
- if (xvidenc->par_width == xvidenc->par_height)
- xframe.par = XVID_PAR_11_VGA;
- else {
- xframe.par = XVID_PAR_EXT;
- xframe.par_width = xvidenc->par_width;
- xframe.par_height = xvidenc->par_height;
- }
-
- /* handle options */
- xframe.vol_flags |= xvidenc->quant_type;
- xframe.vop_flags = XVID_VOP_HALFPEL;
- xframe.motion = motion_presets[xvidenc->motion];
-
- if (xvidenc->me_chroma) {
- xframe.motion |= XVID_ME_CHROMA_PVOP;
- xframe.motion |= XVID_ME_CHROMA_BVOP;
- }
-
- if (xvidenc->me_vhq >= 1) {
- xframe.vop_flags |= XVID_VOP_MODEDECISION_RD;
- }
- if (xvidenc->me_vhq >= 2) {
- xframe.motion |= XVID_ME_HALFPELREFINE16_RD;
- xframe.motion |= XVID_ME_QUARTERPELREFINE16_RD;
- }
- if (xvidenc->me_vhq >= 3) {
- xframe.motion |= XVID_ME_HALFPELREFINE8_RD;
- xframe.motion |= XVID_ME_QUARTERPELREFINE8_RD;
- xframe.motion |= XVID_ME_CHECKPREDICTION_RD;
- }
- if (xvidenc->me_vhq >= 4) {
- xframe.motion |= XVID_ME_EXTSEARCH_RD;
- }
-
- /* no motion estimation, then only intra */
- if (xvidenc->motion == 0) {
- xframe.type = XVID_TYPE_IVOP;
- } else {
- xframe.type = XVID_TYPE_AUTO;
- }
-
- if (xvidenc->motion > 4) {
- xframe.vop_flags |= XVID_VOP_INTER4V;
- }
-
- if (xvidenc->me_quarterpel) {
- xframe.vol_flags |= XVID_VOL_QUARTERPEL;
- xframe.motion |= XVID_ME_QUARTERPELREFINE16;
- xframe.motion |= XVID_ME_QUARTERPELREFINE8;
- }
-
- if (xvidenc->gmc) {
- xframe.vol_flags |= XVID_VOL_GMC;
- xframe.motion |= XVID_ME_GME_REFINE;
- }
-
- if (xvidenc->interlaced) {
- xframe.vol_flags |= XVID_VOL_INTERLACING;
- }
-
- if (xvidenc->trellis) {
- xframe.vop_flags |= XVID_VOP_TRELLISQUANT;
- }
-
- if (xvidenc->hqacpred) {
- xframe.vop_flags |= XVID_VOP_HQACPRED;
- }
-
- if (xvidenc->greyscale) {
- xframe.vop_flags |= XVID_VOP_GREYSCALE;
- }
-
- if (xvidenc->cartoon) {
- xframe.vop_flags |= XVID_VOP_CARTOON;
- xframe.motion |= XVID_ME_DETECT_STATIC_MOTION;
- }
-
- xframe.bframe_threshold = xvidenc->bframe_threshold;
- xframe.input.csp = xvidenc->csp;
-
- /* save in cache */
- xvidenc->xframe_cache = g_memdup (&xframe, sizeof (xframe));
- }
-
- outbuf = gst_xvidenc_encode (xvidenc, buf, xframe);
-
- if (!outbuf) /* error or no data yet */
- return GST_FLOW_OK;
-
- /* go out, multiply! */
- return gst_pad_push (xvidenc->srcpad, outbuf);
-}
-
-/* flush xvid encoder buffers caused by bframe usage */
-static void
-gst_xvidenc_flush_buffers (GstXvidEnc * xvidenc, gboolean send)
-{
- GstBuffer *outbuf;
- xvid_enc_frame_t xframe;
-
- /* no need to flush if no handle */
- if (!xvidenc->handle)
- return;
-
- gst_xvid_init_struct (xframe);
-
- /* init a fake frame to force flushing */
- xframe.input.csp = XVID_CSP_NULL;
- xframe.input.plane[0] = NULL;
- xframe.input.plane[1] = NULL;
- xframe.input.plane[2] = NULL;
- xframe.input.stride[0] = 0;
- xframe.input.stride[1] = 0;
- xframe.input.stride[2] = 0;
- xframe.quant = 0;
-
- GST_DEBUG ("flushing buffers with sending %d", send);
-
- while (!g_queue_is_empty (xvidenc->delay)) {
- outbuf = gst_xvidenc_encode (xvidenc, NULL, xframe);
-
- if (outbuf) {
- if (send)
- gst_pad_push (xvidenc->srcpad, outbuf);
- else
- gst_buffer_unref (outbuf);
- } else /* hm, there should have been something in there */
- break;
- }
-
- /* our queue should be empty anyway if we did not have to break out ... */
- while (!g_queue_is_empty (xvidenc->delay))
- gst_buffer_unref (g_queue_pop_head (xvidenc->delay));
-}
-
-static void
-gst_xvidenc_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
-{
- GstXvidEnc *xvidenc;
- guint offset;
-
- xvidenc = GST_XVIDENC (object);
-
- if (prop_id > xvidenc_prop_count) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- return;
- }
-
- /* our param specs should have such qdata */
- offset =
- GPOINTER_TO_UINT (g_param_spec_get_qdata (pspec, xvidenc_pspec_quark));
-
- if (offset == 0)
- return;
-
- switch (G_PARAM_SPEC_VALUE_TYPE (pspec)) {
- case G_TYPE_BOOLEAN:
- G_STRUCT_MEMBER (gboolean, xvidenc, offset) = g_value_get_boolean (value);
- break;
- case G_TYPE_INT:
- G_STRUCT_MEMBER (gint, xvidenc, offset) = g_value_get_int (value);
- break;
- case G_TYPE_STRING:
- g_free (G_STRUCT_MEMBER (gchar *, xvidenc, offset));
- G_STRUCT_MEMBER (gchar *, xvidenc, offset) = g_value_dup_string (value);
- break;
- default: /* must be enum, given the check above */
- if (G_IS_PARAM_SPEC_ENUM (pspec)) {
- G_STRUCT_MEMBER (gint, xvidenc, offset) = g_value_get_enum (value);
- } else {
- G_STRUCT_MEMBER (guint, xvidenc, offset) = g_value_get_flags (value);
- }
- break;
- }
-}
-
-static void
-gst_xvidenc_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- GstXvidEnc *xvidenc;
- guint offset;
-
- xvidenc = GST_XVIDENC (object);
-
- if (prop_id > xvidenc_prop_count) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- return;
- }
-
- /* our param specs should have such qdata */
- offset =
- GPOINTER_TO_UINT (g_param_spec_get_qdata (pspec, xvidenc_pspec_quark));
-
- if (offset == 0)
- return;
-
- switch (G_PARAM_SPEC_VALUE_TYPE (pspec)) {
- case G_TYPE_BOOLEAN:
- g_value_set_boolean (value, G_STRUCT_MEMBER (gboolean, xvidenc, offset));
- break;
- case G_TYPE_INT:
- g_value_set_int (value, G_STRUCT_MEMBER (gint, xvidenc, offset));
- break;
- case G_TYPE_STRING:
- g_value_take_string (value,
- g_strdup (G_STRUCT_MEMBER (gchar *, xvidenc, offset)));
- break;
- default: /* must be enum, given the check above */
- if (G_IS_PARAM_SPEC_ENUM (pspec)) {
- g_value_set_enum (value, G_STRUCT_MEMBER (gint, xvidenc, offset));
- } else if (G_IS_PARAM_SPEC_FLAGS (pspec)) {
- g_value_set_flags (value, G_STRUCT_MEMBER (guint, xvidenc, offset));
- } else { /* oops, bit lazy we don't cover this case yet */
- g_critical ("%s does not yet support type %s", GST_FUNCTION,
- g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
- }
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_xvidenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstXvidEnc *xvidenc = GST_XVIDENC (element);
- GstStateChangeReturn ret;
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_xvid_init ())
- return GST_STATE_CHANGE_FAILURE;
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- xvidenc->delay = g_queue_new ();
- break;
- default:
- break;
- }
-
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto done;
-
- switch (transition) {
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (xvidenc->handle) {
- gst_xvidenc_flush_buffers (xvidenc, FALSE);
- xvid_encore (xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL);
- xvidenc->handle = NULL;
- }
- g_queue_free (xvidenc->delay);
- xvidenc->delay = NULL;
- g_free (xvidenc->xframe_cache);
- xvidenc->xframe_cache = NULL;
- break;
- default:
- break;
- }
-
-done:
- return ret;
-}
diff --git a/ext/xvid/gstxvidenc.h b/ext/xvid/gstxvidenc.h
deleted file mode 100644
index ff77aa26c..000000000
--- a/ext/xvid/gstxvidenc.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* GStreamer xvid encoder plugin
- * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * 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., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_XVIDENC_H__
-#define __GST_XVIDENC_H__
-
-#include <gst/gst.h>
-#include "gstxvid.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_XVIDENC \
- (gst_xvidenc_get_type())
-#define GST_XVIDENC(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_XVIDENC, GstXvidEnc))
-#define GST_XVIDENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_XVIDENC, GstXvidEncClass))
-#define GST_IS_XVIDENC(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_XVIDENC))
-#define GST_IS_XVIDENC_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XVIDENC))
-
-typedef struct _GstXvidEnc GstXvidEnc;
-typedef struct _GstXvidEncClass GstXvidEncClass;
-
-struct _GstXvidEnc {
- GstElement element;
-
- /* pads */
- GstPad *sinkpad, *srcpad;
-
- /* xvid handle */
- void *handle;
-
- /* cache in place */
- xvid_enc_frame_t *xframe_cache;
-
- /* caps information */
- gint csp;
- gint width, height;
- gint fbase;
- gint fincr;
- gint par_width;
- gint par_height;
-
- /* delayed buffers if bframe usage */
- GQueue *delay;
-
- /* encoding profile */
- gint profile;
- gint used_profile;
-
- /* quantizer type; h263, MPEG */
- gint quant_type;
-
- /* encoding type; cbr, vbr, quant */
- gint pass;
-
- /* quality of encoded image */
- gint bitrate;
- gint quant;
-
- /* gop */
- gint max_key_interval;
- gboolean closed_gop;
-
- /* motion estimation */
- gint motion;
- gboolean me_chroma;
- gint me_vhq;
- gboolean me_quarterpel;
-
- /* lumimasking */
- gboolean lumimasking;
-
- /* b-frames */
- gint max_bframes;
- gint bquant_ratio;
- gint bquant_offset;
- gint bframe_threshold;
-
- /* misc */
- gboolean gmc;
- gboolean trellis;
- gboolean interlaced;
- gboolean cartoon;
- gboolean greyscale;
- gboolean hqacpred;
-
- /* quantizer ranges */
- gint max_iquant, min_iquant;
- gint max_pquant, min_pquant;
- gint max_bquant, min_bquant;
-
- /* cbr (single pass) encoding */
- gint reaction_delay_factor;
- gint averaging_period;
- gint buffer;
-
- /* vbr (2pass) encoding */
- gchar *filename;
- gint keyframe_boost;
- gint curve_compression_high;
- gint curve_compression_low;
- gint overflow_control_strength;
- gint max_overflow_improvement;
- gint max_overflow_degradation;
- gint kfreduction;
- gint kfthreshold;
- gint container_frame_overhead;
-};
-
-struct _GstXvidEncClass {
- GstElementClass parent_class;
-};
-
-GType gst_xvidenc_get_type(void);
-
-G_END_DECLS
-
-#endif /* __GST_XVIDENC_H__ */