diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | configure.ac | 17 | ||||
-rw-r--r-- | docs/plugins/Makefile.am | 3 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-docs.sgml | 2 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-sections.txt | 9 | ||||
-rw-r--r-- | docs/plugins/inspect/plugin-taglib.xml | 20 | ||||
-rw-r--r-- | ext/Makefile.am | 8 | ||||
-rw-r--r-- | ext/taglib/Makefile.am | 16 | ||||
-rw-r--r-- | ext/taglib/gstid3v2mux.cc | 364 | ||||
-rw-r--r-- | ext/taglib/gstid3v2mux.h | 54 | ||||
-rw-r--r-- | ext/taglib/gsttaglib.cc | 390 | ||||
-rw-r--r-- | ext/taglib/gsttaglib.h | 69 | ||||
-rw-r--r-- | tests/check/Makefile.am | 9 | ||||
-rw-r--r-- | tests/check/elements/tagid3v2mux.c | 426 |
14 files changed, 19 insertions, 1385 deletions
@@ -1,3 +1,20 @@ +2006-05-01 Thomas Vander Stichele <thomas at apestaart dot org> + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/inspect/plugin-taglib.xml: + * ext/Makefile.am: + * ext/taglib/Makefile.am: + * ext/taglib/gstid3v2mux.cc: + * ext/taglib/gstid3v2mux.h: + * ext/taglib/gsttaglib.cc: + * ext/taglib/gsttaglib.h: + * tests/check/Makefile.am: + * tests/check/elements/tagid3v2mux.c: + moved to good. Closes #336110 + 2006-04-30 Thomas Vander Stichele <thomas at apestaart dot org> * docs/plugins/Makefile.am: diff --git a/configure.ac b/configure.ac index f5343663..ff6704b4 100644 --- a/configure.ac +++ b/configure.ac @@ -523,22 +523,6 @@ GST_CHECK_FEATURE(SWFDEC, [swfdec plug-in], swfdec, [ AC_SUBST(SWFDEC_LIBS) ]) - -dnl *** taglib *** -translit(dnm, m, l) AM_CONDITIONAL(USE_TAGLIB, true) -GST_CHECK_FEATURE(TAGLIB, [taglib ID3v2 tag writer], taglib, [ - PKG_CHECK_MODULES(TAGLIB, taglib >= 1.4, HAVE_TAGLIB="yes", [ - HAVE_TAGLIB="no" - AC_MSG_RESULT(no) - ]) - AC_SUBST(TAGLIB_CFLAGS) - AC_SUBST(TAGLIB_LIBS) - if test "x$HAVE_CXX" != "xyes"; then - USE_TAGLIB=false - AC_MSG_NOTICE([Not building taglib plugin: no C++ compiler found]) - fi -]) - dnl *** theora *** translit(dnm, m, l) AM_CONDITIONAL(USE_THEORADEC, true) GST_CHECK_FEATURE(THEORADEC, [ogg theora codec], theoraexpdec, [ @@ -668,7 +652,6 @@ ext/neon/Makefile ext/sdl/Makefile ext/soundtouch/Makefile ext/swfdec/Makefile -ext/taglib/Makefile ext/theora/Makefile ext/wavpack/Makefile ext/xvid/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 6c6b4c51..0ccb0ff6 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -86,8 +86,7 @@ EXAMPLE_CFILES = \ $(top_srcdir)/ext/directfb/dfb-example.c EXTRA_HFILES = \ - $(top_srcdir)/ext/directfb/dfbvideosink.h \ - $(top_srcdir)/ext/taglib/gsttaglib.h + $(top_srcdir)/ext/directfb/dfbvideosink.h # Images to copy into HTML directory. HTML_IMAGES = diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index 06115c72..22cddda3 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -14,7 +14,6 @@ <title>gst-plugins-bad Elements</title> <xi:include href="xml/element-dfbvideosink.xml" /> - <xi:include href="xml/element-id3v2mux.xml" /> </chapter> <chapter> @@ -33,7 +32,6 @@ <xi:include href="xml/plugin-sdlvideosink.xml" /> <xi:include href="xml/plugin-sdl.xml" /> <xi:include href="xml/plugin-speed.xml" /> - <xi:include href="xml/plugin-taglib.xml" /> <xi:include href="xml/plugin-tta.xml" /> <xi:include href="xml/plugin-video4linux2.xml" /> <xi:include href="xml/plugin-xingheader.xml" /> diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index 23cd0f51..8510d4b0 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -5,12 +5,3 @@ GstDfbVideoSink <SUBSECTION Standard> GstDfbVideoSinkClass </SECTION> - -<SECTION> -<FILE>element-id3v2mux</FILE> -GstId3v2Mux -<TITLE>id3v2mux</TITLE> -<SUBSECTION Standard> -GstId3v2MuxClass -</SECTION> - diff --git a/docs/plugins/inspect/plugin-taglib.xml b/docs/plugins/inspect/plugin-taglib.xml deleted file mode 100644 index 3e000415..00000000 --- a/docs/plugins/inspect/plugin-taglib.xml +++ /dev/null @@ -1,20 +0,0 @@ -<plugin> - <name>taglib</name> - <description>Tag-writing plug-in based on taglib</description> - <filename>../../ext/taglib/.libs/libgsttaglib.so</filename> - <basename>libgsttaglib.so</basename> - <version>0.10.2.1</version> - <license>LGPL</license> - <source>gst-plugins-bad</source> - <package>GStreamer Bad Plug-ins CVS/prerelease</package> - <origin>Unknown package origin</origin> - <elements> - <element> - <name>id3v2mux</name> - <longname>TagLib ID3v2 Muxer</longname> - <class>Formatter/Metadata</class> - <description>Adds an ID3v2 header to the beginning of MP3 files using taglib</description> - <author>Christophe Fergeau <teuf@gnome.org></author> - </element> - </elements> -</plugin>
\ No newline at end of file diff --git a/ext/Makefile.am b/ext/Makefile.am index 561874b5..c28a13aa 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -202,12 +202,6 @@ else SWFDEC_DIR= endif -if USE_TAGLIB -TAGLIB_DIR = taglib -else -TAGLIB_DIR = -endif - if USE_THEORADEC THEORA_DIR = theora else @@ -267,7 +261,6 @@ SUBDIRS=\ $(SNDFILE_DIR) \ $(SOUNDTOUCH_DIR) \ $(SWFDEC_DIR) \ - $(TAGLIB_DIR) \ $(TARKIN_DIR) \ $(THEORA_DIR) \ $(WAVPACK_DIR) \ @@ -290,7 +283,6 @@ DIST_SUBDIRS= \ sdl \ swfdec \ soundtouch \ - taglib \ theora \ wavpack \ xvid diff --git a/ext/taglib/Makefile.am b/ext/taglib/Makefile.am deleted file mode 100644 index 0b608f3d..00000000 --- a/ext/taglib/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -plugin_LTLIBRARIES = libgsttaglib.la - -libgsttaglib_la_SOURCES = gsttaglib.cc gstid3v2mux.cc -libgsttaglib_la_CXXFLAGS = \ - $(GST_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) \ - $(TAGLIB_CFLAGS) -libgsttaglib_la_LIBADD = \ - $(GST_LIBS) \ - $(GST_PLUGINS_BASE_LIBS) -lgsttag-@GST_MAJORMINOR@ \ - $(TAGLIB_LIBS) -libgsttaglib_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = gsttaglib.h gstid3v2mux.h - -#EXTRA_DIST = README diff --git a/ext/taglib/gstid3v2mux.cc b/ext/taglib/gstid3v2mux.cc deleted file mode 100644 index a1e4537e..00000000 --- a/ext/taglib/gstid3v2mux.cc +++ /dev/null @@ -1,364 +0,0 @@ -/* GStreamer taglib-based ID3v2 muxer - * Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org> - * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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. - */ - -/** - * SECTION:element-id3v2mux - * @see_also: #GstID3Demux, #GstTagSetter - * - * <refsect2> - * <para> - * This element adds ID3v2 tags to the beginning of a stream using the taglib - * library. More precisely, the tags written are ID3 version 2.4.0 tags (which - * means in practice that some hardware players or outdated programs might not - * be able to read them properly). - * </para> - * <para> - * Applications can set the tags to write using the #GstTagSetter interface. - * Tags sent by upstream elements will be picked up automatically (and merged - * according to the merge mode set via the tag setter interface). - * </para> - * <para> - * Here is a simple pipeline that transcodes a file from Ogg/Vorbis to mp3 - * format with an ID3v2 that contains the same as the the Ogg/Vorbis file: - * <programlisting> - * gst-launch -v filesrc location=foo.ogg ! decodebin ! audioconvert ! lame ! id3v2mux ! filesink location=foo.mp3 - * </programlisting> - * Make sure the Ogg/Vorbis file actually has comments to preserve. - * You can verify the tags were written using: - * <programlisting> - * gst-launch -m filesrc location=foo.mp3 ! id3demux ! fakesink silent=TRUE 2> /dev/null | grep taglist - * </programlisting> - * </para> - * </refsect2> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "gstid3v2mux.h" - -#include <string.h> - -#include <textidentificationframe.h> -#include <uniquefileidentifierframe.h> -#include <id3v2tag.h> -#include <gst/tag/tag.h> - -using namespace TagLib; - -GST_DEBUG_CATEGORY_STATIC (gst_id3v2_mux_debug); -#define GST_CAT_DEFAULT gst_id3v2_mux_debug - -static const GstElementDetails gst_id3v2_mux_details = -GST_ELEMENT_DETAILS ("TagLib-based ID3v2 Muxer", - "Formatter/Metadata", - "Adds an ID3v2 header to the beginning of MP3 files using taglib", - "Christophe Fergeau <teuf@gnome.org>"); - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-id3")); - - -GST_BOILERPLATE (GstId3v2Mux, gst_id3v2_mux, GstTagLibMux, - GST_TYPE_TAG_LIB_MUX); - -static GstBuffer *gst_id3v2_mux_render_tag (GstTagLibMux * mux, - GstTagList * taglist); - -static void -gst_id3v2_mux_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); - - gst_element_class_set_details (element_class, &gst_id3v2_mux_details); - - GST_DEBUG_CATEGORY_INIT (gst_id3v2_mux_debug, "id3v2mux", 0, - "taglib-based ID3v2 tag muxer"); -} - -static void -gst_id3v2_mux_class_init (GstId3v2MuxClass * klass) -{ - GST_TAG_LIB_MUX_CLASS (klass)->render_tag = - GST_DEBUG_FUNCPTR (gst_id3v2_mux_render_tag); -} - -static void -gst_id3v2_mux_init (GstId3v2Mux * id3v2mux, GstId3v2MuxClass * id3v2mux_class) -{ - /* nothing to do */ -} - -static void -add_one_txxx_musicbrainz_tag (ID3v2::Tag * id3v2tag, const gchar * spec_id, - const gchar * realworld_id, const gchar * id_str) -{ - ID3v2::UserTextIdentificationFrame * frame; - - if (id_str == NULL) - return; - - GST_DEBUG ("Setting %s to %s", GST_STR_NULL (spec_id), id_str); - - if (spec_id) { - frame = new ID3v2::UserTextIdentificationFrame (String::Latin1); - id3v2tag->addFrame (frame); - frame->setDescription (spec_id); - frame->setText (id_str); - } - - if (realworld_id) { - frame = new ID3v2::UserTextIdentificationFrame (String::Latin1); - id3v2tag->addFrame (frame); - frame->setDescription (realworld_id); - frame->setText (id_str); - } -} - -static void -add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) -{ - ID3v2::Tag * id3v2tag = (ID3v2::Tag *) user_data; - gboolean result; - - /* FIXME: if there are several values set for the same tag, this won't - * work, only the first value will be taken into account - */ - if (strcmp (tag, GST_TAG_TITLE) == 0) { - char *title; - - result = gst_tag_list_get_string_index (list, tag, 0, &title); - if (result != FALSE) { - GST_DEBUG ("Setting title to %s", title); - id3v2tag->setTitle (String::String (title, String::UTF8)); - } - g_free (title); - } else if (strcmp (tag, GST_TAG_ALBUM) == 0) { - char *album; - - result = gst_tag_list_get_string_index (list, tag, 0, &album); - if (result != FALSE) { - GST_DEBUG ("Setting album to %s", album); - id3v2tag->setAlbum (String::String (album, String::UTF8)); - } - g_free (album); - } else if (strcmp (tag, GST_TAG_ARTIST) == 0) { - char *artist; - - result = gst_tag_list_get_string_index (list, tag, 0, &artist); - if (result != FALSE) { - GST_DEBUG ("Setting artist to %s", artist); - id3v2tag->setArtist (String::String (artist, String::UTF8)); - } - g_free (artist); - } else if (strcmp (tag, GST_TAG_GENRE) == 0) { - char *genre; - - result = gst_tag_list_get_string_index (list, tag, 0, &genre); - if (result != FALSE) { - GST_DEBUG ("Setting genre to %s", genre); - id3v2tag->setGenre (String::String (genre, String::UTF8)); - } - g_free (genre); - } else if (strcmp (tag, GST_TAG_COMMENT) == 0) { - char *comment; - - result = gst_tag_list_get_string_index (list, tag, 0, &comment); - if (result != FALSE) { - GST_DEBUG ("Setting comment to %s", comment); - id3v2tag->setComment (String::String (comment, String::UTF8)); - } - g_free (comment); - } else if (strcmp (tag, GST_TAG_DATE) == 0) { - GDate *date; - - result = gst_tag_list_get_date_index (list, tag, 0, &date); - if (result != FALSE) { - GDateYear year; - - year = g_date_get_year (date); - GST_DEBUG ("Setting track year to %d", year); - id3v2tag->setYear (year); - g_date_free (date); - } - } else if (strcmp (tag, GST_TAG_TRACK_NUMBER) == 0) { - guint track_number; - - result = gst_tag_list_get_uint_index (list, tag, 0, &track_number); - if (result != FALSE) { - guint total_tracks; - - result = gst_tag_list_get_uint_index (list, GST_TAG_TRACK_COUNT, - 0, &total_tracks); - if (result) { - gchar *tag_str; - - ID3v2::TextIdentificationFrame * frame; - - frame = new ID3v2::TextIdentificationFrame ("TRCK", String::UTF8); - tag_str = g_strdup_printf ("%d/%d", track_number, total_tracks); - GST_DEBUG ("Setting track number to %s", tag_str); - id3v2tag->addFrame (frame); - frame->setText (tag_str); - g_free (tag_str); - } else { - GST_DEBUG ("Setting track number to %d", track_number); - id3v2tag->setTrack (track_number); - } - } - } else if (strcmp (tag, GST_TAG_ALBUM_VOLUME_NUMBER) == 0) { - guint volume_number; - - result = gst_tag_list_get_uint_index (list, tag, 0, &volume_number); - - if (result != FALSE) { - guint volume_count; - gchar *tag_str; - - ID3v2::TextIdentificationFrame * frame; - - frame = new ID3v2::TextIdentificationFrame ("TPOS", String::UTF8); - result = gst_tag_list_get_uint_index (list, GST_TAG_ALBUM_VOLUME_COUNT, - 0, &volume_count); - if (result) { - tag_str = g_strdup_printf ("%d/%d", volume_number, volume_count); - } else { - tag_str = g_strdup_printf ("%d", volume_number); - } - - GST_DEBUG ("Setting album number to %s", tag_str); - - id3v2tag->addFrame (frame); - frame->setText (tag_str); - g_free (tag_str); - } - } else if (strcmp (tag, GST_TAG_COPYRIGHT) == 0) { - gchar *copyright; - - result = gst_tag_list_get_string_index (list, tag, 0, ©right); - - if (result != FALSE) { - ID3v2::TextIdentificationFrame * frame; - - GST_DEBUG ("Setting copyright to %s", copyright); - - frame = new ID3v2::TextIdentificationFrame ("TCOP", String::UTF8); - - id3v2tag->addFrame (frame); - frame->setText (copyright); - g_free (copyright); - } - } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ARTISTID) == 0) { - gchar *id_str; - - if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) { - add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Artist Id", - "musicbrainz_artistid", id_str); - g_free (id_str); - } - } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ALBUMID) == 0) { - gchar *id_str; - - if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) { - add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Album Id", - "musicbrainz_albumid", id_str); - g_free (id_str); - } - } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_ALBUMARTISTID) == 0) { - gchar *id_str; - - if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) { - add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz Album Artist Id", - "musicbrainz_albumartistid", id_str); - g_free (id_str); - } - } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_TRMID) == 0) { - gchar *id_str; - - if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) { - add_one_txxx_musicbrainz_tag (id3v2tag, "MusicBrainz TRM Id", - "musicbrainz_trmid", id_str); - g_free (id_str); - } - } else if (strcmp (tag, GST_TAG_MUSICBRAINZ_TRACKID) == 0) { - gchar *id_str; - - if (gst_tag_list_get_string_index (list, tag, 0, &id_str) && id_str) { - ID3v2::UniqueFileIdentifierFrame * frame; - - GST_DEBUG ("Setting Musicbrainz Track Id to %s", id_str); - - frame = new ID3v2::UniqueFileIdentifierFrame ("http://musicbrainz.org", - id_str); - id3v2tag->addFrame (frame); - g_free (id_str); - } - } else { - GST_WARNING ("Unsupported tag: %s", tag); - } -} - -static GstBuffer * -gst_id3v2_mux_render_tag (GstTagLibMux * mux, GstTagList * taglist) -{ - ID3v2::Tag id3v2tag; - ByteVector rendered_tag; - GstBuffer *buf; - guint tag_size; - - /* Render the tag */ - gst_tag_list_foreach (taglist, add_one_tag, &id3v2tag); - - rendered_tag = id3v2tag.render (); - tag_size = rendered_tag.size (); - - GST_LOG_OBJECT (mux, "tag size = %d bytes", tag_size); - - /* Create buffer with tag */ - buf = gst_buffer_new_and_alloc (tag_size); - memcpy (GST_BUFFER_DATA (buf), rendered_tag.data (), tag_size); - gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad)); - - return buf; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "id3v2mux", GST_RANK_NONE, - GST_TYPE_ID3V2_MUX)) - return FALSE; - - gst_tag_register_musicbrainz_tags (); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "taglib", - "Tag writing plug-in based on taglib", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/ext/taglib/gstid3v2mux.h b/ext/taglib/gstid3v2mux.h deleted file mode 100644 index 855b2296..00000000 --- a/ext/taglib/gstid3v2mux.h +++ /dev/null @@ -1,54 +0,0 @@ -/* GStreamer taglib-based ID3v2 muxer - * Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org> - * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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_ID3V2_MUX_H -#define GST_ID3V2_MUX_H - -#include "gsttaglib.h" - -G_BEGIN_DECLS - -typedef struct _GstId3v2Mux GstId3v2Mux; -typedef struct _GstId3v2MuxClass GstId3v2MuxClass; - -typedef struct _GstId3v2Mux { - GstTagLibMux taglibmux; -}; - -typedef struct _GstId3v2MuxClass { - GstTagLibMuxClass taglibmux_class; -}; - -#define GST_TYPE_ID3V2_MUX \ - (gst_id3v2_mux_get_type()) -#define GST_ID3V2_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ID3V2_MUX,GstId3v2Mux)) -#define GST_ID3V2_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ID3V2_MUX,GstId3v2MuxClass)) -#define GST_IS_ID3V2_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ID3V2_MUX)) -#define GST_IS_ID3V2_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ID3V2_MUX)) - -GType gst_id3v2_mux_get_type (void); - -G_END_DECLS - -#endif /* GST_ID3V2_MUX_H */ diff --git a/ext/taglib/gsttaglib.cc b/ext/taglib/gsttaglib.cc deleted file mode 100644 index 35ec89fe..00000000 --- a/ext/taglib/gsttaglib.cc +++ /dev/null @@ -1,390 +0,0 @@ -/* GStreamer taglib-based muxer base class - * Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org> - * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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 <gst/gsttagsetter.h> -#include <gst/tag/tag.h> -#include "gsttaglib.h" - -GST_DEBUG_CATEGORY_STATIC (gst_tag_lib_mux_debug); -#define GST_CAT_DEFAULT gst_tag_lib_mux_debug - -static GstStaticPadTemplate gst_tag_lib_mux_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("ANY")); - -static void -gst_tag_lib_mux_iface_init (GType taglib_type) -{ - static const GInterfaceInfo tag_setter_info = { - NULL, - NULL, - NULL - }; - - g_type_add_interface_static (taglib_type, GST_TYPE_TAG_SETTER, - &tag_setter_info); -} - -GST_BOILERPLATE_FULL (GstTagLibMux, gst_tag_lib_mux, - GstElement, GST_TYPE_ELEMENT, gst_tag_lib_mux_iface_init); - - -static GstStateChangeReturn -gst_tag_lib_mux_change_state (GstElement * element, GstStateChange transition); -static GstFlowReturn gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer); -static gboolean gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event); - -static void -gst_tag_lib_mux_finalize (GObject * obj) -{ - GstTagLibMux *mux = GST_TAG_LIB_MUX (obj); - - if (mux->newsegment_ev) { - gst_event_unref (mux->newsegment_ev); - mux->newsegment_ev = NULL; - } - - if (mux->event_tags) { - gst_tag_list_free (mux->event_tags); - mux->event_tags = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -gst_tag_lib_mux_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_tag_lib_mux_sink_template)); - - GST_DEBUG_CATEGORY_INIT (gst_tag_lib_mux_debug, "taglibmux", 0, - "taglib-based muxer"); -} - -static void -gst_tag_lib_mux_class_init (GstTagLibMuxClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_tag_lib_mux_finalize); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_tag_lib_mux_change_state); -} - -static void -gst_tag_lib_mux_init (GstTagLibMux * mux, GstTagLibMuxClass * mux_class) -{ - GstElementClass *element_klass = GST_ELEMENT_CLASS (mux_class); - GstPadTemplate *tmpl; - - /* pad through which data comes in to the element */ - mux->sinkpad = - gst_pad_new_from_static_template (&gst_tag_lib_mux_sink_template, "sink"); - gst_pad_set_chain_function (mux->sinkpad, - GST_DEBUG_FUNCPTR (gst_tag_lib_mux_chain)); - gst_pad_set_event_function (mux->sinkpad, - GST_DEBUG_FUNCPTR (gst_tag_lib_mux_sink_event)); - gst_element_add_pad (GST_ELEMENT (mux), mux->sinkpad); - - /* pad through which data goes out of the element */ - tmpl = gst_element_class_get_pad_template (element_klass, "src"); - if (tmpl) { - mux->srcpad = gst_pad_new_from_template (tmpl, "src"); - gst_pad_use_fixed_caps (mux->srcpad); - gst_pad_set_caps (mux->srcpad, gst_pad_template_get_caps (tmpl)); - gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad); - } - - mux->render_tag = TRUE; -} - -static GstBuffer * -gst_tag_lib_mux_render_tag (GstTagLibMux * mux) -{ - GstTagLibMuxClass *klass; - GstBuffer *buffer; - GstTagSetter *tagsetter = GST_TAG_SETTER (mux); - const GstTagList *tagsetter_tags; - GstTagList *taglist; - GstEvent *event; - - if (mux->event_tags != NULL) { - taglist = gst_tag_list_copy (mux->event_tags); - } else { - taglist = gst_tag_list_new (); - } - - tagsetter_tags = gst_tag_setter_get_tag_list (tagsetter); - if (tagsetter_tags) { - GstTagMergeMode merge_mode; - - merge_mode = gst_tag_setter_get_tag_merge_mode (tagsetter); - GST_LOG_OBJECT (mux, "merging tags, merge mode = %d", merge_mode); - GST_LOG_OBJECT (mux, "event tags: %" GST_PTR_FORMAT, taglist); - GST_LOG_OBJECT (mux, "set tags: %" GST_PTR_FORMAT, tagsetter_tags); - gst_tag_list_insert (taglist, tagsetter_tags, merge_mode); - } - - GST_LOG_OBJECT (mux, "final tags: %" GST_PTR_FORMAT, taglist); - - klass = GST_TAG_LIB_MUX_CLASS (G_OBJECT_GET_CLASS (mux)); - - if (klass->render_tag == NULL) - goto no_vfunc; - - buffer = klass->render_tag (mux, taglist); - - if (buffer == NULL) - goto render_error; - - mux->tag_size = GST_BUFFER_SIZE (buffer); - GST_LOG_OBJECT (mux, "tag size = %d bytes", mux->tag_size); - - /* Send newsegment event from byte position 0, so the tag really gets - * written to the start of the file, independent of the upstream segment */ - gst_pad_push_event (mux->srcpad, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)); - - /* Send an event about the new tags to downstream elements */ - /* gst_event_new_tag takes ownership of the list, so no need to unref it */ - event = gst_event_new_tag (taglist); - gst_pad_push_event (mux->srcpad, event); - - GST_BUFFER_OFFSET (buffer) = 0; - - return buffer; - -no_vfunc: - { - GST_ERROR_OBJECT (mux, "Subclass does not implement render_tag vfunc!"); - return NULL; - } - -render_error: - { - GST_ERROR_OBJECT (mux, "Failed to render tag"); - return NULL; - } -} - -static GstEvent * -gst_tag_lib_mux_adjust_event_offsets (GstTagLibMux * mux, - const GstEvent * newsegment_event) -{ - GstFormat format; - gint64 start, stop, cur; - - gst_event_parse_new_segment ((GstEvent *) newsegment_event, NULL, NULL, - &format, &start, &stop, &cur); - - g_assert (format == GST_FORMAT_BYTES); - - if (start != -1) - start += mux->tag_size; - if (stop != -1) - stop += mux->tag_size; - if (cur != -1) - cur += mux->tag_size; - - GST_DEBUG_OBJECT (mux, "adjusting newsegment event offsets to start=%" - G_GINT64_FORMAT ", stop=%" G_GINT64_FORMAT ", cur=%" G_GINT64_FORMAT - " (delta = +%u)", start, stop, cur, mux->tag_size); - - return gst_event_new_new_segment (TRUE, 1.0, format, start, stop, cur); -} - -static GstFlowReturn -gst_tag_lib_mux_chain (GstPad * pad, GstBuffer * buffer) -{ - GstTagLibMux *mux = GST_TAG_LIB_MUX (GST_OBJECT_PARENT (pad)); - - if (mux->render_tag) { - GstFlowReturn ret; - GstBuffer *tag_buffer; - - GST_INFO_OBJECT (mux, "Adding tags to stream"); - tag_buffer = gst_tag_lib_mux_render_tag (mux); - if (tag_buffer == NULL) - goto no_tag_buffer; - ret = gst_pad_push (mux->srcpad, tag_buffer); - if (ret != GST_FLOW_OK) { - GST_DEBUG_OBJECT (mux, "flow: %s", gst_flow_get_name (ret)); - gst_buffer_unref (buffer); - return ret; - } - - /* Now send the cached newsegment event that we got from upstream */ - if (mux->newsegment_ev) { - GST_DEBUG_OBJECT (mux, "sending cached newsegment event"); - gst_pad_push_event (mux->srcpad, - gst_tag_lib_mux_adjust_event_offsets (mux, mux->newsegment_ev)); - gst_event_unref (mux->newsegment_ev); - mux->newsegment_ev = NULL; - } else { - /* upstream sent no newsegment event or only one in a non-BYTE format */ - } - - mux->render_tag = FALSE; - } - - buffer = gst_buffer_make_metadata_writable (buffer); - - if (GST_BUFFER_OFFSET (buffer) != GST_BUFFER_OFFSET_NONE) { - GST_LOG_OBJECT (mux, "Adjusting buffer offset from %" G_GINT64_FORMAT - " to %" G_GINT64_FORMAT, GST_BUFFER_OFFSET (buffer), - GST_BUFFER_OFFSET (buffer) + mux->tag_size); - GST_BUFFER_OFFSET (buffer) += mux->tag_size; - } - - gst_buffer_set_caps (buffer, GST_PAD_CAPS (mux->srcpad)); - return gst_pad_push (mux->srcpad, buffer); - -/* ERRORS */ -no_tag_buffer: - { - GST_ELEMENT_ERROR (mux, LIBRARY, ENCODE, (NULL), (NULL)); - return GST_FLOW_ERROR; - } -} - -static gboolean -gst_tag_lib_mux_sink_event (GstPad * pad, GstEvent * event) -{ - GstTagLibMux *mux; - gboolean result; - - mux = GST_TAG_LIB_MUX (gst_pad_get_parent (pad)); - result = FALSE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_TAG:{ - GstTagList *tags; - - gst_event_parse_tag (event, &tags); - - GST_INFO_OBJECT (mux, "Got tag event: %" GST_PTR_FORMAT, tags); - - if (mux->event_tags != NULL) { - gst_tag_list_insert (mux->event_tags, tags, GST_TAG_MERGE_REPLACE); - } else { - mux->event_tags = gst_tag_list_copy (tags); - } - - GST_INFO_OBJECT (mux, "Event tags are now: %" GST_PTR_FORMAT, - mux->event_tags); - - /* just drop the event, we'll push a new tag event in render_tag */ - gst_event_unref (event); - result = TRUE; - break; - } - case GST_EVENT_NEWSEGMENT:{ - GstFormat fmt; - - gst_event_parse_new_segment (event, NULL, NULL, &fmt, NULL, NULL, NULL); - - if (fmt != GST_FORMAT_BYTES) { - GST_WARNING_OBJECT (mux, "dropping newsegment event in %s format", - gst_format_get_name (fmt)); - gst_event_unref (event); - break; - } - - if (mux->render_tag) { - /* we have not rendered the tag yet, which means that we don't know - * how large it is going to be yet, so we can't adjust the offsets - * here at this point and need to cache the newsegment event for now - * (also, there could be tag events coming after this newsegment event - * and before the first buffer). */ - if (mux->newsegment_ev) { - GST_WARNING_OBJECT (mux, "discarding old cached newsegment event"); - gst_event_unref (mux->newsegment_ev); - } - - GST_LOG_OBJECT (mux, "caching newsegment event for later"); - mux->newsegment_ev = event; - } else { - GST_DEBUG_OBJECT (mux, "got newsegment event, adjusting offsets"); - gst_pad_push_event (mux->srcpad, - gst_tag_lib_mux_adjust_event_offsets (mux, event)); - gst_event_unref (event); - } - event = NULL; - result = TRUE; - break; - } - default: - result = gst_pad_event_default (pad, event); - break; - } - - gst_object_unref (mux); - - return result; -} - - -static GstStateChangeReturn -gst_tag_lib_mux_change_state (GstElement * element, GstStateChange transition) -{ - GstTagLibMux *mux; - GstStateChangeReturn result; - - mux = GST_TAG_LIB_MUX (element); - - result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - if (result != GST_STATE_CHANGE_SUCCESS) { - return result; - } - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY:{ - if (mux->newsegment_ev) { - gst_event_unref (mux->newsegment_ev); - mux->newsegment_ev = NULL; - } - if (mux->event_tags) { - gst_tag_list_free (mux->event_tags); - mux->event_tags = NULL; - } - mux->tag_size = 0; - mux->render_tag = TRUE; - break; - } - default: - break; - } - - return result; -} diff --git a/ext/taglib/gsttaglib.h b/ext/taglib/gsttaglib.h deleted file mode 100644 index 5b91a93e..00000000 --- a/ext/taglib/gsttaglib.h +++ /dev/null @@ -1,69 +0,0 @@ -/* GStreamer taglib-based muxer base class - * Copyright (C) 2006 Christophe Fergeau <teuf@gnome.org> - * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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_TAG_LIB_H -#define GST_TAG_LIB_H - -#include <gst/gst.h> - -G_BEGIN_DECLS - -typedef struct _GstTagLibMux GstTagLibMux; -typedef struct _GstTagLibMuxClass GstTagLibMuxClass; - -/* Definition of structure storing data for this element. */ -typedef struct _GstTagLibMux { - GstElement element; - - GstPad *srcpad; - GstPad *sinkpad; - GstTagList *event_tags; /* tags received from upstream elements */ - gsize tag_size; - gboolean render_tag; - - GstEvent *newsegment_ev; /* cached newsegment event from upstream */ -}; - -/* Standard definition defining a class for this element. */ -typedef struct _GstTagLibMuxClass { - GstElementClass parent_class; - - /* vfuncs */ - GstBuffer * (*render_tag) (GstTagLibMux * mux, GstTagList * tag_list); -}; - -/* Standard macros for defining types for this element. */ -#define GST_TYPE_TAG_LIB_MUX \ - (gst_tag_lib_mux_get_type()) -#define GST_TAG_LIB_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TAG_LIB_MUX,GstTagLibMux)) -#define GST_TAG_LIB_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TAG_LIB_MUX,GstTagLibMuxClass)) -#define GST_IS_TAG_LIB_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TAG_LIB_MUX)) -#define GST_IS_TAG_LIB_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TAG_LIB_MUX)) - -/* Standard function returning type information. */ -GType gst_tag_lib_mux_get_type (void); - -G_END_DECLS - -#endif diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index ba7b0de6..c1663887 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -26,14 +26,7 @@ SUPPRESSIONS = $(top_srcdir)/common/gst.supp clean-local: clean-local-check - -if USE_TAGLIB -check_taglib = elements/tagid3v2mux -else -check_taglib = -endif - -check_PROGRAMS = $(check_taglib) +check_PROGRAMS = TESTS = $(check_PROGRAMS) diff --git a/tests/check/elements/tagid3v2mux.c b/tests/check/elements/tagid3v2mux.c deleted file mode 100644 index fe753d5c..00000000 --- a/tests/check/elements/tagid3v2mux.c +++ /dev/null @@ -1,426 +0,0 @@ -/* GStreamer - * - * unit test for the taglib-based id3v2mux element - * - * Copyright (C) 2006 Tim-Philipp Müller <tim centricular 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. - */ - -#include <gst/check/gstcheck.h> - -#include <gst/gst.h> -#include <string.h> - -#define TEST_ARTIST "Ar T\303\255st" -#define TEST_TITLE "M\303\274llermilch!" -#define TEST_ALBUM "Boom" -#define TEST_DATE g_date_new_dmy(1,1,2006) -#define TEST_TRACK_NUMBER 7 -#define TEST_TRACK_COUNT 19 -#define TEST_VOLUME_NUMBER 2 -#define TEST_VOLUME_COUNT 3 - -/* #define TEST_TRACK_GAIN 1.45 (not implemented yet) */ -/* #define TEST_ALBUM_GAIN 0.78 (not implemented yet) */ - -/* for dummy mp3 frame sized MP3_FRAME_SIZE bytes, - * start: ff fb b0 44 00 00 08 00 00 4b 00 00 00 00 00 00 */ -static const guint8 mp3_dummyhdr[] = { 0xff, 0xfb, 0xb0, 0x44, 0x00, 0x00, - 0x08, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 -}; - -#define MP3_FRAME_SIZE 626 - -static GstTagList * -test_taglib_id3mux_create_tags (guint32 mask) -{ - GstTagList *tags; - - tags = gst_tag_list_new (); - - if (mask & (1 << 0)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ARTIST, TEST_ARTIST, NULL); - } - if (mask & (1 << 1)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_TITLE, TEST_TITLE, NULL); - } - if (mask & (1 << 2)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ALBUM, TEST_ALBUM, NULL); - } - if (mask & (1 << 3)) { - GDate *date; - - date = TEST_DATE; - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, GST_TAG_DATE, date, NULL); - g_date_free (date); - } - if (mask & (1 << 4)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_TRACK_NUMBER, TEST_TRACK_NUMBER, NULL); - } - if (mask & (1 << 5)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_TRACK_COUNT, TEST_TRACK_COUNT, NULL); - } - if (mask & (1 << 6)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ALBUM_VOLUME_NUMBER, TEST_VOLUME_NUMBER, NULL); - } - if (mask & (1 << 7)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ALBUM_VOLUME_COUNT, TEST_VOLUME_COUNT, NULL); - } - if (mask & (1 << 8)) { - } - if (mask & (1 << 9)) { - } - if (mask & (1 << 10)) { - } - if (mask & (1 << 11)) { - } - if (mask & (1 << 12)) { - } - if (mask & (1 << 13)) { - } - return tags; -} - -static void -test_taglib_id3mux_check_tags (GstTagList * tags, guint32 mask) -{ - if (mask & (1 << 0)) { - gchar *s = NULL; - - fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &s)); - fail_unless (g_str_equal (s, TEST_ARTIST)); - g_free (s); - } - if (mask & (1 << 1)) { - gchar *s = NULL; - - fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s)); - fail_unless (g_str_equal (s, TEST_TITLE)); - g_free (s); - } - if (mask & (1 << 2)) { - gchar *s = NULL; - - fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &s)); - fail_unless (g_str_equal (s, TEST_ALBUM)); - g_free (s); - } - if (mask & (1 << 3)) { - GDate *shouldbe, *date = NULL; - - shouldbe = TEST_DATE; - fail_unless (gst_tag_list_get_date (tags, GST_TAG_DATE, &date)); - fail_unless (g_date_compare (shouldbe, date) == 0); - g_date_free (shouldbe); - g_date_free (date); - } - if (mask & (1 << 4)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_TRACK_NUMBER, TEST_TRACK_NUMBER, NULL); - } - if (mask & (1 << 5)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_TRACK_COUNT, TEST_TRACK_COUNT, NULL); - } - if (mask & (1 << 6)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ALBUM_VOLUME_NUMBER, TEST_VOLUME_NUMBER, NULL); - } - if (mask & (1 << 7)) { - gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, - GST_TAG_ALBUM_VOLUME_COUNT, TEST_VOLUME_COUNT, NULL); - } - if (mask & (1 << 8)) { - } - if (mask & (1 << 9)) { - } - if (mask & (1 << 10)) { - } - if (mask & (1 << 11)) { - } - if (mask & (1 << 12)) { - } - if (mask & (1 << 13)) { - } -} - -static void -fill_mp3_buffer (GstElement * fakesrc, GstBuffer * buf, GstPad * pad, - guint64 * p_offset) -{ - GstCaps *caps; - - g_assert (GST_BUFFER_SIZE (buf) == MP3_FRAME_SIZE); - - GST_LOG ("filling buffer with fake mp3 data, offset = %" G_GUINT64_FORMAT, - *p_offset); - - memcpy (GST_BUFFER_DATA (buf), mp3_dummyhdr, sizeof (mp3_dummyhdr)); - caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, - "layer", G_TYPE_INT, 3, NULL); - gst_buffer_set_caps (buf, caps); - gst_caps_unref (caps); - - GST_BUFFER_OFFSET (buf) = *p_offset; - *p_offset += GST_BUFFER_SIZE (buf); -} - -static void -got_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad, - GstBuffer ** p_buf) -{ - gint64 off; - guint size; - - off = GST_BUFFER_OFFSET (buf); - size = GST_BUFFER_SIZE (buf); - - GST_LOG ("got buffer, size=%u, offset=%" G_GINT64_FORMAT, size, off); - - fail_unless (GST_BUFFER_OFFSET_IS_VALID (buf)); - - if (*p_buf == NULL || (off + size) > GST_BUFFER_SIZE (*p_buf)) { - GstBuffer *newbuf; - - /* not very elegant, but who cares */ - newbuf = gst_buffer_new_and_alloc (off + size); - if (*p_buf) { - memcpy (GST_BUFFER_DATA (newbuf), GST_BUFFER_DATA (*p_buf), - GST_BUFFER_SIZE (*p_buf)); - } - memcpy (GST_BUFFER_DATA (newbuf) + off, GST_BUFFER_DATA (buf), size); - if (*p_buf) - gst_buffer_unref (*p_buf); - *p_buf = newbuf; - } else { - memcpy (GST_BUFFER_DATA (*p_buf) + off, GST_BUFFER_DATA (buf), size); - } -} -static void -demux_pad_added (GstElement * id3demux, GstPad * srcpad, GstBuffer ** p_outbuf) -{ - GstElement *fakesink, *pipeline; - - GST_LOG ("id3demux added source pad with caps %" GST_PTR_FORMAT, - GST_PAD_CAPS (srcpad)); - - pipeline = id3demux; - while (GST_OBJECT_PARENT (pipeline) != NULL) - pipeline = (GstElement *) GST_OBJECT_PARENT (pipeline); - - fakesink = gst_element_factory_make ("fakesink", "fakesink"); - g_assert (fakesink != NULL); - - /* set up sink */ - g_object_set (fakesink, "signal-handoffs", TRUE, NULL); - g_signal_connect (fakesink, "handoff", G_CALLBACK (got_buffer), p_outbuf); - - gst_bin_add (GST_BIN (pipeline), fakesink); - gst_element_set_state (fakesink, GST_STATE_PLAYING); - - fail_unless (gst_element_link (id3demux, fakesink)); -} - -static void -test_taglib_id3mux_check_output_buffer (GstBuffer * buf) -{ - guint8 *data = GST_BUFFER_DATA (buf); - guint size = GST_BUFFER_SIZE (buf); - guint off; - - g_assert (size % MP3_FRAME_SIZE == 0); - - for (off = 0; off < size; off += MP3_FRAME_SIZE) { - fail_unless (memcmp (data + off, mp3_dummyhdr, sizeof (mp3_dummyhdr)) == 0); - } -} - -static void -test_taglib_id3mux_with_tags (GstTagList * tags, guint32 mask) -{ - GstMessage *msg; - GstTagList *tags_read = NULL; - GstElement *pipeline, *id3mux, *id3demux, *fakesrc; - GstBus *bus; - guint64 offset; - GstBuffer *outbuf = NULL; - - pipeline = gst_pipeline_new ("pipeline"); - g_assert (pipeline != NULL); - - fakesrc = gst_element_factory_make ("fakesrc", "fakesrc"); - g_assert (fakesrc != NULL); - - id3mux = gst_element_factory_make ("id3v2mux", "id3v2mux"); - g_assert (id3mux != NULL); - - id3demux = gst_element_factory_make ("id3demux", "id3demux"); - g_assert (id3demux != NULL); - - outbuf = NULL; - g_signal_connect (id3demux, "pad-added", - G_CALLBACK (demux_pad_added), &outbuf); - - gst_bin_add (GST_BIN (pipeline), fakesrc); - gst_bin_add (GST_BIN (pipeline), id3mux); - gst_bin_add (GST_BIN (pipeline), id3demux); - - gst_tag_setter_merge_tags (GST_TAG_SETTER (id3mux), tags, - GST_TAG_MERGE_APPEND); - - gst_element_link_many (fakesrc, id3mux, id3demux, NULL); - - /* set up source */ - g_object_set (fakesrc, "signal-handoffs", TRUE, "can-activate-pull", FALSE, - "filltype", 2, "sizetype", 2, "sizemax", MP3_FRAME_SIZE, - "num-buffers", 16, NULL); - - offset = 0; - g_signal_connect (fakesrc, "handoff", G_CALLBACK (fill_mp3_buffer), &offset); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - fail_unless (gst_element_get_state (pipeline, NULL, NULL, - -1) == GST_STATE_CHANGE_SUCCESS); - - bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); - - GST_LOG ("Waiting for tag ..."); - msg = - gst_bus_poll (bus, GST_MESSAGE_TAG | GST_MESSAGE_EOS | GST_MESSAGE_ERROR, - -1); - if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { - GError *err; - gchar *dbg; - - gst_message_parse_error (msg, &err, &dbg); - g_printerr ("ERROR from element %s: %s\n%s\n", - GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg)); - g_error_free (err); - g_free (dbg); - } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) { - g_printerr ("EOS message, but were waiting for TAGS!\n"); - } - fail_unless (msg->type == GST_MESSAGE_TAG); - - gst_message_parse_tag (msg, &tags_read); - gst_message_unref (msg); - - GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags_read); - test_taglib_id3mux_check_tags (tags_read, mask); - gst_tag_list_free (tags_read); - - GST_LOG ("Waiting for EOS ..."); - msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); - if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { - GError *err; - gchar *dbg; - - gst_message_parse_error (msg, &err, &dbg); - g_printerr ("ERROR from element %s: %s\n%s\n", - GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg)); - g_error_free (err); - g_free (dbg); - } - fail_unless (msg->type == GST_MESSAGE_EOS); - gst_message_unref (msg); - - gst_object_unref (bus); - - GST_LOG ("Got EOS, shutting down ..."); - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (pipeline); - - test_taglib_id3mux_check_output_buffer (outbuf); - gst_buffer_unref (outbuf); - - GST_LOG ("Done"); -} - -GST_START_TEST (test_id3v2mux) -{ - GstTagList *tags; - gint i; - - g_random_set_seed (247166295); - - /* internal consistency check */ - tags = test_taglib_id3mux_create_tags (0xFFFFFFFF); - test_taglib_id3mux_check_tags (tags, 0xFFFFFFFF); - gst_tag_list_free (tags); - - /* now the real tests */ - for (i = 0; i < 50; ++i) { - guint32 mask; - - mask = g_random_int (); - GST_LOG ("tag mask = %08x (i=%d)", mask, i); - - if (mask == 0) - continue; - - /* create tags */ - tags = test_taglib_id3mux_create_tags (mask); - GST_LOG ("tags for mask %08x = %" GST_PTR_FORMAT, mask, tags); - - /* double-check for internal consistency */ - test_taglib_id3mux_check_tags (tags, mask); - - /* test with pipeline */ - test_taglib_id3mux_with_tags (tags, mask); - - /* free tags */ - gst_tag_list_free (tags); - } -} - -GST_END_TEST; - -static Suite * -tagid3v2mux_suite (void) -{ - Suite *s = suite_create ("tagid3v2mux"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_id3v2mux); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = tagid3v2mux_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} |