Commit ea5845cb authored by Benjamin Otte's avatar Benjamin Otte

ext/xine/: add first version of xine plugin wrapper. Currently only wraps the

Original commit message from CVS:
2004-02-20  Benjamin Otte  <otte@gnome.org>

* ext/xine/Makefile.am:
* ext/xine/gstxine.h:
* ext/xine/xine.c:
* ext/xine/xineaudiodec.c:
* ext/xine/xinecaps.c:
add first version of xine plugin wrapper. Currently only wraps the
QDM2 win32 DLL, and even that only in proof-of-concept quality.
* configure.ac:
* ext/Makefile.am:
add xine plugin wrapper, disabled by default. Use --enable-xine to
build. Note that it'll segfault on gst-register if you don't remove
the goom and tvtime post plugins from xine.
* gst/qtdemux/qtdemux.c: (gst_qtdemux_handle_sink_event),
(qtdemux_parse), (qtdemux_parse_trak), (qtdemux_audio_caps):
add extradata parsing for QDM2.
change around debugging prints.
parent fd2dd233
2004-02-20 Benjamin Otte <otte@gnome.org>
* ext/xine/Makefile.am:
* ext/xine/gstxine.h:
* ext/xine/xine.c:
* ext/xine/xineaudiodec.c:
* ext/xine/xinecaps.c:
add first version of xine plugin wrapper. Currently only wraps the
QDM2 win32 DLL, and even that only in proof-of-concept quality.
* configure.ac:
* ext/Makefile.am:
add xine plugin wrapper, disabled by default. Use --enable-xine to
build. Note that it'll segfault on gst-register if you don't remove
the goom and tvtime post plugins from xine.
* gst/qtdemux/qtdemux.c: (gst_qtdemux_handle_sink_event),
(qtdemux_parse), (qtdemux_parse_trak), (qtdemux_audio_caps):
add extradata parsing for QDM2.
change around debugging prints.
2004-02-19 Benjamin Otte <otte@gnome.org>
* ext/lame/gstlame.c: (gst_lame_chain):
......
......@@ -1320,6 +1320,14 @@ vorbis_synthesis_restart (v);
CFLAGS="$ac_cflags_save"
fi
dnl *** xine ***
translit(dnm, m, l) AM_CONDITIONAL(USE_XINE, true)
GST_CHECK_FEATURE(XINE, [xine wrapper], xine, [
PKG_CHECK_MODULES(XINE, libxine >= 1.0.0, HAVE_XINE=yes, HAVE_XINE=no)
AC_SUBST(XINE_CFLAGS)
AC_SUBST(XINE_LIBS)
],disabled)
dnl *** XVID ***
translit(dnm, m, l) AM_CONDITIONAL(USE_XVID, true)
GST_CHECK_FEATURE(XVID, [xvid plugins], xvid, [
......@@ -1664,6 +1672,7 @@ ext/swfdec/Makefile
ext/tarkin/Makefile
ext/theora/Makefile
ext/vorbis/Makefile
ext/xine/Makefile
ext/xvid/Makefile
gst-libs/Makefile
gst-libs/gst/Makefile
......
......@@ -310,6 +310,12 @@ else
SPEEX_DIR=
endif
if USE_XINE
XINE_DIR=xine
else
XINE_DIR=
endif
SUBDIRS=\
$(A52DEC_DIR) \
$(AALIB_DIR) \
......@@ -361,6 +367,7 @@ SUBDIRS=\
$(THEORA_DIR) \
$(IVORBIS_DIR) \
$(VORBIS_DIR) \
$(XINE_DIR) \
$(XVID_DIR)
DIST_SUBDIRS=\
......@@ -415,4 +422,5 @@ DIST_SUBDIRS=\
tarkin \
theora \
vorbis \
xine \
xvid
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
plugin_LTLIBRARIES = libgstxine.la
libgstxine_la_SOURCES = xine.c xinecaps.c xineaudiodec.c
libgstxine_la_CFLAGS = $(GST_CFLAGS) $(XINE_CFLAGS)
libgstxine_la_LIBADD = $(XINE_LIBS)
libgstxine_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstxine.h
/* GStreamer
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_XINE_H__
#define __GST_XINE_H__
#include <gst/gst.h>
#include <xine.h>
#include <xine/buffer.h>
G_BEGIN_DECLS
#define GST_TYPE_XINE \
(gst_xine_get_type())
#define GST_XINE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XINE,GstXine))
#define GST_XINE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XINE, GstXineClass))
#define GST_XINE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_XINE,GstXineClass))
#define GST_IS_XINE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XINE))
#define GST_IS_XINE_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XINE))
typedef struct _GstXine GstXine;
typedef struct _GstXineClass GstXineClass;
struct _GstXine
{
GstElement element;
xine_stream_t * stream;
xine_ao_driver_t * audio_driver;
xine_vo_driver_t * video_driver;
};
struct _GstXineClass
{
GstElementClass parent_class;
xine_t * xine;
xine_ao_driver_t * (* create_audio_driver) (GstXine * xine);
xine_vo_driver_t * (* create_video_driver) (GstXine * xine);
};
GType gst_xine_get_type (void);
xine_stream_t * gst_xine_get_stream (GstXine *xine);
void gst_xine_free_stream (GstXine *xine);
void gst_buffer_to_xine_buffer (buf_element_t *element, GstBuffer *buffer);
/* conversion functions from xinecaps.c */
const gchar * gst_xine_get_caps_for_format (guint32 format);
guint32 gst_xine_get_format_for_caps (const GstCaps *caps);
/* init functions for the plugins */
gboolean gst_xine_audio_dec_init_plugin (GstPlugin *plugin);
G_END_DECLS
#endif /* __GST_XINE_H__ */
/* GStreamer
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gstxine.h"
GST_BOILERPLATE (GstXine, gst_xine, GstElement, GST_TYPE_ELEMENT)
static GstElementStateReturn gst_xine_change_state (GstElement * element);
static xine_ao_driver_t * _xine_create_audio_driver (GstXine * xine);
static xine_vo_driver_t * _xine_create_video_driver (GstXine * xine);
static void
gst_xine_base_init (gpointer klass)
{
}
static void
gst_xine_class_init (GstXineClass *klass)
{
GstElementClass *element = GST_ELEMENT_CLASS (klass);
klass->xine = xine_new ();
xine_init (klass->xine);
klass->create_audio_driver = _xine_create_audio_driver;
klass->create_video_driver = _xine_create_video_driver;
element->change_state = gst_xine_change_state;
}
static void
gst_xine_init (GstXine *filter)
{
}
static GstElementStateReturn
gst_xine_change_state (GstElement *element)
{
GstXine *xine = GST_XINE (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
break;
case GST_STATE_READY_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_PLAYING:
break;
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
break;
case GST_STATE_READY_TO_NULL:
if (xine->stream != NULL)
gst_xine_free_stream (xine);
break;
default:
GST_ERROR_OBJECT (element, "invalid state change");
break;
}
return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state, (element), GST_STATE_SUCCESS);
}
static xine_ao_driver_t *
_xine_create_audio_driver (GstXine *xine)
{
return xine_open_audio_driver (GST_XINE_GET_CLASS (xine)->xine, "none", NULL);
}
static xine_vo_driver_t *
_xine_create_video_driver (GstXine *xine)
{
return xine_open_video_driver (GST_XINE_GET_CLASS (xine)->xine, "none", XINE_VISUAL_TYPE_NONE, NULL);
}
xine_stream_t *
gst_xine_get_stream (GstXine *xine)
{
if (!xine->stream) {
GstXineClass *klass = GST_XINE_GET_CLASS (xine);
g_assert (xine->video_driver == NULL);
g_assert (xine->audio_driver == NULL);
xine->audio_driver = klass->create_audio_driver (xine);
xine->video_driver = klass->create_video_driver (xine);
xine->stream = xine_stream_new (klass->xine, xine->audio_driver, xine->video_driver);
/* FIXME: fail gracefully */
g_assert (xine->stream);
}
return xine->stream;
}
void
gst_xine_free_stream (GstXine *xine)
{
g_return_if_fail (xine->stream != NULL);
g_assert (xine->video_driver != NULL);
g_assert (xine->audio_driver != NULL);
xine_dispose (xine->stream);
xine->stream = NULL;
xine_close_video_driver (GST_XINE_GET_CLASS (xine)->xine, xine->video_driver);
xine->video_driver = NULL;
xine_close_audio_driver (GST_XINE_GET_CLASS (xine)->xine, xine->audio_driver);
xine->audio_driver = NULL;
}
static void
_free_xine_buf_element (buf_element_t *buffer)
{
gst_buffer_unref (GST_BUFFER (buffer->source));
}
void
gst_buffer_to_xine_buffer (buf_element_t *ret, GstBuffer *buffer)
{
g_return_if_fail (ret != NULL);
g_return_if_fail (buffer != NULL);
/* FIXME: what's the difference? */
ret->mem = GST_BUFFER_DATA (buffer);
ret->content = GST_BUFFER_DATA (buffer);
ret->size = GST_BUFFER_SIZE (buffer);
ret->max_size = GST_BUFFER_MAXSIZE (buffer);
/* FIXME: add more */
ret->free_buffer = _free_xine_buf_element;
ret->source = buffer;
}
static gboolean
plugin_init (GstPlugin *plugin)
{
return gst_xine_audio_dec_init_plugin (plugin);
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"xine",
"wrapper for libxine (version "XINE_VERSION") plugins",
plugin_init,
VERSION,
"GPL",
GST_PACKAGE,
GST_ORIGIN
)
This diff is collapsed.
/* GStreamer
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstxine.h"
#include <xine/buffer.h>
typedef struct {
guint32 xine;
gchar * caps;
} GstXineCapsMap;
static GstXineCapsMap _gst_xine_caps_map[] = {
{ BUF_AUDIO_QDESIGN2, "audio/x-qdm2" },
/* FIXME:
#define BUF_AUDIO_A52 0x03000000
#define BUF_AUDIO_MPEG 0x03010000
#define BUF_AUDIO_LPCM_BE 0x03020000
#define BUF_AUDIO_LPCM_LE 0x03030000
#define BUF_AUDIO_WMAV1 0x03040000
#define BUF_AUDIO_DTS 0x03050000
#define BUF_AUDIO_MSADPCM 0x03060000
#define BUF_AUDIO_MSIMAADPCM 0x03070000
#define BUF_AUDIO_MSGSM 0x03080000
#define BUF_AUDIO_VORBIS 0x03090000
#define BUF_AUDIO_IMC 0x030a0000
#define BUF_AUDIO_LH 0x030b0000
#define BUF_AUDIO_VOXWARE 0x030c0000
#define BUF_AUDIO_ACELPNET 0x030d0000
#define BUF_AUDIO_AAC 0x030e0000
#define BUF_AUDIO_DNET 0x030f0000
#define BUF_AUDIO_VIVOG723 0x03100000
#define BUF_AUDIO_DK3ADPCM 0x03110000
#define BUF_AUDIO_DK4ADPCM 0x03120000
#define BUF_AUDIO_ROQ 0x03130000
#define BUF_AUDIO_QTIMAADPCM 0x03140000
#define BUF_AUDIO_MAC3 0x03150000
#define BUF_AUDIO_MAC6 0x03160000
#define BUF_AUDIO_QDESIGN1 0x03170000
#define BUF_AUDIO_QDESIGN2 0x03180000
#define BUF_AUDIO_QCLP 0x03190000
#define BUF_AUDIO_SMJPEG_IMA 0x031A0000
#define BUF_AUDIO_VQA_IMA 0x031B0000
#define BUF_AUDIO_MULAW 0x031C0000
#define BUF_AUDIO_ALAW 0x031D0000
#define BUF_AUDIO_GSM610 0x031E0000
#define BUF_AUDIO_EA_ADPCM 0x031F0000
#define BUF_AUDIO_WMAV2 0x03200000
#define BUF_AUDIO_COOK 0x03210000
#define BUF_AUDIO_ATRK 0x03220000
#define BUF_AUDIO_14_4 0x03230000
#define BUF_AUDIO_28_8 0x03240000
#define BUF_AUDIO_SIPRO 0x03250000
#define BUF_AUDIO_WMAV3 0x03260000
#define BUF_AUDIO_INTERPLAY 0x03270000
#define BUF_AUDIO_XA_ADPCM 0x03280000
#define BUF_AUDIO_WESTWOOD 0x03290000
#define BUF_AUDIO_DIALOGIC_IMA 0x032A0000
#define BUF_AUDIO_NSF 0x032B0000
#define BUF_AUDIO_FLAC 0x032C0000
#define BUF_AUDIO_DV 0x032D0000
#define BUF_AUDIO_WMAV 0x032E0000
#define BUF_AUDIO_SPEEX 0x032F0000
#define BUF_AUDIO_RAWPCM 0x03300000
#define BUF_AUDIO_4X_ADPCM 0x03310000
*/
{ 0, NULL }
};
const gchar *
gst_xine_get_caps_for_format (guint32 format)
{
guint i = 0;
while (_gst_xine_caps_map[i].xine != 0) {
if (_gst_xine_caps_map[i].xine == format)
return _gst_xine_caps_map[i].caps;
i++;
}
return NULL;
}
guint32
gst_xine_get_format_for_caps (const GstCaps *caps)
{
guint i = 0;
GstCaps *compare, *intersect;
while (_gst_xine_caps_map[i].xine != 0) {
compare = gst_caps_from_string (_gst_xine_caps_map[i].caps);
intersect = gst_caps_intersect (caps, compare);
gst_caps_free (compare);
if (!gst_caps_is_empty (intersect)) {
gst_caps_free (intersect);
return _gst_xine_caps_map[i].xine;
}
gst_caps_free (intersect);
i++;
}
return 0;
}
......@@ -153,7 +153,7 @@ static QtNodeType *qtdemux_type_get(guint32 fourcc);
static void qtdemux_node_dump(GstQTDemux *qtdemux, GNode *node);
static void qtdemux_parse_tree(GstQTDemux *qtdemux);
static GstCaps *qtdemux_video_caps(GstQTDemux *qtdemux, guint32 fourcc, const guint8 *stsd_data);
static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc);
static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc, const guint8 *data);
static GType gst_qtdemux_get_type (void)
{
......@@ -284,7 +284,7 @@ static gboolean gst_qtdemux_handle_sink_event (GstQTDemux *qtdemux)
gst_pad_event_default(qtdemux->sinkpad, event);
return FALSE;
case GST_EVENT_FLUSH:
g_warning("flush event");
//g_warning("flush event");
break;
case GST_EVENT_DISCONTINUOUS:
GST_DEBUG ("discontinuous event\n");
......@@ -780,15 +780,15 @@ static void qtdemux_parse(GstQTDemux *qtdemux, GNode *node, void *buffer, int le
QtNodeType *type;
void *end;
//g_print("qtdemux_parse %p %d\n",buffer, length);
g_print("qtdemux_parse %p %d\n",buffer, length);
node_length = QTDEMUX_GUINT32_GET(buffer);
fourcc = QTDEMUX_FOURCC_GET(buffer+4);
type = qtdemux_type_get(fourcc);
/*g_print("parsing '" GST_FOURCC_FORMAT "', length=%d\n",
GST_FOURCC_ARGS(fourcc), node_length);*/
g_print("parsing '" GST_FOURCC_FORMAT "', length=%d\n",
GST_FOURCC_ARGS(fourcc), node_length);
if(type->flags & QT_CONTAINER){
void *buf;
......@@ -1301,20 +1301,22 @@ static void qtdemux_parse_trak(GstQTDemux *qtdemux, GNode *trak)
g_print("sample rate: %g\n", QTDEMUX_FP32_GET(stsd->data+offset + 16));
stream->rate = QTDEMUX_FP32_GET(stsd->data+offset + 16);
offset = 52;
if(version == 0x00010000){
g_print("samples/packet: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 20));
stream->samples_per_packet = QTDEMUX_GUINT32_GET(stsd->data+offset + 20);
g_print("bytes/packet: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 24));
g_print("bytes/frame: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 28));
stream->bytes_per_frame = QTDEMUX_GUINT32_GET(stsd->data+offset + 28);
g_print("bytes/sample: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 32));
g_print("samples/packet: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset));
stream->samples_per_packet = QTDEMUX_GUINT32_GET(stsd->data+offset);
g_print("bytes/packet: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 4));
g_print("bytes/frame: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 8));
stream->bytes_per_frame = QTDEMUX_GUINT32_GET(stsd->data+offset + 8);
g_print("bytes/sample: %d\n", QTDEMUX_GUINT32_GET(stsd->data+offset + 12));
offset = 68;
} else {
stream->bytes_per_frame = stream->n_channels * QTDEMUX_GUINT16_GET(stsd->data+offset + 10);
stream->samples_per_packet = 1;
}
stream->caps = qtdemux_audio_caps(qtdemux,
QTDEMUX_FOURCC_GET(stsd->data+16+4));
QTDEMUX_FOURCC_GET(stsd->data+16+4), (QTDEMUX_GUINT32_GET(stsd->data) > offset) ? stsd->data + offset : NULL);
g_print("caps %s\n",gst_caps_to_string(stream->caps));
}else{
g_print("unknown subtype\n");
......@@ -1597,7 +1599,7 @@ static GstCaps *qtdemux_video_caps(GstQTDemux *qtdemux, guint32 fourcc, const gu
}
}
static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc)
static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc, const guint8 *data)
{
switch(fourcc){
case GST_MAKE_FOURCC('N','O','N','E'):
......@@ -1685,8 +1687,15 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc)
return gst_caps_from_string ("audio/mpeg, "
"mpegversion = (int) 4");
case GST_MAKE_FOURCC('Q','D','M','2'):
/* QDesign music version 2 (no constant) */
return gst_caps_from_string ("audio/x-qdm2");
/* FIXME: QDesign music version 2 (no constant) */
if (QTDEMUX_GUINT32_GET (data) <= 100) {
gst_util_dump_mem ((guint8*)data, 100);
return gst_caps_new_simple ("audio/x-qdm2",
"framesize", G_TYPE_INT, QTDEMUX_GUINT32_GET (data + 52),
"bitrate", G_TYPE_INT, QTDEMUX_GUINT32_GET (data + 40),
"blocksize", G_TYPE_INT, QTDEMUX_GUINT32_GET (data + 44),
NULL);
}
case GST_MAKE_FOURCC('q','t','v','r'):
/* ? */
case GST_MAKE_FOURCC('Q','D','M','C'):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment