summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2003-12-18 09:49:50 +0000
committerDavid Schleef <ds@schleef.org>2003-12-18 09:49:50 +0000
commitef3ed344af7d0eb330f68c85d31acfa9471d1573 (patch)
tree012d45187cfa98f972073142ce341190252e17f7
parent70a4a0e00218745b2bf7ad0b145fe9a967981cb4 (diff)
downloadgstreamer-plugins-bad-ef3ed344af7d0eb330f68c85d31acfa9471d1573.tar.gz
Merge HEAD from CAPS-ROOT to CAPS-MERGE-3
Original commit message from CVS: Merge HEAD from CAPS-ROOT to CAPS-MERGE-3
-rw-r--r--ext/Makefile.am8
-rw-r--r--ext/arts/gst_arts.c1
-rw-r--r--ext/artsd/gstartsdsink.c1
-rw-r--r--ext/audiofile/gstaf.c1
-rw-r--r--ext/divx/gstdivxdec.c1
-rw-r--r--ext/divx/gstdivxenc.c1
-rw-r--r--ext/faac/gstfaac.c1
-rw-r--r--ext/faad/gstfaad.c1
-rw-r--r--ext/gsm/gstgsm.c1
-rw-r--r--ext/hermes/gstcolorspace.c1
-rw-r--r--ext/ivorbis/vorbis.c1
-rw-r--r--ext/jack/gstjack.c1
-rw-r--r--ext/jack/gstjackbin.c2
-rw-r--r--ext/ladspa/gstladspa.c15
-rw-r--r--ext/libfame/gstlibfame.c1
-rw-r--r--ext/mas/massink.c1
-rw-r--r--ext/mpeg2enc/Makefile.am18
-rw-r--r--ext/mpeg2enc/gstmpeg2enc.cc319
-rw-r--r--ext/mpeg2enc/gstmpeg2enc.hh63
-rw-r--r--ext/mpeg2enc/gstmpeg2encoder.cc95
-rw-r--r--ext/mpeg2enc/gstmpeg2encoder.hh44
-rw-r--r--ext/mpeg2enc/gstmpeg2encoptions.cc703
-rw-r--r--ext/mpeg2enc/gstmpeg2encoptions.hh42
-rw-r--r--ext/mpeg2enc/gstmpeg2encpicturereader.cc129
-rw-r--r--ext/mpeg2enc/gstmpeg2encpicturereader.hh49
-rw-r--r--ext/mpeg2enc/gstmpeg2encstreamwriter.cc99
-rw-r--r--ext/mpeg2enc/gstmpeg2encstreamwriter.hh (renamed from gst-libs/gst/riff/riffutil.c)46
-rw-r--r--ext/mplex/gstmplex.cc1
-rw-r--r--ext/sdl/sdlvideosink.c15
-rw-r--r--ext/shout/gstshout.c1
-rw-r--r--ext/smoothwave/gstsmoothwave.c1
-rw-r--r--ext/snapshot/gstsnapshot.c1
-rw-r--r--ext/sndfile/gstsf.c1
-rw-r--r--ext/swfdec/gstswfdec.c1
-rw-r--r--ext/tarkin/gsttarkin.c1
-rw-r--r--ext/xvid/gstxvid.c1
-rw-r--r--gst-libs/gst/Makefile.am18
-rw-r--r--gst-libs/gst/audio/audio.c1
-rw-r--r--gst-libs/gst/audio/audioclock.h4
-rw-r--r--gst-libs/gst/audio/gstaudiofilter.c2
-rw-r--r--gst-libs/gst/audio/gstaudiofilterexample.c1
-rw-r--r--gst-libs/gst/colorbalance/Makefile.am22
-rw-r--r--gst-libs/gst/colorbalance/colorbalance.c37
-rw-r--r--gst-libs/gst/colorbalance/colorbalance.h18
-rw-r--r--gst-libs/gst/colorbalance/colorbalancechannel.c3
-rw-r--r--gst-libs/gst/colorbalance/colorbalancechannel.h2
-rw-r--r--gst-libs/gst/colorbalance/colorbalancemarshal.list1
-rw-r--r--gst-libs/gst/idct/idct.c1
-rw-r--r--gst-libs/gst/media-info/media-info.h4
-rw-r--r--gst-libs/gst/mixer/Makefile.am22
-rw-r--r--gst-libs/gst/mixer/mixer.c82
-rw-r--r--gst-libs/gst/mixer/mixer.h54
-rw-r--r--gst-libs/gst/mixer/mixermarshal.list2
-rw-r--r--gst-libs/gst/mixer/mixertrack.h7
-rw-r--r--gst-libs/gst/navigation/navigation.h2
-rw-r--r--gst-libs/gst/play/Makefile.am8
-rw-r--r--gst-libs/gst/play/gstplay.c1004
-rw-r--r--gst-libs/gst/play/gstplay.h89
-rw-r--r--gst-libs/gst/play/play.c1004
-rw-r--r--gst-libs/gst/play/play.h89
-rw-r--r--gst-libs/gst/play/play.old.h4
-rw-r--r--gst-libs/gst/propertyprobe/propertyprobe.h2
-rw-r--r--gst-libs/gst/resample/resample.c1
-rw-r--r--gst-libs/gst/riff/Makefile.am11
-rw-r--r--gst-libs/gst/riff/riff-ids.h319
-rw-r--r--gst-libs/gst/riff/riff-media.c369
-rw-r--r--gst-libs/gst/riff/riff-media.h55
-rw-r--r--gst-libs/gst/riff/riff-read.c868
-rw-r--r--gst-libs/gst/riff/riff-read.h100
-rw-r--r--gst-libs/gst/riff/riff.c17
-rw-r--r--gst-libs/gst/riff/riff.h448
-rw-r--r--gst-libs/gst/riff/riffencode.c181
-rw-r--r--gst-libs/gst/riff/riffparse.c250
-rw-r--r--gst-libs/gst/tag/Makefile.am5
-rw-r--r--gst-libs/gst/tag/tag.h62
-rw-r--r--gst-libs/gst/tuner/Makefile.am21
-rw-r--r--gst-libs/gst/tuner/tuner.c94
-rw-r--r--gst-libs/gst/tuner/tuner.h30
-rw-r--r--gst-libs/gst/tuner/tunerchannel.h6
-rw-r--r--gst-libs/gst/tuner/tunermarshal.list2
-rw-r--r--gst-libs/gst/tuner/tunernorm.h2
-rw-r--r--gst-libs/gst/video/gstvideosink.h4
-rw-r--r--gst-libs/gst/video/video.c1
-rw-r--r--gst-libs/gst/video/videosink.h4
-rw-r--r--gst-libs/gst/xoverlay/xoverlay.c5
-rw-r--r--gst-libs/gst/xoverlay/xoverlay.h7
-rw-r--r--gst-libs/gst/xwindowlistener/xwindowlistener.c1
-rw-r--r--gst/smoothwave/gstsmoothwave.c1
88 files changed, 5998 insertions, 1017 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am
index a26660d71..cdcfefe7e 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -190,6 +190,12 @@ else
MPEG2DEC_DIR=
endif
+if USE_MPEG2ENC
+MPEG2ENC_DIR=mpeg2enc
+else
+MPEG2ENC_DIR=
+endif
+
if USE_MPLEX
MPLEX_DIR=mplex
else
@@ -318,6 +324,7 @@ SUBDIRS=\
$(MAS_DIR) \
$(MIKMOD_DIR) \
$(MPEG2DEC_DIR) \
+ $(MPEG2ENC_DIR) \
$(MPLEX_DIR) \
$(OGG_DIR) \
$(PANGO_DIR) \
@@ -367,6 +374,7 @@ DIST_SUBDIRS=\
mad \
mikmod \
mpeg2dec \
+ mpeg2enc \
mplex \
ogg \
pango \
diff --git a/ext/arts/gst_arts.c b/ext/arts/gst_arts.c
index 85e31e1aa..196bd7c1c 100644
--- a/ext/arts/gst_arts.c
+++ b/ext/arts/gst_arts.c
@@ -171,7 +171,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/ext/artsd/gstartsdsink.c b/ext/artsd/gstartsdsink.c
index 7bb917576..6012f9337 100644
--- a/ext/artsd/gstartsdsink.c
+++ b/ext/artsd/gstartsdsink.c
@@ -275,7 +275,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/audiofile/gstaf.c b/ext/audiofile/gstaf.c
index 1d05ae3ff..188caf423 100644
--- a/ext/audiofile/gstaf.c
+++ b/ext/audiofile/gstaf.c
@@ -48,6 +48,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/divx/gstdivxdec.c b/ext/divx/gstdivxdec.c
index 049691f4e..c68d12dce 100644
--- a/ext/divx/gstdivxdec.c
+++ b/ext/divx/gstdivxdec.c
@@ -479,7 +479,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
"5.03",
GST_LICENSE_UNKNOWN,
- "(c) 2002 DivX Networks",
"divx4linux",
"http://www.divx.com/"
)
diff --git a/ext/divx/gstdivxenc.c b/ext/divx/gstdivxenc.c
index b5a0458e3..ba9c03513 100644
--- a/ext/divx/gstdivxenc.c
+++ b/ext/divx/gstdivxenc.c
@@ -582,7 +582,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
"5.03",
GST_LICENSE_UNKNOWN,
- "(c) 2002 DivX Networks",
"divx4linux",
"http://www.divx.com/"
)
diff --git a/ext/faac/gstfaac.c b/ext/faac/gstfaac.c
index e5dddc17a..be4c56cba 100644
--- a/ext/faac/gstfaac.c
+++ b/ext/faac/gstfaac.c
@@ -674,7 +674,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index c14ba44e8..56f38a4e4 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -472,7 +472,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"GPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/ext/gsm/gstgsm.c b/ext/gsm/gstgsm.c
index c186ed1b2..346cf219a 100644
--- a/ext/gsm/gstgsm.c
+++ b/ext/gsm/gstgsm.c
@@ -43,6 +43,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/hermes/gstcolorspace.c b/ext/hermes/gstcolorspace.c
index de1bd88f7..837c24e41 100644
--- a/ext/hermes/gstcolorspace.c
+++ b/ext/hermes/gstcolorspace.c
@@ -679,7 +679,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/ivorbis/vorbis.c b/ext/ivorbis/vorbis.c
index 4098e53f9..b104ec663 100644
--- a/ext/ivorbis/vorbis.c
+++ b/ext/ivorbis/vorbis.c
@@ -48,6 +48,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/jack/gstjack.c b/ext/jack/gstjack.c
index 3aff6d7cd..85d57658c 100644
--- a/ext/jack/gstjack.c
+++ b/ext/jack/gstjack.c
@@ -519,6 +519,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"GPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/jack/gstjackbin.c b/ext/jack/gstjackbin.c
index cb1839c41..b0cea9bc3 100644
--- a/ext/jack/gstjackbin.c
+++ b/ext/jack/gstjackbin.c
@@ -279,7 +279,7 @@ process (jack_nframes_t nframes, void *arg)
bin->nframes = nframes;
JACK_DEBUG ("jackbin: iterating to process %ld frames of audio...", nframes);
- if (!gst_bin_iterate (GST_BIN_CAST (bin))) {
+ if (!gst_bin_iterate (GST_BIN (bin))) {
g_warning ("bin failed to iterate");
return -1;
}
diff --git a/ext/ladspa/gstladspa.c b/ext/ladspa/gstladspa.c
index 6dc8763f9..6ecb3ce16 100644
--- a/ext/ladspa/gstladspa.c
+++ b/ext/ladspa/gstladspa.c
@@ -1,6 +1,7 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* <2001> Steve Baker <stevebaker_org@yahoo.co.uk>
+ * 2003 Andy Wingo <wingo at pobox.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,6 +31,11 @@
#include <ladspa.h> /* main ladspa sdk include file */
#include "utils.h" /* ladspa sdk utility functions */
+/* 1.0 and the 1.1 preliminary headers don't define a version, but 1.1 final
+ does */
+#ifndef LADSPA_VERSION
+#define LADSPA_VERSION "1.0"
+#endif
/* takes ownership of the name */
static GstPadTemplate*
@@ -1038,9 +1044,8 @@ GST_PLUGIN_DEFINE (
"ladspa",
"All LADSPA plugins",
plugin_init,
- LADSPA_VERSION,
- "LGPL",
- "(c) 2003 The LADSPA team",
- "LADSPA",
- "http://www.ladspa.org/"
+ VERSION,
+ GST_LICENSE,
+ GST_PACKAGE,
+ GST_ORIGIN
)
diff --git a/ext/libfame/gstlibfame.c b/ext/libfame/gstlibfame.c
index 17ea96691..be2404d5d 100644
--- a/ext/libfame/gstlibfame.c
+++ b/ext/libfame/gstlibfame.c
@@ -612,7 +612,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
LIBFAME_VERSION,
"LGPL",
- "(c) 2000-2001, Vivien Chappelier",
"libfame",
"http://fame.sourceforge.net/"
)
diff --git a/ext/mas/massink.c b/ext/mas/massink.c
index 67ca47b4e..0a87c9c86 100644
--- a/ext/mas/massink.c
+++ b/ext/mas/massink.c
@@ -349,7 +349,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
);
diff --git a/ext/mpeg2enc/Makefile.am b/ext/mpeg2enc/Makefile.am
new file mode 100644
index 000000000..da5d01d1f
--- /dev/null
+++ b/ext/mpeg2enc/Makefile.am
@@ -0,0 +1,18 @@
+plugin_LTLIBRARIES = libgstmpeg2enc.la
+
+libgstmpeg2enc_la_SOURCES = \
+ gstmpeg2enc.cc \
+ gstmpeg2encoptions.cc \
+ gstmpeg2encoder.cc \
+ gstmpeg2encstreamwriter.cc \
+ gstmpeg2encpicturereader.cc
+libgstmpeg2enc_la_CXXFLAGS = $(MPEG2ENC_CFLAGS) $(GST_CFLAGS)
+libgstmpeg2enc_la_LIBADD = $(MPEG2ENC_LIBS)
+libgstmpeg2enc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+noinst_HEADERS = \
+ gstmpeg2enc.hh \
+ gstmpeg2encoder.hh \
+ gstmpeg2encoptions.hh \
+ gstmpeg2encstreamwriter.hh \
+ gstmpeg2encpicturereader.hh
diff --git a/ext/mpeg2enc/gstmpeg2enc.cc b/ext/mpeg2enc/gstmpeg2enc.cc
new file mode 100644
index 000000000..5e5e028df
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2enc.cc
@@ -0,0 +1,319 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2enc.cc: gstreamer wrapping
+ *
+ * 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 "gstmpeg2enc.hh"
+
+GST_PAD_TEMPLATE_FACTORY (sink_templ,
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "mpeg2enc_sink",
+ "video/x-raw-yuv",
+ "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096),
+ "framerate", GST_PROPS_LIST (
+ GST_PROPS_FLOAT (24/1.001),
+ GST_PROPS_FLOAT (24.),
+ GST_PROPS_FLOAT (25.),
+ GST_PROPS_FLOAT (30/1.001),
+ GST_PROPS_FLOAT (30.),
+ GST_PROPS_FLOAT (50.),
+ GST_PROPS_FLOAT (60/1.001),
+ GST_PROPS_FLOAT (60.)
+ )
+ )
+)
+
+GST_PAD_TEMPLATE_FACTORY (src_templ,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "mpeg2enc_src",
+ "video/mpeg",
+ "systemstream", GST_PROPS_BOOLEAN (FALSE),
+ "mpegversion", GST_PROPS_INT_RANGE (1, 2),
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096),
+ "framerate", GST_PROPS_LIST (
+ GST_PROPS_FLOAT (24/1.001),
+ GST_PROPS_FLOAT (24.),
+ GST_PROPS_FLOAT (25.),
+ GST_PROPS_FLOAT (30/1.001),
+ GST_PROPS_FLOAT (30.),
+ GST_PROPS_FLOAT (50.),
+ GST_PROPS_FLOAT (60/1.001),
+ GST_PROPS_FLOAT (60.)
+ )
+ )
+)
+
+static void gst_mpeg2enc_base_init (GstMpeg2encClass *klass);
+static void gst_mpeg2enc_class_init (GstMpeg2encClass *klass);
+static void gst_mpeg2enc_init (GstMpeg2enc *enc);
+static void gst_mpeg2enc_dispose (GObject *object);
+
+static void gst_mpeg2enc_loop (GstElement *element);
+
+static GstPadLinkReturn
+ gst_mpeg2enc_sink_link (GstPad *pad,
+ GstCaps *caps);
+static GstCaps *
+ gst_mpeg2enc_src_getcaps (GstPad *pad,
+ GstCaps *caps);
+
+static GstElementStateReturn
+ gst_mpeg2enc_change_state (GstElement *element);
+
+static void gst_mpeg2enc_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gst_mpeg2enc_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static GstElementClass *parent_class = NULL;
+
+GType
+gst_mpeg2enc_get_type (void)
+{
+ static GType gst_mpeg2enc_type = 0;
+
+ if (!gst_mpeg2enc_type) {
+ static const GTypeInfo gst_mpeg2enc_info = {
+ sizeof (GstMpeg2encClass),
+ (GBaseInitFunc) gst_mpeg2enc_base_init,
+ NULL,
+ (GClassInitFunc) gst_mpeg2enc_class_init,
+ NULL,
+ NULL,
+ sizeof (GstMpeg2enc),
+ 0,
+ (GInstanceInitFunc) gst_mpeg2enc_init,
+ };
+
+ gst_mpeg2enc_type =
+ g_type_register_static (GST_TYPE_ELEMENT,
+ "GstMpeg2enc",
+ &gst_mpeg2enc_info,
+ (GTypeFlags) 0);
+ }
+
+ return gst_mpeg2enc_type;
+}
+
+static void
+gst_mpeg2enc_base_init (GstMpeg2encClass *klass)
+{
+ static GstElementDetails gst_mpeg2enc_details = {
+ "mpeg2enc video encoder",
+ "Codec/Video/Encoder",
+ "High-quality MPEG-1/2 video encoder",
+ "Ronald Bultje <rbultje@ronald.bitfreak.net>",
+ };
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_add_pad_template (element_class,
+ GST_PAD_TEMPLATE_GET (src_templ));
+ gst_element_class_add_pad_template (element_class,
+ GST_PAD_TEMPLATE_GET (sink_templ));
+ gst_element_class_set_details (element_class,
+ &gst_mpeg2enc_details);
+}
+
+static void
+gst_mpeg2enc_class_init (GstMpeg2encClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT));
+
+ /* register arguments */
+ mjpeg_default_handler_verbosity (0);
+ GstMpeg2EncOptions::initProperties (object_class);
+
+ object_class->set_property = gst_mpeg2enc_set_property;
+ object_class->get_property = gst_mpeg2enc_get_property;
+
+ object_class->dispose = gst_mpeg2enc_dispose;
+
+ element_class->change_state = gst_mpeg2enc_change_state;
+}
+
+static void
+gst_mpeg2enc_dispose (GObject *object)
+{
+ GstMpeg2enc *enc = GST_MPEG2ENC (object);
+
+ if (enc->encoder) {
+ delete enc->encoder;
+ enc->encoder = NULL;
+ }
+ delete enc->options;
+}
+
+static void
+gst_mpeg2enc_init (GstMpeg2enc *enc)
+{
+ GstElement *element = GST_ELEMENT (enc);
+
+ enc->sinkpad = gst_pad_new_from_template (
+ gst_element_get_pad_template (element, "sink"), "sink");
+ gst_pad_set_link_function (enc->sinkpad, gst_mpeg2enc_sink_link);
+ gst_element_add_pad (element, enc->sinkpad);
+
+ enc->srcpad = gst_pad_new_from_template (
+ gst_element_get_pad_template (element, "src"), "src");
+ gst_pad_set_getcaps_function (enc->srcpad, gst_mpeg2enc_src_getcaps);
+ gst_element_add_pad (element, enc->srcpad);
+
+ enc->options = new GstMpeg2EncOptions ();
+
+ gst_element_set_loop_function (element, gst_mpeg2enc_loop);
+
+ enc->encoder = NULL;
+}
+
+static void
+gst_mpeg2enc_loop (GstElement *element)
+{
+ GstMpeg2enc *enc = GST_MPEG2ENC (element);
+
+ if (!enc->encoder) {
+ GstCaps *caps;
+
+ /* create new encoder with these settings */
+ enc->encoder = new GstMpeg2Encoder (enc->options,
+ enc->sinkpad,
+ GST_PAD_CAPS (enc->sinkpad),
+ enc->srcpad);
+
+ /* and set caps on other side */
+ caps = enc->encoder->getFormat ();
+ if (gst_pad_try_set_caps (enc->srcpad, caps) <= 0) {
+ gst_element_error (element,
+ "Failed to set up encoder properly");
+ delete enc->encoder;
+ enc->encoder = NULL;
+ return;
+ }
+ }
+
+ enc->encoder->encodePicture ();
+}
+
+static GstPadLinkReturn
+gst_mpeg2enc_sink_link (GstPad *pad,
+ GstCaps *caps)
+{
+ GstMpeg2enc *enc = GST_MPEG2ENC (gst_pad_get_parent (pad));
+
+ if (!GST_CAPS_IS_FIXED (caps))
+ return GST_PAD_LINK_DELAYED;
+
+ if (enc->encoder) {
+ delete enc->encoder;
+ enc->encoder = NULL;
+ }
+
+ return GST_PAD_LINK_OK;
+}
+
+static GstCaps *
+gst_mpeg2enc_src_getcaps (GstPad *pad,
+ GstCaps *caps)
+{
+ GstMpeg2enc *enc = GST_MPEG2ENC (gst_pad_get_parent (pad));
+
+ if (enc->encoder) {
+ return enc->encoder->getFormat ();
+ }
+
+ return gst_caps_ref (gst_pad_template_get_caps (
+ gst_element_get_pad_template (gst_pad_get_parent (pad), "src")));
+}
+
+static void
+gst_mpeg2enc_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GST_MPEG2ENC (object)->options->getProperty (prop_id, value);
+}
+
+static void
+gst_mpeg2enc_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GST_MPEG2ENC (object)->options->setProperty (prop_id, value);
+}
+
+static GstElementStateReturn
+gst_mpeg2enc_change_state (GstElement *element)
+{
+ GstMpeg2enc *enc = GST_MPEG2ENC (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_PAUSED_TO_READY:
+ delete enc->encoder;
+ enc->encoder = NULL;
+ break;
+ default:
+ break;
+ }
+
+ if (parent_class->change_state)
+ return parent_class->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
+
+static gboolean
+plugin_init (GstPlugin *plugin)
+{
+ return gst_element_register (plugin, "mpeg2enc",
+ GST_RANK_NONE,
+ GST_TYPE_MPEG2ENC);
+}
+
+GST_PLUGIN_DEFINE (
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "mpeg2enc",
+ "High-quality MPEG-1/2 video encoder",
+ plugin_init,
+ VERSION,
+ "GPL",
+ GST_PACKAGE,
+ GST_ORIGIN
+)
diff --git a/ext/mpeg2enc/gstmpeg2enc.hh b/ext/mpeg2enc/gstmpeg2enc.hh
new file mode 100644
index 000000000..25c61e61a
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2enc.hh
@@ -0,0 +1,63 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2enc.hh: object definition
+ *
+ * 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_MPEG2ENC_H__
+#define __GST_MPEG2ENC_H__
+
+#include <gst/gst.h>
+#include "gstmpeg2encoptions.hh"
+#include "gstmpeg2encoder.hh"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_MPEG2ENC \
+ (gst_mpeg2enc_get_type ())
+#define GST_MPEG2ENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPEG2ENC, GstMpeg2enc))
+#define GST_MPEG2ENC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPEG2ENC, GstMpeg2enc))
+#define GST_IS_MPEG2ENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPEG2ENC))
+#define GST_IS_MPEG2ENC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPEG2ENC))
+
+typedef struct _GstMpeg2enc {
+ GstElement parent;
+
+ /* pads */
+ GstPad *sinkpad, *srcpad;
+
+ /* options wrapper */
+ GstMpeg2EncOptions *options;
+
+ /* general encoding object (contains rest) */
+ GstMpeg2Encoder *encoder;
+} GstMpeg2enc;
+
+typedef struct _GstMpeg2encClass {
+ GstElementClass parent;
+} GstMpeg2encClass;
+
+GType gst_mpeg2enc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_MPEG2ENC_H__ */
diff --git a/ext/mpeg2enc/gstmpeg2encoder.cc b/ext/mpeg2enc/gstmpeg2encoder.cc
new file mode 100644
index 000000000..e0952db13
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encoder.cc
@@ -0,0 +1,95 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encoder.cc: gstreamer/mpeg2enc encoder class
+ *
+ * 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 <mpegconsts.h>
+#include <quantize.hh>
+#include <ratectl.hh>
+#include <seqencoder.hh>
+#include <mpeg2coder.hh>
+
+#include "gstmpeg2encoder.hh"
+
+/*
+ * Class init stuff.
+ */
+
+GstMpeg2Encoder::GstMpeg2Encoder (GstMpeg2EncOptions *options,
+ GstPad *sinkpad,
+ GstCaps *caps,
+ GstPad *srcpad) :
+ MPEG2Encoder (*options)
+{
+ MPEG2EncInVidParams strm;
+
+ /* I/O */
+ reader = new GstMpeg2EncPictureReader (sinkpad, caps, &parms);
+ reader->StreamPictureParams (strm);
+ if (options->SetFormatPresets (strm)) {
+ g_warning ("Eek! Format presets failed. This is really bad!");
+ }
+ writer = new GstMpeg2EncStreamWriter (srcpad, &parms);
+
+ /* encoding internals */
+ quantizer = new Quantizer (parms);
+ coder = new MPEG2Coder (parms, *writer);
+ bitrate_controller = new OnTheFlyRateCtl (parms);
+
+ /* sequencer */
+ seqencoder = new SeqEncoder (parms, *reader, *quantizer,
+ *writer, *coder, *bitrate_controller);
+
+ parms.Init (*options);
+ reader->Init ();
+ quantizer->Init ();
+}
+
+/*
+ * One image.
+ */
+
+void
+GstMpeg2Encoder::encodePicture ()
+{
+ /* hm, this is all... eek! */
+ seqencoder->Encode ();
+}
+
+/*
+ * Get current output format.
+ */
+
+GstCaps *
+GstMpeg2Encoder::getFormat ()
+{
+ gdouble fps = Y4M_RATIO_DBL (mpeg_framerate (options.frame_rate));
+
+ return GST_CAPS_NEW ("mpeg2enc_src",
+ "video/mpeg",
+ "systemstream", GST_PROPS_BOOLEAN (FALSE),
+ "mpegversion", GST_PROPS_INT (options.mpeg),
+ "width", GST_PROPS_INT (options.in_img_width),
+ "height", GST_PROPS_INT (options.in_img_height),
+ "framerate", GST_PROPS_FLOAT (fps));
+}
diff --git a/ext/mpeg2enc/gstmpeg2encoder.hh b/ext/mpeg2enc/gstmpeg2encoder.hh
new file mode 100644
index 000000000..ebe296927
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encoder.hh
@@ -0,0 +1,44 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encoder.hh: gstreamer/mpeg2enc encoder class
+ *
+ * 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_MPEG2ENCODER_H__
+#define __GST_MPEG2ENCODER_H__
+
+#include <mpeg2encoder.hh>
+#include "gstmpeg2encoptions.hh"
+#include "gstmpeg2encpicturereader.hh"
+#include "gstmpeg2encstreamwriter.hh"
+
+class GstMpeg2Encoder : public MPEG2Encoder {
+public:
+ GstMpeg2Encoder (GstMpeg2EncOptions *options,
+ GstPad *sinkpad,
+ GstCaps *caps,
+ GstPad *srcpad);
+
+ /* one image */
+ void encodePicture ();
+
+ /* get current output format */
+ GstCaps *getFormat ();
+};
+
+#endif /* __GST_MPEG2ENCODER_H__ */
diff --git a/ext/mpeg2enc/gstmpeg2encoptions.cc b/ext/mpeg2enc/gstmpeg2encoptions.cc
new file mode 100644
index 000000000..5dbf9ac73
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encoptions.cc
@@ -0,0 +1,703 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encoptions.cc: gobject/mpeg2enc option wrapping class
+ *
+ * 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 "gstmpeg2encoptions.hh"
+
+/*
+ * Property enumeration.
+ */
+
+enum {
+ ARG_0,
+ ARG_FORMAT,
+ ARG_FRAMERATE,
+ ARG_ASPECT,
+ ARG_INTERLACE_MODE,
+ ARG_BITRATE,
+ ARG_NONVIDEO_BITRATE,
+ ARG_QUANTISATION,
+ ARG_VCD_STILL_SIZE,
+ ARG_MOTION_SEARCH_RADIUS,
+ ARG_REDUCTION_4_4,
+ ARG_REDUCTION_2_2,
+ ARG_UNIT_COEFF_ELIM,
+ ARG_MIN_GOP_SIZE,
+ ARG_MAX_GOP_SIZE,
+ ARG_CLOSED_GOP,
+ ARG_FORCE_B_B_P,
+ ARG_B_PER_REFFRAME,
+ ARG_QUANTISATION_REDUCTION,
+ ARG_QUANT_REDUCTION_MAX_VAR,
+ ARG_INTRA_DC_PRECISION,
+ ARG_REDUCE_HF,
+ ARG_KEEP_HF,
+ ARG_QUANTISATION_MATRIX,
+ ARG_BUFSIZE,
+ ARG_VIDEO_NORM,
+ ARG_SEQUENCE_LENGTH,
+ ARG_3_2_PULLDOWN,
+ ARG_SEQUENCE_HEADER_EVERY_GOP,
+ ARG_PLAYBACK_FIELD_ORDER,
+ ARG_DUMMY_SVCD_SOF,
+ ARG_CORRECT_SVCD_HDS,
+ ARG_ALTSCAN_MPEG2,
+ ARG_CONSTRAINTS
+ /* FILL ME */
+};
+
+/*
+ * Property enumeration types.
+ */
+
+#define GST_TYPE_MPEG2ENC_FORMAT \
+ (gst_mpeg2enc_format_get_type ())
+
+static GType
+gst_mpeg2enc_format_get_type (void)
+{
+ static GType mpeg2enc_format_type = 0;
+
+ if (!mpeg2enc_format_type) {
+ static const GEnumValue mpeg2enc_formats[] = {
+ { 0, "0", "Generic MPEG-1" },
+ { 1, "1", "Standard VCD" },
+ { 2, "2", "User VCD" },
+ { 3, "3", "Generic MPEG-2" },
+ { 4, "4", "Standard SVCD" },
+ { 5, "5", "User SVCD" },
+ { 6, "6", "VCD Stills sequences" },
+ { 7, "7", "SVCD Stills sequences" },
+ { 8, "8", "DVD MPEG-2 for dvdauthor" },
+ { 9, "9", "DVD MPEG-2" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_format_type =
+ g_enum_register_static ("GstMpeg2encFormat",
+ mpeg2enc_formats);
+ }
+
+ return mpeg2enc_format_type;
+}
+
+#define GST_TYPE_MPEG2ENC_FRAMERATE \
+ (gst_mpeg2enc_framerate_get_type ())
+
+static GType
+gst_mpeg2enc_framerate_get_type (void)
+{
+ static GType mpeg2enc_framerate_type = 0;
+
+ if (!mpeg2enc_framerate_type) {
+ static const GEnumValue mpeg2enc_framerates[] = {
+ { 0, "0", "Same as input" },
+ { 1, "1", "24/1.001 (NTSC 3:2 pulldown converted film)" },
+ { 2, "2", "24 (native film)" },
+ { 3, "3", "25 (PAL/SECAM video)" },
+ { 4, "4", "30/1.001 (NTSC video)" },
+ { 5, "5", "30" },
+ { 6, "6", "50 (PAL/SECAM fields)" },
+ { 7, "7", "60/1.001 (NTSC fields)" },
+ { 8, "8", "60" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_framerate_type =
+ g_enum_register_static ("GstMpeg2encFramerate",
+ mpeg2enc_framerates);
+ }
+
+ return mpeg2enc_framerate_type;
+}
+
+#define GST_TYPE_MPEG2ENC_ASPECT \
+ (gst_mpeg2enc_aspect_get_type ())
+
+static GType
+gst_mpeg2enc_aspect_get_type (void)
+{
+ static GType mpeg2enc_aspect_type = 0;
+
+ if (!mpeg2enc_aspect_type) {
+ static const GEnumValue mpeg2enc_aspects[] = {
+ { 0, "0", "Deduce from input" },
+ { 1, "1", "1:1" },
+ { 2, "2", "4:3" },
+ { 3, "3", "16:9" },
+ { 4, "4", "2.21:1" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_aspect_type =
+ g_enum_register_static ("GstMpeg2encAspect",
+ mpeg2enc_aspects);
+ }
+
+ return mpeg2enc_aspect_type;
+}
+
+#define GST_TYPE_MPEG2ENC_INTERLACE_MODE \
+ (gst_mpeg2enc_interlace_mode_get_type ())
+
+static GType
+gst_mpeg2enc_interlace_mode_get_type (void)
+{
+ static GType mpeg2enc_interlace_mode_type = 0;
+
+ if (!mpeg2enc_interlace_mode_type) {
+ static const GEnumValue mpeg2enc_interlace_modes[] = {
+ { -1, "-1", "Format default mode" },
+ { 0, "0", "Progressive" },
+ { 1, "1", "Interlaced, per-frame encoding" },
+ { 2, "2", "Interlaced, per-field-encoding" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_interlace_mode_type =
+ g_enum_register_static ("GstMpeg2encInterlaceMode",
+ mpeg2enc_interlace_modes);
+ }
+
+ return mpeg2enc_interlace_mode_type;
+}
+
+#define GST_TYPE_MPEG2ENC_QUANTISATION_MATRIX \
+ (gst_mpeg2enc_quantisation_matrix_get_type ())
+
+#define GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT 0
+#define GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES 1
+#define GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD 2
+#define GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC 3
+
+static GType
+gst_mpeg2enc_quantisation_matrix_get_type (void)
+{
+ static GType mpeg2enc_quantisation_matrix_type = 0;
+
+ if (!mpeg2enc_quantisation_matrix_type) {
+ static const GEnumValue mpeg2enc_quantisation_matrixes[] = {
+ { GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT,
+ "0", "Default" },
+ { GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES,
+ "1", "High resolution" },
+ { GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD,
+ "2", "KVCD" },
+ { GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC,
+ "3", "TMPGEnc" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_quantisation_matrix_type =
+ g_enum_register_static ("GstMpeg2encQuantisationMatrix",
+ mpeg2enc_quantisation_matrixes);
+ }
+
+ return mpeg2enc_quantisation_matrix_type;
+}
+
+#define GST_TYPE_MPEG2ENC_VIDEO_NORM \
+ (gst_mpeg2enc_video_norm_get_type ())
+
+static GType
+gst_mpeg2enc_video_norm_get_type (void)
+{
+ static GType mpeg2enc_video_norm_type = 0;
+
+ if (!mpeg2enc_video_norm_type) {
+ static const GEnumValue mpeg2enc_video_norms[] = {
+ { 0, "0", "Unspecified" },
+ { 'p', "p", "PAL" },
+ { 'n', "n", "NTSC" },
+ { 's', "s", "SECAM" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_video_norm_type =
+ g_enum_register_static ("GstMpeg2encVideoNorm",
+ mpeg2enc_video_norms);
+ }
+
+ return mpeg2enc_video_norm_type;
+}
+
+#define GST_TYPE_MPEG2ENC_PLAYBACK_FIELD_ORDER \
+ (gst_mpeg2enc_playback_field_order_get_type ())
+
+static GType
+gst_mpeg2enc_playback_field_order_get_type (void)
+{
+ static GType mpeg2enc_playback_field_order_type = 0;
+
+ if (!mpeg2enc_playback_field_order_type) {
+ static const GEnumValue mpeg2enc_playback_field_orders[] = {
+ { Y4M_UNKNOWN, "0", "Unspecified" },
+ { Y4M_ILACE_TOP_FIRST, "1", "Top-field first" },
+ { Y4M_ILACE_BOTTOM_FIRST, "2", "Bottom-field first" },
+ { 0, NULL, NULL },
+ };
+
+ mpeg2enc_playback_field_order_type =
+ g_enum_register_static ("GstMpeg2encPlaybackFieldOrders",
+ mpeg2enc_playback_field_orders);
+ }
+
+ return mpeg2enc_playback_field_order_type;
+}
+
+/*
+ * Class init stuff.
+ */
+
+GstMpeg2EncOptions::GstMpeg2EncOptions () :
+ MPEG2EncOptions ()
+{
+ /* autodetect number of CPUs */
+ num_cpus = sysconf (_SC_NPROCESSORS_ONLN);
+ if (num_cpus < 0)
+ num_cpus = 1;
+ if (num_cpus > 32)
+ num_cpus = 32;
+}
+
+/*
+ * Init properties (call once).
+ */
+
+void
+GstMpeg2EncOptions::initProperties (GObjectClass *klass)
+{
+ /* encoding profile */
+ g_object_class_install_property (klass, ARG_FORMAT,
+ g_param_spec_enum ("format", "Format", "Encoding profile format",
+ GST_TYPE_MPEG2ENC_FORMAT, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+
+ /* input/output stream overrides */
+ g_object_class_install_property (klass, ARG_FRAMERATE,
+ g_param_spec_enum ("framerate", "Framerate", "Output framerate",
+ GST_TYPE_MPEG2ENC_FRAMERATE, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_ASPECT,
+ g_param_spec_enum ("aspect", "Aspect", "Display aspect ratio",
+ GST_TYPE_MPEG2ENC_ASPECT, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_INTERLACE_MODE,
+ g_param_spec_enum ("interlace-mode", "Interlace mode",
+ "MPEG-2 motion estimation and encoding modes",
+ GST_TYPE_MPEG2ENC_INTERLACE_MODE, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+
+ /* general encoding stream options */
+ g_object_class_install_property (klass, ARG_BITRATE,
+ g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)",
+ 0, 10*1024, 1125, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_NONVIDEO_BITRATE,
+ g_param_spec_int ("non-video-bitrate", "Non-video bitrate",
+ "Assumed bitrate of non-video for sequence splitting (kbps)",
+ 0, 10*1024, 0, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_QUANTISATION,
+ g_param_spec_int ("quantisation", "Quantisation",
+ "Quantisation factor (0=default, 1=best, 31=worst)",
+ 0, 31, 0, (GParamFlags) G_PARAM_READWRITE));
+
+ /* stills options */
+ g_object_class_install_property (klass, ARG_VCD_STILL_SIZE,
+ g_param_spec_int ("vcd-still-size", "VCD stills size",
+ "Size of VCD stills (in kB)",
+ 0, 512, 0, (GParamFlags) G_PARAM_READWRITE));
+
+ /* motion estimation options */
+ g_object_class_install_property (klass, ARG_MOTION_SEARCH_RADIUS,
+ g_param_spec_int ("motion-search-radius", "Motion search radius",
+ "Motion compensation search radius",
+ 0, 32, 16, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_REDUCTION_4_4,
+ g_param_spec_int ("reduction-4x4", "4x4 reduction",
+ "Reduction factor for 4x4 subsampled candidate motion estimates"
+ " (1=max. quality, 4=max. speed)",
+ 1, 4, 2, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_REDUCTION_2_2,
+ g_param_spec_int ("reduction-2x2", "2x2 reduction",
+ "Reduction factor for 2x2 subsampled candidate motion estimates"
+ " (1=max. quality, 4=max. speed)",
+ 1, 4, 3, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_UNIT_COEFF_ELIM,
+ g_param_spec_int ("unit-coeff-elim", "Unit coefficience elimination",
+ "How agressively small-unit picture blocks should be skipped",
+ -40, 40, 0, (GParamFlags) G_PARAM_READWRITE));
+
+ /* GOP options */
+ g_object_class_install_property (klass, ARG_MIN_GOP_SIZE,
+ g_param_spec_int ("min-gop-size", "Min. GOP size",
+ "Minimal size per Group-of-Pictures (-1=default)",
+ -1, 250, 0, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_MAX_GOP_SIZE,
+ g_param_spec_int ("max-gop-size", "Max. GOP size",
+ "Maximal size per Group-of-Pictures (-1=default)",
+ -1, 250, 0, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_CLOSED_GOP,
+ g_param_spec_boolean ("closed-gop", "Closed GOP",
+ "All Group-of-Pictures are closed (for multi-angle DVDs)",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_FORCE_B_B_P,
+ g_param_spec_boolean ("force-b-b-p", "Force B-B-P",
+ "Force two B frames between I/P frames when closing GOP boundaries",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_B_PER_REFFRAME,
+ g_param_spec_int ("b-per-refframe", "B per ref. frame",
+ "Number of B frames between each I/P frame",
+ 0, 2, 2, (GParamFlags) G_PARAM_READWRITE));
+
+ /* quantisation options */
+ g_object_class_install_property (klass, ARG_QUANTISATION_REDUCTION,
+ g_param_spec_float ("quantisation-reduction", "Quantisation reduction",
+ "Max. quantisation reduction for highly active blocks",
+ -4., 10., 0., (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_QUANT_REDUCTION_MAX_VAR,
+ g_param_spec_float ("quant-reduction-max-var", "Max. quant. reduction variance",
+ "Maximal luma variance below which quantisation boost is used",
+ 0., 2500., 0., (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_INTRA_DC_PRECISION,
+ g_param_spec_int ("intra-dc-prec", "Intra. DC precision",
+ "Number of bits precision for DC (base colour) in MPEG-2 blocks",
+ 8, 11, 9, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_REDUCE_HF,
+ g_param_spec_float ("reduce-hf", "Reduce HF",
+ "How much to reduce high-frequency resolution (by increasing quantisation)",
+ 0., 2., 0., (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_KEEP_HF,
+ g_param_spec_boolean ("keep-hf", "Keep HF",
+ "Maximize high-frequency resolution (for high-quality sources)",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_QUANTISATION_MATRIX,
+ g_param_spec_enum ("quant-matrix", "Quant. matrix",
+ "Quantisation matrix to use for encoding",
+ GST_TYPE_MPEG2ENC_QUANTISATION_MATRIX, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+
+ /* general options */
+ g_object_class_install_property (klass, ARG_BUFSIZE,
+ g_param_spec_int ("bufsize", "Decoder buf. size",
+ "Target decoders video buffer size (kB)",
+ 20, 4000, 46, (GParamFlags) G_PARAM_READWRITE));
+
+ /* header flag settings */
+ g_object_class_install_property (klass, ARG_VIDEO_NORM,
+ g_param_spec_enum ("norm", "Norm",
+ "Tag output for specific video norm",
+ GST_TYPE_MPEG2ENC_VIDEO_NORM, 0,
+ (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_SEQUENCE_LENGTH,
+ g_param_spec_int ("sequence-length", "Sequence length",
+ "Place a sequence boundary after each <num> MB (0=disable)",
+ 0, 10*1024, 0, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_3_2_PULLDOWN,
+ g_param_spec_boolean ("pulldown-3-2", "3-2 pull down",
+ "Generate header flags for 3-2 pull down 24fps movies",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_SEQUENCE_HEADER_EVERY_GOP,
+ g_param_spec_boolean ("sequence-header-every-gop",
+ "Sequence hdr. every GOP",
+ "Include a sequence header in every GOP",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_DUMMY_SVCD_SOF,
+ g_param_spec_boolean ("dummy-svcd-sof", "Dummy SVCD SOF",
+ "Generate dummy SVCD scan-data (for vcdimager)",
+ TRUE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_PLAYBACK_FIELD_ORDER,
+ g_param_spec_enum ("playback-field-order", "Playback field order",
+ "Force specific playback field order",
+ GST_TYPE_MPEG2ENC_PLAYBACK_FIELD_ORDER, Y4M_UNKNOWN,
+ (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_CORRECT_SVCD_HDS,
+ g_param_spec_boolean ("correct-svcd-hds", "Correct SVCD hor. size",
+ "Force SVCD width to 480 instead of 540/720",
+ FALSE, (GParamFlags) G_PARAM_READWRITE));
+ g_object_class_install_property (klass, ARG_ALTSCAN_MPEG2,
+ g_param_spec_boolean ("altscan-mpeg2", "Alt. MPEG-2 scan",
+ "Alternate MPEG-2 block scanning. Disabling this might "
+ "make buggy players play SVCD streams",
+ TRUE, (GParamFlags) G_PARAM_READWRITE));
+#if 0
+"--dxr2-hack"
+#endif
+
+ /* dangerous/experimental stuff */
+ g_object_class_install_property (klass, ARG_CONSTRAINTS,
+ g_param_spec_boolean ("constraints", "Constraints",
+ "Use strict video resolution and bitrate checks",
+ TRUE, (GParamFlags) G_PARAM_READWRITE));
+}
+
+/*
+ * GObject property foo, C++ style.
+ */
+
+void
+GstMpeg2EncOptions::getProperty (guint prop_id,
+ GValue *value)
+{
+ switch (prop_id) {
+ case ARG_FORMAT:
+ g_value_set_enum (value, format);
+ break;
+ case ARG_FRAMERATE:
+ g_value_set_enum (value, frame_rate);
+ break;
+ case ARG_ASPECT:
+ g_value_set_enum (value, aspect_ratio);
+ break;
+ case ARG_INTERLACE_MODE:
+ g_value_set_enum (value, fieldenc);
+ break;
+ case ARG_BITRATE:
+ g_value_set_int (value, bitrate/1024);
+ break;
+ case ARG_NONVIDEO_BITRATE:
+ g_value_set_int (value, nonvid_bitrate/1024);
+ break;
+ case ARG_QUANTISATION:
+ g_value_set_int (value, quant);
+ break;
+ case ARG_VCD_STILL_SIZE:
+ g_value_set_int (value, still_size / 1024);
+ break;
+ case ARG_MOTION_SEARCH_RADIUS:
+ g_value_set_int (value, searchrad);
+ break;
+ case ARG_REDUCTION_4_4:
+ g_value_set_int (value, me44_red);
+ break;
+ case ARG_REDUCTION_2_2:
+ g_value_set_int (value, me22_red);
+ break;
+ case ARG_UNIT_COEFF_ELIM:
+ g_value_set_int (value, unit_coeff_elim);
+ break;
+ case ARG_MIN_GOP_SIZE:
+ g_value_set_int (value, min_GOP_size);
+ break;
+ case ARG_MAX_GOP_SIZE:
+ g_value_set_int (value, max_GOP_size);
+ break;
+ case ARG_CLOSED_GOP:
+ g_value_set_boolean (value, closed_GOPs);
+ break;
+ case ARG_FORCE_B_B_P:
+ g_value_set_boolean (value, preserve_B);
+ break;
+ case ARG_B_PER_REFFRAME:
+ g_value_set_int (value, Bgrp_size - 1);
+ break;
+ case ARG_QUANTISATION_REDUCTION:
+ g_value_set_float (value, act_boost);
+ break;
+ case ARG_QUANT_REDUCTION_MAX_VAR:
+ g_value_set_float (value, boost_var_ceil);
+ break;
+ case ARG_INTRA_DC_PRECISION:
+ g_value_set_int (value, mpeg2_dc_prec - 8);
+ break;
+ case ARG_REDUCE_HF:
+ g_value_set_float (value, hf_q_boost);
+ break;
+ case ARG_KEEP_HF:
+ g_value_set_boolean (value, hf_quant == 2);
+ break;
+ case ARG_QUANTISATION_MATRIX:
+ switch (hf_quant) {
+ case 0:
+ g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT);
+ break;
+ case 2:
+ g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES);
+ break;
+ case 3:
+ g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD);
+ break;
+ case 4:
+ g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC);
+ break;
+ }
+ break;
+ case ARG_BUFSIZE:
+ g_value_set_int (value, video_buffer_size);
+ break;
+ case ARG_VIDEO_NORM:
+ g_value_set_enum (value, norm);
+ break;
+ case ARG_SEQUENCE_LENGTH:
+ g_value_set_int (value, seq_length_limit);
+ break;
+ case ARG_3_2_PULLDOWN:
+ g_value_set_boolean (value, vid32_pulldown);
+ break;
+ case ARG_SEQUENCE_HEADER_EVERY_GOP:
+ g_value_set_boolean (value, seq_hdr_every_gop);
+ break;
+ case ARG_DUMMY_SVCD_SOF:
+ g_value_set_boolean (value, svcd_scan_data);
+ break;
+ case ARG_PLAYBACK_FIELD_ORDER:
+ g_value_set_enum (value, force_interlacing);
+ break;
+ case ARG_CORRECT_SVCD_HDS:
+ g_value_set_boolean (value, !hack_svcd_hds_bug);
+ break;
+ case ARG_ALTSCAN_MPEG2:
+ g_value_set_boolean (value, !hack_altscan_bug);
+ break;
+ case ARG_CONSTRAINTS:
+ g_value_set_boolean (value, !ignore_constraints);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+GstMpeg2EncOptions::setProperty (guint prop_id,
+ const GValue *value)
+{
+ switch (prop_id) {
+ case ARG_FORMAT:
+ format = g_value_get_enum (value);
+ break;
+ case ARG_FRAMERATE:
+ frame_rate = g_value_get_enum (value);
+ break;
+ case ARG_ASPECT:
+ aspect_ratio = g_value_get_enum (value);
+ break;
+ case ARG_INTERLACE_MODE:
+ fieldenc = g_value_get_enum (value);
+ break;
+ case ARG_BITRATE:
+ bitrate = g_value_get_int (value) * 1024;
+ break;
+ case ARG_NONVIDEO_BITRATE:
+ nonvid_bitrate = g_value_get_int (value) * 1024;
+ break;
+ case ARG_QUANTISATION:
+ quant = g_value_get_int (value);
+ break;
+ case ARG_VCD_STILL_SIZE:
+ still_size = g_value_get_int (value) * 1024;
+ break;
+ case ARG_MOTION_SEARCH_RADIUS:
+ searchrad = g_value_get_int (value);
+ break;
+ case ARG_REDUCTION_4_4:
+ me44_red = g_value_get_int (value);
+ break;
+ case ARG_REDUCTION_2_2:
+ me22_red = g_value_get_int (value);
+ break;
+ case ARG_UNIT_COEFF_ELIM:
+ unit_coeff_elim = g_value_get_int (value);
+ break;
+ case ARG_MIN_GOP_SIZE:
+ min_GOP_size = g_value_get_int (value);
+ break;
+ case ARG_MAX_GOP_SIZE:
+ max_GOP_size = g_value_get_int (value);
+ break;
+ case ARG_CLOSED_GOP:
+ closed_GOPs = g_value_get_boolean (value);
+ break;
+ case ARG_FORCE_B_B_P:
+ preserve_B = g_value_get_boolean (value);
+ break;
+ case ARG_B_PER_REFFRAME:
+ Bgrp_size = g_value_get_int (value) + 1;
+ break;
+ case ARG_QUANTISATION_REDUCTION:
+ act_boost = g_value_get_float (value);
+ break;
+ case ARG_QUANT_REDUCTION_MAX_VAR:
+ boost_var_ceil = g_value_get_float (value);
+ break;
+ case ARG_INTRA_DC_PRECISION:
+ mpeg2_dc_prec = g_value_get_int (value) + 8;
+ break;
+ case ARG_REDUCE_HF:
+ hf_q_boost = g_value_get_float (value);
+ if (hf_quant == 0 && hf_q_boost != 0.)
+ hf_quant = 1;
+ break;
+ case ARG_KEEP_HF:
+ hf_quant = g_value_get_boolean (value) ? 2 : 0;
+ break;
+ case ARG_QUANTISATION_MATRIX:
+ switch (g_value_get_enum (value)) {
+ case GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT:
+ hf_quant = 0;
+ hf_q_boost = 0;
+ break;
+ case GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES:
+ hf_quant = 2;
+ break;
+ case GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD:
+ hf_quant = 3;
+ break;
+ case GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC:
+ hf_quant = 4;
+ break;
+ }
+ break;
+ case ARG_BUFSIZE:
+ video_buffer_size = g_value_get_int (value);
+ break;
+ case ARG_VIDEO_NORM:
+ norm = g_value_get_enum (value);
+ break;
+ case ARG_SEQUENCE_LENGTH:
+ seq_length_limit = g_value_get_int (value);
+ break;
+ case ARG_3_2_PULLDOWN:
+ vid32_pulldown = g_value_get_boolean (value);
+ break;
+ case ARG_SEQUENCE_HEADER_EVERY_GOP:
+ seq_hdr_every_gop = g_value_get_boolean (value);
+ break;
+ case ARG_DUMMY_SVCD_SOF:
+ svcd_scan_data = g_value_get_boolean (value);
+ break;
+ case ARG_PLAYBACK_FIELD_ORDER:
+ force_interlacing = g_value_get_enum (value);
+ break;
+ case ARG_CORRECT_SVCD_HDS:
+ hack_svcd_hds_bug = !g_value_get_boolean (value);
+ break;
+ case ARG_ALTSCAN_MPEG2:
+ hack_altscan_bug = !g_value_get_boolean (value);
+ break;
+ case ARG_CONSTRAINTS:
+ ignore_constraints = !g_value_get_boolean (value);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/ext/mpeg2enc/gstmpeg2encoptions.hh b/ext/mpeg2enc/gstmpeg2encoptions.hh
new file mode 100644
index 000000000..ccacd9518
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encoptions.hh
@@ -0,0 +1,42 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encoptions.hh: gobject/mpeg2enc option wrapping class
+ *
+ * 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_MPEG2ENCOPTIONS_H__
+#define __GST_MPEG2ENCOPTIONS_H__
+
+#include <glib-object.h>
+#include <mpeg2encoptions.hh>
+
+class GstMpeg2EncOptions : public MPEG2EncOptions {
+public:
+ GstMpeg2EncOptions ();
+
+ /* Init properties (call once) */
+ static void initProperties (GObjectClass *klass);
+
+ /* GObject property foo, C++ style */
+ void getProperty (guint prop_id,
+ GValue *value);
+ void setProperty (guint prop_id,
+ const GValue *value);
+};
+
+#endif /* __GST_MPEG2ENCOPTIONS_H__ */
diff --git a/ext/mpeg2enc/gstmpeg2encpicturereader.cc b/ext/mpeg2enc/gstmpeg2encpicturereader.cc
new file mode 100644
index 000000000..226acc8dc
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encpicturereader.cc
@@ -0,0 +1,129 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encpicturereader.cc: GStreamer/mpeg2enc input wrapper
+ *
+ * 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 <encoderparams.hh>
+
+#include "gstmpeg2encpicturereader.hh"
+
+/*
+ * Class init stuff.
+ */
+
+GstMpeg2EncPictureReader::GstMpeg2EncPictureReader (GstPad *in_pad,
+ GstCaps *in_caps,
+ EncoderParams *params) :
+ PictureReader (*params)
+{
+ pad = in_pad;
+ caps = gst_caps_copy (in_caps);
+}
+
+GstMpeg2EncPictureReader::~GstMpeg2EncPictureReader ()
+{
+ gst_caps_unref (caps);
+}
+
+/*
+ * Get input picture parameters (width/height etc.).
+ */
+
+void
+GstMpeg2EncPictureReader::StreamPictureParams (MPEG2EncInVidParams &strm)
+{
+ gint width, height;
+ gfloat fps;
+
+ gst_caps_get (caps, "width", &width,
+ "height", &height,
+ "framerate", &fps, NULL);
+
+ strm.horizontal_size = width;
+ strm.vertical_size = height;
+ strm.frame_rate_code = mpeg_framerate_code (mpeg_conform_framerate (fps));
+ strm.interlacing_code = Y4M_ILACE_NONE;
+ strm.aspect_ratio_code = mpeg_guess_mpeg_aspect_code (2, y4m_sar_SQUARE,
+ strm.horizontal_size,
+ strm.vertical_size);
+
+ /* FIXME:
+ * strm.interlacing_code = y4m_si_get_interlace(&si);
+ * sar = y4m_si_get_sampleaspect(&si);
+ * strm.aspect_ratio_code =
+ * mpeg_guess_mpeg_aspect_code(2, sar,
+ * strm.horizontal_size,
+ * strm.vertical_size);
+ */
+}
+
+/*
+ * Read a frame.
+ */
+
+bool
+GstMpeg2EncPictureReader::LoadFrame ()
+{
+ GstData *data;
+ GstBuffer *buf = NULL;
+ gint i, x, y, n;
+ guint8 *frame;
+
+ do {
+ if (!(data = gst_pad_pull (pad))) {
+ return true;
+ } else if (GST_IS_EVENT (data)) {
+ if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) {
+ gst_pad_event_default (pad, GST_EVENT (data));
+ return true;
+ }
+ gst_pad_event_default (pad, GST_EVENT (data));
+ } else {
+ buf = GST_BUFFER (data);
+ }
+ } while (!buf);
+
+ frame = GST_BUFFER_DATA (buf);
+ n = frames_read % input_imgs_buf_size;
+ x = encparams.horizontal_size;
+ y = encparams.vertical_size;
+
+ for (i = 0; i < y; i++) {
+ memcpy (input_imgs_buf[n][0]+i*encparams.phy_width, frame, x);
+ frame += x;
+ }
+ lum_mean[n] = LumMean (input_imgs_buf[n][0]);
+ x >>= 1;
+ y >>= 1;
+ for (i = 0; i < y; i++) {
+ memcpy (input_imgs_buf[n][1]+i*encparams.phy_chrom_width, frame, x);
+ frame += x;
+ }
+ for (i = 0; i < y; i++) {
+ memcpy (input_imgs_buf[n][2]+i*encparams.phy_chrom_width, frame, x);
+ frame += x;
+ }
+ gst_buffer_unref (buf);
+
+ return false;
+}
diff --git a/ext/mpeg2enc/gstmpeg2encpicturereader.hh b/ext/mpeg2enc/gstmpeg2encpicturereader.hh
new file mode 100644
index 000000000..93ed8bdc0
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encpicturereader.hh
@@ -0,0 +1,49 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encpicturereader.hh: GStreamer/mpeg2enc input wrapper
+ *
+ * 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_MPEG2ENCPICTUREREADER_H__
+#define __GST_MPEG2ENCPICTUREREADER_H__
+
+#include <gst/gst.h>
+
+#include <picturereader.hh>
+#include "gstmpeg2encoptions.hh"
+
+class GstMpeg2EncPictureReader : public PictureReader {
+public:
+ GstMpeg2EncPictureReader (GstPad *pad,
+ GstCaps *caps,
+ EncoderParams *params);
+ ~GstMpeg2EncPictureReader ();
+
+ /* get input picture parameters (width/height etc.) */
+ void StreamPictureParams (MPEG2EncInVidParams &strm);
+
+protected:
+ /* read a frame */
+ bool LoadFrame ();
+
+private:
+ GstPad *pad;
+ GstCaps *caps;
+};
+
+#endif /* __GST_MPEG2ENCPICTUREREADER_H__ */
diff --git a/ext/mpeg2enc/gstmpeg2encstreamwriter.cc b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc
new file mode 100644
index 000000000..ba59f3d49
--- /dev/null
+++ b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc
@@ -0,0 +1,99 @@
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encstreamwriter.cc: GStreamer/mpeg2enc output wrapper
+ *
+ * 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 "gstmpeg2encstreamwriter.hh"
+
+#define BUFSIZE (128*1024)
+
+/*
+ * Class init stuff.
+ */
+
+GstMpeg2EncStreamWriter::GstMpeg2EncStreamWriter (GstPad *in_pad,
+ EncoderParams *params) :
+ ElemStrmWriter (*params)
+{
+ pad = in_pad;
+ buf = NULL;
+}
+
+/*
+ * Output functions.
+ */
+
+void
+GstMpeg2EncStreamWriter::PutBits (guint32 val,
+ gint n)
+{
+ /* only relevant bits. Note that (according to Andrew),
+ * some CPUs do bitshifts modulo wordsize (32), which
+ * means that we have to check for n != 32 before
+ * bitshifting to the relevant bits (i.e. 0xffffffff <<
+ * 32 == 0xffffffff). */
+ if (n != 32)
+ val &= ~(0xffffffffU << n);
+
+ /* write data */
+ while (n >= outcnt) {
+ if (!buf) {
+ buf = gst_buffer_new_and_alloc (BUFSIZE);
+ GST_BUFFER_SIZE (buf) = 0;
+ }
+
+ outbfr = (outbfr << outcnt ) | (val >> (n - outcnt));
+ GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf)++] = outbfr;
+ n -= outcnt;
+ outcnt = 8;
+ bytecnt++;
+
+ if (GST_BUFFER_SIZE (buf) >= GST_BUFFER_MAXSIZE (buf))
+ FrameFlush ();
+ }
+
+ /* cache remaining bits */
+ if (n != 0) {
+ outbfr = (outbfr << n) | val;
+ outcnt -= n;
+ }
+}
+
+void
+GstMpeg2EncStreamWriter::FrameBegin ()
+{
+}
+
+void
+GstMpeg2EncStreamWriter::FrameFlush ()
+{
+ if (buf) {
+ gst_pad_push (pad, GST_DATA (buf));
+ buf = NULL;
+ }
+}
+
+void
+GstMpeg2EncStreamWriter::FrameDiscard ()
+{
+}
diff --git a/gst-libs/gst/riff/riffutil.c b/ext/mpeg2enc/gstmpeg2encstreamwriter.hh
index d33aefe34..708b942e0 100644
--- a/gst-libs/gst/riff/riffutil.c
+++ b/ext/mpeg2enc/gstmpeg2encstreamwriter.hh
@@ -1,5 +1,7 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+/* GStreamer mpeg2enc (mjpegtools) wrapper
+ * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * gstmpeg2encstreamwriter.hh: GStreamer/mpeg2enc output wrapper
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -17,31 +19,27 @@
* Boston, MA 02111-1307, USA.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <riff.h>
-
+#ifndef __GST_MPEG2ENCSTREAMWRITER_H__
+#define __GST_MPEG2ENCSTREAMWRITER_H__
-gulong gst_riff_fourcc_to_id(gchar *fourcc) {
- g_return_val_if_fail(fourcc != NULL, 0);
+#include <gst/gst.h>
- return GUINT32_FROM_LE((gulong)(fourcc[0] << 0) | (fourcc[1] << 8) |
- (fourcc[2] << 16) | (fourcc[3] << 24));
-}
+#include <elemstrmwriter.hh>
-gchar *gst_riff_id_to_fourcc(gulong id) {
- static gchar fourcc[5];
+class GstMpeg2EncStreamWriter : public ElemStrmWriter {
+public:
+ GstMpeg2EncStreamWriter (GstPad *pad,
+ EncoderParams *params);
- g_return_val_if_fail(fourcc != NULL, NULL);
+ /* output functions */
+ void PutBits (guint32 val, gint n);
+ void FrameBegin ();
+ void FrameFlush ();
+ void FrameDiscard ();
- id = GUINT32_FROM_LE(id);
- fourcc[0] = (id >> 0) & 0xff;
- fourcc[1] = (id >> 8) & 0xff;
- fourcc[2] = (id >> 16) & 0xff;
- fourcc[3] = (id >> 24) & 0xff;
- fourcc[4] = 0;
+private:
+ GstPad *pad;
+ GstBuffer *buf;
+};
- return fourcc;
-}
+#endif /* __GST_MPEG2ENCSTREAMWRITER_H__ */
diff --git a/ext/mplex/gstmplex.cc b/ext/mplex/gstmplex.cc
index 6ef731708..535b058fd 100644
--- a/ext/mplex/gstmplex.cc
+++ b/ext/mplex/gstmplex.cc
@@ -598,7 +598,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/sdl/sdlvideosink.c b/ext/sdl/sdlvideosink.c
index 659c88c6a..b71142677 100644
--- a/ext/sdl/sdlvideosink.c
+++ b/ext/sdl/sdlvideosink.c
@@ -44,8 +44,8 @@ static void gst_sdlvideosink_base_init (gpointer g_class);
static void gst_sdlvideosink_class_init (GstSDLVideoSinkClass *klass);
static void gst_sdlvideosink_init (GstSDLVideoSink *sdl);
-static void gst_sdlvideosink_interface_init (GstInterfaceClass *klass);
-static gboolean gst_sdlvideosink_interface_supported (GstInterface *iface,
+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);
@@ -115,7 +115,7 @@ gst_sdlvideosink_get_type (void)
sdlvideosink_type = g_type_register_static(GST_TYPE_VIDEOSINK,
"GstSDLVideoSink",
&sdlvideosink_info, 0);
- g_type_add_interface_static(sdlvideosink_type, GST_TYPE_INTERFACE,
+ g_type_add_interface_static(sdlvideosink_type, GST_TYPE_IMPLEMENTS_INTERFACE,
&iface_info);
g_type_add_interface_static(sdlvideosink_type, GST_TYPE_X_OVERLAY,
&xoverlay_info);
@@ -293,14 +293,14 @@ gst_sdlvideosink_init (GstSDLVideoSink *sdlvideosink)
}
static void
-gst_sdlvideosink_interface_init (GstInterfaceClass *klass)
+gst_sdlvideosink_interface_init (GstImplementsInterfaceClass *klass)
{
- klass->supported = gst_sdlvideosink_interface_supported;
+ klass->supported = gst_sdlvideosink_supported;
}
static gboolean
-gst_sdlvideosink_interface_supported (GstInterface *interface,
- GType iface_type)
+gst_sdlvideosink_supported (GstImplementsInterface *interface,
+ GType iface_type)
{
g_assert (iface_type == GST_TYPE_X_OVERLAY);
@@ -701,6 +701,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/shout/gstshout.c b/ext/shout/gstshout.c
index cda20e7fe..2af0bc993 100644
--- a/ext/shout/gstshout.c
+++ b/ext/shout/gstshout.c
@@ -473,7 +473,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"GPL",
- GST_COPYRIGHT,
"libshout",
"http://developer.icecast.org/libshout/"
)
diff --git a/ext/smoothwave/gstsmoothwave.c b/ext/smoothwave/gstsmoothwave.c
index a113bc539..57c267e51 100644
--- a/ext/smoothwave/gstsmoothwave.c
+++ b/ext/smoothwave/gstsmoothwave.c
@@ -310,6 +310,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/snapshot/gstsnapshot.c b/ext/snapshot/gstsnapshot.c
index 8408a1503..eac0cdf86 100644
--- a/ext/snapshot/gstsnapshot.c
+++ b/ext/snapshot/gstsnapshot.c
@@ -385,6 +385,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/sndfile/gstsf.c b/ext/sndfile/gstsf.c
index af961a8ca..34a8b60f7 100644
--- a/ext/sndfile/gstsf.c
+++ b/ext/sndfile/gstsf.c
@@ -829,6 +829,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/swfdec/gstswfdec.c b/ext/swfdec/gstswfdec.c
index 74a731cda..4cf19378d 100644
--- a/ext/swfdec/gstswfdec.c
+++ b/ext/swfdec/gstswfdec.c
@@ -630,7 +630,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/ext/tarkin/gsttarkin.c b/ext/tarkin/gsttarkin.c
index e4619c663..c98873f38 100644
--- a/ext/tarkin/gsttarkin.c
+++ b/ext/tarkin/gsttarkin.c
@@ -44,6 +44,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/ext/xvid/gstxvid.c b/ext/xvid/gstxvid.c
index 44f40b852..4ed5733cb 100644
--- a/ext/xvid/gstxvid.c
+++ b/ext/xvid/gstxvid.c
@@ -101,6 +101,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"GPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)
diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am
index 68d20eb74..c54b55fef 100644
--- a/gst-libs/gst/Makefile.am
+++ b/gst-libs/gst/Makefile.am
@@ -1,25 +1,27 @@
if USE_GCONF
-GCONF_DIR=gconf
+GCONF_DIR = gconf
else
-GCONF_DIR=
+GCONF_DIR =
endif
if USE_X
-X_DIR=xwindowlistener
+X_DIR = xwindowlistener xoverlay
+X_INTERFACE_LIBS = xoverlay/libgstxoverlay.la
else
-X_DIR=
+X_DIR =
+X_INTERFACE_LIBS =
endif
SUBDIRS = audio colorbalance floatcast \
$(GCONF_DIR) idct media-info \
mixer navigation play propertyprobe \
- resample riff tuner video \
- xoverlay $(X_DIR)
+ resample riff tag tuner video \
+ $(X_DIR)
DIST_SUBDIRS = audio colorbalance floatcast \
gconf idct media-info \
mixer navigation play propertyprobe \
- resample riff tuner video \
+ resample riff tag tuner video \
xoverlay xwindowlistener
@@ -33,7 +35,7 @@ libgstinterfaces_@GST_MAJORMINOR@_la_LIBADD = \
navigation/libgstnavigation.la \
propertyprobe/libgstpropertyprobe.la \
tuner/libgsttuner.la \
- xoverlay/libgstxoverlay.la \
+ $(X_INTERFACE_LIBS) \
$(GST_LIBS)
libgstinterfaces_@GST_MAJORMINOR@_la_LDFLAGS = @GST_PLUGINS_LT_LDFLAGS@ -version-info @GST_PLUGINS_LIBVERSION@
diff --git a/gst-libs/gst/audio/audio.c b/gst-libs/gst/audio/audio.c
index 3ae47b1e2..f3c85a59f 100644
--- a/gst-libs/gst/audio/audio.c
+++ b/gst-libs/gst/audio/audio.c
@@ -199,7 +199,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
);
diff --git a/gst-libs/gst/audio/audioclock.h b/gst-libs/gst/audio/audioclock.h
index f588dee86..17439242b 100644
--- a/gst-libs/gst/audio/audioclock.h
+++ b/gst-libs/gst/audio/audioclock.h
@@ -60,13 +60,13 @@ struct _GstAudioClock {
gboolean active;
- GST_OBJECT_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstAudioClockClass {
GstSystemClockClass parent_class;
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
GType gst_audio_clock_get_type (void);
diff --git a/gst-libs/gst/audio/gstaudiofilter.c b/gst-libs/gst/audio/gstaudiofilter.c
index c097b5d3f..adbb97485 100644
--- a/gst-libs/gst/audio/gstaudiofilter.c
+++ b/gst-libs/gst/audio/gstaudiofilter.c
@@ -316,7 +316,7 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- NULL,
GST_PACKAGE,
GST_ORIGIN
)
+
diff --git a/gst-libs/gst/audio/gstaudiofilterexample.c b/gst-libs/gst/audio/gstaudiofilterexample.c
index bfa711c27..15e111af4 100644
--- a/gst-libs/gst/audio/gstaudiofilterexample.c
+++ b/gst-libs/gst/audio/gstaudiofilterexample.c
@@ -165,7 +165,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- NULL,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/gst-libs/gst/colorbalance/Makefile.am b/gst-libs/gst/colorbalance/Makefile.am
index dc8bd0ea6..a86319c24 100644
--- a/gst-libs/gst/colorbalance/Makefile.am
+++ b/gst-libs/gst/colorbalance/Makefile.am
@@ -9,5 +9,25 @@ noinst_LTLIBRARIES = libgstcolorbalance.la
libgstcolorbalance_la_SOURCES = \
colorbalance.c \
- colorbalancechannel.c
+ colorbalancechannel.c \
+ colorbalancemarshal.c
libgstcolorbalance_la_CFLAGS = $(GST_CFLAGS) $(GST_OPT_CFLAGS)
+
+BUILT_SOURCES = \
+ colorbalancemarshal.c \
+ colorbalancemarshal.h
+built_headers = \
+ colorbalancemarshal.h
+
+EXTRA_DIST = colorbalancemarshal.list
+
+CLEANFILES = $(BUILT_SOURCES)
+
+colorbalancemarshal.h: colorbalancemarshal.list
+ glib-genmarshal --header --prefix=gst_color_balance_marshal $^ > colorbalancemarshal.h.tmp
+ mv colorbalancemarshal.h.tmp colorbalancemarshal.h
+
+colorbalancemarshal.c: colorbalancemarshal.list
+ echo "#include \"colorbalancemarshal.h\"" >> colorbalancemarshal.c.tmp
+ glib-genmarshal --body --prefix=gst_color_balance_marshal $^ >> colorbalancemarshal.c.tmp
+ mv colorbalancemarshal.c.tmp colorbalancemarshal.c
diff --git a/gst-libs/gst/colorbalance/colorbalance.c b/gst-libs/gst/colorbalance/colorbalance.c
index 829cf5f63..163111cd6 100644
--- a/gst-libs/gst/colorbalance/colorbalance.c
+++ b/gst-libs/gst/colorbalance/colorbalance.c
@@ -25,9 +25,17 @@
#endif
#include "colorbalance.h"
+#include "colorbalancemarshal.h"
+
+enum {
+ VALUE_CHANGED,
+ LAST_SIGNAL
+};
static void gst_color_balance_class_init (GstColorBalanceClass *klass);
+static guint gst_color_balance_signals[LAST_SIGNAL] = { 0 };
+
GType
gst_color_balance_get_type (void)
{
@@ -50,7 +58,7 @@ gst_color_balance_get_type (void)
"GstColorBalance",
&gst_color_balance_info, 0);
g_type_interface_add_prerequisite (gst_color_balance_type,
- GST_TYPE_INTERFACE);
+ GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_color_balance_type;
@@ -59,6 +67,21 @@ gst_color_balance_get_type (void)
static void
gst_color_balance_class_init (GstColorBalanceClass *klass)
{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ gst_color_balance_signals[VALUE_CHANGED] =
+ g_signal_new ("value_changed",
+ GST_TYPE_COLOR_BALANCE, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstColorBalanceClass, value_changed),
+ NULL, NULL,
+ gst_color_balance_marshal_VOID__OBJECT_INT,
+ G_TYPE_NONE, 2,
+ GST_TYPE_COLOR_BALANCE_CHANNEL, G_TYPE_INT);
+
+ initialized = TRUE;
+ }
+
/* default virtual functions */
klass->list_channels = NULL;
klass->set_value = NULL;
@@ -101,3 +124,15 @@ gst_color_balance_get_value (GstColorBalance *balance,
return channel->min_value;
}
+
+void
+gst_color_balance_value_changed (GstColorBalance *balance,
+ GstColorBalanceChannel *channel,
+ gint value)
+{
+ g_signal_emit (G_OBJECT (balance),
+ gst_color_balance_signals[VALUE_CHANGED],
+ 0, channel, value);
+
+ g_signal_emit_by_name (G_OBJECT (channel), "value_changed", value);
+}
diff --git a/gst-libs/gst/colorbalance/colorbalance.h b/gst-libs/gst/colorbalance/colorbalance.h
index 2b9d27d3a..f4a0d78a1 100644
--- a/gst-libs/gst/colorbalance/colorbalance.h
+++ b/gst-libs/gst/colorbalance/colorbalance.h
@@ -30,13 +30,13 @@ G_BEGIN_DECLS
#define GST_TYPE_COLOR_BALANCE \
(gst_color_balance_get_type ())
#define GST_COLOR_BALANCE(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE, \
- GstColorBalance))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE, \
+ GstColorBalance))
#define GST_COLOR_BALANCE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_COLOR_BALANCE, \
GstColorBalanceClass))
#define GST_IS_COLOR_BALANCE(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE))
#define GST_IS_COLOR_BALANCE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE))
#define GST_COLOR_BALANCE_GET_CLASS(inst) \
@@ -55,6 +55,13 @@ typedef struct _GstColorBalanceClass {
gint value);
gint (* get_value) (GstColorBalance *balance,
GstColorBalanceChannel *channel);
+
+ /* signals */
+ void (* value_changed) (GstColorBalance *balance,
+ GstColorBalanceChannel *channel,
+ gint value);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceClass;
GType gst_color_balance_get_type (void);
@@ -68,6 +75,11 @@ void gst_color_balance_set_value (GstColorBalance *balance,
gint gst_color_balance_get_value (GstColorBalance *balance,
GstColorBalanceChannel *channel);
+/* trigger signal */
+void gst_color_balance_value_changed (GstColorBalance *balance,
+ GstColorBalanceChannel *channel,
+ gint value);
+
G_END_DECLS
#endif /* __GST_COLOR_BALANCE_H__ */
diff --git a/gst-libs/gst/colorbalance/colorbalancechannel.c b/gst-libs/gst/colorbalance/colorbalancechannel.c
index 8241bfe70..f87101200 100644
--- a/gst-libs/gst/colorbalance/colorbalancechannel.c
+++ b/gst-libs/gst/colorbalance/colorbalancechannel.c
@@ -96,8 +96,7 @@ gst_color_balance_channel_dispose (GObject *object)
{
GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object);
- if (channel->label)
- g_free (channel->label);
+ g_free (channel->label);
if (parent_class->dispose)
parent_class->dispose (object);
diff --git a/gst-libs/gst/colorbalance/colorbalancechannel.h b/gst-libs/gst/colorbalance/colorbalancechannel.h
index 5f738ecb8..23f73f8ec 100644
--- a/gst-libs/gst/colorbalance/colorbalancechannel.h
+++ b/gst-libs/gst/colorbalance/colorbalancechannel.h
@@ -53,6 +53,8 @@ typedef struct _GstColorBalanceChannelClass {
/* signals */
void (* value_changed) (GstColorBalanceChannel *channel,
gint value);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstColorBalanceChannelClass;
GType gst_color_balance_channel_get_type (void);
diff --git a/gst-libs/gst/colorbalance/colorbalancemarshal.list b/gst-libs/gst/colorbalance/colorbalancemarshal.list
new file mode 100644
index 000000000..b9d0c499a
--- /dev/null
+++ b/gst-libs/gst/colorbalance/colorbalancemarshal.list
@@ -0,0 +1 @@
+VOID:OBJECT,INT
diff --git a/gst-libs/gst/idct/idct.c b/gst-libs/gst/idct/idct.c
index 4e62a4717..59c6a844d 100644
--- a/gst-libs/gst/idct/idct.c
+++ b/gst-libs/gst/idct/idct.c
@@ -141,7 +141,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/gst-libs/gst/media-info/media-info.h b/gst-libs/gst/media-info/media-info.h
index 4ff628198..069bfd7c0 100644
--- a/gst-libs/gst/media-info/media-info.h
+++ b/gst-libs/gst/media-info/media-info.h
@@ -35,7 +35,7 @@ struct _GstMediaInfo
GstMediaInfoPriv *priv;
- GST_OBJECT_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstMediaInfoClass
@@ -45,7 +45,7 @@ struct _GstMediaInfoClass
/* signals */
void (*media_info_signal) (GstMediaInfo *gst_media_info);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
/* structure for "physical" stream,
diff --git a/gst-libs/gst/mixer/Makefile.am b/gst-libs/gst/mixer/Makefile.am
index 193b5a107..ca153dd0a 100644
--- a/gst-libs/gst/mixer/Makefile.am
+++ b/gst-libs/gst/mixer/Makefile.am
@@ -9,5 +9,25 @@ noinst_LTLIBRARIES = libgstmixer.la
libgstmixer_la_SOURCES = \
mixer.c \
- mixertrack.c
+ mixertrack.c \
+ mixermarshal.c
libgstmixer_la_CFLAGS = $(GST_CFLAGS)
+
+BUILT_SOURCES = \
+ mixermarshal.c \
+ mixermarshal.h
+built_headers = \
+ mixermarshal.h
+
+EXTRA_DIST = mixermarshal.list
+
+CLEANFILES = $(BUILT_SOURCES)
+
+mixermarshal.h: mixermarshal.list
+ glib-genmarshal --header --prefix=gst_mixer_marshal $^ > mixermarshal.h.tmp
+ mv mixermarshal.h.tmp mixermarshal.h
+
+mixermarshal.c: mixermarshal.list
+ echo "#include \"mixermarshal.h\"" >> mixermarshal.c.tmp
+ glib-genmarshal --body --prefix=gst_mixer_marshal $^ >> mixermarshal.c.tmp
+ mv mixermarshal.c.tmp mixermarshal.c
diff --git a/gst-libs/gst/mixer/mixer.c b/gst-libs/gst/mixer/mixer.c
index 28d10e6a2..cbdfdad4a 100644
--- a/gst-libs/gst/mixer/mixer.c
+++ b/gst-libs/gst/mixer/mixer.c
@@ -24,9 +24,19 @@
#endif
#include "mixer.h"
+#include "mixermarshal.h"
+
+enum {
+ MUTE_TOGGLED,
+ RECORD_TOGGLED,
+ VOLUME_CHANGED,
+ LAST_SIGNAL
+};
static void gst_mixer_class_init (GstMixerClass *klass);
+static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
+
GType
gst_mixer_get_type (void)
{
@@ -49,7 +59,7 @@ gst_mixer_get_type (void)
"GstMixer",
&gst_mixer_info, 0);
g_type_interface_add_prerequisite (gst_mixer_type,
- GST_TYPE_INTERFACE);
+ GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_mixer_type;
@@ -58,6 +68,34 @@ gst_mixer_get_type (void)
static void
gst_mixer_class_init (GstMixerClass *klass)
{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ gst_mixer_signals[RECORD_TOGGLED] =
+ g_signal_new ("record_toggled",
+ GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstMixerClass, record_toggled),
+ NULL, NULL,
+ gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 1,
+ GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
+ gst_mixer_signals[MUTE_TOGGLED] =
+ g_signal_new ("mute_toggled",
+ GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
+ NULL, NULL,
+ gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 1,
+ GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
+ gst_mixer_signals[VOLUME_CHANGED] =
+ g_signal_new ("volume_changed",
+ GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstMixerClass, volume_changed),
+ NULL, NULL,
+ gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 1,
+ GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
+
+ initialized = TRUE;
+ }
+
/* default virtual functions */
klass->list_tracks = NULL;
klass->set_volume = NULL;
@@ -131,3 +169,45 @@ gst_mixer_set_record (GstMixer *mixer,
klass->set_record (mixer, track, record);
}
}
+
+void
+gst_mixer_mute_toggled (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean mute)
+{
+ g_signal_emit (G_OBJECT (mixer),
+ gst_mixer_signals[MUTE_TOGGLED], 0,
+ track, mute);
+
+ g_signal_emit_by_name (G_OBJECT (track),
+ "mute_toggled",
+ mute);
+}
+
+void
+gst_mixer_record_toggled (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean record)
+{
+ g_signal_emit (G_OBJECT (mixer),
+ gst_mixer_signals[RECORD_TOGGLED], 0,
+ track, record);
+
+ g_signal_emit_by_name (G_OBJECT (track),
+ "record_toggled",
+ record);
+}
+
+void
+gst_mixer_volume_changed (GstMixer *mixer,
+ GstMixerTrack *track,
+ gint *volumes)
+{
+ g_signal_emit (G_OBJECT (mixer),
+ gst_mixer_signals[VOLUME_CHANGED], 0,
+ track, volumes);
+
+ g_signal_emit_by_name (G_OBJECT (track),
+ "volume_changed",
+ volumes);
+}
diff --git a/gst-libs/gst/mixer/mixer.h b/gst-libs/gst/mixer/mixer.h
index 6ee49e3ac..cfc168754 100644
--- a/gst-libs/gst/mixer/mixer.h
+++ b/gst-libs/gst/mixer/mixer.h
@@ -30,11 +30,11 @@ G_BEGIN_DECLS
#define GST_TYPE_MIXER \
(gst_mixer_get_type ())
#define GST_MIXER(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER, GstMixer))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER, GstMixer))
#define GST_MIXER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER, GstMixerClass))
#define GST_IS_MIXER(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER))
#define GST_IS_MIXER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
#define GST_MIXER_GET_CLASS(inst) \
@@ -62,25 +62,47 @@ typedef struct _GstMixerClass {
GstMixerTrack *track,
gboolean record);
- GST_CLASS_PADDING
+ /* signals */
+ void (* mute_toggled) (GstMixer *mixer,
+ GstMixerTrack *channel,
+ gboolean mute);
+ void (* record_toggled) (GstMixer *mixer,
+ GstMixerTrack *channel,
+ gboolean record);
+ void (* volume_changed) (GstMixer *mixer,
+ GstMixerTrack *channel,
+ gint *volumes);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstMixerClass;
GType gst_mixer_get_type (void);
/* virtual class function wrappers */
-const GList * gst_mixer_list_tracks (GstMixer *mixer);
-void gst_mixer_set_volume (GstMixer *mixer,
- GstMixerTrack *track,
- gint *volumes);
-void gst_mixer_get_volume (GstMixer *mixer,
- GstMixerTrack *track,
- gint *volumes);
-void gst_mixer_set_mute (GstMixer *mixer,
- GstMixerTrack *track,
- gboolean mute);
-void gst_mixer_set_record (GstMixer *mixer,
- GstMixerTrack *track,
- gboolean record);
+const GList * gst_mixer_list_tracks (GstMixer *mixer);
+void gst_mixer_set_volume (GstMixer *mixer,
+ GstMixerTrack *track,
+ gint *volumes);
+void gst_mixer_get_volume (GstMixer *mixer,
+ GstMixerTrack *track,
+ gint *volumes);
+void gst_mixer_set_mute (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean mute);
+void gst_mixer_set_record (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean record);
+
+/* trigger signals */
+void gst_mixer_mute_toggled (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean mute);
+void gst_mixer_record_toggled (GstMixer *mixer,
+ GstMixerTrack *track,
+ gboolean record);
+void gst_mixer_volume_changed (GstMixer *mixer,
+ GstMixerTrack *track,
+ gint *volumes);
G_END_DECLS
diff --git a/gst-libs/gst/mixer/mixermarshal.list b/gst-libs/gst/mixer/mixermarshal.list
new file mode 100644
index 000000000..ac2cd6b88
--- /dev/null
+++ b/gst-libs/gst/mixer/mixermarshal.list
@@ -0,0 +1,2 @@
+VOID:OBJECT,BOOLEAN
+VOID:OBJECT,POINTER
diff --git a/gst-libs/gst/mixer/mixertrack.h b/gst-libs/gst/mixer/mixertrack.h
index cb0108225..7776a3537 100644
--- a/gst-libs/gst/mixer/mixertrack.h
+++ b/gst-libs/gst/mixer/mixertrack.h
@@ -71,12 +71,15 @@ typedef struct _GstMixerTrack {
typedef struct _GstMixerTrackClass {
GObjectClass parent;
+ /* signals */
void (* mute_toggled) (GstMixerTrack *channel,
- gboolean on);
+ gboolean mute);
void (* record_toggled) (GstMixerTrack *channel,
- gboolean on);
+ gboolean record);
void (* volume_changed) (GstMixerTrack *channel,
gint *volumes);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstMixerTrackClass;
GType gst_mixer_track_get_type (void);
diff --git a/gst-libs/gst/navigation/navigation.h b/gst-libs/gst/navigation/navigation.h
index 22a66632d..faa5b809f 100644
--- a/gst-libs/gst/navigation/navigation.h
+++ b/gst-libs/gst/navigation/navigation.h
@@ -44,7 +44,7 @@ typedef struct _GstNavigationInterface {
/* virtual functions */
void (*send_event) (GstNavigation *navigation, GstStructure *structure);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
} GstNavigationInterface;
GType gst_navigation_get_type (void);
diff --git a/gst-libs/gst/play/Makefile.am b/gst-libs/gst/play/Makefile.am
index 360fff49d..db444521f 100644
--- a/gst-libs/gst/play/Makefile.am
+++ b/gst-libs/gst/play/Makefile.am
@@ -2,13 +2,13 @@ librarydir = $(libdir)
library_LTLIBRARIES = libgstplay-@GST_MAJORMINOR@.la
-libgstplay_@GST_MAJORMINOR@_la_SOURCES = play.c
+libgstplay_@GST_MAJORMINOR@_la_SOURCES = gstplay.c
libgstplay_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/play
-libgstplay_@GST_MAJORMINOR@include_HEADERS = play.h
+libgstplay_@GST_MAJORMINOR@include_HEADERS = gstplay.h
libgstplay_@GST_MAJORMINOR@_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_CFLAGS)
libgstplay_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_LIBS) $(GST_CONTROL_LIBS)
-libgstplay_@GST_MAJORMINOR@_la_LDFLAGS = -version-info @GST_PLUGINS_LIBVERSION@
+libgstplay_@GST_MAJORMINOR@_la_LDFLAGS = \
+ -version-info @GST_PLUGINS_LIBVERSION@
-noinst_HEADERS = playpipelines.c
diff --git a/gst-libs/gst/play/gstplay.c b/gst-libs/gst/play/gstplay.c
new file mode 100644
index 000000000..e4c652a54
--- /dev/null
+++ b/gst-libs/gst/play/gstplay.c
@@ -0,0 +1,1004 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <string.h>
+
+#include "gstplay.h"
+
+enum
+{
+ TIME_TICK,
+ STREAM_LENGTH,
+ HAVE_VIDEO_SIZE,
+ LAST_SIGNAL
+};
+
+struct _GstPlayPrivate {
+ char *location;
+
+ GHashTable *elements;
+
+ gint64 time_nanos;
+ gint64 length_nanos;
+
+ gint get_length_attempt;
+
+ guint tick_id;
+ guint length_id;
+};
+
+static guint gst_play_signals[LAST_SIGNAL] = { 0 };
+
+static GstPipelineClass *parent_class = NULL;
+
+/* ======================================================= */
+/* */
+/* Private Methods */
+/* */
+/* ======================================================= */
+
+static gboolean
+gst_play_pipeline_setup (GstPlay *play)
+{
+ GstElement *work_thread, *video_thread;
+ GstElement *source, *autoplugger, *video_switch;
+ GstElement *video_queue, *video_colorspace, *video_scaler, *video_sink;
+ GstElement *audio_thread, *audio_queue, *audio_volume, *audio_sink;
+ GstElement *audio_tee, *vis_thread, *vis_queue, *vis_element;
+ GstPad *audio_tee_pad1, *audio_tee_pad2, *vis_thread_pad, *audio_sink_pad;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ work_thread = gst_element_factory_make ("thread", "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "work_thread", work_thread);
+ gst_bin_add (GST_BIN (play), work_thread);
+
+ /* Placeholder for the source and autoplugger { fakesrc ! spider } */
+ source = gst_element_factory_make ("fakesrc", "source");
+ if (!GST_IS_ELEMENT (source))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "source", source);
+
+ autoplugger = gst_element_factory_make ("spider", "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "autoplugger", autoplugger);
+
+ gst_bin_add_many (GST_BIN (work_thread), source, autoplugger, NULL);
+ gst_element_link (source, autoplugger);
+
+ /* Creating our video output bin
+ { queue ! colorspace ! videoscale ! fakesink } */
+ video_thread = gst_element_factory_make ("thread", "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_thread", video_thread);
+ gst_bin_add (GST_BIN (work_thread), video_thread);
+
+ /* Buffer queue for our video thread */
+ video_queue = gst_element_factory_make ("queue", "video_queue");
+ if (!GST_IS_ELEMENT (video_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_queue", video_queue);
+
+ /* Colorspace conversion */
+ /* FIXME: Use ffcolorspace and fallback to Hermes on failure ?*/
+ video_colorspace = gst_element_factory_make ("colorspace",
+ "video_colorspace");
+ if (!GST_IS_ELEMENT (video_colorspace))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_colorspace",
+ video_colorspace);
+
+ /* Software scaling of video stream */
+ video_scaler = gst_element_factory_make ("videoscale", "video_scaler");
+ if (!GST_IS_ELEMENT (video_scaler))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_scaler", video_scaler);
+
+ /* Placeholder for future video sink bin */
+ video_sink = gst_element_factory_make ("fakesink", "video_sink");
+ if (!GST_IS_ELEMENT (video_sink))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_sink", video_sink);
+
+ /* Linking, Adding, Ghosting */
+ gst_element_link_many (video_queue, video_colorspace,
+ video_scaler, video_sink, NULL);
+ gst_bin_add_many (GST_BIN (video_thread), video_queue, video_colorspace,
+ video_scaler, video_sink, NULL);
+ gst_element_add_ghost_pad (video_thread,
+ gst_element_get_pad (video_queue, "sink"),
+ "sink");
+
+ video_switch = gst_element_factory_make ("switch",
+ "video_switch");
+ if (!GST_IS_ELEMENT (video_switch))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_switch", video_switch);
+
+ gst_bin_add (GST_BIN (work_thread), video_switch);
+
+ /* Connecting autoplugger to video switch and video switch to video output
+ gst_element_link (autoplugger, video_switch);
+ gst_element_link (video_switch, video_thread);*/
+ gst_element_link (autoplugger, video_thread);
+
+ /* Creating our audio output bin
+ { queue ! volume ! tee ! { queue ! goom } ! fakesink } */
+ audio_thread = gst_element_factory_make ("thread", "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_thread", audio_thread);
+ gst_bin_add (GST_BIN (work_thread), audio_thread);
+
+ /* Buffer queue for our audio thread */
+ audio_queue = gst_element_factory_make ("queue", "audio_queue");
+ if (!GST_IS_ELEMENT (audio_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_queue", audio_queue);
+
+ /* Volume control */
+ audio_volume = gst_element_factory_make ("volume", "audio_volume");
+ if (!GST_IS_ELEMENT (audio_volume))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_volume", audio_volume);
+
+ /* Duplicate audio signal to sink and visualization thread */
+ audio_tee = gst_element_factory_make ("tee", "audio_tee");
+ if (!GST_IS_ELEMENT (audio_tee))
+ return FALSE;
+
+ audio_tee_pad1 = gst_element_get_request_pad (audio_tee, "src%d");
+ audio_tee_pad2 = gst_element_get_request_pad (audio_tee, "src%d");
+ g_hash_table_insert (play->priv->elements, "audio_tee_pad1",
+ audio_tee_pad1);
+ g_hash_table_insert (play->priv->elements, "audio_tee_pad2",
+ audio_tee_pad2);
+ g_hash_table_insert (play->priv->elements, "audio_tee", audio_tee);
+
+ /* Placeholder for future audio sink bin */
+ audio_sink = gst_element_factory_make ("fakesink", "audio_sink");
+ if (!GST_IS_ELEMENT (audio_sink))
+ return FALSE;
+
+ audio_sink_pad = gst_element_get_pad (audio_sink, "sink");
+ g_hash_table_insert (play->priv->elements, "audio_sink_pad",
+ audio_sink_pad);
+ g_hash_table_insert (play->priv->elements, "audio_sink", audio_sink);
+
+ /* Visualization thread */
+ vis_thread = gst_element_factory_make ("thread", "vis_thread");
+ if (!GST_IS_ELEMENT (vis_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_thread", vis_thread);
+
+ /* Buffer queue for our visualization thread */
+ vis_queue = gst_element_factory_make ("queue", "vis_queue");
+ if (!GST_IS_ELEMENT (vis_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_queue", vis_queue);
+
+ vis_element = gst_element_factory_make ("identity", "vis_element");
+ if (!GST_IS_ELEMENT (vis_element))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_element", vis_element);
+
+ /* Adding, Linking, Ghosting in visualization */
+ gst_bin_add_many (GST_BIN (vis_thread), vis_queue, vis_element, NULL);
+ gst_element_link (vis_queue, vis_element);
+ vis_thread_pad = gst_element_add_ghost_pad (vis_thread,
+ gst_element_get_pad (vis_queue, "sink"),
+ "sink");
+ g_hash_table_insert (play->priv->elements, "vis_thread_pad",
+ vis_thread_pad);
+
+
+ /* Linking, Adding, Ghosting in audio */
+ gst_element_link_many (audio_queue, audio_volume, audio_tee, NULL);
+ gst_pad_link (audio_tee_pad1, audio_sink_pad);
+ gst_bin_add_many (GST_BIN (audio_thread), audio_queue, audio_volume,
+ audio_tee, vis_thread, audio_sink, NULL);
+ gst_element_add_ghost_pad (audio_thread,
+ gst_element_get_pad (audio_queue, "sink"),
+ "sink");
+
+ /* Connecting audio output to autoplugger */
+ gst_element_link (autoplugger, audio_thread);
+
+ return TRUE;
+}
+
+static void
+gst_play_have_video_size (GstElement *element, gint width,
+ gint height, GstPlay *play)
+{
+ g_return_if_fail (play != NULL);
+ g_return_if_fail (GST_IS_PLAY (play));
+ g_signal_emit (G_OBJECT (play), gst_play_signals[HAVE_VIDEO_SIZE],
+ 0, width, height);
+}
+
+static gboolean
+gst_play_tick_callback (GstPlay *play)
+{
+ GstClock *clock = NULL;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+
+ if (!GST_IS_PLAY (play)) {
+ play->priv->tick_id = 0;
+ return FALSE;
+ }
+
+ clock = gst_bin_get_clock (GST_BIN (play));
+ play->priv->time_nanos = gst_clock_get_time (clock);
+
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
+ 0,play->priv->time_nanos);
+
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING)
+ return TRUE;
+ else {
+ play->priv->tick_id = 0;
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_play_get_length_callback (GstPlay *play)
+{
+ GstElement *audio_sink_element, *video_sink_element;
+ GstFormat format = GST_FORMAT_TIME;
+ gint64 value;
+ gboolean q = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We try to get length from all real sink elements */
+ audio_sink_element = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_element");
+ video_sink_element = g_hash_table_lookup (play->priv->elements,
+ "video_sink_element");
+ if (!GST_IS_ELEMENT (audio_sink_element) &&
+ !GST_IS_ELEMENT (video_sink_element)) {
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+
+ /* Audio first and then Video */
+ q = gst_element_query (audio_sink_element, GST_QUERY_TOTAL, &format, &value);
+ if (!q)
+ q = gst_element_query (video_sink_element, GST_QUERY_TOTAL, &format,
+ &value);
+
+ if (q) {
+ play->priv->length_nanos = value;
+ g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH],
+ 0,play->priv->length_nanos);
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+
+ play->priv->get_length_attempt++;
+
+ /* We try 16 times */
+ if (play->priv->get_length_attempt > 15) {
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+static void
+gst_play_state_change (GstElement *element, GstElementState old,
+ GstElementState state)
+{
+ GstPlay *play;
+
+ g_return_if_fail (element != NULL);
+ g_return_if_fail (GST_IS_PLAY (element));
+
+ play = GST_PLAY (element);
+
+ if (state == GST_STATE_PLAYING) {
+ if (play->priv->tick_id) {
+ g_source_remove (play->priv->tick_id);
+ play->priv->tick_id = 0;
+ }
+
+ play->priv->tick_id = g_timeout_add (200,
+ (GSourceFunc) gst_play_tick_callback,
+ play);
+
+ play->priv->get_length_attempt = 0;
+
+ if (play->priv->length_id) {
+ g_source_remove (play->priv->length_id);
+ play->priv->length_id = 0;
+ }
+
+ play->priv->length_id = g_timeout_add (200,
+ (GSourceFunc) gst_play_get_length_callback,
+ play);
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->state_change)
+ GST_ELEMENT_CLASS (parent_class)->state_change (element, old, state);
+}
+
+/* =========================================== */
+/* */
+/* Init & Dispose & Class init */
+/* */
+/* =========================================== */
+
+static void
+gst_play_dispose (GObject *object)
+{
+ GstPlay *play;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GST_IS_PLAY (object));
+
+ play = GST_PLAY (object);
+
+ if (play->priv->length_id) {
+ g_source_remove (play->priv->length_id);
+ play->priv->length_id = 0;
+ }
+
+ if (play->priv->tick_id) {
+ g_source_remove (play->priv->tick_id);
+ play->priv->tick_id = 0;
+ }
+
+ if (play->priv->location) {
+ g_free (play->priv->location);
+ play->priv->location = NULL;
+ }
+
+ if (play->priv->elements) {
+ g_hash_table_destroy (play->priv->elements);
+ play->priv->elements = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_play_init (GstPlay *play)
+{
+ play->priv = g_new0 (GstPlayPrivate, 1);
+ play->priv->location = NULL;
+ play->priv->length_nanos = 0;
+ play->priv->time_nanos = 0;
+ play->priv->elements = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (!gst_play_pipeline_setup (play))
+ g_warning ("libgstplay: failed initializing pipeline");
+}
+
+static void
+gst_play_class_init (GstPlayClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->dispose = gst_play_dispose;
+
+ element_class->state_change = gst_play_state_change;
+
+ gst_play_signals[TIME_TICK] =
+ g_signal_new ("time_tick", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, time_tick), NULL, NULL,
+ gst_marshal_VOID__INT64, G_TYPE_NONE, 1, G_TYPE_INT64);
+ gst_play_signals[STREAM_LENGTH] =
+ g_signal_new ("stream_length", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, stream_length), NULL, NULL,
+ gst_marshal_VOID__INT64, G_TYPE_NONE, 1, G_TYPE_INT64);
+ gst_play_signals[HAVE_VIDEO_SIZE] =
+ g_signal_new ("have_video_size", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, have_video_size), NULL, NULL,
+ gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+}
+
+/* ======================================================= */
+/* */
+/* Public Methods */
+/* */
+/* ======================================================= */
+
+/**
+ * gst_play_set_location:
+ * @play: a #GstPlay.
+ * @location: a const #char* indicating location to play
+ *
+ * Set location of @play to @location.
+ *
+ * Returns: TRUE if location was set successfully.
+ */
+gboolean
+gst_play_set_location (GstPlay *play, const char *location)
+{
+ GstElement *work_thread, *source, *autoplugger, *video_thread, *audio_thread;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ if (play->priv->location)
+ g_free (play->priv->location);
+
+ play->priv->location = g_strdup (location);
+
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ work_thread = g_hash_table_lookup (play->priv->elements, "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+ video_thread = g_hash_table_lookup (play->priv->elements, "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+ audio_thread = g_hash_table_lookup (play->priv->elements, "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+ source = g_hash_table_lookup (play->priv->elements, "source");
+ if (!GST_IS_ELEMENT (source))
+ return FALSE;
+ autoplugger = g_hash_table_lookup (play->priv->elements, "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ /* Spider can autoplugg only once. We remove the actual one and put a new
+ autoplugger */
+ gst_element_unlink (source, autoplugger);
+ gst_element_unlink (autoplugger, video_thread);
+ gst_element_unlink (autoplugger, audio_thread);
+ gst_bin_remove (GST_BIN (work_thread), autoplugger);
+
+ autoplugger = gst_element_factory_make ("spider", "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ gst_bin_add (GST_BIN (work_thread), autoplugger);
+ gst_element_link (source, autoplugger);
+ gst_element_link (autoplugger, video_thread);
+ gst_element_link (autoplugger, audio_thread);
+
+ g_hash_table_replace (play->priv->elements, "autoplugger", autoplugger);
+
+ /* FIXME: Why don't we have an interface to do that kind of stuff ? */
+ g_object_set (G_OBJECT (source), "location", play->priv->location, NULL);
+
+ play->priv->length_nanos = 0LL;
+ play->priv->time_nanos = 0LL;
+
+ g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH], 0, 0LL);
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK], 0, 0LL);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_get_location:
+ * @play: a #GstPlay.
+ *
+ * Get current location of @play.
+ *
+ * Returns: a const #char* pointer to current location.
+ */
+char *
+gst_play_get_location (GstPlay *play)
+{
+ g_return_val_if_fail (play != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PLAY (play), NULL);
+ return g_strdup (play->priv->location);
+}
+
+/**
+ * gst_play_seek_to_time:
+ * @play: a #GstPlay.
+ * @time_nanos: a #gint64 indicating a time position.
+ *
+ * Performs a seek on @play until @time_nanos.
+ */
+gboolean
+gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
+{
+ GstElement *audio_sink_element, *video_sink_element;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ if (time_nanos < 0LL)
+ time_nanos = 0LL;
+
+ audio_sink_element = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_element");
+ video_sink_element = g_hash_table_lookup (play->priv->elements,
+ "video_sink_element");
+
+ if (GST_IS_ELEMENT (audio_sink_element) &&
+ GST_IS_ELEMENT (video_sink_element)) {
+ gboolean s = FALSE;
+
+ s = gst_element_seek (audio_sink_element, GST_FORMAT_TIME |
+ GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
+ time_nanos);
+ if (!s) {
+ s = gst_element_seek (video_sink_element, GST_FORMAT_TIME |
+ GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
+ time_nanos);
+ }
+
+ if (s) {
+ GstClock *clock = gst_bin_get_clock (GST_BIN (play));
+ play->priv->time_nanos = gst_clock_get_time (clock);
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
+ 0,play->priv->time_nanos);
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_data_src:
+ * @play: a #GstPlay.
+ * @data_src: a #GstElement.
+ *
+ * Set @data_src as the source element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_data_src (GstPlay *play, GstElement *data_src)
+{
+ GstElement *work_thread, *old_data_src, *autoplugger;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ work_thread = g_hash_table_lookup (play->priv->elements, "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+ old_data_src = g_hash_table_lookup (play->priv->elements, "source");
+ if (!GST_IS_ELEMENT (old_data_src))
+ return FALSE;
+ autoplugger = g_hash_table_lookup (play->priv->elements, "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ /* Unlinking old source from autoplugger, removing it from pipeline, adding
+ the new one and connecting it to autoplugger FIXME: we should put a new
+ autoplugger here as spider can autoplugg only once */
+ gst_element_unlink (old_data_src, autoplugger);
+ gst_bin_remove (GST_BIN (work_thread), old_data_src);
+ gst_bin_add (GST_BIN (work_thread), data_src);
+ gst_element_link (data_src, autoplugger);
+
+ g_hash_table_replace (play->priv->elements, "source", data_src);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_video_sink:
+ * @play: a #GstPlay.
+ * @video_sink: a #GstElement.
+ *
+ * Set @video_sink as the video sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
+{
+ GstElement *video_thread, *old_video_sink, *video_scaler, *video_sink_element;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ video_thread = g_hash_table_lookup (play->priv->elements, "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+ old_video_sink = g_hash_table_lookup (play->priv->elements, "video_sink");
+ if (!GST_IS_ELEMENT (old_video_sink))
+ return FALSE;
+ video_scaler = g_hash_table_lookup (play->priv->elements, "video_scaler");
+ if (!GST_IS_ELEMENT (video_scaler))
+ return FALSE;
+
+ /* Unlinking old video sink from video scaler, removing it from pipeline,
+ adding the new one and linking it */
+ gst_element_unlink (video_scaler, old_video_sink);
+ gst_bin_remove (GST_BIN (video_thread), old_video_sink);
+ gst_bin_add (GST_BIN (video_thread), video_sink);
+ gst_element_link (video_scaler, video_sink);
+
+ g_hash_table_replace (play->priv->elements, "video_sink", video_sink);
+
+ video_sink_element = gst_play_get_sink_element (play, video_sink,
+ GST_PLAY_SINK_TYPE_VIDEO);
+ if (GST_IS_ELEMENT (video_sink_element)) {
+ g_hash_table_replace (play->priv->elements, "video_sink_element",
+ video_sink_element);
+ g_signal_connect (G_OBJECT (video_sink_element), "have_video_size",
+ G_CALLBACK (gst_play_have_video_size), play);
+ }
+
+ gst_element_set_state (video_sink, GST_STATE (GST_ELEMENT(play)));
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_audio_sink:
+ * @play: a #GstPlay.
+ * @audio_sink: a #GstElement.
+ *
+ * Set @audio_sink as the audio sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
+{
+ GstElement *old_audio_sink, *audio_thread, *audio_sink_element;
+ GstPad *audio_tee_pad1, *audio_sink_pad, *old_audio_sink_pad;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ old_audio_sink = g_hash_table_lookup (play->priv->elements, "audio_sink");
+ if (!GST_IS_ELEMENT (old_audio_sink))
+ return FALSE;
+ old_audio_sink_pad = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_pad");
+ if (!GST_IS_PAD (old_audio_sink_pad))
+ return FALSE;
+ audio_thread = g_hash_table_lookup (play->priv->elements, "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+ audio_tee_pad1 = g_hash_table_lookup (play->priv->elements,
+ "audio_tee_pad1");
+ if (!GST_IS_PAD (audio_tee_pad1))
+ return FALSE;
+ audio_sink_pad = gst_element_get_pad (audio_sink, "sink");
+ if (!GST_IS_PAD (audio_sink_pad))
+ return FALSE;
+
+ /* Unlinking old audiosink, removing it from pipeline, putting the new one
+ and linking it */
+ gst_pad_unlink (audio_tee_pad1, old_audio_sink_pad);
+ gst_bin_remove (GST_BIN (audio_thread), old_audio_sink);
+ gst_bin_add (GST_BIN (audio_thread), audio_sink);
+ gst_pad_link (audio_tee_pad1, audio_sink_pad);
+
+ g_hash_table_replace (play->priv->elements, "audio_sink", audio_sink);
+ g_hash_table_replace (play->priv->elements, "audio_sink_pad",
+ audio_sink_pad);
+
+ audio_sink_element = gst_play_get_sink_element (play, audio_sink,
+ GST_PLAY_SINK_TYPE_AUDIO);
+ if (GST_IS_ELEMENT (audio_sink_element)) {
+ g_hash_table_replace (play->priv->elements, "audio_sink_element",
+ audio_sink_element);
+ }
+
+ gst_element_set_state (audio_sink, GST_STATE (GST_ELEMENT(play)));
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_visualization:
+ * @play: a #GstPlay.
+ * @element: a #GstElement.
+ *
+ * Set @video_sink as the video sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_visualization (GstPlay *play, GstElement *vis_element)
+{
+ GstElement *old_vis_element, *vis_thread, *vis_queue/*, *video_switch*/;
+ gboolean was_playing = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING) {
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PAUSED);
+ was_playing = TRUE;
+ }
+
+ /* Getting needed objects */
+ vis_thread = g_hash_table_lookup (play->priv->elements, "vis_thread");
+ if (!GST_IS_ELEMENT (vis_thread))
+ return FALSE;
+ old_vis_element = g_hash_table_lookup (play->priv->elements,
+ "vis_element");
+ if (!GST_IS_ELEMENT (old_vis_element))
+ return FALSE;
+ vis_queue = g_hash_table_lookup (play->priv->elements, "vis_queue");
+ if (!GST_IS_ELEMENT (vis_queue))
+ return FALSE;
+ /*video_switch = g_hash_table_lookup (play->priv->elements, "video_switch");
+ if (!GST_IS_ELEMENT (video_switch))
+ return FALSE;*/
+
+ /* Unlinking, removing the old element then adding and linking the new one */
+ gst_element_unlink (vis_queue, old_vis_element);
+ /*gst_element_unlink (old_vis_element, video_switch);*/
+ gst_bin_remove (GST_BIN (vis_thread), old_vis_element);
+ gst_bin_add (GST_BIN (vis_thread), vis_element);
+ gst_element_link (vis_queue, vis_element);
+ /*gst_element_link (vis_element, video_switch);*/
+
+ if (was_playing)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_connect_visualization:
+ * @play: a #GstPlay.
+ * @connect: a #gboolean indicating wether or not
+ * visualization should be connected.
+ *
+ * Connect or disconnect visualization bin in @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_connect_visualization (GstPlay * play, gboolean connect)
+{
+ GstPad *audio_tee_pad2, *vis_thread_pad;
+ gboolean connected = FALSE, was_playing = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ vis_thread_pad = g_hash_table_lookup (play->priv->elements,
+ "vis_thread_pad");
+ if (!GST_IS_PAD (vis_thread_pad))
+ return FALSE;
+ audio_tee_pad2 = g_hash_table_lookup (play->priv->elements,
+ "audio_tee_pad2");
+ if (!GST_IS_PAD (audio_tee_pad2))
+ return FALSE;
+
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING) {
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PAUSED);
+ was_playing = TRUE;
+ }
+
+ if (gst_pad_get_peer (vis_thread_pad) != NULL)
+ connected = TRUE;
+ else
+ connected = FALSE;
+
+ if ((connect) && (!connected))
+ gst_pad_link (audio_tee_pad2, vis_thread_pad);
+ else if ((!connect) && (connected))
+ gst_pad_unlink (audio_tee_pad2, vis_thread_pad);
+
+ if (was_playing)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_get_sink_element:
+ * @play: a #GstPlay.
+ * @element: a #GstElement.
+ * @sink_type: a #GstPlaySinkType.
+ *
+ * Searches recursively for a sink #GstElement with
+ * type @sink_type in @element which is supposed to be a #GstBin.
+ *
+ * Returns: the sink #GstElement of @element.
+ */
+GstElement *
+gst_play_get_sink_element (GstPlay *play,
+ GstElement *element, GstPlaySinkType sink_type)
+{
+ GList *elements = NULL;
+ const GList *pads = NULL;
+ gboolean has_src, has_correct_type;
+
+ g_return_val_if_fail (play != NULL, NULL);
+ g_return_val_if_fail (element != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PLAY (play), NULL);
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+
+ if (!GST_IS_BIN (element)) {
+ /* since its not a bin, we'll presume this
+ * element is a sink element */
+ return element;
+ }
+
+ elements = (GList *) gst_bin_get_list (GST_BIN (element));
+
+ /* traverse all elements looking for a src pad */
+
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+
+ /* Recursivity :) */
+
+ if (GST_IS_BIN (element)) {
+ element = gst_play_get_sink_element (play, element, sink_type);
+ if (GST_IS_ELEMENT (element))
+ return element;
+ }
+ else {
+ pads = gst_element_get_pad_list (element);
+ has_src = FALSE;
+ has_correct_type = FALSE;
+ while (pads) {
+ /* check for src pad */
+ if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC) {
+ has_src = TRUE;
+ break;
+ }
+ else {
+ /* If not a src pad checking caps */
+ const GstCaps2 *caps;
+ GstStructure *structure;
+ gboolean has_video_cap = FALSE;
+ gboolean has_audio_cap = FALSE;
+
+ caps = gst_pad_get_caps (GST_PAD (pads->data));
+ structure = gst_caps2_get_nth_cap (caps, 0);
+
+ if (strcmp (gst_structure_get_name (structure),
+ "audio/x-raw-int") == 0) {
+ has_audio_cap = TRUE;
+ }
+
+ if (strcmp (gst_structure_get_name (structure),
+ "video/x-raw-yuv") == 0 ||
+ strcmp (gst_structure_get_name (structure),
+ "video/x-raw-rgb") == 0) {
+ has_video_cap = TRUE;
+ }
+
+ switch (sink_type) {
+ case GST_PLAY_SINK_TYPE_AUDIO:
+ if (has_audio_cap)
+ has_correct_type = TRUE;
+ break;;
+ case GST_PLAY_SINK_TYPE_VIDEO:
+ if (has_video_cap)
+ has_correct_type = TRUE;
+ break;;
+ case GST_PLAY_SINK_TYPE_ANY:
+ if ((has_video_cap) || (has_audio_cap))
+ has_correct_type = TRUE;
+ break;;
+ default:
+ has_correct_type = FALSE;
+ }
+ }
+
+ pads = g_list_next (pads);
+
+ }
+
+ if ((!has_src) && (has_correct_type))
+ return element;
+ }
+
+ elements = g_list_next (elements);
+ }
+
+ /* we didn't find a sink element */
+
+ return NULL;
+}
+
+GstPlay *
+gst_play_new (void)
+{
+ GstPlay *play = g_object_new (GST_TYPE_PLAY, NULL);
+
+ return play;
+}
+
+/* =========================================== */
+/* */
+/* Object typing & Creation */
+/* */
+/* =========================================== */
+
+GType
+gst_play_get_type (void)
+{
+ static GType play_type = 0;
+
+ if (!play_type) {
+ static const GTypeInfo play_info = {
+ sizeof (GstPlayClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_play_class_init,
+ NULL,
+ NULL,
+ sizeof (GstPlay),
+ 0,
+ (GInstanceInitFunc) gst_play_init,
+ NULL
+ };
+
+ play_type = g_type_register_static (GST_TYPE_PIPELINE, "GstPlay",
+ &play_info, 0);
+ }
+
+ return play_type;
+}
diff --git a/gst-libs/gst/play/gstplay.h b/gst-libs/gst/play/gstplay.h
new file mode 100644
index 000000000..0c45d9431
--- /dev/null
+++ b/gst-libs/gst/play/gstplay.h
@@ -0,0 +1,89 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_PLAY_H__
+#define __GST_PLAY_H__
+
+#include <gst/gst.h>
+
+#define GST_TYPE_PLAY (gst_play_get_type())
+#define GST_PLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY, GstPlay))
+#define GST_PLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAY, GstPlayClass))
+#define GST_IS_PLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY))
+#define GST_IS_PLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY))
+#define GST_PLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PLAY, GstPlayClass))
+
+typedef enum
+{
+ GST_PLAY_SINK_TYPE_AUDIO,
+ GST_PLAY_SINK_TYPE_VIDEO,
+ GST_PLAY_SINK_TYPE_ANY,
+} GstPlaySinkType;
+
+typedef struct _GstPlay GstPlay;
+typedef struct _GstPlayClass GstPlayClass;
+typedef struct _GstPlayPrivate GstPlayPrivate;
+
+struct _GstPlay
+{
+ GstPipeline pipeline;
+
+ GstPlayPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstPlayClass
+{
+ GstPipelineClass parent_class;
+
+ void (*time_tick) (GstPlay *play, gint64 time_nanos);
+ void (*stream_length) (GstPlay *play, gint64 length_nanos);
+ void (*have_video_size) (GstPlay *play, gint width, gint height);
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_play_get_type (void);
+GstPlay * gst_play_new (void);
+
+gboolean gst_play_set_data_src (GstPlay *play,
+ GstElement *data_src);
+gboolean gst_play_set_video_sink (GstPlay *play,
+ GstElement *video_sink);
+gboolean gst_play_set_audio_sink (GstPlay *play,
+ GstElement *audio_sink);
+
+gboolean gst_play_set_visualization (GstPlay *play,
+ GstElement *element);
+gboolean gst_play_connect_visualization (GstPlay *play,
+ gboolean connect);
+
+gboolean gst_play_set_location (GstPlay *play,
+ const char *location);
+char * gst_play_get_location (GstPlay *play);
+
+gboolean gst_play_seek_to_time (GstPlay *play,
+ gint64 time_nanos);
+
+GstElement * gst_play_get_sink_element (GstPlay *play,
+ GstElement *element,
+ GstPlaySinkType sink_type);
+
+#endif /* __GST_PLAY_H__ */
diff --git a/gst-libs/gst/play/play.c b/gst-libs/gst/play/play.c
new file mode 100644
index 000000000..e4c652a54
--- /dev/null
+++ b/gst-libs/gst/play/play.c
@@ -0,0 +1,1004 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <string.h>
+
+#include "gstplay.h"
+
+enum
+{
+ TIME_TICK,
+ STREAM_LENGTH,
+ HAVE_VIDEO_SIZE,
+ LAST_SIGNAL
+};
+
+struct _GstPlayPrivate {
+ char *location;
+
+ GHashTable *elements;
+
+ gint64 time_nanos;
+ gint64 length_nanos;
+
+ gint get_length_attempt;
+
+ guint tick_id;
+ guint length_id;
+};
+
+static guint gst_play_signals[LAST_SIGNAL] = { 0 };
+
+static GstPipelineClass *parent_class = NULL;
+
+/* ======================================================= */
+/* */
+/* Private Methods */
+/* */
+/* ======================================================= */
+
+static gboolean
+gst_play_pipeline_setup (GstPlay *play)
+{
+ GstElement *work_thread, *video_thread;
+ GstElement *source, *autoplugger, *video_switch;
+ GstElement *video_queue, *video_colorspace, *video_scaler, *video_sink;
+ GstElement *audio_thread, *audio_queue, *audio_volume, *audio_sink;
+ GstElement *audio_tee, *vis_thread, *vis_queue, *vis_element;
+ GstPad *audio_tee_pad1, *audio_tee_pad2, *vis_thread_pad, *audio_sink_pad;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ work_thread = gst_element_factory_make ("thread", "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "work_thread", work_thread);
+ gst_bin_add (GST_BIN (play), work_thread);
+
+ /* Placeholder for the source and autoplugger { fakesrc ! spider } */
+ source = gst_element_factory_make ("fakesrc", "source");
+ if (!GST_IS_ELEMENT (source))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "source", source);
+
+ autoplugger = gst_element_factory_make ("spider", "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "autoplugger", autoplugger);
+
+ gst_bin_add_many (GST_BIN (work_thread), source, autoplugger, NULL);
+ gst_element_link (source, autoplugger);
+
+ /* Creating our video output bin
+ { queue ! colorspace ! videoscale ! fakesink } */
+ video_thread = gst_element_factory_make ("thread", "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_thread", video_thread);
+ gst_bin_add (GST_BIN (work_thread), video_thread);
+
+ /* Buffer queue for our video thread */
+ video_queue = gst_element_factory_make ("queue", "video_queue");
+ if (!GST_IS_ELEMENT (video_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_queue", video_queue);
+
+ /* Colorspace conversion */
+ /* FIXME: Use ffcolorspace and fallback to Hermes on failure ?*/
+ video_colorspace = gst_element_factory_make ("colorspace",
+ "video_colorspace");
+ if (!GST_IS_ELEMENT (video_colorspace))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_colorspace",
+ video_colorspace);
+
+ /* Software scaling of video stream */
+ video_scaler = gst_element_factory_make ("videoscale", "video_scaler");
+ if (!GST_IS_ELEMENT (video_scaler))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_scaler", video_scaler);
+
+ /* Placeholder for future video sink bin */
+ video_sink = gst_element_factory_make ("fakesink", "video_sink");
+ if (!GST_IS_ELEMENT (video_sink))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_sink", video_sink);
+
+ /* Linking, Adding, Ghosting */
+ gst_element_link_many (video_queue, video_colorspace,
+ video_scaler, video_sink, NULL);
+ gst_bin_add_many (GST_BIN (video_thread), video_queue, video_colorspace,
+ video_scaler, video_sink, NULL);
+ gst_element_add_ghost_pad (video_thread,
+ gst_element_get_pad (video_queue, "sink"),
+ "sink");
+
+ video_switch = gst_element_factory_make ("switch",
+ "video_switch");
+ if (!GST_IS_ELEMENT (video_switch))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "video_switch", video_switch);
+
+ gst_bin_add (GST_BIN (work_thread), video_switch);
+
+ /* Connecting autoplugger to video switch and video switch to video output
+ gst_element_link (autoplugger, video_switch);
+ gst_element_link (video_switch, video_thread);*/
+ gst_element_link (autoplugger, video_thread);
+
+ /* Creating our audio output bin
+ { queue ! volume ! tee ! { queue ! goom } ! fakesink } */
+ audio_thread = gst_element_factory_make ("thread", "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_thread", audio_thread);
+ gst_bin_add (GST_BIN (work_thread), audio_thread);
+
+ /* Buffer queue for our audio thread */
+ audio_queue = gst_element_factory_make ("queue", "audio_queue");
+ if (!GST_IS_ELEMENT (audio_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_queue", audio_queue);
+
+ /* Volume control */
+ audio_volume = gst_element_factory_make ("volume", "audio_volume");
+ if (!GST_IS_ELEMENT (audio_volume))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "audio_volume", audio_volume);
+
+ /* Duplicate audio signal to sink and visualization thread */
+ audio_tee = gst_element_factory_make ("tee", "audio_tee");
+ if (!GST_IS_ELEMENT (audio_tee))
+ return FALSE;
+
+ audio_tee_pad1 = gst_element_get_request_pad (audio_tee, "src%d");
+ audio_tee_pad2 = gst_element_get_request_pad (audio_tee, "src%d");
+ g_hash_table_insert (play->priv->elements, "audio_tee_pad1",
+ audio_tee_pad1);
+ g_hash_table_insert (play->priv->elements, "audio_tee_pad2",
+ audio_tee_pad2);
+ g_hash_table_insert (play->priv->elements, "audio_tee", audio_tee);
+
+ /* Placeholder for future audio sink bin */
+ audio_sink = gst_element_factory_make ("fakesink", "audio_sink");
+ if (!GST_IS_ELEMENT (audio_sink))
+ return FALSE;
+
+ audio_sink_pad = gst_element_get_pad (audio_sink, "sink");
+ g_hash_table_insert (play->priv->elements, "audio_sink_pad",
+ audio_sink_pad);
+ g_hash_table_insert (play->priv->elements, "audio_sink", audio_sink);
+
+ /* Visualization thread */
+ vis_thread = gst_element_factory_make ("thread", "vis_thread");
+ if (!GST_IS_ELEMENT (vis_thread))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_thread", vis_thread);
+
+ /* Buffer queue for our visualization thread */
+ vis_queue = gst_element_factory_make ("queue", "vis_queue");
+ if (!GST_IS_ELEMENT (vis_queue))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_queue", vis_queue);
+
+ vis_element = gst_element_factory_make ("identity", "vis_element");
+ if (!GST_IS_ELEMENT (vis_element))
+ return FALSE;
+
+ g_hash_table_insert (play->priv->elements, "vis_element", vis_element);
+
+ /* Adding, Linking, Ghosting in visualization */
+ gst_bin_add_many (GST_BIN (vis_thread), vis_queue, vis_element, NULL);
+ gst_element_link (vis_queue, vis_element);
+ vis_thread_pad = gst_element_add_ghost_pad (vis_thread,
+ gst_element_get_pad (vis_queue, "sink"),
+ "sink");
+ g_hash_table_insert (play->priv->elements, "vis_thread_pad",
+ vis_thread_pad);
+
+
+ /* Linking, Adding, Ghosting in audio */
+ gst_element_link_many (audio_queue, audio_volume, audio_tee, NULL);
+ gst_pad_link (audio_tee_pad1, audio_sink_pad);
+ gst_bin_add_many (GST_BIN (audio_thread), audio_queue, audio_volume,
+ audio_tee, vis_thread, audio_sink, NULL);
+ gst_element_add_ghost_pad (audio_thread,
+ gst_element_get_pad (audio_queue, "sink"),
+ "sink");
+
+ /* Connecting audio output to autoplugger */
+ gst_element_link (autoplugger, audio_thread);
+
+ return TRUE;
+}
+
+static void
+gst_play_have_video_size (GstElement *element, gint width,
+ gint height, GstPlay *play)
+{
+ g_return_if_fail (play != NULL);
+ g_return_if_fail (GST_IS_PLAY (play));
+ g_signal_emit (G_OBJECT (play), gst_play_signals[HAVE_VIDEO_SIZE],
+ 0, width, height);
+}
+
+static gboolean
+gst_play_tick_callback (GstPlay *play)
+{
+ GstClock *clock = NULL;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+
+ if (!GST_IS_PLAY (play)) {
+ play->priv->tick_id = 0;
+ return FALSE;
+ }
+
+ clock = gst_bin_get_clock (GST_BIN (play));
+ play->priv->time_nanos = gst_clock_get_time (clock);
+
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
+ 0,play->priv->time_nanos);
+
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING)
+ return TRUE;
+ else {
+ play->priv->tick_id = 0;
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_play_get_length_callback (GstPlay *play)
+{
+ GstElement *audio_sink_element, *video_sink_element;
+ GstFormat format = GST_FORMAT_TIME;
+ gint64 value;
+ gboolean q = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We try to get length from all real sink elements */
+ audio_sink_element = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_element");
+ video_sink_element = g_hash_table_lookup (play->priv->elements,
+ "video_sink_element");
+ if (!GST_IS_ELEMENT (audio_sink_element) &&
+ !GST_IS_ELEMENT (video_sink_element)) {
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+
+ /* Audio first and then Video */
+ q = gst_element_query (audio_sink_element, GST_QUERY_TOTAL, &format, &value);
+ if (!q)
+ q = gst_element_query (video_sink_element, GST_QUERY_TOTAL, &format,
+ &value);
+
+ if (q) {
+ play->priv->length_nanos = value;
+ g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH],
+ 0,play->priv->length_nanos);
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+
+ play->priv->get_length_attempt++;
+
+ /* We try 16 times */
+ if (play->priv->get_length_attempt > 15) {
+ play->priv->length_id = 0;
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+static void
+gst_play_state_change (GstElement *element, GstElementState old,
+ GstElementState state)
+{
+ GstPlay *play;
+
+ g_return_if_fail (element != NULL);
+ g_return_if_fail (GST_IS_PLAY (element));
+
+ play = GST_PLAY (element);
+
+ if (state == GST_STATE_PLAYING) {
+ if (play->priv->tick_id) {
+ g_source_remove (play->priv->tick_id);
+ play->priv->tick_id = 0;
+ }
+
+ play->priv->tick_id = g_timeout_add (200,
+ (GSourceFunc) gst_play_tick_callback,
+ play);
+
+ play->priv->get_length_attempt = 0;
+
+ if (play->priv->length_id) {
+ g_source_remove (play->priv->length_id);
+ play->priv->length_id = 0;
+ }
+
+ play->priv->length_id = g_timeout_add (200,
+ (GSourceFunc) gst_play_get_length_callback,
+ play);
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->state_change)
+ GST_ELEMENT_CLASS (parent_class)->state_change (element, old, state);
+}
+
+/* =========================================== */
+/* */
+/* Init & Dispose & Class init */
+/* */
+/* =========================================== */
+
+static void
+gst_play_dispose (GObject *object)
+{
+ GstPlay *play;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GST_IS_PLAY (object));
+
+ play = GST_PLAY (object);
+
+ if (play->priv->length_id) {
+ g_source_remove (play->priv->length_id);
+ play->priv->length_id = 0;
+ }
+
+ if (play->priv->tick_id) {
+ g_source_remove (play->priv->tick_id);
+ play->priv->tick_id = 0;
+ }
+
+ if (play->priv->location) {
+ g_free (play->priv->location);
+ play->priv->location = NULL;
+ }
+
+ if (play->priv->elements) {
+ g_hash_table_destroy (play->priv->elements);
+ play->priv->elements = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_play_init (GstPlay *play)
+{
+ play->priv = g_new0 (GstPlayPrivate, 1);
+ play->priv->location = NULL;
+ play->priv->length_nanos = 0;
+ play->priv->time_nanos = 0;
+ play->priv->elements = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (!gst_play_pipeline_setup (play))
+ g_warning ("libgstplay: failed initializing pipeline");
+}
+
+static void
+gst_play_class_init (GstPlayClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->dispose = gst_play_dispose;
+
+ element_class->state_change = gst_play_state_change;
+
+ gst_play_signals[TIME_TICK] =
+ g_signal_new ("time_tick", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, time_tick), NULL, NULL,
+ gst_marshal_VOID__INT64, G_TYPE_NONE, 1, G_TYPE_INT64);
+ gst_play_signals[STREAM_LENGTH] =
+ g_signal_new ("stream_length", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, stream_length), NULL, NULL,
+ gst_marshal_VOID__INT64, G_TYPE_NONE, 1, G_TYPE_INT64);
+ gst_play_signals[HAVE_VIDEO_SIZE] =
+ g_signal_new ("have_video_size", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstPlayClass, have_video_size), NULL, NULL,
+ gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+}
+
+/* ======================================================= */
+/* */
+/* Public Methods */
+/* */
+/* ======================================================= */
+
+/**
+ * gst_play_set_location:
+ * @play: a #GstPlay.
+ * @location: a const #char* indicating location to play
+ *
+ * Set location of @play to @location.
+ *
+ * Returns: TRUE if location was set successfully.
+ */
+gboolean
+gst_play_set_location (GstPlay *play, const char *location)
+{
+ GstElement *work_thread, *source, *autoplugger, *video_thread, *audio_thread;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ if (play->priv->location)
+ g_free (play->priv->location);
+
+ play->priv->location = g_strdup (location);
+
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ work_thread = g_hash_table_lookup (play->priv->elements, "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+ video_thread = g_hash_table_lookup (play->priv->elements, "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+ audio_thread = g_hash_table_lookup (play->priv->elements, "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+ source = g_hash_table_lookup (play->priv->elements, "source");
+ if (!GST_IS_ELEMENT (source))
+ return FALSE;
+ autoplugger = g_hash_table_lookup (play->priv->elements, "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ /* Spider can autoplugg only once. We remove the actual one and put a new
+ autoplugger */
+ gst_element_unlink (source, autoplugger);
+ gst_element_unlink (autoplugger, video_thread);
+ gst_element_unlink (autoplugger, audio_thread);
+ gst_bin_remove (GST_BIN (work_thread), autoplugger);
+
+ autoplugger = gst_element_factory_make ("spider", "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ gst_bin_add (GST_BIN (work_thread), autoplugger);
+ gst_element_link (source, autoplugger);
+ gst_element_link (autoplugger, video_thread);
+ gst_element_link (autoplugger, audio_thread);
+
+ g_hash_table_replace (play->priv->elements, "autoplugger", autoplugger);
+
+ /* FIXME: Why don't we have an interface to do that kind of stuff ? */
+ g_object_set (G_OBJECT (source), "location", play->priv->location, NULL);
+
+ play->priv->length_nanos = 0LL;
+ play->priv->time_nanos = 0LL;
+
+ g_signal_emit (G_OBJECT (play), gst_play_signals[STREAM_LENGTH], 0, 0LL);
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK], 0, 0LL);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_get_location:
+ * @play: a #GstPlay.
+ *
+ * Get current location of @play.
+ *
+ * Returns: a const #char* pointer to current location.
+ */
+char *
+gst_play_get_location (GstPlay *play)
+{
+ g_return_val_if_fail (play != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PLAY (play), NULL);
+ return g_strdup (play->priv->location);
+}
+
+/**
+ * gst_play_seek_to_time:
+ * @play: a #GstPlay.
+ * @time_nanos: a #gint64 indicating a time position.
+ *
+ * Performs a seek on @play until @time_nanos.
+ */
+gboolean
+gst_play_seek_to_time (GstPlay * play, gint64 time_nanos)
+{
+ GstElement *audio_sink_element, *video_sink_element;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ if (time_nanos < 0LL)
+ time_nanos = 0LL;
+
+ audio_sink_element = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_element");
+ video_sink_element = g_hash_table_lookup (play->priv->elements,
+ "video_sink_element");
+
+ if (GST_IS_ELEMENT (audio_sink_element) &&
+ GST_IS_ELEMENT (video_sink_element)) {
+ gboolean s = FALSE;
+
+ s = gst_element_seek (audio_sink_element, GST_FORMAT_TIME |
+ GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
+ time_nanos);
+ if (!s) {
+ s = gst_element_seek (video_sink_element, GST_FORMAT_TIME |
+ GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH,
+ time_nanos);
+ }
+
+ if (s) {
+ GstClock *clock = gst_bin_get_clock (GST_BIN (play));
+ play->priv->time_nanos = gst_clock_get_time (clock);
+ g_signal_emit (G_OBJECT (play), gst_play_signals[TIME_TICK],
+ 0,play->priv->time_nanos);
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_data_src:
+ * @play: a #GstPlay.
+ * @data_src: a #GstElement.
+ *
+ * Set @data_src as the source element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_data_src (GstPlay *play, GstElement *data_src)
+{
+ GstElement *work_thread, *old_data_src, *autoplugger;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ work_thread = g_hash_table_lookup (play->priv->elements, "work_thread");
+ if (!GST_IS_ELEMENT (work_thread))
+ return FALSE;
+ old_data_src = g_hash_table_lookup (play->priv->elements, "source");
+ if (!GST_IS_ELEMENT (old_data_src))
+ return FALSE;
+ autoplugger = g_hash_table_lookup (play->priv->elements, "autoplugger");
+ if (!GST_IS_ELEMENT (autoplugger))
+ return FALSE;
+
+ /* Unlinking old source from autoplugger, removing it from pipeline, adding
+ the new one and connecting it to autoplugger FIXME: we should put a new
+ autoplugger here as spider can autoplugg only once */
+ gst_element_unlink (old_data_src, autoplugger);
+ gst_bin_remove (GST_BIN (work_thread), old_data_src);
+ gst_bin_add (GST_BIN (work_thread), data_src);
+ gst_element_link (data_src, autoplugger);
+
+ g_hash_table_replace (play->priv->elements, "source", data_src);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_video_sink:
+ * @play: a #GstPlay.
+ * @video_sink: a #GstElement.
+ *
+ * Set @video_sink as the video sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_video_sink (GstPlay *play, GstElement *video_sink)
+{
+ GstElement *video_thread, *old_video_sink, *video_scaler, *video_sink_element;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ video_thread = g_hash_table_lookup (play->priv->elements, "video_thread");
+ if (!GST_IS_ELEMENT (video_thread))
+ return FALSE;
+ old_video_sink = g_hash_table_lookup (play->priv->elements, "video_sink");
+ if (!GST_IS_ELEMENT (old_video_sink))
+ return FALSE;
+ video_scaler = g_hash_table_lookup (play->priv->elements, "video_scaler");
+ if (!GST_IS_ELEMENT (video_scaler))
+ return FALSE;
+
+ /* Unlinking old video sink from video scaler, removing it from pipeline,
+ adding the new one and linking it */
+ gst_element_unlink (video_scaler, old_video_sink);
+ gst_bin_remove (GST_BIN (video_thread), old_video_sink);
+ gst_bin_add (GST_BIN (video_thread), video_sink);
+ gst_element_link (video_scaler, video_sink);
+
+ g_hash_table_replace (play->priv->elements, "video_sink", video_sink);
+
+ video_sink_element = gst_play_get_sink_element (play, video_sink,
+ GST_PLAY_SINK_TYPE_VIDEO);
+ if (GST_IS_ELEMENT (video_sink_element)) {
+ g_hash_table_replace (play->priv->elements, "video_sink_element",
+ video_sink_element);
+ g_signal_connect (G_OBJECT (video_sink_element), "have_video_size",
+ G_CALLBACK (gst_play_have_video_size), play);
+ }
+
+ gst_element_set_state (video_sink, GST_STATE (GST_ELEMENT(play)));
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_audio_sink:
+ * @play: a #GstPlay.
+ * @audio_sink: a #GstElement.
+ *
+ * Set @audio_sink as the audio sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_audio_sink (GstPlay *play, GstElement *audio_sink)
+{
+ GstElement *old_audio_sink, *audio_thread, *audio_sink_element;
+ GstPad *audio_tee_pad1, *audio_sink_pad, *old_audio_sink_pad;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) != GST_STATE_READY)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+ /* Getting needed objects */
+ old_audio_sink = g_hash_table_lookup (play->priv->elements, "audio_sink");
+ if (!GST_IS_ELEMENT (old_audio_sink))
+ return FALSE;
+ old_audio_sink_pad = g_hash_table_lookup (play->priv->elements,
+ "audio_sink_pad");
+ if (!GST_IS_PAD (old_audio_sink_pad))
+ return FALSE;
+ audio_thread = g_hash_table_lookup (play->priv->elements, "audio_thread");
+ if (!GST_IS_ELEMENT (audio_thread))
+ return FALSE;
+ audio_tee_pad1 = g_hash_table_lookup (play->priv->elements,
+ "audio_tee_pad1");
+ if (!GST_IS_PAD (audio_tee_pad1))
+ return FALSE;
+ audio_sink_pad = gst_element_get_pad (audio_sink, "sink");
+ if (!GST_IS_PAD (audio_sink_pad))
+ return FALSE;
+
+ /* Unlinking old audiosink, removing it from pipeline, putting the new one
+ and linking it */
+ gst_pad_unlink (audio_tee_pad1, old_audio_sink_pad);
+ gst_bin_remove (GST_BIN (audio_thread), old_audio_sink);
+ gst_bin_add (GST_BIN (audio_thread), audio_sink);
+ gst_pad_link (audio_tee_pad1, audio_sink_pad);
+
+ g_hash_table_replace (play->priv->elements, "audio_sink", audio_sink);
+ g_hash_table_replace (play->priv->elements, "audio_sink_pad",
+ audio_sink_pad);
+
+ audio_sink_element = gst_play_get_sink_element (play, audio_sink,
+ GST_PLAY_SINK_TYPE_AUDIO);
+ if (GST_IS_ELEMENT (audio_sink_element)) {
+ g_hash_table_replace (play->priv->elements, "audio_sink_element",
+ audio_sink_element);
+ }
+
+ gst_element_set_state (audio_sink, GST_STATE (GST_ELEMENT(play)));
+
+ return TRUE;
+}
+
+/**
+ * gst_play_set_visualization:
+ * @play: a #GstPlay.
+ * @element: a #GstElement.
+ *
+ * Set @video_sink as the video sink element of @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_set_visualization (GstPlay *play, GstElement *vis_element)
+{
+ GstElement *old_vis_element, *vis_thread, *vis_queue/*, *video_switch*/;
+ gboolean was_playing = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ /* We bring back the pipeline to READY */
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING) {
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PAUSED);
+ was_playing = TRUE;
+ }
+
+ /* Getting needed objects */
+ vis_thread = g_hash_table_lookup (play->priv->elements, "vis_thread");
+ if (!GST_IS_ELEMENT (vis_thread))
+ return FALSE;
+ old_vis_element = g_hash_table_lookup (play->priv->elements,
+ "vis_element");
+ if (!GST_IS_ELEMENT (old_vis_element))
+ return FALSE;
+ vis_queue = g_hash_table_lookup (play->priv->elements, "vis_queue");
+ if (!GST_IS_ELEMENT (vis_queue))
+ return FALSE;
+ /*video_switch = g_hash_table_lookup (play->priv->elements, "video_switch");
+ if (!GST_IS_ELEMENT (video_switch))
+ return FALSE;*/
+
+ /* Unlinking, removing the old element then adding and linking the new one */
+ gst_element_unlink (vis_queue, old_vis_element);
+ /*gst_element_unlink (old_vis_element, video_switch);*/
+ gst_bin_remove (GST_BIN (vis_thread), old_vis_element);
+ gst_bin_add (GST_BIN (vis_thread), vis_element);
+ gst_element_link (vis_queue, vis_element);
+ /*gst_element_link (vis_element, video_switch);*/
+
+ if (was_playing)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_connect_visualization:
+ * @play: a #GstPlay.
+ * @connect: a #gboolean indicating wether or not
+ * visualization should be connected.
+ *
+ * Connect or disconnect visualization bin in @play.
+ *
+ * Returns: TRUE if call succeeded.
+ */
+gboolean
+gst_play_connect_visualization (GstPlay * play, gboolean connect)
+{
+ GstPad *audio_tee_pad2, *vis_thread_pad;
+ gboolean connected = FALSE, was_playing = FALSE;
+
+ g_return_val_if_fail (play != NULL, FALSE);
+ g_return_val_if_fail (GST_IS_PLAY (play), FALSE);
+
+ vis_thread_pad = g_hash_table_lookup (play->priv->elements,
+ "vis_thread_pad");
+ if (!GST_IS_PAD (vis_thread_pad))
+ return FALSE;
+ audio_tee_pad2 = g_hash_table_lookup (play->priv->elements,
+ "audio_tee_pad2");
+ if (!GST_IS_PAD (audio_tee_pad2))
+ return FALSE;
+
+ if (GST_STATE (GST_ELEMENT (play)) == GST_STATE_PLAYING) {
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PAUSED);
+ was_playing = TRUE;
+ }
+
+ if (gst_pad_get_peer (vis_thread_pad) != NULL)
+ connected = TRUE;
+ else
+ connected = FALSE;
+
+ if ((connect) && (!connected))
+ gst_pad_link (audio_tee_pad2, vis_thread_pad);
+ else if ((!connect) && (connected))
+ gst_pad_unlink (audio_tee_pad2, vis_thread_pad);
+
+ if (was_playing)
+ gst_element_set_state (GST_ELEMENT (play), GST_STATE_PLAYING);
+
+ return TRUE;
+}
+
+/**
+ * gst_play_get_sink_element:
+ * @play: a #GstPlay.
+ * @element: a #GstElement.
+ * @sink_type: a #GstPlaySinkType.
+ *
+ * Searches recursively for a sink #GstElement with
+ * type @sink_type in @element which is supposed to be a #GstBin.
+ *
+ * Returns: the sink #GstElement of @element.
+ */
+GstElement *
+gst_play_get_sink_element (GstPlay *play,
+ GstElement *element, GstPlaySinkType sink_type)
+{
+ GList *elements = NULL;
+ const GList *pads = NULL;
+ gboolean has_src, has_correct_type;
+
+ g_return_val_if_fail (play != NULL, NULL);
+ g_return_val_if_fail (element != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PLAY (play), NULL);
+ g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+
+ if (!GST_IS_BIN (element)) {
+ /* since its not a bin, we'll presume this
+ * element is a sink element */
+ return element;
+ }
+
+ elements = (GList *) gst_bin_get_list (GST_BIN (element));
+
+ /* traverse all elements looking for a src pad */
+
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+
+ /* Recursivity :) */
+
+ if (GST_IS_BIN (element)) {
+ element = gst_play_get_sink_element (play, element, sink_type);
+ if (GST_IS_ELEMENT (element))
+ return element;
+ }
+ else {
+ pads = gst_element_get_pad_list (element);
+ has_src = FALSE;
+ has_correct_type = FALSE;
+ while (pads) {
+ /* check for src pad */
+ if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SRC) {
+ has_src = TRUE;
+ break;
+ }
+ else {
+ /* If not a src pad checking caps */
+ const GstCaps2 *caps;
+ GstStructure *structure;
+ gboolean has_video_cap = FALSE;
+ gboolean has_audio_cap = FALSE;
+
+ caps = gst_pad_get_caps (GST_PAD (pads->data));
+ structure = gst_caps2_get_nth_cap (caps, 0);
+
+ if (strcmp (gst_structure_get_name (structure),
+ "audio/x-raw-int") == 0) {
+ has_audio_cap = TRUE;
+ }
+
+ if (strcmp (gst_structure_get_name (structure),
+ "video/x-raw-yuv") == 0 ||
+ strcmp (gst_structure_get_name (structure),
+ "video/x-raw-rgb") == 0) {
+ has_video_cap = TRUE;
+ }
+
+ switch (sink_type) {
+ case GST_PLAY_SINK_TYPE_AUDIO:
+ if (has_audio_cap)
+ has_correct_type = TRUE;
+ break;;
+ case GST_PLAY_SINK_TYPE_VIDEO:
+ if (has_video_cap)
+ has_correct_type = TRUE;
+ break;;
+ case GST_PLAY_SINK_TYPE_ANY:
+ if ((has_video_cap) || (has_audio_cap))
+ has_correct_type = TRUE;
+ break;;
+ default:
+ has_correct_type = FALSE;
+ }
+ }
+
+ pads = g_list_next (pads);
+
+ }
+
+ if ((!has_src) && (has_correct_type))
+ return element;
+ }
+
+ elements = g_list_next (elements);
+ }
+
+ /* we didn't find a sink element */
+
+ return NULL;
+}
+
+GstPlay *
+gst_play_new (void)
+{
+ GstPlay *play = g_object_new (GST_TYPE_PLAY, NULL);
+
+ return play;
+}
+
+/* =========================================== */
+/* */
+/* Object typing & Creation */
+/* */
+/* =========================================== */
+
+GType
+gst_play_get_type (void)
+{
+ static GType play_type = 0;
+
+ if (!play_type) {
+ static const GTypeInfo play_info = {
+ sizeof (GstPlayClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_play_class_init,
+ NULL,
+ NULL,
+ sizeof (GstPlay),
+ 0,
+ (GInstanceInitFunc) gst_play_init,
+ NULL
+ };
+
+ play_type = g_type_register_static (GST_TYPE_PIPELINE, "GstPlay",
+ &play_info, 0);
+ }
+
+ return play_type;
+}
diff --git a/gst-libs/gst/play/play.h b/gst-libs/gst/play/play.h
new file mode 100644
index 000000000..0c45d9431
--- /dev/null
+++ b/gst-libs/gst/play/play.h
@@ -0,0 +1,89 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_PLAY_H__
+#define __GST_PLAY_H__
+
+#include <gst/gst.h>
+
+#define GST_TYPE_PLAY (gst_play_get_type())
+#define GST_PLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY, GstPlay))
+#define GST_PLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAY, GstPlayClass))
+#define GST_IS_PLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY))
+#define GST_IS_PLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY))
+#define GST_PLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PLAY, GstPlayClass))
+
+typedef enum
+{
+ GST_PLAY_SINK_TYPE_AUDIO,
+ GST_PLAY_SINK_TYPE_VIDEO,
+ GST_PLAY_SINK_TYPE_ANY,
+} GstPlaySinkType;
+
+typedef struct _GstPlay GstPlay;
+typedef struct _GstPlayClass GstPlayClass;
+typedef struct _GstPlayPrivate GstPlayPrivate;
+
+struct _GstPlay
+{
+ GstPipeline pipeline;
+
+ GstPlayPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstPlayClass
+{
+ GstPipelineClass parent_class;
+
+ void (*time_tick) (GstPlay *play, gint64 time_nanos);
+ void (*stream_length) (GstPlay *play, gint64 length_nanos);
+ void (*have_video_size) (GstPlay *play, gint width, gint height);
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_play_get_type (void);
+GstPlay * gst_play_new (void);
+
+gboolean gst_play_set_data_src (GstPlay *play,
+ GstElement *data_src);
+gboolean gst_play_set_video_sink (GstPlay *play,
+ GstElement *video_sink);
+gboolean gst_play_set_audio_sink (GstPlay *play,
+ GstElement *audio_sink);
+
+gboolean gst_play_set_visualization (GstPlay *play,
+ GstElement *element);
+gboolean gst_play_connect_visualization (GstPlay *play,
+ gboolean connect);
+
+gboolean gst_play_set_location (GstPlay *play,
+ const char *location);
+char * gst_play_get_location (GstPlay *play);
+
+gboolean gst_play_seek_to_time (GstPlay *play,
+ gint64 time_nanos);
+
+GstElement * gst_play_get_sink_element (GstPlay *play,
+ GstElement *element,
+ GstPlaySinkType sink_type);
+
+#endif /* __GST_PLAY_H__ */
diff --git a/gst-libs/gst/play/play.old.h b/gst-libs/gst/play/play.old.h
index fec75173b..956923e73 100644
--- a/gst-libs/gst/play/play.old.h
+++ b/gst-libs/gst/play/play.old.h
@@ -133,7 +133,7 @@ struct _GstPlay
GstPlayTimeoutAdd timeout_add_func;
GstPlayIdleAdd idle_add_func;
- GST_OBJECT_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstPlayClass
@@ -155,7 +155,7 @@ struct _GstPlayClass
void (*have_video_size) (GstPlay * play, gint width, gint height);
void (*have_vis_size) (GstPlay * play, gint width, gint height);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstPlayIdleData
diff --git a/gst-libs/gst/propertyprobe/propertyprobe.h b/gst-libs/gst/propertyprobe/propertyprobe.h
index 3fe08f0bc..695aa4daf 100644
--- a/gst-libs/gst/propertyprobe/propertyprobe.h
+++ b/gst-libs/gst/propertyprobe/propertyprobe.h
@@ -56,7 +56,7 @@ typedef struct _GstPropertyProbeInterface {
guint prop_id,
const GParamSpec *pspec);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
} GstPropertyProbeInterface;
GType gst_property_probe_get_type (void);
diff --git a/gst-libs/gst/resample/resample.c b/gst-libs/gst/resample/resample.c
index 52a80e61a..575922dc3 100644
--- a/gst-libs/gst/resample/resample.c
+++ b/gst-libs/gst/resample/resample.c
@@ -886,7 +886,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
);
diff --git a/gst-libs/gst/riff/Makefile.am b/gst-libs/gst/riff/Makefile.am
index 8795515f1..03cd8d545 100644
--- a/gst-libs/gst/riff/Makefile.am
+++ b/gst-libs/gst/riff/Makefile.am
@@ -1,10 +1,15 @@
-
plugin_LTLIBRARIES = libgstriff.la
-libgstriff_la_SOURCES = riffparse.c riffencode.c riffutil.c riff.c
+libgstriff_la_SOURCES = \
+ riff.c \
+ riff-media.c \
+ riff-read.c
libgstriffincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/riff
-libgstriffinclude_HEADERS = riff.h
+libgstriffinclude_HEADERS = \
+ riff-ids.h \
+ riff-media.h \
+ riff-read.h
libgstriff_la_LIBADD =
libgstriff_la_CFLAGS = $(GST_CFLAGS)
diff --git a/gst-libs/gst/riff/riff-ids.h b/gst-libs/gst/riff/riff-ids.h
new file mode 100644
index 000000000..da465c2df
--- /dev/null
+++ b/gst-libs/gst/riff/riff-ids.h
@@ -0,0 +1,319 @@
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff-ids.h: RIFF IDs and structs
+ *
+ * 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_RIFF_IDS_H__
+#define __GST_RIFF_IDS_H__
+
+#include <gst/gst.h>
+
+/* RIFF types */
+#define GST_RIFF_RIFF_WAVE GST_MAKE_FOURCC ('W','A','V','E')
+#define GST_RIFF_RIFF_AVI GST_MAKE_FOURCC ('A','V','I',' ')
+
+/* tags */
+#define GST_RIFF_TAG_RIFF GST_MAKE_FOURCC ('R','I','F','F')
+#define GST_RIFF_TAG_RIFX GST_MAKE_FOURCC ('R','I','F','X')
+#define GST_RIFF_TAG_LIST GST_MAKE_FOURCC ('L','I','S','T')
+#define GST_RIFF_TAG_avih GST_MAKE_FOURCC ('a','v','i','h')
+#define GST_RIFF_TAG_strd GST_MAKE_FOURCC ('s','t','r','d')
+#define GST_RIFF_TAG_strn GST_MAKE_FOURCC ('s','t','r','n')
+#define GST_RIFF_TAG_strh GST_MAKE_FOURCC ('s','t','r','h')
+#define GST_RIFF_TAG_strf GST_MAKE_FOURCC ('s','t','r','f')
+#define GST_RIFF_TAG_vedt GST_MAKE_FOURCC ('v','e','d','t')
+#define GST_RIFF_TAG_JUNK GST_MAKE_FOURCC ('J','U','N','K')
+#define GST_RIFF_TAG_idx1 GST_MAKE_FOURCC ('i','d','x','1')
+#define GST_RIFF_TAG_dmlh GST_MAKE_FOURCC ('d','m','l','h')
+/* WAV stuff */
+#define GST_RIFF_TAG_fmt GST_MAKE_FOURCC ('f','m','t',' ')
+#define GST_RIFF_TAG_data GST_MAKE_FOURCC ('d','a','t','a')
+
+/* LIST types */
+#define GST_RIFF_LIST_movi GST_MAKE_FOURCC ('m','o','v','i')
+#define GST_RIFF_LIST_hdrl GST_MAKE_FOURCC ('h','d','r','l')
+#define GST_RIFF_LIST_odml GST_MAKE_FOURCC ('o','d','m','l')
+#define GST_RIFF_LIST_strl GST_MAKE_FOURCC ('s','t','r','l')
+#define GST_RIFF_LIST_INFO GST_MAKE_FOURCC ('I','N','F','O')
+#define GST_RIFF_LIST_AVIX GST_MAKE_FOURCC ('A','V','I','X')
+
+/* fcc types */
+#define GST_RIFF_FCC_vids GST_MAKE_FOURCC ('v','i','d','s')
+#define GST_RIFF_FCC_auds GST_MAKE_FOURCC ('a','u','d','s')
+#define GST_RIFF_FCC_pads GST_MAKE_FOURCC ('p','a','d','s')
+#define GST_RIFF_FCC_txts GST_MAKE_FOURCC ('t','x','t','s')
+#define GST_RIFF_FCC_vidc GST_MAKE_FOURCC ('v','i','d','c')
+#define GST_RIFF_FCC_iavs GST_MAKE_FOURCC ('i','a','v','s')
+/* fcc handlers */
+#define GST_RIFF_FCCH_RLE GST_MAKE_FOURCC ('R','L','E',' ')
+#define GST_RIFF_FCCH_msvc GST_MAKE_FOURCC ('m','s','v','c')
+#define GST_RIFF_FCCH_MSVC GST_MAKE_FOURCC ('M','S','V','C')
+
+/* INFO types - see http://www.saettler.com/RIFFMCI/riffmci.html */
+#define GST_RIFF_INFO_IARL GST_MAKE_FOURCC ('I','A','R','L') /* location */
+#define GST_RIFF_INFO_IART GST_MAKE_FOURCC ('I','A','R','T') /* artist */
+#define GST_RIFF_INFO_ICMS GST_MAKE_FOURCC ('I','C','M','S') /* commissioned */
+#define GST_RIFF_INFO_ICMT GST_MAKE_FOURCC ('I','C','M','T') /* comment */
+#define GST_RIFF_INFO_ICOP GST_MAKE_FOURCC ('I','C','O','P') /* copyright */
+#define GST_RIFF_INFO_ICRD GST_MAKE_FOURCC ('I','C','R','D') /* creation date */
+#define GST_RIFF_INFO_ICRP GST_MAKE_FOURCC ('I','C','R','P') /* cropped */
+#define GST_RIFF_INFO_IDIM GST_MAKE_FOURCC ('I','D','I','M') /* dimensions */
+#define GST_RIFF_INFO_IDPI GST_MAKE_FOURCC ('I','D','P','I') /* dots-per-inch */
+#define GST_RIFF_INFO_IENG GST_MAKE_FOURCC ('I','E','N','G') /* engineer(s) */
+#define GST_RIFF_INFO_IGNR GST_MAKE_FOURCC ('I','G','N','R') /* genre */
+#define GST_RIFF_INFO_IKEY GST_MAKE_FOURCC ('I','K','E','Y') /* keywords */
+#define GST_RIFF_INFO_ILGT GST_MAKE_FOURCC ('I','L','G','T') /* lightness */
+#define GST_RIFF_INFO_IMED GST_MAKE_FOURCC ('I','M','E','D') /* medium */
+#define GST_RIFF_INFO_INAM GST_MAKE_FOURCC ('I','N','A','M') /* name */
+#define GST_RIFF_INFO_IPLT GST_MAKE_FOURCC ('I','P','L','T') /* palette setting */
+#define GST_RIFF_INFO_IPRD GST_MAKE_FOURCC ('I','P','R','D') /* product */
+#define GST_RIFF_INFO_ISBJ GST_MAKE_FOURCC ('I','S','B','J') /* subject */
+#define GST_RIFF_INFO_ISFT GST_MAKE_FOURCC ('I','S','F','T') /* software */
+#define GST_RIFF_INFO_ISHP GST_MAKE_FOURCC ('I','S','H','P') /* sharpness */
+#define GST_RIFF_INFO_ISRC GST_MAKE_FOURCC ('I','S','R','C') /* source */
+#define GST_RIFF_INFO_ISRF GST_MAKE_FOURCC ('I','S','R','F') /* source form */
+#define GST_RIFF_INFO_ITCH GST_MAKE_FOURCC ('I','T','C','H') /* technician(s) */
+
+/*********Chunk Names***************/
+#define GST_RIFF_FF00 GST_MAKE_FOURCC (0xFF,0xFF,0x00,0x00)
+#define GST_RIFF_00 GST_MAKE_FOURCC ('0', '0',0x00,0x00)
+#define GST_RIFF_01 GST_MAKE_FOURCC ('0', '1',0x00,0x00)
+#define GST_RIFF_02 GST_MAKE_FOURCC ('0', '2',0x00,0x00)
+#define GST_RIFF_03 GST_MAKE_FOURCC ('0', '3',0x00,0x00)
+#define GST_RIFF_04 GST_MAKE_FOURCC ('0', '4',0x00,0x00)
+#define GST_RIFF_05 GST_MAKE_FOURCC ('0', '5',0x00,0x00)
+#define GST_RIFF_06 GST_MAKE_FOURCC ('0', '6',0x00,0x00)
+#define GST_RIFF_07 GST_MAKE_FOURCC ('0', '7',0x00,0x00)
+#define GST_RIFF_00pc GST_MAKE_FOURCC ('0', '0', 'p', 'c')
+#define GST_RIFF_01pc GST_MAKE_FOURCC ('0', '1', 'p', 'c')
+#define GST_RIFF_00dc GST_MAKE_FOURCC ('0', '0', 'd', 'c')
+#define GST_RIFF_00dx GST_MAKE_FOURCC ('0', '0', 'd', 'x')
+#define GST_RIFF_00db GST_MAKE_FOURCC ('0', '0', 'd', 'b')
+#define GST_RIFF_00xx GST_MAKE_FOURCC ('0', '0', 'x', 'x')
+#define GST_RIFF_00id GST_MAKE_FOURCC ('0', '0', 'i', 'd')
+#define GST_RIFF_00rt GST_MAKE_FOURCC ('0', '0', 'r', 't')
+#define GST_RIFF_0021 GST_MAKE_FOURCC ('0', '0', '2', '1')
+#define GST_RIFF_00iv GST_MAKE_FOURCC ('0', '0', 'i', 'v')
+#define GST_RIFF_0031 GST_MAKE_FOURCC ('0', '0', '3', '1')
+#define GST_RIFF_0032 GST_MAKE_FOURCC ('0', '0', '3', '2')
+#define GST_RIFF_00vc GST_MAKE_FOURCC ('0', '0', 'v', 'c')
+#define GST_RIFF_00xm GST_MAKE_FOURCC ('0', '0', 'x', 'm')
+#define GST_RIFF_01wb GST_MAKE_FOURCC ('0', '1', 'w', 'b')
+#define GST_RIFF_01dc GST_MAKE_FOURCC ('0', '1', 'd', 'c')
+#define GST_RIFF_00__ GST_MAKE_FOURCC ('0', '0', '_', '_')
+
+/*********VIDEO CODECS**************/
+#define GST_RIFF_cram GST_MAKE_FOURCC ('c', 'r', 'a', 'm')
+#define GST_RIFF_CRAM GST_MAKE_FOURCC ('C', 'R', 'A', 'M')
+#define GST_RIFF_wham GST_MAKE_FOURCC ('w', 'h', 'a', 'm')
+#define GST_RIFF_WHAM GST_MAKE_FOURCC ('W', 'H', 'A', 'M')
+#define GST_RIFF_rgb GST_MAKE_FOURCC (0x00,0x00,0x00,0x00)
+#define GST_RIFF_RGB GST_MAKE_FOURCC ('R', 'G', 'B', ' ')
+#define GST_RIFF_rle8 GST_MAKE_FOURCC (0x01,0x00,0x00,0x00)
+#define GST_RIFF_RLE8 GST_MAKE_FOURCC ('R', 'L', 'E', '8')
+#define GST_RIFF_rle4 GST_MAKE_FOURCC (0x02,0x00,0x00,0x00)
+#define GST_RIFF_RLE4 GST_MAKE_FOURCC ('R', 'L', 'E', '4')
+#define GST_RIFF_none GST_MAKE_FOURCC (0x00,0x00,0xFF,0xFF)
+#define GST_RIFF_NONE GST_MAKE_FOURCC ('N', 'O', 'N', 'E')
+#define GST_RIFF_pack GST_MAKE_FOURCC (0x01,0x00,0xFF,0xFF)
+#define GST_RIFF_PACK GST_MAKE_FOURCC ('P', 'A', 'C', 'K')
+#define GST_RIFF_tran GST_MAKE_FOURCC (0x02,0x00,0xFF,0xFF)
+#define GST_RIFF_TRAN GST_MAKE_FOURCC ('T', 'R', 'A', 'N')
+#define GST_RIFF_ccc GST_MAKE_FOURCC (0x03,0x00,0xFF,0xFF)
+#define GST_RIFF_CCC GST_MAKE_FOURCC ('C', 'C', 'C', ' ')
+#define GST_RIFF_cyuv GST_MAKE_FOURCC ('c', 'y', 'u', 'v')
+#define GST_RIFF_CYUV GST_MAKE_FOURCC ('C', 'Y', 'U', 'V')
+#define GST_RIFF_jpeg GST_MAKE_FOURCC (0x04,0x00,0xFF,0xFF)
+#define GST_RIFF_JPEG GST_MAKE_FOURCC ('J', 'P', 'E', 'G')
+#define GST_RIFF_MJPG GST_MAKE_FOURCC ('M', 'J', 'P', 'G')
+#define GST_RIFF_mJPG GST_MAKE_FOURCC ('m', 'J', 'P', 'G')
+#define GST_RIFF_IJPG GST_MAKE_FOURCC ('I', 'J', 'P', 'G')
+#define GST_RIFF_rt21 GST_MAKE_FOURCC ('r', 't', '2', '1')
+#define GST_RIFF_RT21 GST_MAKE_FOURCC ('R', 'T', '2', '1')
+#define GST_RIFF_iv31 GST_MAKE_FOURCC ('i', 'v', '3', '1')
+#define GST_RIFF_IV31 GST_MAKE_FOURCC ('I', 'V', '3', '1')
+#define GST_RIFF_iv32 GST_MAKE_FOURCC ('i', 'v', '3', '2')
+#define GST_RIFF_IV32 GST_MAKE_FOURCC ('I', 'V', '3', '2')
+#define GST_RIFF_iv41 GST_MAKE_FOURCC ('i', 'v', '4', '1')
+#define GST_RIFF_IV41 GST_MAKE_FOURCC ('I', 'V', '4', '1')
+#define GST_RIFF_iv50 GST_MAKE_FOURCC ('i', 'v', '5', '0')
+#define GST_RIFF_IV50 GST_MAKE_FOURCC ('I', 'V', '5', '0')
+#define GST_RIFF_cvid GST_MAKE_FOURCC ('c', 'v', 'i', 'd')
+#define GST_RIFF_CVID GST_MAKE_FOURCC ('C', 'V', 'I', 'D')
+#define GST_RIFF_ULTI GST_MAKE_FOURCC ('U', 'L', 'T', 'I')
+#define GST_RIFF_ulti GST_MAKE_FOURCC ('u', 'l', 't', 'i')
+#define GST_RIFF_YUV9 GST_MAKE_FOURCC ('Y', 'V', 'U', '9')
+#define GST_RIFF_YVU9 GST_MAKE_FOURCC ('Y', 'U', 'V', '9')
+#define GST_RIFF_XMPG GST_MAKE_FOURCC ('X', 'M', 'P', 'G')
+#define GST_RIFF_xmpg GST_MAKE_FOURCC ('x', 'm', 'p', 'g')
+#define GST_RIFF_VDOW GST_MAKE_FOURCC ('V', 'D', 'O', 'W')
+#define GST_RIFF_MVI1 GST_MAKE_FOURCC ('M', 'V', 'I', '1')
+#define GST_RIFF_v422 GST_MAKE_FOURCC ('v', '4', '2', '2')
+#define GST_RIFF_V422 GST_MAKE_FOURCC ('V', '4', '2', '2')
+#define GST_RIFF_mvi1 GST_MAKE_FOURCC ('m', 'v', 'i', '1')
+#define GST_RIFF_MPIX GST_MAKE_FOURCC (0x04,0x00, 'i', '1') /* MotionPixels munged their id */
+#define GST_RIFF_AURA GST_MAKE_FOURCC ('A', 'U', 'R', 'A')
+#define GST_RIFF_DMB1 GST_MAKE_FOURCC ('D', 'M', 'B', '1')
+#define GST_RIFF_dmb1 GST_MAKE_FOURCC ('d', 'm', 'b', '1')
+
+#define GST_RIFF_BW10 GST_MAKE_FOURCC ('B', 'W', '1', '0')
+#define GST_RIFF_bw10 GST_MAKE_FOURCC ('b', 'w', '1', '0')
+
+#define GST_RIFF_yuy2 GST_MAKE_FOURCC ('y', 'u', 'y', '2')
+#define GST_RIFF_YUY2 GST_MAKE_FOURCC ('Y', 'U', 'Y', '2')
+#define GST_RIFF_YUV8 GST_MAKE_FOURCC ('Y', 'U', 'V', '8')
+#define GST_RIFF_WINX GST_MAKE_FOURCC ('W', 'I', 'N', 'X')
+#define GST_RIFF_WPY2 GST_MAKE_FOURCC ('W', 'P', 'Y', '2')
+#define GST_RIFF_m263 GST_MAKE_FOURCC ('m', '2', '6', '3')
+#define GST_RIFF_M263 GST_MAKE_FOURCC ('M', '2', '6', '3')
+
+#define GST_RIFF_Q1_0 GST_MAKE_FOURCC ('Q', '1',0x2e, '0')
+#define GST_RIFF_SFMC GST_MAKE_FOURCC ('S', 'F', 'M', 'C')
+
+#define GST_RIFF_y41p GST_MAKE_FOURCC ('y', '4', '1', 'p')
+#define GST_RIFF_Y41P GST_MAKE_FOURCC ('Y', '4', '1', 'P')
+#define GST_RIFF_yv12 GST_MAKE_FOURCC ('y', 'v', '1', '2')
+#define GST_RIFF_YV12 GST_MAKE_FOURCC ('Y', 'V', '1', '2')
+#define GST_RIFF_vixl GST_MAKE_FOURCC ('v', 'i', 'x', 'l')
+#define GST_RIFF_VIXL GST_MAKE_FOURCC ('V', 'I', 'X', 'L')
+#define GST_RIFF_iyuv GST_MAKE_FOURCC ('i', 'y', 'u', 'v')
+#define GST_RIFF_IYUV GST_MAKE_FOURCC ('I', 'Y', 'U', 'V')
+#define GST_RIFF_i420 GST_MAKE_FOURCC ('i', '4', '2', '0')
+#define GST_RIFF_I420 GST_MAKE_FOURCC ('I', '4', '2', '0')
+#define GST_RIFF_vyuy GST_MAKE_FOURCC ('v', 'y', 'u', 'y')
+#define GST_RIFF_VYUY GST_MAKE_FOURCC ('V', 'Y', 'U', 'Y')
+
+#define GST_RIFF_DIV3 GST_MAKE_FOURCC ('D', 'I', 'V', '3')
+
+#define GST_RIFF_rpza GST_MAKE_FOURCC ('r', 'p', 'z', 'a')
+/* And this here's the mistakes that need to be supported */
+#define GST_RIFF_azpr GST_MAKE_FOURCC ('a', 'z', 'p', 'r') /* recognize Apple's rpza mangled? */
+
+/*********** FND in MJPG **********/
+#define GST_RIFF_ISFT GST_MAKE_FOURCC ('I', 'S', 'F', 'T')
+#define GST_RIFF_IDIT GST_MAKE_FOURCC ('I', 'D', 'I', 'T')
+
+#define GST_RIFF_00AM GST_MAKE_FOURCC ('0', '0', 'A', 'M')
+#define GST_RIFF_DISP GST_MAKE_FOURCC ('D', 'I', 'S', 'P')
+#define GST_RIFF_ISBJ GST_MAKE_FOURCC ('I', 'S', 'B', 'J')
+
+#define GST_RIFF_rec GST_MAKE_FOURCC ('r', 'e', 'c', ' ')
+
+/* common data structures */
+typedef struct _gst_riff_strh {
+ guint32 type; /* stream type */
+ guint32 fcc_handler; /* fcc_handler */
+ guint32 flags;
+/* flags values */
+#define GST_RIFF_STRH_DISABLED 0x000000001
+#define GST_RIFF_STRH_VIDEOPALCHANGES 0x000010000
+ guint32 priority;
+ guint32 init_frames; /* initial frames (???) */
+ guint32 scale;
+ guint32 rate;
+ guint32 start;
+ guint32 length;
+ guint32 bufsize; /* suggested buffer size */
+ guint32 quality;
+ guint32 samplesize;
+ /* XXX 16 bytes ? */
+} gst_riff_strh;
+
+typedef struct _gst_riff_strf_vids { /* == BitMapInfoHeader */
+ guint32 size;
+ guint32 width;
+ guint32 height;
+ guint16 planes;
+ guint16 bit_cnt;
+ guint32 compression;
+ guint32 image_size;
+ guint32 xpels_meter;
+ guint32 ypels_meter;
+ guint32 num_colors; /* used colors */
+ guint32 imp_colors; /* important colors */
+ /* may be more for some codecs */
+} gst_riff_strf_vids;
+
+
+typedef struct _gst_riff_strf_auds { /* == WaveHeader (?) */
+ guint16 format;
+/**** from public Microsoft RIFF docs ******/
+#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000)
+#define GST_RIFF_WAVE_FORMAT_PCM (0x0001)
+#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002)
+#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005)
+#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006)
+#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007)
+#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010)
+#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011)
+#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015)
+#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016)
+#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020)
+#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022)
+#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031)
+#define GST_RIFF_WAVE_FORMAT_MSN (0x0032)
+#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050)
+#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055)
+#define GST_RIFF_IBM_FORMAT_MULAW (0x0101)
+#define GST_RIFF_IBM_FORMAT_ALAW (0x0102)
+#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103)
+#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV1 (0x0160)
+#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV2 (0x0161)
+#define GST_RIFF_WAVE_FORMAT_WMAV9 (0x0162)
+#define GST_RIFF_WAVE_FORMAT_A52 (0x2000)
+#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f)
+#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750)
+#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751)
+#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f)
+#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770)
+#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771)
+ guint16 channels;
+ guint32 rate;
+ guint32 av_bps;
+ guint16 blockalign;
+ guint16 size;
+} gst_riff_strf_auds;
+
+typedef struct _gst_riff_strf_iavs {
+ guint32 DVAAuxSrc;
+ guint32 DVAAuxCtl;
+ guint32 DVAAuxSrc1;
+ guint32 DVAAuxCtl1;
+ guint32 DVVAuxSrc;
+ guint32 DVVAuxCtl;
+ guint32 DVReserved1;
+ guint32 DVReserved2;
+} gst_riff_strf_iavs;
+
+typedef struct _gst_riff_index_entry {
+ guint32 id;
+ guint32 flags;
+#define GST_RIFF_IF_LIST (0x00000001L)
+#define GST_RIFF_IF_KEYFRAME (0x00000010L)
+#define GST_RIFF_IF_NO_TIME (0x00000100L)
+#define GST_RIFF_IF_COMPUSE (0x0FFF0000L)
+ guint32 offset;
+ guint32 size;
+} gst_riff_index_entry;
+
+typedef struct _gst_riff_dmlh {
+ guint32 totalframes;
+} gst_riff_dmlh;
+
+#endif /* __GST_RIFF_IDS_H__ */
diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c
new file mode 100644
index 000000000..79db94202
--- /dev/null
+++ b/gst-libs/gst/riff/riff-media.c
@@ -0,0 +1,369 @@
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff-media.h: RIFF-id to/from caps routines
+ *
+ * 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 "riff-ids.h"
+#include "riff-media.h"
+
+GstCaps2 *
+gst_riff_create_video_caps (guint32 codec_fcc,
+ gst_riff_strh *strh,
+ gst_riff_strf_vids *strf)
+{
+ GstCaps2 *caps = NULL;
+
+ switch (codec_fcc) {
+ case GST_MAKE_FOURCC('I','4','2','0'):
+ case GST_MAKE_FOURCC('Y','U','Y','2'):
+ caps = gst_caps2_new_simple ("video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, codec_fcc,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('M','J','P','G'): /* YUY2 MJPEG */
+ case GST_MAKE_FOURCC('J','P','E','G'): /* generic (mostly RGB) MJPEG */
+ case GST_MAKE_FOURCC('P','I','X','L'): /* Miro/Pinnacle fourccs */
+ case GST_MAKE_FOURCC('V','I','X','L'): /* Miro/Pinnacle fourccs */
+ caps = gst_caps2_new_simple ("video/x-jpeg", NULL);
+ break;
+
+ case GST_MAKE_FOURCC('H','F','Y','U'):
+ caps = gst_caps2_new_simple ( "video/x-huffyuv", NULL);
+ break;
+
+ case GST_MAKE_FOURCC('M','P','E','G'):
+ case GST_MAKE_FOURCC('M','P','G','I'):
+ caps = gst_caps2_new_simple ("video/mpeg",
+ "systemstream", G_TYPE_BOOLEAN, FALSE,
+ "mpegversion", G_TYPE_BOOLEAN, 1,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('H','2','6','3'):
+ case GST_MAKE_FOURCC('i','2','6','3'):
+ case GST_MAKE_FOURCC('L','2','6','3'):
+ case GST_MAKE_FOURCC('M','2','6','3'):
+ case GST_MAKE_FOURCC('V','D','O','W'):
+ case GST_MAKE_FOURCC('V','I','V','O'):
+ case GST_MAKE_FOURCC('x','2','6','3'):
+ caps = gst_caps2_new_simple ("video/x-h263", NULL);
+ break;
+
+ case GST_MAKE_FOURCC('D','I','V','3'):
+ case GST_MAKE_FOURCC('D','I','V','4'):
+ case GST_MAKE_FOURCC('D','I','V','5'):
+ caps = gst_caps2_new_simple ("video/x-divx",
+ "divxversion", G_TYPE_INT, 3,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('d','i','v','x'):
+ case GST_MAKE_FOURCC('D','I','V','X'):
+ case GST_MAKE_FOURCC('D','X','5','0'):
+ caps = gst_caps2_new_simple ("video/x-divx",
+ "divxversion", G_TYPE_INT, 5,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('X','V','I','D'):
+ case GST_MAKE_FOURCC('x','v','i','d'):
+ caps = gst_caps2_new_simple ("video/x-xvid", NULL);
+ break;
+
+ case GST_MAKE_FOURCC('M','P','G','4'):
+ caps = gst_caps2_new_simple ("video/x-msmpeg",
+ "msmpegversion", G_TYPE_INT, 41,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('M','P','4','2'):
+ caps = gst_caps2_new_simple ("video/x-msmpeg",
+ "msmpegversion", G_TYPE_INT, 42,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('M','P','4','3'):
+ caps = gst_caps2_new_simple ("video/x-msmpeg",
+ "msmpegversion", G_TYPE_INT, 43,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('3','I','V','1'):
+ case GST_MAKE_FOURCC('3','I','V','2'):
+ caps = gst_caps2_new_simple ( "video/x-3ivx", NULL);
+ break;
+
+ case GST_MAKE_FOURCC('D','V','S','D'):
+ case GST_MAKE_FOURCC('d','v','s','d'):
+ caps = gst_caps2_new_simple ("video/x-dv",
+ "systemstream", G_TYPE_BOOLEAN, FALSE,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('W','M','V','1'):
+ caps = gst_caps2_new_simple ("video/x-wmv",
+ "wmvversion", G_TYPE_INT, 1,
+ NULL);
+ break;
+
+ case GST_MAKE_FOURCC('W','M','V','2'):
+ caps = gst_caps2_new_simple ("video/x-wmv",
+ "wmvversion", G_TYPE_INT, 2,
+ NULL);
+ break;
+
+ default:
+ GST_WARNING ("Unkown video fourcc " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (codec_fcc));
+ return NULL;
+ }
+
+ if (strh != NULL) {
+ gfloat fps = 1. * strh->rate / strh->scale;
+
+ gst_caps2_set_simple (caps, "framerate", G_TYPE_DOUBLE, fps, NULL);
+ } else {
+ gst_caps2_set_simple (caps,
+ "framerate", GST_TYPE_DOUBLE_RANGE, 0., G_MAXDOUBLE,
+ NULL);
+ }
+
+ if (strf != NULL) {
+ gst_caps2_set_simple (caps,
+ "width", G_TYPE_INT, strf->width,
+ "height", G_TYPE_INT, strf->height,
+ NULL);
+ } else {
+ gst_caps2_set_simple (caps,
+ "width", GST_TYPE_INT_RANGE, 16, 4096,
+ "height", GST_TYPE_INT_RANGE, 16, 4096,
+ NULL);
+ }
+
+ return caps;
+}
+
+GstCaps2 *
+gst_riff_create_audio_caps (guint16 codec_id,
+ gst_riff_strh *strh,
+ gst_riff_strf_auds *strf)
+{
+ GstCaps2 *caps = NULL;
+
+ switch (codec_id) {
+ case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */
+ caps = gst_caps2_new_simple ("audio/mpeg",
+ "mpegversion", G_TYPE_INT, 1,
+ "layer", G_TYPE_INT, 3,
+ NULL);
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
+ caps = gst_caps2_new_simple ("audio/mpeg",
+ "layer", G_TYPE_INT, 2,
+ NULL);
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */
+ if (strf != NULL) {
+ gint ba = GUINT16_FROM_LE (strf->blockalign);
+ gint ch = GUINT16_FROM_LE (strf->channels);
+ gint ws = GUINT16_FROM_LE (strf->size);
+
+ caps = gst_caps2_new_simple ("audio/x-raw-int",
+ "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
+ "width", G_TYPE_INT, (int)(ba * 8 / ch),
+ "depth", G_TYPE_INT, ws,
+ "signed", G_TYPE_BOOLEAN, ws != 8,
+ NULL);
+ } else {
+ caps = gst_caps2_from_string ("audio/x-raw-int, "
+ "endianness = (int) LITTLE_ENDIAN, "
+ "signed = (boolean) { true, false }, "
+ "width = (int) { 8, 16 }, "
+ "height = (int) { 8, 16 }");
+ }
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_MULAW:
+ if (strf != NULL && strf->size != 8) {
+ GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
+ strf->size);
+ }
+ caps = gst_caps2_new_simple ("audio/x-mulaw", NULL);
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_ALAW:
+ if (strf != NULL && strf->size != 8) {
+ GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
+ strf->size);
+ }
+ caps = gst_caps2_new_simple ("audio/x-alaw", NULL);
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
+ case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */
+ case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */
+ case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */
+ case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */
+ case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */
+ caps = gst_caps2_new_simple ("audio/x-vorbis", NULL);
+ break;
+
+ case GST_RIFF_WAVE_FORMAT_A52:
+ caps = gst_caps2_new_simple ("audio/x-ac3", NULL);
+ break;
+
+ default:
+ GST_WARNING ("Unkown audio tag 0x%04x",
+ codec_id);
+ break;
+ }
+
+ if (strf != NULL) {
+ gst_caps2_set_simple (caps,
+ "rate", G_TYPE_INT, strf->rate,
+ "channels", G_TYPE_INT, strf->channels,
+ NULL);
+ } else {
+ gst_caps2_set_simple (caps,
+ "rate", GST_TYPE_INT_RANGE, 8000, 96000,
+ "channels", GST_TYPE_INT_RANGE, 1, 2,
+ NULL);
+ }
+
+ return caps;
+}
+
+GstCaps2 *
+gst_riff_create_iavs_caps (guint32 codec_fcc,
+ gst_riff_strh *strh,
+ gst_riff_strf_iavs *strf)
+{
+ GstCaps2 *caps = NULL;
+
+ switch (codec_fcc) {
+ /* is this correct? */
+ case GST_MAKE_FOURCC ('D','V','S','D'):
+ case GST_MAKE_FOURCC ('d','v','s','d'):
+ caps = gst_caps2_new_simple ("video/x-dv",
+ "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
+
+ default:
+ GST_WARNING ("Unkown IAVS fourcc " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (codec_fcc));
+ return NULL;
+ }
+
+ return caps;
+}
+
+/*
+ * Functions below are for template caps. All is variable.
+ */
+
+GstCaps2 *
+gst_riff_create_video_template_caps (void)
+{
+ guint32 tags[] = {
+ GST_MAKE_FOURCC ('I','4','2','0'),
+ GST_MAKE_FOURCC ('Y','U','Y','2'),
+ GST_MAKE_FOURCC ('M','J','P','G'),
+ GST_MAKE_FOURCC ('D','V','S','D'),
+ GST_MAKE_FOURCC ('W','M','V','1'),
+ GST_MAKE_FOURCC ('W','M','V','2'),
+ GST_MAKE_FOURCC ('M','P','G','4'),
+ GST_MAKE_FOURCC ('M','P','4','2'),
+ GST_MAKE_FOURCC ('M','P','4','3'),
+ GST_MAKE_FOURCC ('H','F','Y','U'),
+ GST_MAKE_FOURCC ('D','I','V','3'),
+ GST_MAKE_FOURCC ('M','P','E','G'),
+ GST_MAKE_FOURCC ('H','2','6','3'),
+ GST_MAKE_FOURCC ('D','I','V','X'),
+ GST_MAKE_FOURCC ('X','V','I','D'),
+ GST_MAKE_FOURCC ('3','I','V','1'),
+ /* FILL ME */
+ 0
+ };
+ guint i;
+ GstCaps2 *caps, *one;
+
+ caps = gst_caps2_new_empty ();
+ for (i = 0; tags[i] != 0; i++) {
+ one = gst_riff_create_video_caps (tags[i], NULL, NULL);
+ if (one)
+ gst_caps2_append (caps, one);
+ }
+
+ return caps;
+}
+
+GstCaps2 *
+gst_riff_create_audio_template_caps (void)
+{
+ guint16 tags[] = {
+ GST_RIFF_WAVE_FORMAT_MPEGL3,
+ GST_RIFF_WAVE_FORMAT_MPEGL12,
+ GST_RIFF_WAVE_FORMAT_PCM,
+ GST_RIFF_WAVE_FORMAT_VORBIS1,
+ GST_RIFF_WAVE_FORMAT_A52,
+ GST_RIFF_WAVE_FORMAT_ALAW,
+ GST_RIFF_WAVE_FORMAT_MULAW,
+ /* FILL ME */
+ 0
+ };
+ guint i;
+ GstCaps2 *caps, *one;
+
+ caps = gst_caps2_new_empty ();
+ for (i = 0; tags[i] != 0; i++) {
+ one = gst_riff_create_audio_caps (tags[i], NULL, NULL);
+ if (one)
+ gst_caps2_append (caps, one);
+ }
+
+ return caps;
+}
+
+GstCaps2 *
+gst_riff_create_iavs_template_caps (void)
+{
+ guint32 tags[] = {
+ GST_MAKE_FOURCC ('D','V','S','D'),
+ /* FILL ME */
+ 0
+ };
+ guint i;
+ GstCaps2 *caps, *one;
+
+ caps = gst_caps2_new_empty ();
+ for (i = 0; tags[i] != 0; i++) {
+ one = gst_riff_create_iavs_caps (tags[i], NULL, NULL);
+ if (one)
+ gst_caps2_append (caps, one);
+ }
+
+ return caps;
+}
+
diff --git a/gst-libs/gst/riff/riff-media.h b/gst-libs/gst/riff/riff-media.h
new file mode 100644
index 000000000..1607fc3a3
--- /dev/null
+++ b/gst-libs/gst/riff/riff-media.h
@@ -0,0 +1,55 @@
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff-media.h: RIFF-id to/from caps routines
+ *
+ * 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_RIFF_MEDIA_H__
+#define __GST_RIFF_MEDIA_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include "riff-ids.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Create one caps. strh/strf can be NULL (for non-fixed caps).
+ */
+
+GstCaps2 *gst_riff_create_video_caps (guint32 codec_fcc,
+ gst_riff_strh *strh,
+ gst_riff_strf_vids *strf);
+GstCaps2 *gst_riff_create_audio_caps (guint16 codec_id,
+ gst_riff_strh *strh,
+ gst_riff_strf_auds *strf);
+GstCaps2 *gst_riff_create_iavs_caps (guint32 codec_fcc,
+ gst_riff_strh *strh,
+ gst_riff_strf_iavs *strf);
+
+/*
+ * Create template caps (includes all known types).
+ */
+
+GstCaps2 *gst_riff_create_video_template_caps (void);
+GstCaps2 *gst_riff_create_audio_template_caps (void);
+GstCaps2 *gst_riff_create_iavs_template_caps (void);
+
+G_END_DECLS
+
+#endif /* __GST_RIFF_READ_H__ */
diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c
new file mode 100644
index 000000000..17daf0241
--- /dev/null
+++ b/gst-libs/gst/riff/riff-read.c
@@ -0,0 +1,868 @@
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff-read.c: RIFF input file parsing
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "riff-ids.h"
+#include "riff-read.h"
+
+enum {
+ ARG_0,
+ ARG_METADATA
+ /* FILL ME */
+};
+
+static void gst_riff_read_class_init (GstRiffReadClass *klass);
+static void gst_riff_read_init (GstRiffRead *riff);
+static void gst_riff_read_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GstElementStateReturn
+ gst_riff_read_change_state (GstElement *element);
+
+static GstElementClass *parent_class = NULL;
+
+GType
+gst_riff_read_get_type (void)
+{
+ static GType gst_riff_read_type = 0;
+
+ if (!gst_riff_read_type) {
+ static const GTypeInfo gst_riff_read_info = {
+ sizeof (GstRiffReadClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_riff_read_class_init,
+ NULL,
+ NULL,
+ sizeof (GstRiffRead),
+ 0,
+ (GInstanceInitFunc) gst_riff_read_init,
+ };
+
+ gst_riff_read_type =
+ g_type_register_static (GST_TYPE_ELEMENT, "GstRiffRead",
+ &gst_riff_read_info, 0);
+ }
+
+ return gst_riff_read_type;
+}
+
+static void
+gst_riff_read_class_init (GstRiffReadClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+ g_object_class_install_property (gobject_class, ARG_METADATA,
+ g_param_spec_boxed ("metadata", "Metadata", "Metadata",
+ GST_TYPE_CAPS2, G_PARAM_READABLE));
+
+ parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+ gobject_class->get_property = gst_riff_read_get_property;
+
+ gstelement_class->change_state = gst_riff_read_change_state;
+}
+
+static void
+gst_riff_read_init (GstRiffRead *riff)
+{
+ riff->sinkpad = NULL;
+ riff->bs = NULL;
+ riff->level = NULL;
+ riff->metadata = NULL;
+}
+
+static void
+gst_riff_read_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GstRiffRead *riff = GST_RIFF_READ (object);
+
+ switch (prop_id) {
+ case ARG_METADATA:
+ g_value_set_boxed (value, riff->metadata);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GstElementStateReturn
+gst_riff_read_change_state (GstElement *element)
+{
+ GstRiffRead *riff = GST_RIFF_READ (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_READY_TO_PAUSED:
+ if (!riff->sinkpad)
+ return GST_STATE_FAILURE;
+ riff->bs = gst_bytestream_new (riff->sinkpad);
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+ gst_caps2_replace (&riff->metadata, NULL);
+ gst_bytestream_destroy (riff->bs);
+ while (riff->level) {
+ GstRiffLevel *level = riff->level->data;
+
+ riff->level = g_list_remove (riff->level, level);
+ g_free (level);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
+
+/*
+ * Return: the amount of levels in the hierarchy that the
+ * current element lies higher than the previous one.
+ * The opposite isn't done - that's auto-done using list
+ * element reading.
+ */
+
+static guint
+gst_riff_read_element_level_up (GstRiffRead *riff)
+{
+ guint num = 0;
+ guint64 pos = gst_bytestream_tell (riff->bs);
+
+ while (riff->level != NULL) {
+ GList *last = g_list_last (riff->level);
+ GstRiffLevel *level = last->data;
+
+ if (pos >= level->start + level->length) {
+ riff->level = g_list_remove (riff->level, level);
+ g_free (level);
+ num++;
+ } else
+ break;
+ }
+
+ return num;
+}
+
+/*
+ * Read the next tag plus length (may be NULL). Return
+ * TRUE on success or FALSE on failure.
+ */
+
+static gboolean
+gst_riff_peek_head (GstRiffRead *riff,
+ guint32 *tag,
+ guint32 *length,
+ guint *level_up)
+{
+ guint8 *data;
+
+ /* read */
+ if (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) {
+ GstEvent *event = NULL;
+ guint32 remaining;
+
+ /* Here, we might encounter EOS */
+ gst_bytestream_get_status (riff->bs, &remaining, &event);
+ if (event && GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
+ gst_pad_event_default (riff->sinkpad, event);
+ } else {
+ gst_event_unref (event);
+ gst_element_error (GST_ELEMENT (riff), "Read error");
+ }
+ return FALSE;
+ }
+
+ /* parse tag + length (if wanted) */
+ *tag = GUINT32_FROM_LE (((guint32 *) data)[0]);
+ if (length)
+ *length = GUINT32_FROM_LE (((guint32 *) data)[1]);
+
+ /* level */
+ if (level_up)
+ *level_up = gst_riff_read_element_level_up (riff);
+
+ return TRUE;
+}
+
+/*
+ * Read: the actual data (plus alignment and flush).
+ * Return: the data, as a GstBuffer.
+ */
+
+static GstBuffer *
+gst_riff_read_element_data (GstRiffRead *riff,
+ guint length)
+{
+ GstBuffer *buf = NULL;
+
+ if (gst_bytestream_peek (riff->bs, &buf, length) != length) {
+ gst_element_error (GST_ELEMENT (riff), "Read error");
+ if (buf)
+ gst_buffer_unref (buf);
+ return NULL;
+ }
+
+ /* we need 16-bit alignment */
+ if (length & 1)
+ length++;
+
+ gst_bytestream_flush (riff->bs, length);
+
+ return buf;
+}
+
+/*
+ * Seek.
+ */
+
+GstEvent *
+gst_riff_read_seek (GstRiffRead *riff,
+ guint64 offset)
+{
+ guint64 length = gst_bytestream_length (riff->bs);
+ guint32 remaining;
+ GstEvent *event;
+ guchar *data;
+
+ /* hack for AVI files with broken idx1 size chunk markers */
+ if (offset > length)
+ offset = length;
+
+ /* first, flush remaining buffers */
+ gst_bytestream_get_status (riff->bs, &remaining, &event);
+ if (event) {
+ g_warning ("Unexpected event before seek");
+ gst_event_unref (event);
+ }
+ if (remaining)
+ gst_bytestream_flush_fast (riff->bs, remaining);
+
+ /* now seek */
+ if (!gst_bytestream_seek (riff->bs, offset, GST_SEEK_METHOD_SET)) {
+ gst_element_error (GST_ELEMENT (riff), "Seek failed");
+ return NULL;
+ }
+
+ /* and now, peek a new byte. This will fail because there's a
+ * pending event. Then, take the event and return it. */
+ if (gst_bytestream_peek_bytes (riff->bs, &data, 1))
+ g_warning ("Unexpected data after seek");
+
+ /* get the discont event and return */
+ gst_bytestream_get_status (riff->bs, &remaining, &event);
+ if (!event || GST_EVENT_TYPE (event) != GST_EVENT_DISCONTINUOUS) {
+ gst_element_error (GST_ELEMENT (riff),
+ "No discontinuity event after seek");
+ if (event)
+ gst_event_unref (event);
+ return NULL;
+ }
+
+ return event;
+}
+
+/*
+ * Gives the tag of the next RIFF element.
+ */
+
+guint32
+gst_riff_peek_tag (GstRiffRead *riff,
+ guint *level_up)
+{
+ guint32 tag;
+
+ if (!gst_riff_peek_head (riff, &tag, NULL, level_up))
+ return 0;
+
+ return tag;
+}
+
+/*
+ * Gives the tag of the next LIST/RIFF element.
+ */
+
+guint32
+gst_riff_peek_list (GstRiffRead *riff)
+{
+ guint32 lst;
+ guint8 *data;
+
+ if (!gst_riff_peek_head (riff, &lst, NULL, NULL))
+ return FALSE;
+ if (lst != GST_RIFF_TAG_LIST) {
+ g_warning ("Not a LIST object");
+ return 0;
+ }
+
+ if (gst_bytestream_peek_bytes (riff->bs, &data, 12) != 12) {
+ gst_element_error (GST_ELEMENT (riff), "Read error");
+ return 0;
+ }
+
+ return GUINT32_FROM_LE (((guint32 *) data)[2]);
+}
+
+/*
+ * Don't read data.
+ */
+
+gboolean
+gst_riff_read_skip (GstRiffRead *riff)
+{
+ guint32 tag, length;
+ GstEvent *event;
+ guint32 remaining;
+
+ if (!gst_riff_peek_head (riff, &tag, &length, NULL))
+ return FALSE;
+
+ /* 16-bit alignment */
+ if (length & 1)
+ length++;
+
+ /* header itself */
+ length += 8;
+
+ /* see if we have that much data available */
+ gst_bytestream_get_status (riff->bs, &remaining, &event);
+ if (event) {
+ g_warning ("Unexpected event in skip");
+ gst_event_unref (event);
+ }
+
+ /* yes */
+ if (remaining >= length) {
+ gst_bytestream_flush_fast (riff->bs, length);
+ return TRUE;
+ }
+
+ /* no */
+ if (!(event = gst_riff_read_seek (riff,
+ gst_bytestream_tell (riff->bs) + length)))
+ return FALSE;
+
+ gst_event_unref (event);
+
+ return TRUE;
+}
+
+/*
+ * Read any type of data.
+ */
+
+gboolean
+gst_riff_read_data (GstRiffRead *riff,
+ guint32 *tag,
+ GstBuffer **buf)
+{
+ guint32 length;
+
+ if (!gst_riff_peek_head (riff, tag, &length, NULL))
+ return FALSE;
+ gst_bytestream_flush_fast (riff->bs, 8);
+
+ return ((*buf = gst_riff_read_element_data (riff, length)) != NULL);
+}
+
+/*
+ * Read a string.
+ */
+
+gboolean
+gst_riff_read_ascii (GstRiffRead *riff,
+ guint32 *tag,
+ gchar **str)
+{
+ GstBuffer *buf;
+
+ if (!gst_riff_read_data (riff, tag, &buf))
+ return FALSE;
+
+ *str = g_malloc (GST_BUFFER_SIZE (buf) + 1);
+ memcpy (*str, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ (*str)[GST_BUFFER_SIZE (buf)] = '\0';
+
+ gst_buffer_unref (buf);
+
+ return TRUE;
+}
+
+/*
+ * Read media structs.
+ */
+
+gboolean
+gst_riff_read_strh (GstRiffRead *riff,
+ gst_riff_strh **header)
+{
+ guint32 tag;
+ GstBuffer *buf;
+ gst_riff_strh *strh;
+
+ if (!gst_riff_read_data (riff, &tag, &buf))
+ return FALSE;
+
+ if (tag != GST_RIFF_TAG_strh) {
+ g_warning ("Not a strh chunk");
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+ if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strh)) {
+ g_warning ("Too small strh (%d available, %d needed)",
+ GST_BUFFER_SIZE (buf), sizeof (gst_riff_strh));
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+
+ strh = g_memdup (GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
+ gst_buffer_unref (buf);
+
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ strh->type = GUINT32_FROM_LE (strh->type);
+ strh->fcc_handler = GUINT32_FROM_LE (strh->fcc_handler);
+ strh->flags = GUINT32_FROM_LE (strh->flags);
+ strh->priority = GUINT32_FROM_LE (strh->priority);
+ strh->init_frames = GUINT32_FROM_LE (strh->init_frames);
+ strh->scale = GUINT32_FROM_LE (strh->scale);
+ strh->rate = GUINT32_FROM_LE (strh->rate);
+ strh->start = GUINT32_FROM_LE (strh->start);
+ strh->length = GUINT32_FROM_LE (strh->length);
+ strh->bufsize = GUINT32_FROM_LE (strh->bufsize);
+ strh->quality = GUINT32_FROM_LE (strh->quality);
+ strh->samplesize = GUINT32_FROM_LE (strh->samplesize);
+#endif
+
+ /* avoid divisions by zero */
+ if (!strh->scale)
+ strh->scale = 1;
+ if (!strh->rate)
+ strh->rate = 1;
+
+ /* debug */
+ GST_INFO ("strh tag found");
+ GST_INFO (" type " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (strh->type));
+ GST_INFO (" fcc_handler " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (strh->fcc_handler));
+ GST_INFO (" flags 0x%08x", strh->flags);
+ GST_INFO (" priority %d", strh->priority);
+ GST_INFO (" init_frames %d", strh->init_frames);
+ GST_INFO (" scale %d", strh->scale);
+ GST_INFO (" rate %d", strh->rate);
+ GST_INFO (" start %d", strh->start);
+ GST_INFO (" length %d", strh->length);
+ GST_INFO (" bufsize %d", strh->bufsize);
+ GST_INFO (" quality %d", strh->quality);
+ GST_INFO (" samplesize %d", strh->samplesize);
+
+ *header = strh;
+
+ return TRUE;
+}
+
+gboolean
+gst_riff_read_strf_vids (GstRiffRead *riff,
+ gst_riff_strf_vids **header)
+{
+ guint32 tag;
+ GstBuffer *buf;
+ gst_riff_strf_vids *strf;
+
+ if (!gst_riff_read_data (riff, &tag, &buf))
+ return FALSE;
+
+ if (tag != GST_RIFF_TAG_strf) {
+ g_warning ("Not a strf chunk");
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+ if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_vids)) {
+ g_warning ("Too small strf_vids (%d available, %d needed)",
+ GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_vids));
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+
+ strf = g_memdup (GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
+
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ strf->size = GUINT32_FROM_LE (strf->size);
+ strf->width = GUINT32_FROM_LE (strf->width);
+ strf->height = GUINT32_FROM_LE (strf->height);
+ strf->planes = GUINT16_FROM_LE (strf->planes);
+ strf->bit_cnt = GUINT16_FROM_LE (strf->bit_cnt);
+ strf->compression = GUINT32_FROM_LE (strf->compression);
+ strf->image_size = GUINT32_FROM_LE (strf->image_size);
+ strf->xpels_meter = GUINT32_FROM_LE (strf->xpels_meter);
+ strf->ypels_meter = GUINT32_FROM_LE (strf->ypels_meter);
+ strf->num_colors = GUINT32_FROM_LE (strf->num_colors);
+ strf->imp_colors = GUINT32_FROM_LE (strf->imp_colors);
+#endif
+
+ /* size checking */
+ if (strf->size > GST_BUFFER_SIZE (buf)) {
+ g_warning ("strf_vids header gave %d bytes data, only %d available",
+ strf->size, GST_BUFFER_SIZE (buf));
+ strf->size = GST_BUFFER_SIZE (buf);
+ }
+
+ /* debug */
+ GST_INFO ("strf tag found in context vids:");
+ GST_INFO (" size %d", strf->size);
+ GST_INFO (" width %d", strf->width);
+ GST_INFO (" height %d", strf->height);
+ GST_INFO (" planes %d", strf->planes);
+ GST_INFO (" bit_cnt %d", strf->bit_cnt);
+ GST_INFO (" compression " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (strf->compression));
+ GST_INFO (" image_size %d", strf->image_size);
+ GST_INFO (" xpels_meter %d", strf->xpels_meter);
+ GST_INFO (" ypels_meter %d", strf->ypels_meter);
+ GST_INFO (" num_colors %d", strf->num_colors);
+ GST_INFO (" imp_colors %d", strf->imp_colors);
+
+ gst_buffer_unref (buf);
+
+ *header = strf;
+
+ return TRUE;
+}
+
+gboolean
+gst_riff_read_strf_auds (GstRiffRead *riff,
+ gst_riff_strf_auds **header)
+{
+ guint32 tag;
+ GstBuffer *buf;
+ gst_riff_strf_auds *strf;
+
+ if (!gst_riff_read_data (riff, &tag, &buf))
+ return FALSE;
+
+ if (tag != GST_RIFF_TAG_strf) {
+ g_warning ("Not a strf chunk");
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+ if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_auds)) {
+ g_warning ("Too small strf_auds (%d available, %d needed)",
+ GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_auds));
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+
+ strf = g_memdup (GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
+
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ strf->format = GUINT16_FROM_LE (strf->format);
+ strf->channels = GUINT16_FROM_LE (strf->channels);
+ strf->rate = GUINT32_FROM_LE (strf->rate);
+ strf->av_bps = GUINT32_FROM_LE (strf->av_bps);
+ strf->blockalign = GUINT16_FROM_LE (strf->blockalign);
+ strf->size = GUINT16_FROM_LE (strf->size);
+#endif
+
+ /* debug */
+ GST_INFO ("strf tag found in context auds:");
+ GST_INFO (" format %d", strf->format);
+ GST_INFO (" channels %d", strf->channels);
+ GST_INFO (" rate %d", strf->rate);
+ GST_INFO (" av_bps %d", strf->av_bps);
+ GST_INFO (" blockalign %d", strf->blockalign);
+ GST_INFO (" size %d", strf->size); /* wordsize, not extrasize! */
+
+ gst_buffer_unref (buf);
+
+ *header = strf;
+
+ return TRUE;
+}
+
+gboolean
+gst_riff_read_strf_iavs (GstRiffRead *riff,
+ gst_riff_strf_iavs **header)
+{
+ guint32 tag;
+ GstBuffer *buf;
+ gst_riff_strf_iavs *strf;
+
+ if (!gst_riff_read_data (riff, &tag, &buf))
+ return FALSE;
+
+ if (tag != GST_RIFF_TAG_strf) {
+ g_warning ("Not a strf chunk");
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+ if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_iavs)) {
+ g_warning ("Too small strf_iavs (%d available, %d needed)",
+ GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_iavs));
+ gst_buffer_unref (buf);
+ return FALSE;
+ }
+
+ strf = g_memdup (GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
+ gst_buffer_unref (buf);
+
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ strf->DVAAuxSrc = GUINT32_FROM_LE (strf->DVAAuxSrc);
+ strf->DVAAuxCtl = GUINT32_FROM_LE (strf->DVAAuxCtl);
+ strf->DVAAuxSrc1 = GUINT32_FROM_LE (strf->DVAAuxSrc1);
+ strf->DVAAuxCtl1 = GUINT32_FROM_LE (strf->DVAAuxCtl1);
+ strf->DVVAuxSrc = GUINT32_FROM_LE (strf->DVVAuxSrc);
+ strf->DVVAuxCtl = GUINT32_FROM_LE (strf->DVVAuxCtl);
+ strf->DVReserved1 = GUINT32_FROM_LE (strf->DVReserved1);
+ strf->DVReserved2 = GUINT32_FROM_LE (strf->DVReserved2);
+#endif
+
+ /* debug */
+ GST_INFO ("strf tag found in context iavs");
+ GST_INFO (" DVAAuxSrc %08x", strf->DVAAuxSrc);
+ GST_INFO (" DVAAuxCtl %08x", strf->DVAAuxCtl);
+ GST_INFO (" DVAAuxSrc1 %08x", strf->DVAAuxSrc1);
+ GST_INFO (" DVAAuxCtl1 %08x", strf->DVAAuxCtl1);
+ GST_INFO (" DVVAuxSrc %08x", strf->DVVAuxSrc);
+ GST_INFO (" DVVAuxCtl %08x", strf->DVVAuxCtl);
+ GST_INFO (" DVReserved1 %08x", strf->DVReserved1);
+ GST_INFO (" DVReserved2 %08x", strf->DVReserved2);
+
+ *header = strf;
+
+ return TRUE;
+}
+
+/*
+ * Read a list.
+ */
+
+gboolean
+gst_riff_read_list (GstRiffRead *riff,
+ guint32 *tag)
+{
+ guint32 length, lst;
+ GstRiffLevel *level;
+ guint8 *data;
+
+ if (!gst_riff_peek_head (riff, &lst, &length, NULL))
+ return FALSE;
+ if (lst != GST_RIFF_TAG_LIST) {
+ g_warning ("Not a LIST object");
+ return FALSE;
+ }
+ gst_bytestream_flush_fast (riff->bs, 8);
+ if (gst_bytestream_peek_bytes (riff->bs, &data, 4) != 4) {
+ gst_element_error (GST_ELEMENT (riff), "Read error");
+ return FALSE;
+ }
+ gst_bytestream_flush_fast (riff->bs, 4);
+ *tag = GUINT32_FROM_LE (* (guint32 *) data);
+
+ /* remember level */
+ level = g_new (GstRiffLevel, 1);
+ level->start = gst_bytestream_tell (riff->bs);
+ level->length = length - 4;
+ riff->level = g_list_append (riff->level, level);
+
+ return TRUE;
+}
+
+/*
+ * Utility function for reading metadata in a RIFF file.
+ */
+
+gboolean
+gst_riff_read_info (GstRiffRead *riff)
+{
+ guint32 tag;
+ guint64 end;
+ GstRiffLevel *level;
+ GList *last;
+ gchar *name, *type;
+ GstCaps2 *caps;
+
+ /* What we're doing here is ugly (oh no!); we look
+ * at our LIST tag size and assure that we do not
+ * cross boundaries. This is to maintain the level
+ * counter for the client app. */
+ last = g_list_last (riff->level);
+ level = last->data;
+ riff->level = g_list_remove (riff->level, level);
+ end = level->start + level->length;
+ g_free (level);
+
+ caps = gst_caps2_new_simple ("application/x-gst-metadata", NULL);
+
+ while (gst_bytestream_tell (riff->bs) < end) {
+ if (!gst_riff_peek_head (riff, &tag, NULL, NULL)) {
+ return FALSE;
+ }
+
+ /* find out the type of metadata */
+ switch (tag) {
+ case GST_RIFF_INFO_IARL:
+ type = "Location";
+ break;
+ case GST_RIFF_INFO_IART:
+ type = "Artist";
+ break;
+ case GST_RIFF_INFO_ICMS:
+ type = "Commissioner";
+ break;
+ case GST_RIFF_INFO_ICMT:
+ type = "Comment";
+ break;
+ case GST_RIFF_INFO_ICOP:
+ type = "Copyright";
+ break;
+ case GST_RIFF_INFO_ICRD:
+ type = "Creation Date";
+ break;
+ case GST_RIFF_INFO_ICRP:
+ type = "Cropped";
+ break;
+ case GST_RIFF_INFO_IDIM:
+ type = "Dimensions";
+ break;
+ case GST_RIFF_INFO_IDPI:
+ type = "Dots per Inch";
+ break;
+ case GST_RIFF_INFO_IENG:
+ type = "Engineer";
+ break;
+ case GST_RIFF_INFO_IGNR:
+ type = "Genre";
+ break;
+ case GST_RIFF_INFO_IKEY:
+ type = "Keywords";
+ break;
+ case GST_RIFF_INFO_ILGT:
+ type = "Lightness";
+ break;
+ case GST_RIFF_INFO_IMED:
+ type = "Medium";
+ break;
+ case GST_RIFF_INFO_INAM:
+ type = "Title"; /* "Name" */
+ break;
+ case GST_RIFF_INFO_IPLT:
+ type = "Palette";
+ break;
+ case GST_RIFF_INFO_IPRD:
+ type = "Product";
+ break;
+ case GST_RIFF_INFO_ISBJ:
+ type = "Subject";
+ break;
+ case GST_RIFF_INFO_ISFT:
+ type = "Encoder"; /* "Software" */
+ break;
+ case GST_RIFF_INFO_ISHP:
+ type = "Sharpness";
+ break;
+ case GST_RIFF_INFO_ISRC:
+ type = "Source";
+ break;
+ case GST_RIFF_INFO_ISRF:
+ type = "Source Form";
+ break;
+ case GST_RIFF_INFO_ITCH:
+ type = "Technician";
+ break;
+ default:
+ type = NULL;
+ GST_WARNING ("Unknown INFO (metadata) tag entry " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (tag));
+ break;
+ }
+
+ if (type) {
+ if (!gst_riff_read_ascii (riff, &tag, &name)) {
+ return FALSE;
+ }
+
+ gst_caps2_set_simple (caps, type, G_TYPE_STRING, name, NULL);
+ } else {
+ gst_riff_read_skip (riff);
+ }
+ }
+
+ /* let the world know about this wonderful thing */
+ gst_caps2_replace (&riff->metadata, caps);
+ g_object_notify (G_OBJECT (riff), "metadata");
+
+ return TRUE;
+}
+
+/*
+ * Read RIFF header and document type.
+ */
+
+gboolean
+gst_riff_read_header (GstRiffRead *riff,
+ guint32 *doctype)
+{
+ GstRiffLevel *level;
+ guint32 tag, length;
+ guint8 *data;
+
+ /* We ignore size for openDML-2.0 support */
+ if (!gst_riff_peek_head (riff, &tag, &length, NULL))
+ return FALSE;
+ if (tag != GST_RIFF_TAG_RIFF) {
+ GST_WARNING ("Not a RIFF file");
+ return FALSE;
+ }
+ gst_bytestream_flush_fast (riff->bs, 8);
+
+ /* doctype */
+ if (gst_bytestream_peek_bytes (riff->bs, &data, 4) != 4) {
+ gst_element_error (GST_ELEMENT (riff), "Read error");
+ return FALSE;
+ }
+ gst_bytestream_flush_fast (riff->bs, 4);
+ *doctype = GUINT32_FROM_LE (* (guint32 *) data);
+
+ /* remember level */
+ level = g_new (GstRiffLevel, 1);
+ level->start = gst_bytestream_tell (riff->bs);
+ level->length = length - 4;
+ riff->level = g_list_append (riff->level, level);
+
+ return TRUE;
+}
diff --git a/gst-libs/gst/riff/riff-read.h b/gst-libs/gst/riff/riff-read.h
new file mode 100644
index 000000000..cf8c379bc
--- /dev/null
+++ b/gst-libs/gst/riff/riff-read.h
@@ -0,0 +1,100 @@
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff-read.h: function declarations for parsing a RIFF file
+ *
+ * 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_RIFF_READ_H__
+#define __GST_RIFF_READ_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/bytestream/bytestream.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_RIFF_READ \
+ (gst_riff_read_get_type ())
+#define GST_RIFF_READ(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RIFF_READ, GstRiffRead))
+#define GST_RIFF_READ_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RIFF_READ, GstRiffReadClass))
+#define GST_IS_RIFF_READ(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RIFF_READ))
+#define GST_IS_RIFF_READ_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RIFF_READ))
+#define GST_RIFF_READ_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RIFF_READ, GstRiffReadClass))
+
+typedef struct _GstRiffLevel {
+ guint64 start,
+ length;
+} GstRiffLevel;
+
+typedef struct _GstRiffRead {
+ GstElement parent;
+
+ GstPad *sinkpad;
+ GstByteStream *bs;
+
+ GList *level;
+
+ /* metadata */
+ GstCaps2 *metadata;
+} GstRiffRead;
+
+typedef struct _GstRiffReadClass {
+ GstElementClass parent;
+} GstRiffReadClass;
+
+GType gst_riff_read_get_type (void);
+
+guint32 gst_riff_peek_tag (GstRiffRead *riff,
+ guint *level_up);
+guint32 gst_riff_peek_list (GstRiffRead *riff);
+
+GstEvent *gst_riff_read_seek (GstRiffRead *riff,
+ guint64 offset);
+gboolean gst_riff_read_skip (GstRiffRead *riff);
+gboolean gst_riff_read_data (GstRiffRead *riff,
+ guint32 *tag,
+ GstBuffer **buf);
+gboolean gst_riff_read_ascii (GstRiffRead *riff,
+ guint32 *tag,
+ gchar **str);
+gboolean gst_riff_read_list (GstRiffRead *riff,
+ guint32 *tag);
+gboolean gst_riff_read_header (GstRiffRead *read,
+ guint32 *doctype);
+
+/*
+ * Utility functions (including byteswapping).
+ */
+gboolean gst_riff_read_strh (GstRiffRead *riff,
+ gst_riff_strh **header);
+gboolean gst_riff_read_strf_vids (GstRiffRead *riff,
+ gst_riff_strf_vids **header);
+gboolean gst_riff_read_strf_auds (GstRiffRead *riff,
+ gst_riff_strf_auds **header);
+gboolean gst_riff_read_strf_iavs (GstRiffRead *riff,
+ gst_riff_strf_iavs **header);
+gboolean gst_riff_read_info (GstRiffRead *riff);
+
+G_END_DECLS
+
+#endif /* __GST_RIFF_READ_H__ */
diff --git a/gst-libs/gst/riff/riff.c b/gst-libs/gst/riff/riff.c
index bb29150c0..9c0ce2aec 100644
--- a/gst-libs/gst/riff/riff.c
+++ b/gst-libs/gst/riff/riff.c
@@ -1,5 +1,7 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+/* GStreamer RIFF I/O
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * riff.c: plugin registering
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -18,26 +20,25 @@
*/
#ifdef HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
#endif
-#include <riff.h>
+#include <gst/gst.h>
static gboolean
plugin_init (GstPlugin *plugin)
{
- return TRUE;
+ return gst_library_load ("gstbytestream");
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
- "gstriff",
- "RIFF convenience routines",
+ "riff",
+ "RIFF I/O functions",
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/gst-libs/gst/riff/riff.h b/gst-libs/gst/riff/riff.h
deleted file mode 100644
index d8f57735b..000000000
--- a/gst-libs/gst/riff/riff.h
+++ /dev/null
@@ -1,448 +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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GST_RIFF_H__
-#define __GST_RIFF_H__
-
-
-#include <gst/gst.h>
-
-typedef enum {
- GST_RIFF_OK = 0,
- GST_RIFF_ENOTRIFF = -1,
- GST_RIFF_EINVAL = -2,
- GST_RIFF_ENOMEM = -3
-} GstRiffReturn;
-
-/* states */
-typedef enum {
- GST_RIFF_STATE_INITIAL = 0,
- GST_RIFF_STATE_HASAVIH = 1,
- GST_RIFF_STATE_HASSTRH = 2,
- GST_RIFF_STATE_HASSTRF = 3,
- GST_RIFF_STATE_MOVI = 4
-} GstRiffParserState;
-
-#define MAKE_FOUR_CC(a,b,c,d) GST_MAKE_FOURCC(a,b,c,d)
-
-/* RIFF types */
-#define GST_RIFF_RIFF_WAVE MAKE_FOUR_CC('W','A','V','E')
-#define GST_RIFF_RIFF_AVI MAKE_FOUR_CC('A','V','I',' ')
-
-/* tags */
-#define GST_RIFF_TAG_RIFF MAKE_FOUR_CC('R','I','F','F')
-#define GST_RIFF_TAG_RIFX MAKE_FOUR_CC('R','I','F','X')
-#define GST_RIFF_TAG_LIST MAKE_FOUR_CC('L','I','S','T')
-#define GST_RIFF_TAG_avih MAKE_FOUR_CC('a','v','i','h')
-#define GST_RIFF_TAG_strd MAKE_FOUR_CC('s','t','r','d')
-#define GST_RIFF_TAG_strn MAKE_FOUR_CC('s','t','r','n')
-#define GST_RIFF_TAG_strh MAKE_FOUR_CC('s','t','r','h')
-#define GST_RIFF_TAG_strf MAKE_FOUR_CC('s','t','r','f')
-#define GST_RIFF_TAG_vedt MAKE_FOUR_CC('v','e','d','t')
-#define GST_RIFF_TAG_JUNK MAKE_FOUR_CC('J','U','N','K')
-#define GST_RIFF_TAG_idx1 MAKE_FOUR_CC('i','d','x','1')
-#define GST_RIFF_TAG_dmlh MAKE_FOUR_CC('d','m','l','h')
-/* WAV stuff */
-#define GST_RIFF_TAG_fmt MAKE_FOUR_CC('f','m','t',' ')
-#define GST_RIFF_TAG_data MAKE_FOUR_CC('d','a','t','a')
-
-/* LIST types */
-#define GST_RIFF_LIST_movi MAKE_FOUR_CC('m','o','v','i')
-#define GST_RIFF_LIST_hdrl MAKE_FOUR_CC('h','d','r','l')
-#define GST_RIFF_LIST_strl MAKE_FOUR_CC('s','t','r','l')
-#define GST_RIFF_LIST_INFO MAKE_FOUR_CC('I','N','F','O')
-
-/* fcc types */
-#define GST_RIFF_FCC_vids MAKE_FOUR_CC('v','i','d','s')
-#define GST_RIFF_FCC_auds MAKE_FOUR_CC('a','u','d','s')
-#define GST_RIFF_FCC_pads MAKE_FOUR_CC('p','a','d','s')
-#define GST_RIFF_FCC_txts MAKE_FOUR_CC('t','x','t','s')
-#define GST_RIFF_FCC_vidc MAKE_FOUR_CC('v','i','d','c')
-#define GST_RIFF_FCC_iavs MAKE_FOUR_CC('i','a','v','s')
-/* fcc handlers */
-#define GST_RIFF_FCCH_RLE MAKE_FOUR_CC('R','L','E',' ')
-#define GST_RIFF_FCCH_msvc MAKE_FOUR_CC('m','s','v','c')
-#define GST_RIFF_FCCH_MSVC MAKE_FOUR_CC('M','S','V','C')
-
-/* INFO types - see http://www.saettler.com/RIFFMCI/riffmci.html */
-#define GST_RIFF_INFO_IARL MAKE_FOUR_CC('I','A','R','L') /* location */
-#define GST_RIFF_INFO_IART MAKE_FOUR_CC('I','A','R','T') /* artist */
-#define GST_RIFF_INFO_ICMS MAKE_FOUR_CC('I','C','M','S') /* commissioned */
-#define GST_RIFF_INFO_ICMT MAKE_FOUR_CC('I','C','M','T') /* comment */
-#define GST_RIFF_INFO_ICOP MAKE_FOUR_CC('I','C','O','P') /* copyright */
-#define GST_RIFF_INFO_ICRD MAKE_FOUR_CC('I','C','R','D') /* creation date */
-#define GST_RIFF_INFO_ICRP MAKE_FOUR_CC('I','C','R','P') /* cropped */
-#define GST_RIFF_INFO_IDIM MAKE_FOUR_CC('I','D','I','M') /* dimensions */
-#define GST_RIFF_INFO_IDPI MAKE_FOUR_CC('I','D','P','I') /* dots-per-inch */
-#define GST_RIFF_INFO_IENG MAKE_FOUR_CC('I','E','N','G') /* engineer(s) */
-#define GST_RIFF_INFO_IGNR MAKE_FOUR_CC('I','G','N','R') /* genre */
-#define GST_RIFF_INFO_IKEY MAKE_FOUR_CC('I','K','E','Y') /* keywords */
-#define GST_RIFF_INFO_ILGT MAKE_FOUR_CC('I','L','G','T') /* lightness */
-#define GST_RIFF_INFO_IMED MAKE_FOUR_CC('I','M','E','D') /* medium */
-#define GST_RIFF_INFO_INAM MAKE_FOUR_CC('I','N','A','M') /* name */
-#define GST_RIFF_INFO_IPLT MAKE_FOUR_CC('I','P','L','T') /* palette setting */
-#define GST_RIFF_INFO_IPRD MAKE_FOUR_CC('I','P','R','D') /* product */
-#define GST_RIFF_INFO_ISBJ MAKE_FOUR_CC('I','S','B','J') /* subject */
-#define GST_RIFF_INFO_ISFT MAKE_FOUR_CC('I','S','F','T') /* software */
-#define GST_RIFF_INFO_ISHP MAKE_FOUR_CC('I','S','H','P') /* sharpness */
-#define GST_RIFF_INFO_ISRC MAKE_FOUR_CC('I','S','R','C') /* source */
-#define GST_RIFF_INFO_ISRF MAKE_FOUR_CC('I','S','R','F') /* source form */
-#define GST_RIFF_INFO_ITCH MAKE_FOUR_CC('I','T','C','H') /* technician(s) */
-
-/*********Chunk Names***************/
-#define GST_RIFF_FF00 MAKE_FOUR_CC(0xFF,0xFF,0x00,0x00)
-#define GST_RIFF_00 MAKE_FOUR_CC( '0', '0',0x00,0x00)
-#define GST_RIFF_01 MAKE_FOUR_CC( '0', '1',0x00,0x00)
-#define GST_RIFF_02 MAKE_FOUR_CC( '0', '2',0x00,0x00)
-#define GST_RIFF_03 MAKE_FOUR_CC( '0', '3',0x00,0x00)
-#define GST_RIFF_04 MAKE_FOUR_CC( '0', '4',0x00,0x00)
-#define GST_RIFF_05 MAKE_FOUR_CC( '0', '5',0x00,0x00)
-#define GST_RIFF_06 MAKE_FOUR_CC( '0', '6',0x00,0x00)
-#define GST_RIFF_07 MAKE_FOUR_CC( '0', '7',0x00,0x00)
-#define GST_RIFF_00pc MAKE_FOUR_CC( '0', '0', 'p', 'c')
-#define GST_RIFF_01pc MAKE_FOUR_CC( '0', '1', 'p', 'c')
-#define GST_RIFF_00dc MAKE_FOUR_CC( '0', '0', 'd', 'c')
-#define GST_RIFF_00dx MAKE_FOUR_CC( '0', '0', 'd', 'x')
-#define GST_RIFF_00db MAKE_FOUR_CC( '0', '0', 'd', 'b')
-#define GST_RIFF_00xx MAKE_FOUR_CC( '0', '0', 'x', 'x')
-#define GST_RIFF_00id MAKE_FOUR_CC( '0', '0', 'i', 'd')
-#define GST_RIFF_00rt MAKE_FOUR_CC( '0', '0', 'r', 't')
-#define GST_RIFF_0021 MAKE_FOUR_CC( '0', '0', '2', '1')
-#define GST_RIFF_00iv MAKE_FOUR_CC( '0', '0', 'i', 'v')
-#define GST_RIFF_0031 MAKE_FOUR_CC( '0', '0', '3', '1')
-#define GST_RIFF_0032 MAKE_FOUR_CC( '0', '0', '3', '2')
-#define GST_RIFF_00vc MAKE_FOUR_CC( '0', '0', 'v', 'c')
-#define GST_RIFF_00xm MAKE_FOUR_CC( '0', '0', 'x', 'm')
-#define GST_RIFF_01wb MAKE_FOUR_CC( '0', '1', 'w', 'b')
-#define GST_RIFF_01dc MAKE_FOUR_CC( '0', '1', 'd', 'c')
-#define GST_RIFF_00__ MAKE_FOUR_CC( '0', '0', '_', '_')
-
-/*********VIDEO CODECS**************/
-#define GST_RIFF_cram MAKE_FOUR_CC( 'c', 'r', 'a', 'm')
-#define GST_RIFF_CRAM MAKE_FOUR_CC( 'C', 'R', 'A', 'M')
-#define GST_RIFF_wham MAKE_FOUR_CC( 'w', 'h', 'a', 'm')
-#define GST_RIFF_WHAM MAKE_FOUR_CC( 'W', 'H', 'A', 'M')
-#define GST_RIFF_rgb MAKE_FOUR_CC(0x00,0x00,0x00,0x00)
-#define GST_RIFF_RGB MAKE_FOUR_CC( 'R', 'G', 'B', ' ')
-#define GST_RIFF_rle8 MAKE_FOUR_CC(0x01,0x00,0x00,0x00)
-#define GST_RIFF_RLE8 MAKE_FOUR_CC( 'R', 'L', 'E', '8')
-#define GST_RIFF_rle4 MAKE_FOUR_CC(0x02,0x00,0x00,0x00)
-#define GST_RIFF_RLE4 MAKE_FOUR_CC( 'R', 'L', 'E', '4')
-#define GST_RIFF_none MAKE_FOUR_CC(0x00,0x00,0xFF,0xFF)
-#define GST_RIFF_NONE MAKE_FOUR_CC( 'N', 'O', 'N', 'E')
-#define GST_RIFF_pack MAKE_FOUR_CC(0x01,0x00,0xFF,0xFF)
-#define GST_RIFF_PACK MAKE_FOUR_CC( 'P', 'A', 'C', 'K')
-#define GST_RIFF_tran MAKE_FOUR_CC(0x02,0x00,0xFF,0xFF)
-#define GST_RIFF_TRAN MAKE_FOUR_CC( 'T', 'R', 'A', 'N')
-#define GST_RIFF_ccc MAKE_FOUR_CC(0x03,0x00,0xFF,0xFF)
-#define GST_RIFF_CCC MAKE_FOUR_CC( 'C', 'C', 'C', ' ')
-#define GST_RIFF_cyuv MAKE_FOUR_CC( 'c', 'y', 'u', 'v')
-#define GST_RIFF_CYUV MAKE_FOUR_CC( 'C', 'Y', 'U', 'V')
-#define GST_RIFF_jpeg MAKE_FOUR_CC(0x04,0x00,0xFF,0xFF)
-#define GST_RIFF_JPEG MAKE_FOUR_CC( 'J', 'P', 'E', 'G')
-#define GST_RIFF_MJPG MAKE_FOUR_CC( 'M', 'J', 'P', 'G')
-#define GST_RIFF_mJPG MAKE_FOUR_CC( 'm', 'J', 'P', 'G')
-#define GST_RIFF_IJPG MAKE_FOUR_CC( 'I', 'J', 'P', 'G')
-#define GST_RIFF_rt21 MAKE_FOUR_CC( 'r', 't', '2', '1')
-#define GST_RIFF_RT21 MAKE_FOUR_CC( 'R', 'T', '2', '1')
-#define GST_RIFF_iv31 MAKE_FOUR_CC( 'i', 'v', '3', '1')
-#define GST_RIFF_IV31 MAKE_FOUR_CC( 'I', 'V', '3', '1')
-#define GST_RIFF_iv32 MAKE_FOUR_CC( 'i', 'v', '3', '2')
-#define GST_RIFF_IV32 MAKE_FOUR_CC( 'I', 'V', '3', '2')
-#define GST_RIFF_iv41 MAKE_FOUR_CC( 'i', 'v', '4', '1')
-#define GST_RIFF_IV41 MAKE_FOUR_CC( 'I', 'V', '4', '1')
-#define GST_RIFF_iv50 MAKE_FOUR_CC( 'i', 'v', '5', '0')
-#define GST_RIFF_IV50 MAKE_FOUR_CC( 'I', 'V', '5', '0')
-#define GST_RIFF_cvid MAKE_FOUR_CC( 'c', 'v', 'i', 'd')
-#define GST_RIFF_CVID MAKE_FOUR_CC( 'C', 'V', 'I', 'D')
-#define GST_RIFF_ULTI MAKE_FOUR_CC( 'U', 'L', 'T', 'I')
-#define GST_RIFF_ulti MAKE_FOUR_CC( 'u', 'l', 't', 'i')
-#define GST_RIFF_YUV9 MAKE_FOUR_CC( 'Y', 'V', 'U', '9')
-#define GST_RIFF_YVU9 MAKE_FOUR_CC( 'Y', 'U', 'V', '9')
-#define GST_RIFF_XMPG MAKE_FOUR_CC( 'X', 'M', 'P', 'G')
-#define GST_RIFF_xmpg MAKE_FOUR_CC( 'x', 'm', 'p', 'g')
-#define GST_RIFF_VDOW MAKE_FOUR_CC( 'V', 'D', 'O', 'W')
-#define GST_RIFF_MVI1 MAKE_FOUR_CC( 'M', 'V', 'I', '1')
-#define GST_RIFF_v422 MAKE_FOUR_CC( 'v', '4', '2', '2')
-#define GST_RIFF_V422 MAKE_FOUR_CC( 'V', '4', '2', '2')
-#define GST_RIFF_mvi1 MAKE_FOUR_CC( 'm', 'v', 'i', '1')
-#define GST_RIFF_MPIX MAKE_FOUR_CC(0x04,0x00, 'i', '1') /* MotionPixels munged their id */
-#define GST_RIFF_AURA MAKE_FOUR_CC( 'A', 'U', 'R', 'A')
-#define GST_RIFF_DMB1 MAKE_FOUR_CC( 'D', 'M', 'B', '1')
-#define GST_RIFF_dmb1 MAKE_FOUR_CC( 'd', 'm', 'b', '1')
-
-#define GST_RIFF_BW10 MAKE_FOUR_CC( 'B', 'W', '1', '0')
-#define GST_RIFF_bw10 MAKE_FOUR_CC( 'b', 'w', '1', '0')
-
-#define GST_RIFF_yuy2 MAKE_FOUR_CC( 'y', 'u', 'y', '2')
-#define GST_RIFF_YUY2 MAKE_FOUR_CC( 'Y', 'U', 'Y', '2')
-#define GST_RIFF_YUV8 MAKE_FOUR_CC( 'Y', 'U', 'V', '8')
-#define GST_RIFF_WINX MAKE_FOUR_CC( 'W', 'I', 'N', 'X')
-#define GST_RIFF_WPY2 MAKE_FOUR_CC( 'W', 'P', 'Y', '2')
-#define GST_RIFF_m263 MAKE_FOUR_CC( 'm', '2', '6', '3')
-#define GST_RIFF_M263 MAKE_FOUR_CC( 'M', '2', '6', '3')
-
-#define GST_RIFF_Q1_0 MAKE_FOUR_CC( 'Q', '1',0x2e, '0')
-#define GST_RIFF_SFMC MAKE_FOUR_CC( 'S', 'F', 'M', 'C')
-
-#define GST_RIFF_y41p MAKE_FOUR_CC( 'y', '4', '1', 'p')
-#define GST_RIFF_Y41P MAKE_FOUR_CC( 'Y', '4', '1', 'P')
-#define GST_RIFF_yv12 MAKE_FOUR_CC( 'y', 'v', '1', '2')
-#define GST_RIFF_YV12 MAKE_FOUR_CC( 'Y', 'V', '1', '2')
-#define GST_RIFF_vixl MAKE_FOUR_CC( 'v', 'i', 'x', 'l')
-#define GST_RIFF_VIXL MAKE_FOUR_CC( 'V', 'I', 'X', 'L')
-#define GST_RIFF_iyuv MAKE_FOUR_CC( 'i', 'y', 'u', 'v')
-#define GST_RIFF_IYUV MAKE_FOUR_CC( 'I', 'Y', 'U', 'V')
-#define GST_RIFF_i420 MAKE_FOUR_CC( 'i', '4', '2', '0')
-#define GST_RIFF_I420 MAKE_FOUR_CC( 'I', '4', '2', '0')
-#define GST_RIFF_vyuy MAKE_FOUR_CC( 'v', 'y', 'u', 'y')
-#define GST_RIFF_VYUY MAKE_FOUR_CC( 'V', 'Y', 'U', 'Y')
-
-#define GST_RIFF_DIV3 MAKE_FOUR_CC( 'D', 'I', 'V', '3')
-
-#define GST_RIFF_rpza MAKE_FOUR_CC( 'r', 'p', 'z', 'a')
-/* And this here's the mistakes that need to be supported */
-#define GST_RIFF_azpr MAKE_FOUR_CC( 'a', 'z', 'p', 'r') /* recognize Apple's rpza mangled? */
-
-/*********** FND in MJPG **********/
-#define GST_RIFF_ISFT MAKE_FOUR_CC( 'I', 'S', 'F', 'T')
-#define GST_RIFF_IDIT MAKE_FOUR_CC( 'I', 'D', 'I', 'T')
-
-#define GST_RIFF_00AM MAKE_FOUR_CC( '0', '0', 'A', 'M')
-#define GST_RIFF_DISP MAKE_FOUR_CC( 'D', 'I', 'S', 'P')
-#define GST_RIFF_ISBJ MAKE_FOUR_CC( 'I', 'S', 'B', 'J')
-
-#define GST_RIFF_rec MAKE_FOUR_CC( 'r', 'e', 'c', ' ')
-
-/* common data structures */
-struct _gst_riff_avih {
- guint32 us_frame; /* microsec per frame */
- guint32 max_bps; /* byte/s overall */
- guint32 pad_gran; /* pad_gran (???) */
- guint32 flags;
-/* flags values */
-#define GST_RIFF_AVIH_HASINDEX 0x00000010 /* has idx1 chunk */
-#define GST_RIFF_AVIH_MUSTUSEINDEX 0x00000020 /* must use idx1 chunk to determine order */
-#define GST_RIFF_AVIH_ISINTERLEAVED 0x00000100 /* AVI file is interleaved */
-#define GST_RIFF_AVIH_WASCAPTUREFILE 0x00010000 /* specially allocated used for capturing real time video */
-#define GST_RIFF_AVIH_COPYRIGHTED 0x00020000 /* contains copyrighted data */
- guint32 tot_frames; /* # of frames (all) */
- guint32 init_frames; /* initial frames (???) */
- guint32 streams;
- guint32 bufsize; /* suggested buffer size */
- guint32 width;
- guint32 height;
- guint32 scale;
- guint32 rate;
- guint32 start;
- guint32 length;
-};
-
-struct _gst_riff_strh {
- guint32 type; /* stream type */
- guint32 fcc_handler; /* fcc_handler */
- guint32 flags;
-/* flags values */
-#define GST_RIFF_STRH_DISABLED 0x000000001
-#define GST_RIFF_STRH_VIDEOPALCHANGES 0x000010000
- guint32 priority;
- guint32 init_frames; /* initial frames (???) */
- guint32 scale;
- guint32 rate;
- guint32 start;
- guint32 length;
- guint32 bufsize; /* suggested buffer size */
- guint32 quality;
- guint32 samplesize;
- /* XXX 16 bytes ? */
-};
-
-struct _gst_riff_strf_vids { /* == BitMapInfoHeader */
- guint32 size;
- guint32 width;
- guint32 height;
- guint16 planes;
- guint16 bit_cnt;
- guint32 compression;
- guint32 image_size;
- guint32 xpels_meter;
- guint32 ypels_meter;
- guint32 num_colors; /* used colors */
- guint32 imp_colors; /* important colors */
- /* may be more for some codecs */
-};
-
-
-struct _gst_riff_strf_auds { /* == WaveHeader (?) */
- guint16 format;
-/**** from public Microsoft RIFF docs ******/
-#define GST_RIFF_WAVE_FORMAT_UNKNOWN (0x0000)
-#define GST_RIFF_WAVE_FORMAT_PCM (0x0001)
-#define GST_RIFF_WAVE_FORMAT_ADPCM (0x0002)
-#define GST_RIFF_WAVE_FORMAT_IBM_CVSD (0x0005)
-#define GST_RIFF_WAVE_FORMAT_ALAW (0x0006)
-#define GST_RIFF_WAVE_FORMAT_MULAW (0x0007)
-#define GST_RIFF_WAVE_FORMAT_OKI_ADPCM (0x0010)
-#define GST_RIFF_WAVE_FORMAT_DVI_ADPCM (0x0011)
-#define GST_RIFF_WAVE_FORMAT_DIGISTD (0x0015)
-#define GST_RIFF_WAVE_FORMAT_DIGIFIX (0x0016)
-#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020)
-#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022)
-#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031)
-#define GST_RIFF_WAVE_FORMAT_MSN (0x0032)
-#define GST_RIFF_WAVE_FORMAT_MPEGL12 (0x0050)
-#define GST_RIFF_WAVE_FORMAT_MPEGL3 (0x0055)
-#define GST_RIFF_IBM_FORMAT_MULAW (0x0101)
-#define GST_RIFF_IBM_FORMAT_ALAW (0x0102)
-#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103)
-#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV1 (0x0160)
-#define GST_RIFF_WAVE_FORMAT_DIVX_WMAV2 (0x0161)
-#define GST_RIFF_WAVE_FORMAT_WMAV9 (0x0162)
-#define GST_RIFF_WAVE_FORMAT_A52 (0x2000)
-#define GST_RIFF_WAVE_FORMAT_VORBIS1 (0x674f)
-#define GST_RIFF_WAVE_FORMAT_VORBIS2 (0x6750)
-#define GST_RIFF_WAVE_FORMAT_VORBIS3 (0x6751)
-#define GST_RIFF_WAVE_FORMAT_VORBIS1PLUS (0x676f)
-#define GST_RIFF_WAVE_FORMAT_VORBIS2PLUS (0x6770)
-#define GST_RIFF_WAVE_FORMAT_VORBIS3PLUS (0x6771)
- guint16 channels;
- guint32 rate;
- guint32 av_bps;
- guint16 blockalign;
- guint16 size;
-};
-
-struct _gst_riff_strf_iavs {
- guint32 DVAAuxSrc;
- guint32 DVAAuxCtl;
- guint32 DVAAuxSrc1;
- guint32 DVAAuxCtl1;
- guint32 DVVAuxSrc;
- guint32 DVVAuxCtl;
- guint32 DVReserved1;
- guint32 DVReserved2;
-};
-
-struct _gst_riff_riff {
- guint32 id;
- guint32 size;
- guint32 type;
-};
-
-struct _gst_riff_list {
- guint32 id;
- guint32 size;
- guint32 type;
-};
-
-struct _gst_riff_chunk {
- guint32 id;
- guint32 size;
-};
-
-struct _gst_riff_index_entry {
- guint32 id;
- guint32 flags;
-#define GST_RIFF_IF_LIST (0x00000001L)
-#define GST_RIFF_IF_KEYFRAME (0x00000010L)
-#define GST_RIFF_IF_NO_TIME (0x00000100L)
-#define GST_RIFF_IF_COMPUSE (0x0FFF0000L)
- guint32 offset;
- guint32 size;
-};
-
-struct _gst_riff_dmlh {
- guint32 totalframes;
-};
-
-typedef struct _gst_riff_riff gst_riff_riff;
-typedef struct _gst_riff_list gst_riff_list;
-typedef struct _gst_riff_chunk gst_riff_chunk;
-typedef struct _gst_riff_index_entry gst_riff_index_entry;
-
-typedef struct _gst_riff_avih gst_riff_avih;
-typedef struct _gst_riff_strh gst_riff_strh;
-typedef struct _gst_riff_strf_vids gst_riff_strf_vids;
-typedef struct _gst_riff_strf_auds gst_riff_strf_auds;
-typedef struct _gst_riff_strf_iavs gst_riff_strf_iavs;
-typedef struct _gst_riff_dmlh gst_riff_dmlh;
-typedef struct _GstRiff GstRiff;
-typedef struct _GstRiffChunk GstRiffChunk;
-
-typedef void (*GstRiffCallback) (GstRiffChunk *chunk, gpointer data);
-
-struct _GstRiff {
- guint32 form;
-
- /* list of chunks, most recent at the head */
- GList *chunks;
-
- /* incomplete chunks are assembled here */
- GstRiffChunk *incomplete_chunk;
- guint32 incomplete_chunk_size;
- /* parse state */
- GstRiffParserState state;
- guint32 curoffset;
- guint32 nextlikely;
- /* leftover data */
- guchar *dataleft;
- guint32 dataleft_size;
-
- /* callback function and data pointer */
- GstRiffCallback new_tag_found;
- gpointer callback_data;
-};
-
-struct _GstRiffChunk {
- gulong offset;
-
- guint32 id;
- guint32 size;
- guint32 form; /* for list chunks */
-
- gchar *data;
-};
-
-
-/* from gstriffparse.c */
-GstRiff* gst_riff_parser_new (GstRiffCallback function, gpointer data);
-GstRiffReturn gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off);
-void gst_riff_parser_resync (GstRiff *riff, gulong offset);
-GstRiffChunk* gst_riff_parser_get_chunk (GstRiff *riff, guint32 fourcc);
-guint32 gst_riff_parser_get_nextlikely (GstRiff *riff);
-
-/* from gstriffencode.c */
-GstRiff* gst_riff_encoder_new (guint32 type);
-GstRiffReturn gst_riff_encoder_avih (GstRiff *riff, gst_riff_avih *head, gulong size);
-GstRiffReturn gst_riff_encoder_strh (GstRiff *riff, guint32 fcc_type,
- gst_riff_strh *head, gulong size);
-GstRiffReturn gst_riff_encoder_strf (GstRiff *riff, void *format, gulong size);
-GstRiffReturn gst_riff_encoder_chunk (GstRiff *riff, guint32 chunk_type,
- void *chunk, gulong size);
-
-GstBuffer* gst_riff_encoder_get_buffer (GstRiff *riff);
-GstBuffer* gst_riff_encoder_get_and_reset_buffer (GstRiff *riff);
-
-/* from gstriffutil.c */
-gulong gst_riff_fourcc_to_id (gchar *fourcc);
-gchar* gst_riff_id_to_fourcc (gulong id);
-
-
-#endif /* __GST_RIFF_H__ */
diff --git a/gst-libs/gst/riff/riffencode.c b/gst-libs/gst/riff/riffencode.c
deleted file mode 100644
index 630725d56..000000000
--- a/gst-libs/gst/riff/riffencode.c
+++ /dev/null
@@ -1,181 +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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-/*#define DEBUG_ENABLED */
-#include "riff.h"
-
-#define GST_RIFF_ENCODER_BUF_SIZE 1024
-
-#define ADD_CHUNK(riffenc, chunkid, chunksize) \
-{ \
- gst_riff_chunk *chunk;\
- chunk = (gst_riff_chunk *)(riffenc->dataleft + riffenc->nextlikely);\
- chunk->id = chunkid; \
- chunk->size = chunksize; \
- riffenc->nextlikely += sizeof(gst_riff_chunk); \
-}
-
-#define ADD_LIST(riffenc, listsize, listtype) \
-{ \
- gst_riff_list *list;\
- list = (gst_riff_list *)(riffenc->dataleft + riffenc->nextlikely); \
- list->id = GST_RIFF_TAG_LIST; \
- list->size = listsize; \
- list->type = listtype; \
- riffenc->nextlikely += sizeof(gst_riff_list); \
-}
-
-
-GstRiff *gst_riff_encoder_new(guint32 type) {
- GstRiff *riff;
- gst_riff_list *list;
-
- GST_DEBUG ("gst_riff_encoder: making %4.4s encoder", (char *)&type);
- riff = (GstRiff *)g_malloc(sizeof(GstRiff));
- g_return_val_if_fail(riff != NULL, NULL);
-
- riff->form = 0;
- riff->chunks = NULL;
- riff->state = GST_RIFF_STATE_INITIAL;
- riff->curoffset = 0;
- riff->incomplete_chunk = NULL;
- riff->dataleft = g_malloc(GST_RIFF_ENCODER_BUF_SIZE);
- riff->dataleft_size = GST_RIFF_ENCODER_BUF_SIZE;
- riff->nextlikely = 0;
-
- list = (gst_riff_list *)riff->dataleft;
- list->id = GST_RIFF_TAG_RIFF;
- list->size = 0x00FFFFFF;
- list->type = GST_RIFF_RIFF_AVI;
-
- riff->nextlikely += sizeof(gst_riff_list);
-
- return riff;
-}
-
-gint gst_riff_encoder_avih(GstRiff *riff, gst_riff_avih *head, gulong size) {
- gst_riff_chunk *chunk;
-
- g_return_val_if_fail(riff->state == GST_RIFF_STATE_INITIAL, GST_RIFF_EINVAL);
-
- GST_DEBUG ("gst_riff_encoder: add avih");
-
- ADD_LIST(riff, 0xB8, GST_RIFF_LIST_hdrl);
-
- ADD_CHUNK(riff, GST_RIFF_TAG_avih, size);
-
- chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely);
- memcpy(chunk, head, size);
- riff->nextlikely += size;
-
- riff->state = GST_RIFF_STATE_HASAVIH;
- return GST_RIFF_OK;
-}
-
-gint gst_riff_encoder_strh(GstRiff *riff, guint32 fcc_type, gst_riff_strh *head, gulong size) {
- gst_riff_chunk *chunk;
-
- g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASAVIH ||
- riff->state == GST_RIFF_STATE_HASSTRF, GST_RIFF_EINVAL);
-
- GST_DEBUG ("gst_riff_encoder: add strh type %08x (%4.4s)", fcc_type, (char *)&fcc_type);
-
- ADD_LIST(riff, 108, GST_RIFF_LIST_strl);
-
- ADD_CHUNK(riff, GST_RIFF_TAG_strh, size);
-
- chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely);
- head->type = fcc_type;
- memcpy(chunk, head, size);
-
- riff->nextlikely += size;
-
- riff->state = GST_RIFF_STATE_HASSTRH;
- return GST_RIFF_OK;
-}
-
-gint gst_riff_encoder_strf(GstRiff *riff, void *format, gulong size) {
- gst_riff_chunk *chunk;
-
- g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASSTRH, GST_RIFF_EINVAL);
-
- GST_DEBUG ("gst_riff_encoder: add strf");
-
- ADD_CHUNK(riff, GST_RIFF_TAG_strf, size);
-
- chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely);
- memcpy(chunk, format, size);
- riff->nextlikely += size;
-
- riff->state = GST_RIFF_STATE_HASSTRF;
- return GST_RIFF_OK;
-}
-
-gint gst_riff_encoder_chunk(GstRiff *riff, guint32 chunk_type, void *chunkdata, gulong size) {
- gst_riff_chunk *chunk;
-
- g_return_val_if_fail(riff->state == GST_RIFF_STATE_HASSTRF ||
- riff->state == GST_RIFF_STATE_MOVI, GST_RIFF_EINVAL);
-
- if (riff->state != GST_RIFF_STATE_MOVI) {
- ADD_LIST(riff, 0x00FFFFFF, GST_RIFF_LIST_movi);
- riff->state = GST_RIFF_STATE_MOVI;
- }
-
- GST_DEBUG ("gst_riff_encoder: add chunk type %08x (%4.4s)", chunk_type, (char *)&chunk_type);
-
- ADD_CHUNK(riff, chunk_type, size);
-
- if (chunkdata != NULL) {
- chunk = (gst_riff_chunk *)(riff->dataleft + riff->nextlikely);
- memcpy(chunk, chunkdata, size);
- riff->nextlikely += size + (size&1);
- }
-
- return GST_RIFF_OK;
-}
-
-GstBuffer *gst_riff_encoder_get_buffer(GstRiff *riff) {
- GstBuffer *newbuf;
-
- newbuf = gst_buffer_new();
- GST_BUFFER_DATA(newbuf) = riff->dataleft;
- GST_BUFFER_SIZE(newbuf) = riff->nextlikely;
-
- return newbuf;
-}
-
-GstBuffer *gst_riff_encoder_get_and_reset_buffer(GstRiff *riff) {
- GstBuffer *newbuf;
-
- newbuf = gst_riff_encoder_get_buffer(riff);
-
- riff->dataleft = g_malloc(GST_RIFF_ENCODER_BUF_SIZE);
- riff->dataleft_size = GST_RIFF_ENCODER_BUF_SIZE;
- riff->nextlikely = 0;
-
- return newbuf;
-}
-
diff --git a/gst-libs/gst/riff/riffparse.c b/gst-libs/gst/riff/riffparse.c
deleted file mode 100644
index 72c9e4bb9..000000000
--- a/gst-libs/gst/riff/riffparse.c
+++ /dev/null
@@ -1,250 +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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-/*#define DEBUG_ENABLED */
-#include <riff.h>
-
-GstRiff*
-gst_riff_parser_new (GstRiffCallback function, gpointer data)
-{
- GstRiff *riff;
-
- riff = (GstRiff *)g_malloc(sizeof(GstRiff));
- g_return_val_if_fail(riff != NULL, NULL);
-
- riff->form = 0;
- riff->chunks = NULL;
- riff->state = 0;
- riff->curoffset = 0;
- riff->nextlikely = 0;
- riff->new_tag_found = function;
- riff->callback_data = data;
- riff->incomplete_chunk = NULL;
- riff->dataleft = NULL;
-
- return riff;
-}
-
-gint
-gst_riff_parser_next_buffer (GstRiff *riff, GstBuffer *buf, gulong off)
-{
- gulong last, size;
- GstRiffChunk *chunk;
-
- g_return_val_if_fail(riff != NULL, GST_RIFF_EINVAL);
- g_return_val_if_fail(buf != NULL, GST_RIFF_EINVAL);
- g_return_val_if_fail(GST_BUFFER_DATA(buf) != NULL, GST_RIFF_EINVAL);
-
- size = GST_BUFFER_SIZE(buf);
- last = off + size;
-
- GST_DEBUG ("gst_riff_parser: offset new buffer 0x%08lx size 0x%08x", off, GST_BUFFER_SIZE(buf));
-
- if (riff->dataleft) {
- gulong newsize;
-
- GST_DEBUG ("gst_riff_parser: recovering left data");
- newsize = riff->dataleft_size + size;
- riff->dataleft = g_realloc(riff->dataleft, newsize);
- memcpy(riff->dataleft+riff->dataleft_size, GST_BUFFER_DATA(buf), size);
- gst_buffer_unref(buf);
-
- buf = gst_buffer_new();
- GST_BUFFER_DATA(buf) = riff->dataleft;
- size = GST_BUFFER_SIZE(buf) = newsize;
- off -= riff->dataleft_size;
- /*last -= riff->dataleft_size; */
- riff->dataleft = NULL;
- }
-
- if (off == 0) {
- guint32 *words = (guint32 *)GST_BUFFER_DATA(buf);
-
- /* don't even try to parse the head if it's not there FIXME */
- if (last < 12) {
- riff->state = GST_RIFF_ENOTRIFF;
- return riff->state;
- }
-
- /*g_print("testing is 0x%08lx '%s'\n",words[0],gst_riff_id_to_fourcc(words[0])); */
- /* verify this is a valid RIFF file, first of all */
- if (GUINT32_FROM_LE (words[0]) != GST_RIFF_TAG_RIFF) {
- riff->state = GST_RIFF_ENOTRIFF;
- return riff->state;
- }
- riff->form = GUINT32_FROM_LE (words[2]);
- /*g_print("form is 0x%08lx '%s'\n",words[2],gst_riff_id_to_fourcc(words[2])); */
- riff->nextlikely = 12; /* skip 'RIFF', length, and form */
- /* all OK here */
- riff->incomplete_chunk = NULL;
- }
-
- /* if we have an incomplete chunk from the previous buffer */
- if (riff->incomplete_chunk) {
- guint leftover;
- GST_DEBUG ("gst_riff_parser: have incomplete chunk %08x filled", riff->incomplete_chunk_size);
- leftover = riff->incomplete_chunk->size - riff->incomplete_chunk_size;
- if (leftover <= size) {
- GST_DEBUG ("gst_riff_parser: we can fill it from %08x with %08x bytes = %08x",
- riff->incomplete_chunk_size, leftover,
- riff->incomplete_chunk_size+leftover);
- memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), leftover);
-
- if (riff->new_tag_found) {
- riff->new_tag_found(riff->incomplete_chunk, riff->callback_data);
- }
- g_free(riff->incomplete_chunk->data);
- g_free(riff->incomplete_chunk);
- riff->incomplete_chunk = NULL;
- }
- else {
- GST_DEBUG ("gst_riff_parser: we cannot fill it %08x >= %08lx", leftover, size);
- memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), size);
- riff->incomplete_chunk_size += size;
- return 0;
- }
- }
-
- if (riff->nextlikely & 0x01) riff->nextlikely++;
-
- GST_DEBUG ("gst_riff_parser: next 0x%08x last 0x%08lx offset %08lx",riff->nextlikely, last, off);
- /* loop while the next likely chunk header is in this buffer */
- while ((riff->nextlikely+12) <= last) {
- guint32 *words = (guint32 *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely - off );
-
- /* loop over all of the chunks to check which one is finished */
- while (riff->chunks) {
- chunk = g_list_nth_data(riff->chunks, 0);
-
- GST_DEBUG ("gst_riff_parser: next 0x%08x offset 0x%08lx size 0x%08x",riff->nextlikely,
- chunk->offset, chunk->size);
- if (riff->nextlikely >= chunk->offset+chunk->size) {
- GST_DEBUG ("gst_riff_parser: found END LIST");
- /* we have the end of the chunk on the stack, remove it */
- riff->chunks = g_list_remove(riff->chunks, chunk);
- }
- else break;
- }
-
- GST_DEBUG ("gst_riff_parser: next likely chunk is at offset 0x%08x",riff->nextlikely);
-
- chunk = (GstRiffChunk *)g_malloc(sizeof(GstRiffChunk));
- g_return_val_if_fail(chunk != NULL, GST_RIFF_ENOMEM);
-
- chunk->offset = riff->nextlikely+8; /* point to the actual data */
- chunk->id = GUINT32_FROM_LE (words[0]);
- chunk->size = GUINT32_FROM_LE (words[1]);
- chunk->data = (gchar *)(words+2);
- /* we need word alignment */
- /*if (chunk->size & 0x01) chunk->size++; */
- chunk->form = GUINT32_FROM_LE (words[2]); /* fill in the form, might not be valid */
-
-
- if (chunk->id == GST_RIFF_TAG_LIST) {
- GST_DEBUG ("found LIST %s", gst_riff_id_to_fourcc(chunk->form));
- riff->nextlikely += 12;
- /* we push the list chunk on our 'stack' */
- riff->chunks = g_list_prepend(riff->chunks,chunk);
- /* send the buffer to the listener if we have received a function */
- if (riff->new_tag_found) {
- riff->new_tag_found(chunk, riff->callback_data);
- }
- }
- else {
-
- GST_DEBUG ("gst_riff_parser: chunk id offset %08x is 0x%08x '" GST_FOURCC_FORMAT "' and is 0x%08x long",
- riff->nextlikely, chunk->id, GST_FOURCC_ARGS(chunk->id),
- chunk->size);
-
- riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */
- /* if this buffer is incomplete */
- if (riff->nextlikely > last) {
- guint left = size - (riff->nextlikely - chunk->size - off);
-
- GST_DEBUG ("make incomplete buffer %08x", left);
- chunk->data = g_malloc(chunk->size);
- memcpy(chunk->data, (gchar *)(words+2), left);
- riff->incomplete_chunk = chunk;
- riff->incomplete_chunk_size = left;
- }
- else {
- /* send the buffer to the listener if we have received a function */
- if (riff->new_tag_found) {
- riff->new_tag_found(chunk, riff->callback_data);
- }
- g_free(chunk);
- }
- if (riff->nextlikely & 0x01) riff->nextlikely++;
-
- /*riff->chunks = g_list_prepend(riff->chunks,chunk);*/
- }
- }
- if ((riff->nextlikely+12) > last && !riff->incomplete_chunk) {
- guint left = last - riff->nextlikely;
- GST_DEBUG ("gst_riff_parser: not enough data next 0x%08x last 0x%08lx %08x %08lx",riff->nextlikely,
- last, left, off);
-
- riff->dataleft = g_malloc(left);
- riff->dataleft_size = left;
- memcpy(riff->dataleft, GST_BUFFER_DATA(buf)+size-left, left);
-
- return 0;
- }
-
- return 0;
-}
-
-void
-gst_riff_parser_resync (GstRiff *riff, gulong offset)
-{
- riff->incomplete_chunk = NULL;
- riff->dataleft = NULL;
- riff->nextlikely = offset;
-}
-
-
-GstRiffChunk *gst_riff_parser_get_chunk(GstRiff *riff, guint32 fourcc)
-{
- GList *chunk;
-
- g_return_val_if_fail(riff != NULL, NULL);
-
- chunk = riff->chunks;
- while (chunk) {
- if (((GstRiffChunk *)(chunk->data))->id == fourcc)
- return (GstRiffChunk *)(chunk->data);
- chunk = g_list_next(chunk);
- }
-
- return NULL;
-}
-
-guint32 gst_riff_parser_get_nextlikely(GstRiff *riff)
-{
- g_return_val_if_fail(riff != NULL, 0);
-
- return riff->nextlikely;
-}
-
diff --git a/gst-libs/gst/tag/Makefile.am b/gst-libs/gst/tag/Makefile.am
new file mode 100644
index 000000000..002d6ffbf
--- /dev/null
+++ b/gst-libs/gst/tag/Makefile.am
@@ -0,0 +1,5 @@
+libgsttagincludedir = \
+ $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/tag
+
+libgsttaginclude_HEADERS = \
+ tag.h
diff --git a/gst-libs/gst/tag/tag.h b/gst-libs/gst/tag/tag.h
new file mode 100644
index 000000000..97eaf9361
--- /dev/null
+++ b/gst-libs/gst/tag/tag.h
@@ -0,0 +1,62 @@
+/* GStreamer
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_TAG_TAG_H__
+#define __GST_TAG_TAG_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+
+/* functions for vorbis comment manipulation */
+
+G_CONST_RETURN gchar * gst_tag_from_vorbis_tag (const gchar * vorbis_tag);
+G_CONST_RETURN gchar * gst_tag_to_vorbis_tag (const gchar * gst_tag);
+void gst_vorbis_tag_add (GstTagList * list,
+ const gchar * tag,
+ const gchar * value);
+
+GList * gst_tag_to_vorbis_comments (const GstTagList * list,
+ const gchar * tag);
+
+/* functions to convert GstBuffers with vorbiscomment contents to GstTagLists and back */
+GstTagList * gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer,
+ const guint8 * id_data,
+ const guint id_data_length,
+ gchar ** vendor_string);
+GstBuffer * gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list,
+ const guint8 * id_data,
+ const guint id_data_length,
+ const gchar * vendor_string);
+
+/* functions for ID3 tag manipulation */
+
+guint gst_tag_id3_genre_count (void);
+G_CONST_RETURN gchar * gst_tag_id3_genre_get (const guint id);
+GstTagList * gst_tag_list_new_from_id3v1 (const guint8 * data);
+
+G_CONST_RETURN gchar * gst_tag_from_id3_tag (const gchar * vorbis_tag);
+G_CONST_RETURN gchar * gst_tag_to_id3_tag (const gchar * gst_tag);
+
+
+G_END_DECLS
+
+#endif /* __GST_TAG_TAG_H__ */
diff --git a/gst-libs/gst/tuner/Makefile.am b/gst-libs/gst/tuner/Makefile.am
index 6d14130d9..f25ab297b 100644
--- a/gst-libs/gst/tuner/Makefile.am
+++ b/gst-libs/gst/tuner/Makefile.am
@@ -11,6 +11,25 @@ noinst_LTLIBRARIES = libgsttuner.la
libgsttuner_la_SOURCES = \
tuner.c \
tunernorm.c \
- tunerchannel.c
+ tunerchannel.c \
+ tunermarshal.c
libgsttuner_la_CFLAGS = $(GST_CFLAGS)
+BUILT_SOURCES = \
+ tunermarshal.c \
+ tunermarshal.h
+built_headers = \
+ tunermarshal.h
+
+EXTRA_DIST = tunermarshal.list
+
+CLEANFILES = $(BUILT_SOURCES)
+
+tunermarshal.h: tunermarshal.list
+ glib-genmarshal --header --prefix=gst_tuner_marshal $^ > tunermarshal.h.tmp
+ mv tunermarshal.h.tmp tunermarshal.h
+
+tunermarshal.c: tunermarshal.list
+ echo "#include \"tunermarshal.h\"" >> tunermarshal.c.tmp
+ glib-genmarshal --body --prefix=gst_tuner_marshal $^ >> tunermarshal.c.tmp
+ mv tunermarshal.c.tmp tunermarshal.c
diff --git a/gst-libs/gst/tuner/tuner.c b/gst-libs/gst/tuner/tuner.c
index 43dda8d0e..24c4aa032 100644
--- a/gst-libs/gst/tuner/tuner.c
+++ b/gst-libs/gst/tuner/tuner.c
@@ -24,9 +24,20 @@
#endif
#include "tuner.h"
+#include "tunermarshal.h"
+
+enum {
+ NORM_CHANGED,
+ CHANNEL_CHANGED,
+ FREQUENCY_CHANGED,
+ SIGNAL_CHANGED,
+ LAST_SIGNAL
+};
static void gst_tuner_class_init (GstTunerClass *klass);
+static guint gst_tuner_signals[LAST_SIGNAL] = { 0 };
+
GType
gst_tuner_get_type (void)
{
@@ -49,7 +60,7 @@ gst_tuner_get_type (void)
"GstTuner",
&gst_tuner_info, 0);
g_type_interface_add_prerequisite (gst_tuner_type,
- GST_TYPE_INTERFACE);
+ GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_tuner_type;
@@ -58,6 +69,41 @@ gst_tuner_get_type (void)
static void
gst_tuner_class_init (GstTunerClass *klass)
{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ gst_tuner_signals[NORM_CHANGED] =
+ g_signal_new ("norm_changed",
+ GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstTunerClass, norm_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GST_TYPE_TUNER_NORM);
+ gst_tuner_signals[CHANNEL_CHANGED] =
+ g_signal_new ("channel_changed",
+ GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstTunerClass, channel_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GST_TYPE_TUNER_CHANNEL);
+ gst_tuner_signals[NORM_CHANGED] =
+ g_signal_new ("frequency_changed",
+ GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstTunerClass, frequency_changed),
+ NULL, NULL,
+ gst_tuner_marshal_VOID__OBJECT_ULONG, G_TYPE_NONE, 2,
+ GST_TYPE_TUNER_CHANNEL, G_TYPE_ULONG);
+ gst_tuner_signals[NORM_CHANGED] =
+ g_signal_new ("signal_changed",
+ GST_TYPE_TUNER, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GstTunerClass, signal_changed),
+ NULL, NULL,
+ gst_tuner_marshal_VOID__OBJECT_INT, G_TYPE_NONE, 2,
+ GST_TYPE_TUNER_CHANNEL, G_TYPE_INT);
+
+ initialized = TRUE;
+ }
+
/* default virtual functions */
klass->list_channels = NULL;
klass->set_channel = NULL;
@@ -188,3 +234,49 @@ gst_tuner_signal_strength (GstTuner *tuner,
return 0;
}
+
+void
+gst_tuner_channel_changed (GstTuner *tuner,
+ GstTunerChannel *channel)
+{
+ g_signal_emit (G_OBJECT (tuner),
+ gst_tuner_signals[CHANNEL_CHANGED], 0,
+ channel);
+}
+
+void
+gst_tuner_norm_changed (GstTuner *tuner,
+ GstTunerNorm *norm)
+{
+ g_signal_emit (G_OBJECT (tuner),
+ gst_tuner_signals[NORM_CHANGED], 0,
+ norm);
+}
+
+void
+gst_tuner_frequency_changed (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gulong frequency)
+{
+ g_signal_emit (G_OBJECT (tuner),
+ gst_tuner_signals[FREQUENCY_CHANGED], 0,
+ channel, frequency);
+
+ g_signal_emit_by_name (G_OBJECT (channel),
+ "frequency_changed",
+ frequency);
+}
+
+void
+gst_tuner_signal_changed (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gint signal)
+{
+ g_signal_emit (G_OBJECT (tuner),
+ gst_tuner_signals[SIGNAL_CHANGED], 0,
+ channel, signal);
+
+ g_signal_emit_by_name (G_OBJECT (channel),
+ "signal_changed",
+ signal);
+}
diff --git a/gst-libs/gst/tuner/tuner.h b/gst-libs/gst/tuner/tuner.h
index 1cd51e111..b1991c2c3 100644
--- a/gst-libs/gst/tuner/tuner.h
+++ b/gst-libs/gst/tuner/tuner.h
@@ -31,11 +31,11 @@ G_BEGIN_DECLS
#define GST_TYPE_TUNER \
(gst_tuner_get_type ())
#define GST_TUNER(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER, GstTuner))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER, GstTuner))
#define GST_TUNER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER, GstTunerClass))
#define GST_IS_TUNER(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER))
#define GST_IS_TUNER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER))
#define GST_TUNER_GET_CLASS(inst) \
@@ -66,6 +66,20 @@ typedef struct _GstTunerClass {
GstTunerChannel *channel);
gint (* signal_strength) (GstTuner *tuner,
GstTunerChannel *channel);
+
+ /* signals */
+ void (*channel_changed) (GstTuner *tuner,
+ GstTunerChannel *channel);
+ void (*norm_changed) (GstTuner *tuner,
+ GstTunerNorm *norm);
+ void (*frequency_changed) (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gulong frequency);
+ void (*signal_changed) (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gint signal);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstTunerClass;
GType gst_tuner_get_type (void);
@@ -91,6 +105,18 @@ gulong gst_tuner_get_frequency (GstTuner *tuner,
gint gst_tuner_signal_strength (GstTuner *tuner,
GstTunerChannel *channel);
+/* trigger signals */
+void gst_tuner_channel_changed (GstTuner *tuner,
+ GstTunerChannel *channel);
+void gst_tuner_norm_changed (GstTuner *tuner,
+ GstTunerNorm *norm);
+void gst_tuner_frequency_changed (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gulong frequency);
+void gst_tuner_signal_changed (GstTuner *tuner,
+ GstTunerChannel *channel,
+ gint signal);
+
G_END_DECLS
#endif /* __GST_TUNER_H__ */
diff --git a/gst-libs/gst/tuner/tunerchannel.h b/gst-libs/gst/tuner/tunerchannel.h
index b80314550..ee5654d0f 100644
--- a/gst-libs/gst/tuner/tunerchannel.h
+++ b/gst-libs/gst/tuner/tunerchannel.h
@@ -64,10 +64,12 @@ typedef struct _GstTunerChannelClass {
GObjectClass parent;
/* signals */
- void (*frequency_changed) (GstTunerChannel *tuner,
+ void (*frequency_changed) (GstTunerChannel *channel,
gulong frequency);
- void (*signal_changed) (GstTunerChannel *tuner,
+ void (*signal_changed) (GstTunerChannel *channel,
gint signal);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstTunerChannelClass;
GType gst_tuner_channel_get_type (void);
diff --git a/gst-libs/gst/tuner/tunermarshal.list b/gst-libs/gst/tuner/tunermarshal.list
new file mode 100644
index 000000000..c99ddc7d2
--- /dev/null
+++ b/gst-libs/gst/tuner/tunermarshal.list
@@ -0,0 +1,2 @@
+VOID:OBJECT,ULONG
+VOID:OBJECT,INT
diff --git a/gst-libs/gst/tuner/tunernorm.h b/gst-libs/gst/tuner/tunernorm.h
index 3e6e801d7..cd89e1ee8 100644
--- a/gst-libs/gst/tuner/tunernorm.h
+++ b/gst-libs/gst/tuner/tunernorm.h
@@ -46,6 +46,8 @@ typedef struct _GstTunerNorm {
typedef struct _GstTunerNormClass {
GObjectClass parent;
+
+ gpointer _gst_reserved[GST_PADDING];
} GstTunerNormClass;
GType gst_tuner_norm_get_type (void);
diff --git a/gst-libs/gst/video/gstvideosink.h b/gst-libs/gst/video/gstvideosink.h
index 5e829b177..6ba23fd43 100644
--- a/gst-libs/gst/video/gstvideosink.h
+++ b/gst-libs/gst/video/gstvideosink.h
@@ -56,7 +56,7 @@ struct _GstVideoSink {
GstClock *clock;
- GST_OBJECT_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstVideoSinkClass {
@@ -65,7 +65,7 @@ struct _GstVideoSinkClass {
/* signals */
void (*have_video_size) (GstVideoSink *element, gint width, gint height);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
GType gst_videosink_get_type (void);
diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
index abcf9bc65..2fc54003a 100644
--- a/gst-libs/gst/video/video.c
+++ b/gst-libs/gst/video/video.c
@@ -113,7 +113,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/gst-libs/gst/video/videosink.h b/gst-libs/gst/video/videosink.h
index 5e829b177..6ba23fd43 100644
--- a/gst-libs/gst/video/videosink.h
+++ b/gst-libs/gst/video/videosink.h
@@ -56,7 +56,7 @@ struct _GstVideoSink {
GstClock *clock;
- GST_OBJECT_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstVideoSinkClass {
@@ -65,7 +65,7 @@ struct _GstVideoSinkClass {
/* signals */
void (*have_video_size) (GstVideoSink *element, gint width, gint height);
- GST_CLASS_PADDING
+ gpointer _gst_reserved[GST_PADDING];
};
GType gst_videosink_get_type (void);
diff --git a/gst-libs/gst/xoverlay/xoverlay.c b/gst-libs/gst/xoverlay/xoverlay.c
index b4c737ff8..390453c15 100644
--- a/gst-libs/gst/xoverlay/xoverlay.c
+++ b/gst-libs/gst/xoverlay/xoverlay.c
@@ -56,7 +56,7 @@ gst_x_overlay_get_type (void)
"GstXOverlay",
&gst_x_overlay_info, 0);
g_type_interface_add_prerequisite (gst_x_overlay_type,
- GST_TYPE_INTERFACE);
+ GST_TYPE_IMPLEMENTS_INTERFACE);
}
return gst_x_overlay_type;
@@ -65,6 +65,7 @@ gst_x_overlay_get_type (void)
static void
gst_x_overlay_base_init (gpointer g_class)
{
+ GstXOverlayClass *overlay_class = (GstXOverlayClass *) g_class;
static gboolean initialized = FALSE;
if (! initialized)
@@ -79,6 +80,8 @@ gst_x_overlay_base_init (gpointer g_class)
initialized = TRUE;
}
+
+ overlay_class->set_xwindow_id = NULL;
}
/**
diff --git a/gst-libs/gst/xoverlay/xoverlay.h b/gst-libs/gst/xoverlay/xoverlay.h
index 65ac1dc78..062fadf4e 100644
--- a/gst-libs/gst/xoverlay/xoverlay.h
+++ b/gst-libs/gst/xoverlay/xoverlay.h
@@ -31,11 +31,12 @@ G_BEGIN_DECLS
#define GST_TYPE_X_OVERLAY \
(gst_x_overlay_get_type ())
#define GST_X_OVERLAY(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_X_OVERLAY, GstXOverlay))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_X_OVERLAY, \
+ GstXOverlay))
#define GST_X_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_X_OVERLAY, GstXOverlayClass))
#define GST_IS_X_OVERLAY(obj) \
- (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_X_OVERLAY))
+ (GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_X_OVERLAY))
#define GST_IS_X_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_X_OVERLAY))
#define GST_X_OVERLAY_GET_CLASS(inst) \
@@ -53,6 +54,8 @@ typedef struct _GstXOverlayClass {
/* signals */
void (*have_xwindow_id) (GstXOverlay *overlay,
XID xwindow_id);
+
+ gpointer _gst_reserved[GST_PADDING];
} GstXOverlayClass;
GType gst_x_overlay_get_type (void);
diff --git a/gst-libs/gst/xwindowlistener/xwindowlistener.c b/gst-libs/gst/xwindowlistener/xwindowlistener.c
index dda220c0e..a2b769941 100644
--- a/gst-libs/gst/xwindowlistener/xwindowlistener.c
+++ b/gst-libs/gst/xwindowlistener/xwindowlistener.c
@@ -650,7 +650,6 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
GST_LICENSE,
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN
)
diff --git a/gst/smoothwave/gstsmoothwave.c b/gst/smoothwave/gstsmoothwave.c
index a113bc539..57c267e51 100644
--- a/gst/smoothwave/gstsmoothwave.c
+++ b/gst/smoothwave/gstsmoothwave.c
@@ -310,6 +310,5 @@ GST_PLUGIN_DEFINE (
plugin_init,
VERSION,
"LGPL",
- GST_COPYRIGHT,
GST_PACKAGE,
GST_ORIGIN)